From webhook-mailer at python.org Sat Feb 1 06:08:39 2020 From: webhook-mailer at python.org (Brandt Bucher) Date: Sat, 01 Feb 2020 11:08:39 -0000 Subject: [Python-checkins] Update sum comment. (#18240) Message-ID: https://github.com/python/cpython/commit/abb9a448dee3e18c69080231fbeba980bf048211 commit: abb9a448dee3e18c69080231fbeba980bf048211 branch: master author: Brandt Bucher committer: GitHub date: 2020-02-01T11:08:34Z summary: Update sum comment. (#18240) files: M Python/bltinmodule.c diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 4f833c1f46253..5818eb9e38f6a 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2440,7 +2440,11 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) empty = [] sum([[x] for x in range(10)], empty) - would change the value of empty. */ + would change the value of empty. In fact, using + in-place addition rather that binary addition for + any of the steps introduces subtle behavior changes: + + https://bugs.python.org/issue18305 */ temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); From webhook-mailer at python.org Sat Feb 1 06:12:56 2020 From: webhook-mailer at python.org (Andrew Svetlov) Date: Sat, 01 Feb 2020 11:12:56 -0000 Subject: [Python-checkins] bpo-34793: Drop old-style context managers in asyncio.locks (GH-17533) Message-ID: https://github.com/python/cpython/commit/90d9ba6ef10af32e8dfe0649789c3a8ccf419e95 commit: 90d9ba6ef10af32e8dfe0649789c3a8ccf419e95 branch: master author: Andrew Svetlov committer: GitHub date: 2020-02-01T13:12:52+02:00 summary: bpo-34793: Drop old-style context managers in asyncio.locks (GH-17533) files: A Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst M Doc/library/asyncio-sync.rst M Doc/whatsnew/3.9.rst M Lib/asyncio/locks.py M Lib/test/test_asyncio/test_locks.py M Lib/test/test_asyncio/test_pep492.py diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index f080b03bc7c51..84a52cb2d5757 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -347,8 +347,8 @@ BoundedSemaphore --------- -.. deprecated:: 3.7 +.. versionchanged:: 3.9 Acquiring a lock using ``await lock`` or ``yield from lock`` and/or :keyword:`with` statement (``with await lock``, ``with (yield from - lock)``) is deprecated. Use ``async with lock`` instead. + lock)``) was removed. Use ``async with lock`` instead. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index c8f407751ec5e..ee37b5a5b7265 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -470,6 +470,11 @@ Removed :exc:`DeprecationWarning` since Python 3.8. (Contributed by Inada Naoki in :issue:`39377`) +* ``with (await asyncio.lock):`` and ``with (yield from asyncio.lock):`` statements are + not longer supported, use ``async with lock`` instead. The same is correct for + ``asyncio.Condition`` and ``asyncio.Semaphore``. + (Contributed by Andrew Svetlov in :issue:`34793`.) + Porting to Python 3.9 ===================== diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index d94daeb5a173f..f1ce7324785ba 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -3,96 +3,13 @@ __all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore') import collections -import types import warnings from . import events -from . import futures from . import exceptions -from .import coroutines - - -class _ContextManager: - """Context manager. - - This enables the following idiom for acquiring and releasing a - lock around a block: - - with (yield from lock): - - - while failing loudly when accidentally using: - - with lock: - - - Deprecated, use 'async with' statement: - async with lock: - - """ - - def __init__(self, lock): - self._lock = lock - - def __enter__(self): - # We have no use for the "as ..." clause in the with - # statement for locks. - return None - - def __exit__(self, *args): - try: - self._lock.release() - finally: - self._lock = None # Crudely prevent reuse. class _ContextManagerMixin: - def __enter__(self): - raise RuntimeError( - '"yield from" should be used as context manager expression') - - def __exit__(self, *args): - # This must exist because __enter__ exists, even though that - # always raises; that's how the with-statement works. - pass - - @types.coroutine - def __iter__(self): - # This is not a coroutine. It is meant to enable the idiom: - # - # with (yield from lock): - # - # - # as an alternative to: - # - # yield from lock.acquire() - # try: - # - # finally: - # lock.release() - # Deprecated, use 'async with' statement: - # async with lock: - # - warnings.warn("'with (yield from lock)' is deprecated " - "use 'async with lock' instead", - DeprecationWarning, stacklevel=2) - yield from self.acquire() - return _ContextManager(self) - - # The flag is needed for legacy asyncio.iscoroutine() - __iter__._is_coroutine = coroutines._is_coroutine - - async def __acquire_ctx(self): - await self.acquire() - return _ContextManager(self) - - def __await__(self): - warnings.warn("'with await lock' is deprecated " - "use 'async with lock' instead", - DeprecationWarning, stacklevel=2) - # To make "with await lock" work. - return self.__acquire_ctx().__await__() - async def __aenter__(self): await self.acquire() # We have no use for the "as ..." clause in the with diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 9468e740b3c1d..8c93fae2b51c6 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -47,13 +47,7 @@ def test_repr(self): self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - with self.assertWarns(DeprecationWarning): - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - yield from lock - - self.loop.run_until_complete(acquire_lock()) + self.loop.run_until_complete(lock.acquire()) self.assertTrue(repr(lock).endswith('[locked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) @@ -61,18 +55,16 @@ def test_lock(self): with self.assertWarns(DeprecationWarning): lock = asyncio.Lock(loop=self.loop) - @asyncio.coroutine def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) - - res = self.loop.run_until_complete(acquire_lock()) + return (yield from lock) - self.assertTrue(res) - self.assertTrue(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "object is not iterable" + ): + self.loop.run_until_complete(acquire_lock()) - lock.release() self.assertFalse(lock.locked()) def test_lock_by_with_statement(self): @@ -90,13 +82,13 @@ def test_lock_by_with_statement(self): def test(lock): yield from asyncio.sleep(0.01) self.assertFalse(lock.locked()) - with self.assertWarns(DeprecationWarning): - with (yield from lock) as _lock: - self.assertIs(_lock, None) - self.assertTrue(lock.locked()) - yield from asyncio.sleep(0.01) - self.assertTrue(lock.locked()) - self.assertFalse(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "object is not iterable" + ): + with (yield from lock): + pass + self.assertFalse(lock.locked()) for primitive in primitives: loop.run_until_complete(test(primitive)) @@ -302,52 +294,16 @@ def test_release_no_waiters(self): self.assertFalse(lock.locked()) def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) + async def f(): + lock = asyncio.Lock() + self.assertFalse(lock.locked()) - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) + async with lock: + self.assertTrue(lock.locked()) - with self.loop.run_until_complete(acquire_lock()): - self.assertTrue(lock.locked()) + self.assertFalse(lock.locked()) - self.assertFalse(lock.locked()) - - def test_context_manager_cant_reuse(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) - - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) - - # This spells "yield from lock" outside a generator. - cm = self.loop.run_until_complete(acquire_lock()) - with cm: - self.assertTrue(lock.locked()) - - self.assertFalse(lock.locked()) - - with self.assertRaises(AttributeError): - with cm: - pass - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) - - try: - with lock: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') - - self.assertFalse(lock.locked()) + self.loop.run_until_complete(f()) class EventTests(test_utils.TestCase): @@ -809,33 +765,14 @@ def test_repr(self): self.assertTrue(RGX_REPR.match(repr(cond))) def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - cond = asyncio.Condition(loop=self.loop) - - with self.assertWarns(DeprecationWarning): - @asyncio.coroutine - def acquire_cond(): - with self.assertWarns(DeprecationWarning): - return (yield from cond) - - with self.loop.run_until_complete(acquire_cond()): - self.assertTrue(cond.locked()) - - self.assertFalse(cond.locked()) - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - cond = asyncio.Condition(loop=self.loop) - - try: - with cond: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') + async def f(): + cond = asyncio.Condition() + self.assertFalse(cond.locked()) + async with cond: + self.assertTrue(cond.locked()) + self.assertFalse(cond.locked()) - self.assertFalse(cond.locked()) + self.loop.run_until_complete(f()) def test_explicit_lock(self): with self.assertWarns(DeprecationWarning): @@ -920,16 +857,14 @@ def test_semaphore(self): with self.assertWarns(DeprecationWarning): @asyncio.coroutine def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from sem) + return (yield from sem) - res = self.loop.run_until_complete(acquire_lock()) - - self.assertTrue(res) - self.assertTrue(sem.locked()) - self.assertEqual(0, sem._value) + with self.assertRaisesRegex( + TypeError, + "'Semaphore' object is not iterable", + ): + self.loop.run_until_complete(acquire_lock()) - sem.release() self.assertFalse(sem.locked()) self.assertEqual(1, sem._value) @@ -1064,38 +999,6 @@ def test_release_no_waiters(self): sem.release() self.assertFalse(sem.locked()) - def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - sem = asyncio.Semaphore(2, loop=self.loop) - - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from sem) - - with self.loop.run_until_complete(acquire_lock()): - self.assertFalse(sem.locked()) - self.assertEqual(1, sem._value) - - with self.loop.run_until_complete(acquire_lock()): - self.assertTrue(sem.locked()) - - self.assertEqual(2, sem._value) - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - sem = asyncio.Semaphore(2, loop=self.loop) - - try: - with sem: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') - - self.assertEqual(2, sem._value) - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py index a1f27dd5721c8..c5e3a5c148357 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -77,13 +77,12 @@ def test_context_manager_with_await(self): async def test(lock): await asyncio.sleep(0.01) self.assertFalse(lock.locked()) - with self.assertWarns(DeprecationWarning): - with await lock as _lock: - self.assertIs(_lock, None) - self.assertTrue(lock.locked()) - await asyncio.sleep(0.01) - self.assertTrue(lock.locked()) - self.assertFalse(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "can't be used in 'await' expression" + ): + with await lock: + pass for primitive in primitives: self.loop.run_until_complete(test(primitive)) diff --git a/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst b/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst new file mode 100644 index 0000000000000..2089285ecdb7f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst @@ -0,0 +1,3 @@ +Remove support for ``with (await asyncio.lock):`` and ``with (yield from +asyncio.lock):``. The same is correct for ``asyncio.Condition`` and +``asyncio.Semaphore``. From webhook-mailer at python.org Sat Feb 1 07:31:22 2020 From: webhook-mailer at python.org (James Corbett) Date: Sat, 01 Feb 2020 12:31:22 -0000 Subject: [Python-checkins] fixes typos in http.client documentation (#18300) Message-ID: https://github.com/python/cpython/commit/b94737a4af96b29bd4c025724f671e7bc0f6b6f1 commit: b94737a4af96b29bd4c025724f671e7bc0f6b6f1 branch: master author: James Corbett committer: GitHub date: 2020-02-01T04:31:00-08:00 summary: fixes typos in http.client documentation (#18300) files: M Doc/library/http.client.rst diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 807dd8bd379a0..35997db2a9d27 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -586,8 +586,8 @@ Here is an example session that shows how to ``POST`` requests:: Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The difference lies only the server side where HTTP server will allow resources to be created via ``PUT`` request. It should be noted that custom HTTP methods -+are also handled in :class:`urllib.request.Request` by sending the appropriate -+method attribute.Here is an example session that shows how to do ``PUT`` +are also handled in :class:`urllib.request.Request` by setting the appropriate +method attribute. Here is an example session that shows how to send a ``PUT`` request using http.client:: >>> # This creates an HTTP message From webhook-mailer at python.org Sat Feb 1 15:45:48 2020 From: webhook-mailer at python.org (Alex Henrie) Date: Sat, 01 Feb 2020 20:45:48 -0000 Subject: [Python-checkins] bpo-39496: Remove redundant checks from _sqlite/cursor.c (GH-18270) Message-ID: https://github.com/python/cpython/commit/78c7183f470b60a39ac2dd0ad1a94d49d1e0b062 commit: 78c7183f470b60a39ac2dd0ad1a94d49d1e0b062 branch: master author: Alex Henrie committer: GitHub date: 2020-02-01T23:45:34+03:00 summary: bpo-39496: Remove redundant checks from _sqlite/cursor.c (GH-18270) files: M Modules/_sqlite/cursor.c diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 2302ca9edac2d..06275ecb26849 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -786,17 +786,9 @@ PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObj return NULL; } - /* just make sure we enter the loop */ - row = Py_None; - - while (row) { - row = pysqlite_cursor_iternext(self); - if (row) { - PyList_Append(list, row); - Py_DECREF(row); - } else { - break; - } + while ((row = pysqlite_cursor_iternext(self))) { + PyList_Append(list, row); + Py_XDECREF(row); if (++counter == maxrows) { break; @@ -821,15 +813,9 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) return NULL; } - /* just make sure we enter the loop */ - row = (PyObject*)Py_None; - - while (row) { - row = pysqlite_cursor_iternext(self); - if (row) { - PyList_Append(list, row); - Py_DECREF(row); - } + while ((row = pysqlite_cursor_iternext(self))) { + PyList_Append(list, row); + Py_XDECREF(row); } if (PyErr_Occurred()) { From webhook-mailer at python.org Sun Feb 2 06:37:20 2020 From: webhook-mailer at python.org (Mark Dickinson) Date: Sun, 02 Feb 2020 11:37:20 -0000 Subject: [Python-checkins] Fix 5-space indentation and trailing whitespace (GH-18311) Message-ID: https://github.com/python/cpython/commit/be8147bdc6111a225ec284a4514277304726c3d0 commit: be8147bdc6111a225ec284a4514277304726c3d0 branch: master author: Mark Dickinson committer: GitHub date: 2020-02-02T11:37:02Z summary: Fix 5-space indentation and trailing whitespace (GH-18311) files: M Objects/floatobject.c diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 89f60b65cd55c..ab486d4ee3d2e 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -641,7 +641,7 @@ _float_div_mod(double vx, double wx, double *floordiv, double *mod) *floordiv = floor(div); if (div - *floordiv > 0.5) { *floordiv += 1.0; - } + } } else { /* div is zero - get the same sign as the true quotient */ @@ -652,16 +652,16 @@ _float_div_mod(double vx, double wx, double *floordiv, double *mod) static PyObject * float_divmod(PyObject *v, PyObject *w) { - double vx, wx; - double mod, floordiv; - CONVERT_TO_DOUBLE(v, vx); - CONVERT_TO_DOUBLE(w, wx); - if (wx == 0.0) { - PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); - return NULL; - } - _float_div_mod(vx, wx, &floordiv, &mod); - return Py_BuildValue("(dd)", floordiv, mod); + double vx, wx; + double mod, floordiv; + CONVERT_TO_DOUBLE(v, vx); + CONVERT_TO_DOUBLE(w, wx); + if (wx == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); + return NULL; + } + _float_div_mod(vx, wx, &floordiv, &mod); + return Py_BuildValue("(dd)", floordiv, mod); } static PyObject * From webhook-mailer at python.org Sun Feb 2 07:49:05 2020 From: webhook-mailer at python.org (Kyle Stanley) Date: Sun, 02 Feb 2020 12:49:05 -0000 Subject: [Python-checkins] bpo-39349: Add *cancel_futures* to Executor.shutdown() (GH-18057) Message-ID: https://github.com/python/cpython/commit/339fd46cb764277cbbdc3e78dcc5b45b156bb6ae commit: 339fd46cb764277cbbdc3e78dcc5b45b156bb6ae branch: master author: Kyle Stanley committer: GitHub date: 2020-02-02T13:49:00+01:00 summary: bpo-39349: Add *cancel_futures* to Executor.shutdown() (GH-18057) files: A Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst M Doc/library/concurrent.futures.rst M Doc/whatsnew/3.9.rst M Lib/concurrent/futures/process.py M Lib/concurrent/futures/thread.py M Lib/test/test_concurrent_futures.py diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index d71f2d80c9e2d..b21d5594c84fa 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -67,7 +67,7 @@ Executor Objects .. versionchanged:: 3.5 Added the *chunksize* argument. - .. method:: shutdown(wait=True) + .. method:: shutdown(wait=True, \*, cancel_futures=False) Signal the executor that it should free any resources that it is using when the currently pending futures are done executing. Calls to @@ -82,6 +82,15 @@ Executor Objects value of *wait*, the entire Python program will not exit until all pending futures are done executing. + If *cancel_futures* is ``True``, this method will cancel all pending + futures that the executor has not started running. Any futures that + are completed or running won't be cancelled, regardless of the value + of *cancel_futures*. + + If both *cancel_futures* and *wait* are ``True``, all futures that the + executor has started running will be completed prior to this method + returning. The remaining futures are cancelled. + You can avoid having to call this method explicitly if you use the :keyword:`with` statement, which will shutdown the :class:`Executor` (waiting as if :meth:`Executor.shutdown` were called with *wait* set to @@ -94,6 +103,9 @@ Executor Objects e.submit(shutil.copy, 'src3.txt', 'dest3.txt') e.submit(shutil.copy, 'src4.txt', 'dest4.txt') + .. versionchanged:: 3.9 + Added *cancel_futures*. + ThreadPoolExecutor ------------------ diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ee37b5a5b7265..931f8bf13fbde 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -146,6 +146,15 @@ that schedules a shutdown for the default executor that waits on the Added :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher implementation that polls process file descriptors. (:issue:`38692`) +concurrent.futures +------------------ + +Added a new *cancel_futures* parameter to +:meth:`concurrent.futures.Executor.shutdown` that cancels all pending futures +which have not started running, instead of waiting for them to complete before +shutting down the executor. +(Contributed by Kyle Stanley in :issue:`39349`.) + curses ------ diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 9e2ab9db64f66..fd9f572b6c711 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -435,6 +435,24 @@ def shutdown_worker(): # is not gc-ed yet. if executor is not None: executor._shutdown_thread = True + # Unless there are pending work items, we have nothing to cancel. + if pending_work_items and executor._cancel_pending_futures: + # Cancel all pending futures and update pending_work_items + # to only have futures that are currently running. + new_pending_work_items = {} + for work_id, work_item in pending_work_items.items(): + if not work_item.future.cancel(): + new_pending_work_items[work_id] = work_item + + pending_work_items = new_pending_work_items + # Drain work_ids_queue since we no longer need to + # add items to the call queue. + while True: + try: + work_ids_queue.get_nowait() + except queue.Empty: + break + # Since no new work items can be added, it is safe to shutdown # this thread if there are no pending work items. if not pending_work_items: @@ -546,6 +564,7 @@ def __init__(self, max_workers=None, mp_context=None, self._broken = False self._queue_count = 0 self._pending_work_items = {} + self._cancel_pending_futures = False # Create communication channels for the executor # Make the call queue slightly larger than the number of processes to @@ -660,9 +679,11 @@ def map(self, fn, *iterables, timeout=None, chunksize=1): timeout=timeout) return _chain_from_iterable_of_lists(results) - def shutdown(self, wait=True): + def shutdown(self, wait=True, *, cancel_futures=False): with self._shutdown_lock: + self._cancel_pending_futures = cancel_futures self._shutdown_thread = True + if self._queue_management_thread: # Wake up queue management thread self._queue_management_thread_wakeup.wakeup() diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index b89f8f24d4d67..be79161bf8561 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -215,9 +215,22 @@ def _initializer_failed(self): if work_item is not None: work_item.future.set_exception(BrokenThreadPool(self._broken)) - def shutdown(self, wait=True): + def shutdown(self, wait=True, *, cancel_futures=False): with self._shutdown_lock: self._shutdown = True + if cancel_futures: + # Drain all work items from the queue, and then cancel their + # associated futures. + while True: + try: + work_item = self._work_queue.get_nowait() + except queue.Empty: + break + if work_item is not None: + work_item.future.cancel() + + # Send a wake-up to prevent threads calling + # _work_queue.get(block=True) from permanently blocking. self._work_queue.put(None) if wait: for t in self._threads: diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index c8fa35e9eeafa..af77f81341910 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -342,6 +342,29 @@ def test_hang_issue12364(self): for f in fs: f.result() + def test_cancel_futures(self): + executor = self.executor_type(max_workers=3) + fs = [executor.submit(time.sleep, .1) for _ in range(50)] + executor.shutdown(cancel_futures=True) + # We can't guarantee the exact number of cancellations, but we can + # guarantee that *some* were cancelled. With setting max_workers to 3, + # most of the submitted futures should have been cancelled. + cancelled = [fut for fut in fs if fut.cancelled()] + self.assertTrue(len(cancelled) >= 35, msg=f"{len(cancelled)=}") + + # Ensure the other futures were able to finish. + # Use "not fut.cancelled()" instead of "fut.done()" to include futures + # that may have been left in a pending state. + others = [fut for fut in fs if not fut.cancelled()] + for fut in others: + self.assertTrue(fut.done(), msg=f"{fut._state=}") + self.assertIsNone(fut.exception()) + + # Similar to the number of cancelled futures, we can't guarantee the + # exact number that completed. But, we can guarantee that at least + # one finished. + self.assertTrue(len(others) > 0, msg=f"{len(others)=}") + def test_hang_issue39205(self): """shutdown(wait=False) doesn't hang at exit with running futures. @@ -422,6 +445,22 @@ def test_thread_names_default(self): self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') t.join() + def test_cancel_futures_wait_false(self): + # Can only be reliably tested for TPE, since PPE often hangs with + # `wait=False` (even without *cancel_futures*). + rc, out, err = assert_python_ok('-c', """if True: + from concurrent.futures import ThreadPoolExecutor + from test.test_concurrent_futures import sleep_and_print + if __name__ == "__main__": + t = ThreadPoolExecutor() + t.submit(sleep_and_print, .1, "apple") + t.shutdown(wait=False, cancel_futures=True) + """.format(executor_type=self.executor_type.__name__)) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + class ProcessPoolShutdownTest(ExecutorShutdownTest): def _prime_executor(self): diff --git a/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst b/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst new file mode 100644 index 0000000000000..cc52700f67031 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst @@ -0,0 +1,4 @@ +Added a new *cancel_futures* parameter to +:meth:`concurrent.futures.Executor.shutdown` that cancels all pending futures +which have not started running, instead of waiting for them to complete before +shutting down the executor. \ No newline at end of file From webhook-mailer at python.org Sun Feb 2 13:55:26 2020 From: webhook-mailer at python.org (Pierre Glaser) Date: Sun, 02 Feb 2020 18:55:26 -0000 Subject: [Python-checkins] bpo-39492: Fix a reference cycle between reducer_override and a Pickler instance (GH-18266) Message-ID: https://github.com/python/cpython/commit/0f2f35e15f9fbee44ce042b724348419d8136bc5 commit: 0f2f35e15f9fbee44ce042b724348419d8136bc5 branch: master author: Pierre Glaser committer: GitHub date: 2020-02-02T10:55:21-08:00 summary: bpo-39492: Fix a reference cycle between reducer_override and a Pickler instance (GH-18266) This also needs a backport to 3.8 https://bugs.python.org/issue39492 Automerge-Triggered-By: @pitrou files: A Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst M Lib/test/pickletester.py M Modules/_pickle.c diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 953fd5c5a278b..ba893f39c2f34 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3499,6 +3499,30 @@ class MyClass: ValueError, 'The reducer just failed'): p.dump(h) + @support.cpython_only + def test_reducer_override_no_reference_cycle(self): + # bpo-39492: reducer_override used to induce a spurious reference cycle + # inside the Pickler object, that could prevent all serialized objects + # from being garbage-collected without explicity invoking gc.collect. + + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + def f(): + pass + + wr = weakref.ref(f) + + bio = io.BytesIO() + p = self.pickler_class(bio, proto) + p.dump(f) + new_f = pickle.loads(bio.getvalue()) + assert new_f == 5 + + del p + del f + + self.assertIsNone(wr()) + class AbstractDispatchTableTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst new file mode 100644 index 0000000000000..6e8b715c46365 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst @@ -0,0 +1 @@ +Fix a reference cycle in the C Pickler that was preventing the garbage collection of deleted, pickled objects. \ No newline at end of file diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 25d5c8da92068..fc48d6057866a 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4455,12 +4455,13 @@ static int dump(PicklerObject *self, PyObject *obj) { const char stop_op = STOP; + int status = -1; PyObject *tmp; _Py_IDENTIFIER(reducer_override); if (_PyObject_LookupAttrId((PyObject *)self, &PyId_reducer_override, &tmp) < 0) { - return -1; + goto error; } /* Cache the reducer_override method, if it exists. */ if (tmp != NULL) { @@ -4477,7 +4478,7 @@ dump(PicklerObject *self, PyObject *obj) assert(self->proto >= 0 && self->proto < 256); header[1] = (unsigned char)self->proto; if (_Pickler_Write(self, header, 2) < 0) - return -1; + goto error; if (self->proto >= 4) self->framing = 1; } @@ -4485,9 +4486,22 @@ dump(PicklerObject *self, PyObject *obj) if (save(self, obj, 0) < 0 || _Pickler_Write(self, &stop_op, 1) < 0 || _Pickler_CommitFrame(self) < 0) - return -1; + goto error; + + // Success + status = 0; + + error: self->framing = 0; - return 0; + + /* Break the reference cycle we generated at the beginning this function + * call when setting the reducer_override attribute of the Pickler instance + * to a bound method of the same instance. This is important as the Pickler + * instance holds a reference to each object it has pickled (through its + * memo): thus, these objects wont be garbage-collected as long as the + * Pickler itself is not collected. */ + Py_CLEAR(self->reducer_override); + return status; } /*[clinic input] From webhook-mailer at python.org Sun Feb 2 15:23:05 2020 From: webhook-mailer at python.org (Antoine Pitrou) Date: Sun, 02 Feb 2020 20:23:05 -0000 Subject: [Python-checkins] [3.8] bpo-39492: Fix a reference cycle between reducer_override and a Pickler instance (GH-18266) (#18316) Message-ID: https://github.com/python/cpython/commit/17236873392533ce0c5d7bbf52cbd61bca171c59 commit: 17236873392533ce0c5d7bbf52cbd61bca171c59 branch: 3.8 author: Antoine Pitrou committer: GitHub date: 2020-02-02T21:22:57+01:00 summary: [3.8] bpo-39492: Fix a reference cycle between reducer_override and a Pickler instance (GH-18266) (#18316) https://bugs.python.org/issue39492 Automerge-Triggered-By: @pitrou (cherry picked from commit 0f2f35e) Co-authored-by: Pierre Glaser files: A Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst M Lib/test/pickletester.py M Modules/_pickle.c diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index c9f374678ae35..3a8aee4320c65 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3497,6 +3497,30 @@ class MyClass: ValueError, 'The reducer just failed'): p.dump(h) + @support.cpython_only + def test_reducer_override_no_reference_cycle(self): + # bpo-39492: reducer_override used to induce a spurious reference cycle + # inside the Pickler object, that could prevent all serialized objects + # from being garbage-collected without explicity invoking gc.collect. + + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + def f(): + pass + + wr = weakref.ref(f) + + bio = io.BytesIO() + p = self.pickler_class(bio, proto) + p.dump(f) + new_f = pickle.loads(bio.getvalue()) + assert new_f == 5 + + del p + del f + + self.assertIsNone(wr()) + class AbstractDispatchTableTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst new file mode 100644 index 0000000000000..6e8b715c46365 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst @@ -0,0 +1 @@ +Fix a reference cycle in the C Pickler that was preventing the garbage collection of deleted, pickled objects. \ No newline at end of file diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 8150bf3b33dc3..9f6e66f70a546 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4457,12 +4457,13 @@ static int dump(PicklerObject *self, PyObject *obj) { const char stop_op = STOP; + int status = -1; PyObject *tmp; _Py_IDENTIFIER(reducer_override); if (_PyObject_LookupAttrId((PyObject *)self, &PyId_reducer_override, &tmp) < 0) { - return -1; + goto error; } /* Cache the reducer_override method, if it exists. */ if (tmp != NULL) { @@ -4479,7 +4480,7 @@ dump(PicklerObject *self, PyObject *obj) assert(self->proto >= 0 && self->proto < 256); header[1] = (unsigned char)self->proto; if (_Pickler_Write(self, header, 2) < 0) - return -1; + goto error; if (self->proto >= 4) self->framing = 1; } @@ -4487,9 +4488,22 @@ dump(PicklerObject *self, PyObject *obj) if (save(self, obj, 0) < 0 || _Pickler_Write(self, &stop_op, 1) < 0 || _Pickler_CommitFrame(self) < 0) - return -1; + goto error; + + // Success + status = 0; + + error: self->framing = 0; - return 0; + + /* Break the reference cycle we generated at the beginning this function + * call when setting the reducer_override attribute of the Pickler instance + * to a bound method of the same instance. This is important as the Pickler + * instance holds a reference to each object it has pickled (through its + * memo): thus, these objects wont be garbage-collected as long as the + * Pickler itself is not collected. */ + Py_CLEAR(self->reducer_override); + return status; } /*[clinic input] From webhook-mailer at python.org Mon Feb 3 02:06:58 2020 From: webhook-mailer at python.org (Steve Cirelli) Date: Mon, 03 Feb 2020 07:06:58 -0000 Subject: [Python-checkins] bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18175) Message-ID: https://github.com/python/cpython/commit/032de7324e30c6b44ef272cea3be205a3d768759 commit: 032de7324e30c6b44ef272cea3be205a3d768759 branch: master author: Steve Cirelli committer: GitHub date: 2020-02-03T07:06:50Z summary: bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18175) files: A Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst M Lib/unittest/case.py M Lib/unittest/test/test_case.py diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index fa64a6ea2378c..5e5d535dc6938 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -512,7 +512,7 @@ def shortDescription(self): the specified test method's docstring. """ doc = self._testMethodDoc - return doc and doc.split("\n")[0].strip() or None + return doc.strip().split("\n")[0].strip() if doc else None def id(self): diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index c2401c39b917e..f855c4dc00b31 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -610,6 +610,15 @@ def testShortDescriptionWithMultiLineDocstring(self): 'Tests shortDescription() for a method with a longer ' 'docstring.') + def testShortDescriptionWhitespaceTrimming(self): + """ + Tests shortDescription() whitespace is trimmed, so that the first + line of nonwhite-space text becomes the docstring. + """ + self.assertEqual( + self.shortDescription(), + 'Tests shortDescription() whitespace is trimmed, so that the first') + def testAddTypeEqualityFunc(self): class SadSnake(object): """Dummy class for test_addTypeEqualityFunc.""" diff --git a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst new file mode 100644 index 0000000000000..55fed519a2d80 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst @@ -0,0 +1,2 @@ +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. From webhook-mailer at python.org Mon Feb 3 02:25:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 03 Feb 2020 07:25:24 -0000 Subject: [Python-checkins] bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18321) Message-ID: https://github.com/python/cpython/commit/7561e7a83ccccf5118fda6c62fe9c8c3458f8cfd commit: 7561e7a83ccccf5118fda6c62fe9c8c3458f8cfd branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T07:25:17Z summary: bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18321) (cherry picked from commit 032de7324e30c6b44ef272cea3be205a3d768759) Co-authored-by: Steve Cirelli files: A Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst M Lib/unittest/case.py M Lib/unittest/test/test_case.py diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 811f5df23dd14..24af29057646a 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -493,7 +493,7 @@ def shortDescription(self): the specified test method's docstring. """ doc = self._testMethodDoc - return doc and doc.split("\n")[0].strip() or None + return doc.strip().split("\n")[0].strip() if doc else None def id(self): diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index 6d58201ea8143..4fac8d5974528 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -610,6 +610,15 @@ def testShortDescriptionWithMultiLineDocstring(self): 'Tests shortDescription() for a method with a longer ' 'docstring.') + def testShortDescriptionWhitespaceTrimming(self): + """ + Tests shortDescription() whitespace is trimmed, so that the first + line of nonwhite-space text becomes the docstring. + """ + self.assertEqual( + self.shortDescription(), + 'Tests shortDescription() whitespace is trimmed, so that the first') + def testAddTypeEqualityFunc(self): class SadSnake(object): """Dummy class for test_addTypeEqualityFunc.""" diff --git a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst new file mode 100644 index 0000000000000..55fed519a2d80 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst @@ -0,0 +1,2 @@ +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. From webhook-mailer at python.org Mon Feb 3 03:20:49 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 03 Feb 2020 08:20:49 -0000 Subject: [Python-checkins] bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18175) (#18323) Message-ID: https://github.com/python/cpython/commit/02395fad8e3a35ef00fa31c308693844013a1dd4 commit: 02395fad8e3a35ef00fa31c308693844013a1dd4 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T08:20:41Z summary: bpo-39450 Stripped whitespace before parsing the docstring in TestCase.shortDescription (GH-18175) (#18323) (cherry picked from commit 032de7324e30c6b44ef272cea3be205a3d768759) Co-authored-by: Steve Cirelli files: A Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst M Lib/unittest/case.py M Lib/unittest/test/test_case.py diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index b639c64d02a7a..e5734b6b7a298 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -529,7 +529,7 @@ def shortDescription(self): the specified test method's docstring. """ doc = self._testMethodDoc - return doc and doc.split("\n")[0].strip() or None + return doc.strip().split("\n")[0].strip() if doc else None def id(self): diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index c2401c39b917e..f855c4dc00b31 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -610,6 +610,15 @@ def testShortDescriptionWithMultiLineDocstring(self): 'Tests shortDescription() for a method with a longer ' 'docstring.') + def testShortDescriptionWhitespaceTrimming(self): + """ + Tests shortDescription() whitespace is trimmed, so that the first + line of nonwhite-space text becomes the docstring. + """ + self.assertEqual( + self.shortDescription(), + 'Tests shortDescription() whitespace is trimmed, so that the first') + def testAddTypeEqualityFunc(self): class SadSnake(object): """Dummy class for test_addTypeEqualityFunc.""" diff --git a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst new file mode 100644 index 0000000000000..55fed519a2d80 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst @@ -0,0 +1,2 @@ +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. From webhook-mailer at python.org Mon Feb 3 05:03:43 2020 From: webhook-mailer at python.org (Inada Naoki) Date: Mon, 03 Feb 2020 10:03:43 -0000 Subject: [Python-checkins] bpo-36051: Fix compiler warning. (GH-18325) Message-ID: https://github.com/python/cpython/commit/869c0c99b94ff9527acc1ca060164ab3d1bdcc53 commit: 869c0c99b94ff9527acc1ca060164ab3d1bdcc53 branch: master author: Inada Naoki committer: GitHub date: 2020-02-03T19:03:34+09:00 summary: bpo-36051: Fix compiler warning. (GH-18325) files: M Objects/stringlib/join.h diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h index 4d023ed1a851e..8ad598ad5c9fd 100644 --- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -20,7 +20,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) Py_buffer static_buffers[NB_STATIC_BUFFERS]; #define GIL_THRESHOLD 1048576 int drop_gil = 1; - PyThreadState *save; + PyThreadState *save = NULL; seq = PySequence_Fast(iterable, "can only join an iterable"); if (seq == NULL) { From webhook-mailer at python.org Mon Feb 3 07:07:42 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 03 Feb 2020 12:07:42 -0000 Subject: [Python-checkins] fixes typos in http.client documentation (GH-18300) Message-ID: https://github.com/python/cpython/commit/db2f3114b2be4f3ee81a3258a979327d539ab51a commit: db2f3114b2be4f3ee81a3258a979327d539ab51a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T04:07:19-08:00 summary: fixes typos in http.client documentation (GH-18300) (cherry picked from commit b94737a4af96b29bd4c025724f671e7bc0f6b6f1) Co-authored-by: James Corbett files: M Doc/library/http.client.rst diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 9cdabc2a03a75..be31c3c07154f 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -563,8 +563,8 @@ Here is an example session that shows how to ``POST`` requests:: Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The difference lies only the server side where HTTP server will allow resources to be created via ``PUT`` request. It should be noted that custom HTTP methods -+are also handled in :class:`urllib.request.Request` by sending the appropriate -+method attribute.Here is an example session that shows how to do ``PUT`` +are also handled in :class:`urllib.request.Request` by setting the appropriate +method attribute. Here is an example session that shows how to send a ``PUT`` request using http.client:: >>> # This creates an HTTP message From webhook-mailer at python.org Mon Feb 3 07:07:46 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 03 Feb 2020 12:07:46 -0000 Subject: [Python-checkins] fixes typos in http.client documentation (GH-18300) Message-ID: https://github.com/python/cpython/commit/4c71c8307347948e7386c3d408a5fbf44dacce92 commit: 4c71c8307347948e7386c3d408a5fbf44dacce92 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T04:07:41-08:00 summary: fixes typos in http.client documentation (GH-18300) (cherry picked from commit b94737a4af96b29bd4c025724f671e7bc0f6b6f1) Co-authored-by: James Corbett files: M Doc/library/http.client.rst diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index d7757d07a4ba4..9a0e86b974f6d 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -547,8 +547,8 @@ Here is an example session that shows how to ``POST`` requests:: Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The difference lies only the server side where HTTP server will allow resources to be created via ``PUT`` request. It should be noted that custom HTTP methods -+are also handled in :class:`urllib.request.Request` by sending the appropriate -+method attribute.Here is an example session that shows how to do ``PUT`` +are also handled in :class:`urllib.request.Request` by setting the appropriate +method attribute. Here is an example session that shows how to send a ``PUT`` request using http.client:: >>> # This creates an HTTP message From webhook-mailer at python.org Mon Feb 3 09:17:23 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 03 Feb 2020 14:17:23 -0000 Subject: [Python-checkins] bpo-39489: Remove COUNT_ALLOCS special build (GH-18259) Message-ID: https://github.com/python/cpython/commit/c6e5c1123bac6cbb4c85265155af5349dcea522e commit: c6e5c1123bac6cbb4c85265155af5349dcea522e branch: master author: Victor Stinner committer: GitHub date: 2020-02-03T15:17:15+01:00 summary: bpo-39489: Remove COUNT_ALLOCS special build (GH-18259) Remove: * COUNT_ALLOCS macro * sys.getcounts() function * SHOW_ALLOC_COUNT code in listobject.c * SHOW_TRACK_COUNT code in tupleobject.c * PyConfig.show_alloc_count field * -X showalloccount command line option * @test.support.requires_type_collecting decorator files: A Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst M Doc/c-api/init_config.rst M Doc/c-api/typeobj.rst M Doc/using/cmdline.rst M Doc/whatsnew/3.9.rst M Include/cpython/initconfig.h M Include/cpython/object.h M Include/object.h M Lib/subprocess.py M Lib/test/support/__init__.py M Lib/test/test_embed.py M Lib/test/test_gc.py M Lib/test/test_io.py M Lib/test/test_logging.py M Lib/test/test_module.py M Lib/test/test_support.py M Lib/test/test_sys.py M Lib/test/test_threading.py M Lib/test/test_traceback.py M Lib/test/test_warnings/__init__.py M Lib/test/test_weakref.py M Misc/SpecialBuilds.txt M Misc/python.man M Modules/_testcapimodule.c M Objects/bytesobject.c M Objects/listobject.c M Objects/longobject.c M Objects/object.c M Objects/tupleobject.c M Programs/_testembed.c M Python/clinic/sysmodule.c.h M Python/initconfig.c M Python/pylifecycle.c M Python/sysmodule.c diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 108bd2c0245ea..c589a6fe3f0ab 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -627,14 +627,6 @@ PyConfig ``python3 -m MODULE`` argument. Used by :c:func:`Py_RunMain`. - .. c:member:: int show_alloc_count - - Show allocation counts at exit? - - Set to 1 by :option:`-X showalloccount <-X>` command line option. - - Need a special Python build with ``COUNT_ALLOCS`` macro defined. - .. c:member:: int show_ref_count Show total reference count at exit? @@ -702,6 +694,10 @@ arguments are stripped from ``argv``: see :ref:`Command Line Arguments The ``xoptions`` options are parsed to set other options: see :option:`-X` option. +.. versionchanged:: 3.9 + + The ``show_alloc_count`` field has been removed. + Initialization with PyConfig ---------------------------- diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 7b205c044953b..a8a779ef6165a 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -148,15 +148,6 @@ Quick Reference | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ -If :const:`COUNT_ALLOCS` is defined then the following (internal-only) -fields exist as well: - -* :c:member:`~PyTypeObject.tp_allocs` -* :c:member:`~PyTypeObject.tp_frees` -* :c:member:`~PyTypeObject.tp_maxalloc` -* :c:member:`~PyTypeObject.tp_prev` -* :c:member:`~PyTypeObject.tp_next` - .. [#slots] A slot name in parentheses indicates it is (effectively) deprecated. Names in angle brackets should be treated as read-only. @@ -1904,31 +1895,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. 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 -subtypes. - -.. c:member:: Py_ssize_t PyTypeObject.tp_allocs - - Number of allocations. - -.. c:member:: Py_ssize_t PyTypeObject.tp_frees - - Number of frees. - -.. c:member:: Py_ssize_t PyTypeObject.tp_maxalloc - - Maximum simultaneously allocated objects. - -.. c:member:: PyTypeObject* PyTypeObject.tp_prev - - Pointer to the previous type object with a non-zero :c:member:`~PyTypeObject.tp_allocs` field. - -.. c:member:: PyTypeObject* PyTypeObject.tp_next - - Pointer to the next type object with a non-zero :c:member:`~PyTypeObject.tp_allocs` field. - Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from any Python thread, not just the thread which created the object (if the object becomes part of a refcount cycle, that cycle might be collected by a garbage diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index fb88673d30b1b..2206e5065be1f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -434,9 +434,6 @@ Miscellaneous options stored in a traceback of a trace. Use ``-X tracemalloc=NFRAME`` to start tracing with a traceback limit of *NFRAME* frames. See the :func:`tracemalloc.start` for more information. - * ``-X showalloccount`` to output the total count of allocated objects for - each type when the program finishes. This only works when Python was built with - ``COUNT_ALLOCS`` defined. * ``-X importtime`` to show how long each import takes. It shows module name, cumulative time (including nested imports) and self time (excluding nested imports). Note that its output may be broken in multi-threaded @@ -479,6 +476,8 @@ Miscellaneous options Using ``-X dev`` option, check *encoding* and *errors* arguments on string encoding and decoding operations. + The ``-X showalloccount`` option has been removed. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 931f8bf13fbde..3b7a9d105d059 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -348,6 +348,9 @@ Build and C API Changes functions are now required to build Python. (Contributed by Victor Stinner in :issue:`39395`.) +* The ``COUNT_ALLOCS`` special build macro has been removed. + (Contributed by Victor Stinner in :issue:`39489`.) + Deprecated ========== @@ -484,6 +487,12 @@ Removed ``asyncio.Condition`` and ``asyncio.Semaphore``. (Contributed by Andrew Svetlov in :issue:`34793`.) +* The :func:`sys.getcounts` function, the ``-X showalloccount`` command line + option and the ``show_alloc_count`` field of the C structure + :c:type:`PyConfig` have been removed. They required a special Python build by + defining ``COUNT_ALLOCS`` macro. + (Contributed by Victor Stinner in :issue:`39489`.) + Porting to Python 3.9 ===================== diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 54e662347e3b2..c5fa2b3857e7a 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -153,7 +153,6 @@ typedef struct { int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */ int show_ref_count; /* -X showrefcount */ - int show_alloc_count; /* -X showalloccount */ int dump_refs; /* PYTHONDUMPREFS */ int malloc_stats; /* PYTHONMALLOCSTATS */ diff --git a/Include/cpython/object.h b/Include/cpython/object.h index dc8fd6fa8987d..5fcad55c5c960 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -255,15 +255,6 @@ typedef struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; - -#ifdef COUNT_ALLOCS - /* these must be last and never explicitly initialized */ - Py_ssize_t tp_allocs; - Py_ssize_t tp_frees; - Py_ssize_t tp_maxalloc; - struct _typeobject *tp_prev; - struct _typeobject *tp_next; -#endif } PyTypeObject; /* The *real* layout of a type object when allocated on the heap */ @@ -341,8 +332,6 @@ static inline void _Py_Dealloc_inline(PyObject *op) destructor dealloc = Py_TYPE(op)->tp_dealloc; #ifdef Py_TRACE_REFS _Py_ForgetReference(op); -#else - _Py_INC_TPFREES(op); #endif (*dealloc)(op); } diff --git a/Include/object.h b/Include/object.h index 7a5f57357b75f..1a2e704e93d23 100644 --- a/Include/object.h +++ b/Include/object.h @@ -405,20 +405,6 @@ PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); #define _Py_DEC_REFTOTAL #endif /* Py_REF_DEBUG */ -#ifdef COUNT_ALLOCS -PyAPI_FUNC(void) _Py_inc_count(struct _typeobject *); -PyAPI_FUNC(void) _Py_dec_count(struct _typeobject *); -#define _Py_INC_TPALLOCS(OP) _Py_inc_count(Py_TYPE(OP)) -#define _Py_INC_TPFREES(OP) _Py_dec_count(Py_TYPE(OP)) -#define _Py_DEC_TPFREES(OP) Py_TYPE(OP)->tp_frees-- -#define _Py_COUNT_ALLOCS_COMMA , -#else -#define _Py_INC_TPALLOCS(OP) -#define _Py_INC_TPFREES(OP) -#define _Py_DEC_TPFREES(OP) -#define _Py_COUNT_ALLOCS_COMMA -#endif /* COUNT_ALLOCS */ - /* Update the Python traceback of an object. This function must be called when a memory block is reused from a free list. */ PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); @@ -438,15 +424,13 @@ static inline void _Py_NewReference(PyObject *op) if (_Py_tracemalloc_config.tracing) { _PyTraceMalloc_NewReference(op); } - _Py_INC_TPALLOCS(op); _Py_INC_REFTOTAL; Py_REFCNT(op) = 1; } -static inline void _Py_ForgetReference(PyObject *op) +static inline void _Py_ForgetReference(PyObject *Py_UNUSED(op)) { - (void)op; /* may be unused, shut up -Wunused-parameter */ - _Py_INC_TPFREES(op); + /* nothing to do */ } #endif /* !Py_TRACE_REFS */ diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 26a1e69bd38c2..c8db387091ba3 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -325,7 +325,7 @@ def _args_from_interpreter_flags(): if dev_mode: args.extend(('-X', 'dev')) for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'showalloccount', 'showrefcount', 'utf8'): + 'showrefcount', 'utf8'): if opt in xoptions: value = xoptions[opt] if value is True: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 215bab8131a04..259c7069bfc0a 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2512,9 +2512,6 @@ def swap_item(obj, item, new_val): if item in obj: del obj[item] -requires_type_collecting = unittest.skipIf(hasattr(sys, 'getcounts'), - 'types are immortal if COUNT_ALLOCS is defined') - def args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current settings in sys.flags and sys.warnoptions.""" diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 73ef96265b711..87842b9377a05 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -356,7 +356,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'tracemalloc': 0, 'import_time': 0, 'show_ref_count': 0, - 'show_alloc_count': 0, 'dump_refs': 0, 'malloc_stats': 0, @@ -729,7 +728,6 @@ def test_init_from_config(self): 'tracemalloc': 2, 'import_time': 1, 'show_ref_count': 1, - 'show_alloc_count': 1, 'malloc_stats': 1, 'stdio_encoding': 'iso8859-1', diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 18f8d10c5ba6a..acb6391944bc0 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -2,7 +2,7 @@ import unittest.mock from test.support import (verbose, refcount_test, run_unittest, cpython_only, start_threads, - temp_dir, requires_type_collecting, TESTFN, unlink, + temp_dir, TESTFN, unlink, import_module) from test.support.script_helper import assert_python_ok, make_script @@ -131,7 +131,6 @@ class A: del a self.assertNotEqual(gc.collect(), 0) - @requires_type_collecting def test_newinstance(self): class A(object): pass @@ -709,7 +708,6 @@ def run_command(code): stderr = run_command(code % "gc.DEBUG_SAVEALL") self.assertNotIn(b"uncollectable objects at shutdown", stderr) - @requires_type_collecting def test_gc_main_module_at_shutdown(self): # Create a reference cycle through the __main__ module and check # it gets collected at interpreter shutdown. @@ -723,7 +721,6 @@ def __del__(self): rc, out, err = assert_python_ok('-c', code) self.assertEqual(out.strip(), b'__del__ called') - @requires_type_collecting def test_gc_ordinary_module_at_shutdown(self): # Same as above, but with a non-__main__ module. with temp_dir() as script_dir: @@ -743,7 +740,6 @@ def __del__(self): rc, out, err = assert_python_ok('-c', code) self.assertEqual(out.strip(), b'__del__ called') - @requires_type_collecting def test_global_del_SystemExit(self): code = """if 1: class ClassWithDel: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 501e9313963bb..8a123fa1dc07a 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3492,7 +3492,6 @@ def __del__(self): """.format(iomod=iomod, kwargs=kwargs) return assert_python_ok("-c", code) - @support.requires_type_collecting def test_create_at_shutdown_without_encoding(self): rc, out, err = self._check_create_at_shutdown() if err: @@ -3502,7 +3501,6 @@ def test_create_at_shutdown_without_encoding(self): else: self.assertEqual("ok", out.decode().strip()) - @support.requires_type_collecting def test_create_at_shutdown_with_encoding(self): rc, out, err = self._check_create_at_shutdown(encoding='utf-8', errors='strict') diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index c38fdae03385e..e223522cc7ecc 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4252,7 +4252,6 @@ def __init__(self, name='MyLogger', level=logging.NOTSET): h.close() logging.setLoggerClass(logging.Logger) - @support.requires_type_collecting def test_logging_at_shutdown(self): # Issue #20037 code = """if 1: diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index efe9a8ed5e571..1d44563579fd2 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -1,7 +1,7 @@ # Test the module type import unittest import weakref -from test.support import gc_collect, requires_type_collecting +from test.support import gc_collect from test.support.script_helper import assert_python_ok import sys @@ -101,7 +101,6 @@ def f(): gc_collect() self.assertEqual(f().__dict__["bar"], 4) - @requires_type_collecting def test_clear_dict_in_ref_cycle(self): destroyed = [] m = ModuleType("foo") @@ -266,7 +265,6 @@ def test_module_repr_source(self): self.assertEqual(r[-len(ends_with):], ends_with, '{!r} does not end with {!r}'.format(r, ends_with)) - @requires_type_collecting def test_module_finalization_at_shutdown(self): # Module globals and builtins should still be available during shutdown rc, out, err = assert_python_ok("-c", "from test import final_a") diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 2f347bd540f33..175f7c845fe8c 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -493,7 +493,6 @@ def test_args_from_interpreter_flags(self): ['-Wignore', '-X', 'dev'], ['-X', 'faulthandler'], ['-X', 'importtime'], - ['-X', 'showalloccount'], ['-X', 'showrefcount'], ['-X', 'tracemalloc'], ['-X', 'tracemalloc=3'], diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 947c935f34728..58701a11f919c 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -819,7 +819,6 @@ def test_getallocatedblocks(self): c = sys.getallocatedblocks() self.assertIn(c, range(b - 50, b + 50)) - @test.support.requires_type_collecting def test_is_finalizing(self): self.assertIs(sys.is_finalizing(), False) # Don't use the atexit module because _Py_Finalizing is only set @@ -841,7 +840,6 @@ def __del__(self): rc, stdout, stderr = assert_python_ok('-c', code) self.assertEqual(stdout.rstrip(), b'True') - @test.support.requires_type_collecting def test_issue20602(self): # sys.flags and sys.float_info were wiped during shutdown. code = """if 1: @@ -1295,8 +1293,6 @@ def delx(self): del self.__x # type # static type: PyTypeObject fmt = 'P2nPI13Pl4Pn9Pn11PIPP' - if hasattr(sys, 'getcounts'): - fmt += '3n2P' s = vsize(fmt) check(int, s) # class diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 62f2d54ad0a8e..a9d31afbe33e6 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -3,8 +3,7 @@ """ import test.support -from test.support import (verbose, import_module, cpython_only, - requires_type_collecting) +from test.support import verbose, import_module, cpython_only from test.support.script_helper import assert_python_ok, assert_python_failure import random @@ -552,7 +551,6 @@ def f(): self.assertEqual(err, b"") self.assertEqual(data, "Thread-1\nTrue\nTrue\n") - @requires_type_collecting def test_main_thread_during_shutdown(self): # bpo-31516: current_thread() should still point to the main thread # at shutdown @@ -1113,7 +1111,6 @@ def run(): self.assertIn("ZeroDivisionError", err) self.assertNotIn("Unhandled exception", err) - @requires_type_collecting def test_print_exception_stderr_is_none_1(self): script = r"""if True: import sys diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 7135d997d54ab..60e0b582756b5 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -174,7 +174,6 @@ def do_test(firstlines, message, charset, lineno): # Issue #18960: coding spec should have no effect do_test("x=0\n# coding: GBK\n", "h\xe9 ho", 'utf-8', 5) - @support.requires_type_collecting def test_print_traceback_at_exit(self): # Issue #22599: Ensure that it is possible to use the traceback module # to display an exception at Python exit diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index c6fb097ae6dd2..268ecb03f4dc6 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -1227,7 +1227,6 @@ def test_issue_8766(self): class FinalizationTest(unittest.TestCase): - @support.requires_type_collecting def test_finalization(self): # Issue #19421: warnings.warn() should not crash # during Python finalization diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 228bc17b23c59..63c725527d5f2 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -649,7 +649,6 @@ class D: del c1, c2, C, D gc.collect() - @support.requires_type_collecting def test_callback_in_cycle_resurrection(self): import gc diff --git a/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst b/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst new file mode 100644 index 0000000000000..652a4356e227f --- /dev/null +++ b/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst @@ -0,0 +1 @@ +Remove ``COUNT_ALLOCS`` special build. diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index d1a032165f852..27369abfb37b3 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -46,9 +46,7 @@ Build option: ``./configure --with-trace-refs``. Turn on heavy reference debugging. This is major surgery. Every PyObject grows two more pointers, to maintain a doubly-linked list of all live heap-allocated objects. Most built-in type objects are not in this list, as they're statically -allocated. Starting in Python 2.3, if COUNT_ALLOCS (see below) is also defined, -a static type object T does appear in this list if at least one object of type T -has been created. +allocated. Note that because the fundamental PyObject layout changes, Python modules compiled with Py_TRACE_REFS are incompatible with modules compiled without it. @@ -165,55 +163,6 @@ by not defining NDEBUG), and some routines do additional sanity checks inside "#ifdef Py_DEBUG" blocks. -COUNT_ALLOCS ------------- - -Each type object grows three new members: - - /* Number of times an object of this type was allocated. */ - int tp_allocs; - - /* Number of times an object of this type was deallocated. */ - int tp_frees; - - /* Highwater mark: the maximum value of tp_allocs - tp_frees so - * far; or, IOW, the largest number of objects of this type alive at - * the same time. - */ - int tp_maxalloc; - -Allocation and deallocation code keeps these counts up to date. Py_FinalizeEx() -displays a summary of the info returned by sys.getcounts() (see below), along -with assorted other special allocation counts (like the number of tuple -allocations satisfied by a tuple free-list, the number of 1-character strings -allocated, etc). - -Before Python 2.2, type objects were immortal, and the COUNT_ALLOCS -implementation relies on that. As of Python 2.2, heap-allocated type/ class -objects can go away. COUNT_ALLOCS can blow up in 2.2 and 2.2.1 because of this; -this was fixed in 2.2.2. Use of COUNT_ALLOCS makes all heap-allocated type -objects immortal, except for those for which no object of that type is ever -allocated. - -Starting with Python 2.3, If Py_TRACE_REFS is also defined, COUNT_ALLOCS -arranges to ensure that the type object for each allocated object appears in the -doubly-linked list of all objects maintained by Py_TRACE_REFS. - -Special gimmicks: - -sys.getcounts() - Return a list of 4-tuples, one entry for each type object for which at least - one object of that type was allocated. Each tuple is of the form: - - (tp_name, tp_allocs, tp_frees, tp_maxalloc) - - Each distinct type object gets a distinct entry in this list, even if two or - more type objects have the same tp_name (in which case there's no way to - distinguish them by looking at this list). The list is ordered by time of - first object allocation: the type object for which the first allocation of - an object of that type occurred most recently is at the front of the list. - - LLTRACE ------- diff --git a/Misc/python.man b/Misc/python.man index 3645b0206eb2b..89a15a5e7b2ff 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -286,10 +286,6 @@ Set implementation specific option. The following options are available: traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a traceback limit of NFRAME frames - -X showalloccount: output the total count of allocated objects for each - type when the program finishes. This only works when Python was built with - COUNT_ALLOCS defined - -X importtime: show how long each import takes. It shows module name, cumulative time (including nested imports) and self time (excluding nested imports). Note that its output may be broken in multi-threaded diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 943bee6e21e19..4dcfde4543730 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3589,16 +3589,6 @@ slot_tp_del(PyObject *self) /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so * we need to undo that. */ _Py_DEC_REFTOTAL; - /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object - * chain, so no more to do there. - * If COUNT_ALLOCS, the original decref bumped tp_frees, and - * _Py_NewReference bumped tp_allocs: both of those need to be - * undone. - */ -#ifdef COUNT_ALLOCS - --Py_TYPE(self)->tp_frees; - --Py_TYPE(self)->tp_allocs; -#endif } static PyObject * diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 5fd92f72a536a..00151b8256615 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -18,10 +18,6 @@ class bytes "PyBytesObject *" "&PyBytes_Type" #include "clinic/bytesobject.c.h" -#ifdef COUNT_ALLOCS -Py_ssize_t _Py_null_strings, _Py_one_strings; -#endif - static PyBytesObject *characters[UCHAR_MAX + 1]; static PyBytesObject *nullstring; @@ -68,9 +64,6 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) assert(size >= 0); if (size == 0 && (op = nullstring) != NULL) { -#ifdef COUNT_ALLOCS - _Py_null_strings++; -#endif Py_INCREF(op); return (PyObject *)op; } @@ -112,9 +105,6 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) if (size == 1 && str != NULL && (op = characters[*str & UCHAR_MAX]) != NULL) { -#ifdef COUNT_ALLOCS - _Py_one_strings++; -#endif Py_INCREF(op); return (PyObject *)op; } @@ -148,16 +138,10 @@ PyBytes_FromString(const char *str) return NULL; } if (size == 0 && (op = nullstring) != NULL) { -#ifdef COUNT_ALLOCS - _Py_null_strings++; -#endif Py_INCREF(op); return (PyObject *)op; } if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { -#ifdef COUNT_ALLOCS - _Py_one_strings++; -#endif Py_INCREF(op); return (PyObject *)op; } diff --git a/Objects/listobject.c b/Objects/listobject.c index 2c07ceb0d412c..c93a0feaf3695 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -94,29 +94,6 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) return 0; } -/* Debug statistic to compare allocations with reuse through the free list */ -#undef SHOW_ALLOC_COUNT -#ifdef SHOW_ALLOC_COUNT -static size_t count_alloc = 0; -static size_t count_reuse = 0; - -static void -show_alloc(void) -{ - PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->config.show_alloc_count) { - return; - } - - fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n", - count_alloc); - fprintf(stderr, "List reuse through freelist: %" PY_FORMAT_SIZE_T - "d\n", count_reuse); - fprintf(stderr, "%.2f%% reuse rate\n\n", - (100.0*count_reuse/(count_alloc+count_reuse))); -} -#endif - /* Empty list reuse scheme to save calls to malloc and free */ #ifndef PyList_MAXFREELIST #define PyList_MAXFREELIST 80 @@ -156,13 +133,6 @@ PyObject * PyList_New(Py_ssize_t size) { PyListObject *op; -#ifdef SHOW_ALLOC_COUNT - static int initialized = 0; - if (!initialized) { - Py_AtExit(show_alloc); - initialized = 1; - } -#endif if (size < 0) { PyErr_BadInternalCall(); @@ -172,16 +142,10 @@ PyList_New(Py_ssize_t size) numfree--; op = free_list[numfree]; _Py_NewReference((PyObject *)op); -#ifdef SHOW_ALLOC_COUNT - count_reuse++; -#endif } else { op = PyObject_GC_New(PyListObject, &PyList_Type); if (op == NULL) return NULL; -#ifdef SHOW_ALLOC_COUNT - count_alloc++; -#endif } if (size <= 0) op->ob_item = NULL; diff --git a/Objects/longobject.c b/Objects/longobject.c index 124b837d008e3..9115fa184f37e 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -35,10 +35,6 @@ PyObject *_PyLong_One = NULL; #define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS) -#ifdef COUNT_ALLOCS -Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; -#endif - static PyObject * get_small_int(sdigit ival) { @@ -46,12 +42,6 @@ get_small_int(sdigit ival) PyThreadState *tstate = _PyThreadState_GET(); PyObject *v = (PyObject*)tstate->interp->small_ints[ival + NSMALLNEGINTS]; Py_INCREF(v); -#ifdef COUNT_ALLOCS - if (ival >= 0) - _Py_quick_int_allocs++; - else - _Py_quick_neg_int_allocs++; -#endif return v; } diff --git a/Objects/object.c b/Objects/object.c index 67a6386e2a51d..2154d119a0206 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -113,120 +113,6 @@ _Py_AddToAllObjects(PyObject *op, int force) } #endif /* Py_TRACE_REFS */ -#ifdef COUNT_ALLOCS -static PyTypeObject *type_list; -/* All types are added to type_list, at least when - they get one object created. That makes them - immortal, which unfortunately contributes to - garbage itself. If unlist_types_without_objects - is set, they will be removed from the type_list - once the last object is deallocated. */ -static int unlist_types_without_objects; -extern Py_ssize_t _Py_tuple_zero_allocs, _Py_fast_tuple_allocs; -extern Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; -extern Py_ssize_t _Py_null_strings, _Py_one_strings; -void -_Py_dump_counts(FILE* f) -{ - PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->config.show_alloc_count) { - return; - } - - PyTypeObject *tp; - for (tp = type_list; tp; tp = tp->tp_next) - fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, " - "freed: %" PY_FORMAT_SIZE_T "d, " - "max in use: %" PY_FORMAT_SIZE_T "d\n", - tp->tp_name, tp->tp_allocs, tp->tp_frees, - tp->tp_maxalloc); - fprintf(f, "fast tuple allocs: %" PY_FORMAT_SIZE_T "d, " - "empty: %" PY_FORMAT_SIZE_T "d\n", - _Py_fast_tuple_allocs, _Py_tuple_zero_allocs); - fprintf(f, "fast int allocs: pos: %" PY_FORMAT_SIZE_T "d, " - "neg: %" PY_FORMAT_SIZE_T "d\n", - _Py_quick_int_allocs, _Py_quick_neg_int_allocs); - fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, " - "1-strings: %" PY_FORMAT_SIZE_T "d\n", - _Py_null_strings, _Py_one_strings); -} - -PyObject * -_Py_get_counts(void) -{ - PyTypeObject *tp; - PyObject *result; - PyObject *v; - - result = PyList_New(0); - if (result == NULL) - return NULL; - for (tp = type_list; tp; tp = tp->tp_next) { - v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs, - tp->tp_frees, tp->tp_maxalloc); - if (v == NULL) { - Py_DECREF(result); - return NULL; - } - if (PyList_Append(result, v) < 0) { - Py_DECREF(v); - Py_DECREF(result); - return NULL; - } - Py_DECREF(v); - } - return result; -} - -void -_Py_inc_count(PyTypeObject *tp) -{ - if (tp->tp_next == NULL && tp->tp_prev == NULL) { - /* first time; insert in linked list */ - if (type_list) - type_list->tp_prev = tp; - tp->tp_next = type_list; - /* Note that as of Python 2.2, heap-allocated type objects - * can go away, but this code requires that they stay alive - * until program exit. That's why we're careful with - * refcounts here. type_list gets a new reference to tp, - * while ownership of the reference type_list used to hold - * (if any) was transferred to tp->tp_next in the line above. - * tp is thus effectively immortal after this. - */ - Py_INCREF(tp); - type_list = tp; -#ifdef Py_TRACE_REFS - /* Also insert in the doubly-linked list of all objects, - * if not already there. - */ - _Py_AddToAllObjects((PyObject *)tp, 0); -#endif - } - tp->tp_allocs++; - if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc) - tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees; -} - -void _Py_dec_count(PyTypeObject *tp) -{ - tp->tp_frees++; - if (unlist_types_without_objects && - tp->tp_allocs == tp->tp_frees) { - /* unlink the type from type_list */ - if (tp->tp_prev) - tp->tp_prev->tp_next = tp->tp_next; - else - type_list = tp->tp_next; - if (tp->tp_next) - tp->tp_next->tp_prev = tp->tp_prev; - tp->tp_next = tp->tp_prev = NULL; - Py_DECREF(tp); - } -} - -#endif - #ifdef Py_REF_DEBUG /* Log a fatal error; doesn't return. */ void @@ -349,15 +235,6 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so * we need to undo that. */ _Py_DEC_REFTOTAL; - /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object - * chain, so no more to do there. - * If COUNT_ALLOCS, the original decref bumped tp_frees, and - * _Py_NewReference bumped tp_allocs: both of those need to be - * undone. */ -#ifdef COUNT_ALLOCS - --Py_TYPE(self)->tp_frees; - --Py_TYPE(self)->tp_allocs; -#endif return -1; } @@ -1970,7 +1847,6 @@ _Py_ForgetReference(PyObject *op) op->_ob_next->_ob_prev = op->_ob_prev; op->_ob_prev->_ob_next = op->_ob_next; op->_ob_next = op->_ob_prev = NULL; - _Py_INC_TPFREES(op); } /* Print all live objects. Because PyObject_Print is called, the @@ -2289,8 +2165,6 @@ _Py_Dealloc(PyObject *op) destructor dealloc = Py_TYPE(op)->tp_dealloc; #ifdef Py_TRACE_REFS _Py_ForgetReference(op); -#else - _Py_INC_TPFREES(op); #endif (*dealloc)(op); } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 08f7022fda25a..2708b9aad3120 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -28,43 +28,10 @@ class tuple "PyTupleObject *" "&PyTuple_Type" static PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; static int numfree[PyTuple_MAXSAVESIZE]; #endif -#ifdef COUNT_ALLOCS -Py_ssize_t _Py_fast_tuple_allocs; -Py_ssize_t _Py_tuple_zero_allocs; -#endif - -/* Debug statistic to count GC tracking of tuples. - Please note that tuples are only untracked when considered by the GC, and - many of them will be dead before. Therefore, a tracking rate close to 100% - does not necessarily prove that the heuristic is inefficient. -*/ -#ifdef SHOW_TRACK_COUNT -static Py_ssize_t count_untracked = 0; -static Py_ssize_t count_tracked = 0; - -static void -show_track(void) -{ - PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->config.show_alloc_count) { - return; - } - - fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n", - count_tracked + count_untracked); - fprintf(stderr, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T - "d\n", count_tracked); - fprintf(stderr, "%.2f%% tuple tracking rate\n\n", - (100.0*count_tracked/(count_untracked+count_tracked))); -} -#endif static inline void tuple_gc_track(PyTupleObject *op) { -#ifdef SHOW_TRACK_COUNT - count_tracked++; -#endif _PyObject_GC_TRACK(op); } @@ -106,9 +73,6 @@ tuple_alloc(Py_ssize_t size) assert(size != 0); free_list[size] = (PyTupleObject *) op->ob_item[0]; numfree[size]--; -#ifdef COUNT_ALLOCS - _Py_fast_tuple_allocs++; -#endif /* Inline PyObject_InitVar */ #ifdef Py_TRACE_REFS Py_SIZE(op) = size; @@ -139,9 +103,6 @@ PyTuple_New(Py_ssize_t size) if (size == 0 && free_list[0]) { op = free_list[0]; Py_INCREF(op); -#ifdef COUNT_ALLOCS - _Py_tuple_zero_allocs++; -#endif return (PyObject *) op; } #endif @@ -227,10 +188,6 @@ _PyTuple_MaybeUntrack(PyObject *op) _PyObject_GC_MAY_BE_TRACKED(elt)) return; } -#ifdef SHOW_TRACK_COUNT - count_tracked--; - count_untracked++; -#endif _PyObject_GC_UNTRACK(op); } @@ -1001,9 +958,6 @@ _PyTuple_Fini(void) (void)PyTuple_ClearFreeList(); #endif -#ifdef SHOW_TRACK_COUNT - show_track(); -#endif } /*********************** Tuple Iterator **************************/ diff --git a/Programs/_testembed.c b/Programs/_testembed.c index b98a38a1ba678..b98696cbe03ae 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -506,7 +506,6 @@ static int test_init_from_config(void) config.import_time = 1; config.show_ref_count = 1; - config.show_alloc_count = 1; /* FIXME: test dump_refs: bpo-34223 */ putenv("PYTHONMALLOCSTATS=0"); diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index daca0e64110b2..4615ebaab5de2 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -758,27 +758,6 @@ sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } -#if defined(COUNT_ALLOCS) - -PyDoc_STRVAR(sys_getcounts__doc__, -"getcounts($module, /)\n" -"--\n" -"\n"); - -#define SYS_GETCOUNTS_METHODDEF \ - {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS, sys_getcounts__doc__}, - -static PyObject * -sys_getcounts_impl(PyObject *module); - -static PyObject * -sys_getcounts(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getcounts_impl(module); -} - -#endif /* defined(COUNT_ALLOCS) */ - PyDoc_STRVAR(sys__getframe__doc__, "_getframe($module, depth=0, /)\n" "--\n" @@ -988,11 +967,7 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #define SYS_GETTOTALREFCOUNT_METHODDEF #endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */ -#ifndef SYS_GETCOUNTS_METHODDEF - #define SYS_GETCOUNTS_METHODDEF -#endif /* !defined(SYS_GETCOUNTS_METHODDEF) */ - #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=decd687b7631de4b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39eb34a01fb9a919 input=a9049054013a1b77]*/ diff --git a/Python/initconfig.c b/Python/initconfig.c index 9a784c75116aa..493b4bb440656 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -73,9 +73,6 @@ static const char usage_3[] = "\ tracemalloc module. By default, only the most recent frame is stored in a\n\ traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ traceback limit of NFRAME frames\n\ - -X showalloccount: output the total count of allocated objects for each\n\ - type when the program finishes. This only works when Python was built with\n\ - COUNT_ALLOCS defined\n\ -X importtime: show how long each import takes. It shows module name,\n\ cumulative time (including nested imports) and self time (excluding\n\ nested imports). Note that its output may be broken in multi-threaded\n\ @@ -800,7 +797,6 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(tracemalloc); COPY_ATTR(import_time); COPY_ATTR(show_ref_count); - COPY_ATTR(show_alloc_count); COPY_ATTR(dump_refs); COPY_ATTR(malloc_stats); @@ -903,7 +899,6 @@ config_as_dict(const PyConfig *config) SET_ITEM_INT(tracemalloc); SET_ITEM_INT(import_time); SET_ITEM_INT(show_ref_count); - SET_ITEM_INT(show_alloc_count); SET_ITEM_INT(dump_refs); SET_ITEM_INT(malloc_stats); SET_ITEM_WSTR(filesystem_encoding); @@ -1691,9 +1686,6 @@ config_read(PyConfig *config) if (config_get_xoption(config, L"showrefcount")) { config->show_ref_count = 1; } - if (config_get_xoption(config, L"showalloccount")) { - config->show_alloc_count = 1; - } status = config_read_complex_options(config); if (_PyStatus_EXCEPTION(status)) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d5d60d0a6d4d9..f1307356a7da0 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1173,10 +1173,6 @@ Py_Initialize(void) } -#ifdef COUNT_ALLOCS -extern void _Py_dump_counts(FILE*); -#endif - /* Flush stdout and stderr */ static int @@ -1393,13 +1389,6 @@ Py_FinalizeEx(void) * XXX I haven't seen a real-life report of either of these. */ _PyGC_CollectIfEnabled(); -#ifdef COUNT_ALLOCS - /* With COUNT_ALLOCS, it helps to run GC multiple times: - each collection might release some types from the type - list, so they become garbage. */ - while (_PyGC_CollectIfEnabled() > 0) - /* nothing */; -#endif /* Clear all loghooks */ /* We want minimal exposure of this function, so define the extern @@ -1451,10 +1440,6 @@ Py_FinalizeEx(void) /* unload faulthandler module */ _PyFaulthandler_Fini(); - /* Debugging stuff */ -#ifdef COUNT_ALLOCS - _Py_dump_counts(stderr); -#endif /* dump hash stats */ _PyHash_Fini(); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 17e79603c29f4..1cb10300d7758 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1685,20 +1685,6 @@ sys_getallocatedblocks_impl(PyObject *module) return _Py_GetAllocatedBlocks(); } -#ifdef COUNT_ALLOCS -/*[clinic input] -sys.getcounts -[clinic start generated code]*/ - -static PyObject * -sys_getcounts_impl(PyObject *module) -/*[clinic end generated code: output=20df00bc164f43cb input=ad2ec7bda5424953]*/ -{ - extern PyObject *_Py_get_counts(void); - - return _Py_get_counts(); -} -#endif /*[clinic input] sys._getframe @@ -1879,7 +1865,6 @@ static PyMethodDef sys_methods[] = { SYS_GETDEFAULTENCODING_METHODDEF SYS_GETDLOPENFLAGS_METHODDEF SYS_GETALLOCATEDBLOCKS_METHODDEF - SYS_GETCOUNTS_METHODDEF #ifdef DYNAMIC_EXECUTION_PROFILE {"getdxp", _Py_GetDXProfile, METH_VARARGS}, #endif From webhook-mailer at python.org Mon Feb 3 11:28:39 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 03 Feb 2020 16:28:39 -0000 Subject: [Python-checkins] bpo-39542: Move object.h debug functions to internal C API (GH-18331) Message-ID: https://github.com/python/cpython/commit/4b524161a0f9d50d782e739a3708434ffd4e94a5 commit: 4b524161a0f9d50d782e739a3708434ffd4e94a5 branch: master author: Victor Stinner committer: GitHub date: 2020-02-03T17:28:26+01:00 summary: bpo-39542: Move object.h debug functions to internal C API (GH-18331) Move the following functions from the public C API to the internal C API: * _PyDebug_PrintTotalRefs(), * _Py_PrintReferenceAddresses() * _Py_PrintReferences() files: M Include/internal/pycore_object.h M Include/object.h M Python/pylifecycle.c M Python/pythonrun.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index ba6636d7f8cfc..eac39c8a3fccc 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -77,6 +77,15 @@ static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, #define _PyObject_GC_UNTRACK(op) \ _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) +#ifdef Py_REF_DEBUG +extern void _PyDebug_PrintTotalRefs(void); +#endif + +#ifdef Py_TRACE_REFS +extern void _Py_PrintReferences(FILE *); +extern void _Py_PrintReferenceAddresses(FILE *); +#endif + #ifdef __cplusplus } #endif diff --git a/Include/object.h b/Include/object.h index 1a2e704e93d23..e1cc47aeb3d5c 100644 --- a/Include/object.h +++ b/Include/object.h @@ -395,11 +395,6 @@ PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); #define _Py_INC_REFTOTAL _Py_RefTotal++ #define _Py_DEC_REFTOTAL _Py_RefTotal-- - -/* Py_REF_DEBUG also controls the display of refcounts and memory block - * allocations at the interactive prompt and at interpreter shutdown - */ -PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); #else #define _Py_INC_REFTOTAL #define _Py_DEC_REFTOTAL @@ -413,8 +408,6 @@ PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); /* Py_TRACE_REFS is such major surgery that we call external routines. */ PyAPI_FUNC(void) _Py_NewReference(PyObject *); PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); -PyAPI_FUNC(void) _Py_PrintReferences(FILE *); -PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *); PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); #else /* Without Py_TRACE_REFS, there's little enough to do that we expand code diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index f1307356a7da0..fbeebbdf99da5 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -10,6 +10,7 @@ #include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_hamt.h" +#include "pycore_object.h" #include "pycore_pathconfig.h" #include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" diff --git a/Python/pythonrun.c b/Python/pythonrun.c index b68a0b5572a1b..f4ded2e24a37e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -12,6 +12,7 @@ #include "Python-ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pystate.h" From webhook-mailer at python.org Mon Feb 3 11:47:24 2020 From: webhook-mailer at python.org (Stefan Pochmann) Date: Mon, 03 Feb 2020 16:47:24 -0000 Subject: [Python-checkins] Fixes in sorting descriptions (GH-18317) Message-ID: https://github.com/python/cpython/commit/24e5ad4689de9adc8e4a7d8c08fe400dcea668e6 commit: 24e5ad4689de9adc8e4a7d8c08fe400dcea668e6 branch: master author: Stefan Pochmann committer: GitHub date: 2020-02-03T08:47:20-08:00 summary: Fixes in sorting descriptions (GH-18317) Improvements in listsort.txt and a comment in sortperf.py. Automerge-Triggered-By: @csabella files: M Lib/test/sortperf.py M Objects/listsort.txt diff --git a/Lib/test/sortperf.py b/Lib/test/sortperf.py index 171e5cef5e29f..14a9d827ed57c 100644 --- a/Lib/test/sortperf.py +++ b/Lib/test/sortperf.py @@ -134,7 +134,7 @@ def tabulate(r): L = list(range(half - 1, -1, -1)) L.extend(range(half)) # Force to float, so that the timings are comparable. This is - # significantly faster if we leave tham as ints. + # significantly faster if we leave them as ints. L = list(map(float, L)) doit(L) # !sort print() diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 43fe1574c3239..174777a2658dc 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -319,13 +319,13 @@ So merging is always done on two consecutive runs at a time, and in-place, although this may require some temp memory (more on that later). When a run is identified, its base address and length are pushed on a stack -in the MergeState struct. merge_collapse() is then called to see whether it -should merge it with preceding run(s). We would like to delay merging as -long as possible in order to exploit patterns that may come up later, but we -like even more to do merging as soon as possible to exploit that the run just -found is still high in the memory hierarchy. We also can't delay merging -"too long" because it consumes memory to remember the runs that are still -unmerged, and the stack has a fixed size. +in the MergeState struct. merge_collapse() is then called to potentially +merge runs on that stack. We would like to delay merging as long as possible +in order to exploit patterns that may come up later, but we like even more to +do merging as soon as possible to exploit that the run just found is still +high in the memory hierarchy. We also can't delay merging "too long" because +it consumes memory to remember the runs that are still unmerged, and the +stack has a fixed size. What turned out to be a good compromise maintains two invariants on the stack entries, where A, B and C are the lengths of the three rightmost not-yet @@ -739,7 +739,7 @@ slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1 inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has (2**k-1)-1 - 2**(k-1) + 1 = 2**k-1 - 2**(k-1) = - 2*2**k-1 - 2**(k-1) = + 2*2**(k-1)-1 - 2**(k-1) = (2-1)*2**(k-1) - 1 = 2**(k-1) - 1 elements. From webhook-mailer at python.org Mon Feb 3 11:55:09 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 03 Feb 2020 16:55:09 -0000 Subject: [Python-checkins] bpo-39542: Simplify _Py_NewReference() (GH-18332) Message-ID: https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924 commit: 49932fec62c616ec88da52642339d83ae719e924 branch: master author: Victor Stinner committer: GitHub date: 2020-02-03T17:55:04+01:00 summary: bpo-39542: Simplify _Py_NewReference() (GH-18332) * Remove _Py_INC_REFTOTAL and _Py_DEC_REFTOTAL macros: modify directly _Py_RefTotal. * _Py_ForgetReference() is no longer defined if the Py_TRACE_REFS macro is not defined. * Remove _Py_NewReference() implementation from object.c: unify the two implementations in object.h inline function. * Fix Py_TRACE_REFS build: _Py_INC_TPALLOCS() macro has been removed. files: M Include/object.h M Modules/_testcapimodule.c M Objects/bytesobject.c M Objects/dictobject.c M Objects/object.c M Objects/tupleobject.c M Objects/unicodeobject.c diff --git a/Include/object.h b/Include/object.h index e1cc47aeb3d5c..175a208f0d2d7 100644 --- a/Include/object.h +++ b/Include/object.h @@ -379,25 +379,11 @@ decision that's up to the implementer of each new type so if you want, you can count such references to the type object.) */ -/* First define a pile of simple helper macros, one set per special - * build symbol. These either expand to the obvious things, or to - * nothing at all when the special mode isn't in effect. The main - * macros can later be defined just once then, yet expand to different - * things depending on which special build options are and aren't in effect. - * Trust me : while painful, this is 20x easier to understand than, - * e.g, defining _Py_NewReference five different times in a maze of nested - * #ifdefs (we used to do that -- it was impenetrable). - */ #ifdef Py_REF_DEBUG PyAPI_DATA(Py_ssize_t) _Py_RefTotal; PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op); PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); -#define _Py_INC_REFTOTAL _Py_RefTotal++ -#define _Py_DEC_REFTOTAL _Py_RefTotal-- -#else -#define _Py_INC_REFTOTAL -#define _Py_DEC_REFTOTAL #endif /* Py_REF_DEBUG */ /* Update the Python traceback of an object. This function must be called @@ -406,33 +392,33 @@ PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); #ifdef Py_TRACE_REFS /* Py_TRACE_REFS is such major surgery that we call external routines. */ -PyAPI_FUNC(void) _Py_NewReference(PyObject *); PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); -#else -/* Without Py_TRACE_REFS, there's little enough to do that we expand code - inline. */ +#endif + + static inline void _Py_NewReference(PyObject *op) { if (_Py_tracemalloc_config.tracing) { _PyTraceMalloc_NewReference(op); } - _Py_INC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif Py_REFCNT(op) = 1; +#ifdef Py_TRACE_REFS + _Py_AddToAllObjects(op, 1); +#endif } -static inline void _Py_ForgetReference(PyObject *Py_UNUSED(op)) -{ - /* nothing to do */ -} -#endif /* !Py_TRACE_REFS */ - PyAPI_FUNC(void) _Py_Dealloc(PyObject *); static inline void _Py_INCREF(PyObject *op) { - _Py_INC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif op->ob_refcnt++; } @@ -444,7 +430,9 @@ static inline void _Py_DECREF( #endif PyObject *op) { - _Py_DEC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif if (--op->ob_refcnt != 0) { #ifdef Py_REF_DEBUG if (op->ob_refcnt < 0) { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 4dcfde4543730..c5812f827dfeb 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3586,9 +3586,11 @@ slot_tp_del(PyObject *self) self->ob_refcnt = refcnt; } assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); - /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so - * we need to undo that. */ - _Py_DEC_REFTOTAL; + /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased + _Py_RefTotal, so we need to undo that. */ +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif } static PyObject * diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 00151b8256615..5334eca7f33e6 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2948,8 +2948,12 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) return (*pv == NULL) ? -1 : 0; } /* XXX UNREF/NEWREF interface should be more symmetrical */ - _Py_DEC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif +#ifdef Py_TRACE_REFS _Py_ForgetReference(v); +#endif *pv = (PyObject *) PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 87f88abbe53bd..ae6b50ff27245 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -311,7 +311,9 @@ static void free_keys_object(PyDictKeysObject *keys); static inline void dictkeys_incref(PyDictKeysObject *dk) { - _Py_INC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif dk->dk_refcnt++; } @@ -319,7 +321,9 @@ static inline void dictkeys_decref(PyDictKeysObject *dk) { assert(dk->dk_refcnt > 0); - _Py_DEC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif if (--dk->dk_refcnt == 0) { free_keys_object(dk); } @@ -563,7 +567,9 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size) return NULL; } } - _Py_INC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif dk->dk_refcnt = 1; dk->dk_size = size; dk->dk_usable = usable; @@ -687,10 +693,12 @@ clone_combined_dict(PyDictObject *orig) } /* Since we copied the keys table we now have an extra reference - in the system. Manually call _Py_INC_REFTOTAL to signal that + in the system. Manually call increment _Py_RefTotal to signal that we have it now; calling dictkeys_incref would be an error as keys->dk_refcnt is already set to 1 (after memcpy). */ - _Py_INC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif return (PyObject *)new; } @@ -1249,13 +1257,15 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize) assert(oldkeys->dk_lookup != lookdict_split); assert(oldkeys->dk_refcnt == 1); +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif if (oldkeys->dk_size == PyDict_MINSIZE && - numfreekeys < PyDict_MAXFREELIST) { - _Py_DEC_REFTOTAL; + numfreekeys < PyDict_MAXFREELIST) + { keys_free_list[numfreekeys++] = oldkeys; } else { - _Py_DEC_REFTOTAL; PyObject_FREE(oldkeys); } } diff --git a/Objects/object.c b/Objects/object.c index 2154d119a0206..085605ae36714 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -232,9 +232,11 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) _PyObject_ASSERT(self, (!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self))); - /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so - * we need to undo that. */ - _Py_DEC_REFTOTAL; + /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased + _Py_RefTotal, so we need to undo that. */ +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif return -1; } @@ -1804,19 +1806,6 @@ _PyTypes_Init(void) #ifdef Py_TRACE_REFS - -void -_Py_NewReference(PyObject *op) -{ - if (_Py_tracemalloc_config.tracing) { - _PyTraceMalloc_NewReference(op); - } - _Py_INC_REFTOTAL; - op->ob_refcnt = 1; - _Py_AddToAllObjects(op, 1); - _Py_INC_TPALLOCS(op); -} - void _Py_ForgetReference(PyObject *op) { diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 2708b9aad3120..8c8c66f266f9d 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -902,10 +902,15 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } /* XXX UNREF/NEWREF interface should be more symmetrical */ - _Py_DEC_REFTOTAL; - if (_PyObject_GC_IS_TRACKED(v)) +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif + if (_PyObject_GC_IS_TRACKED(v)) { _PyObject_GC_UNTRACK(v); + } +#ifdef Py_TRACE_REFS _Py_ForgetReference((PyObject *) v); +#endif /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { Py_CLEAR(v->ob_item[i]); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8e1161e5387b4..5f10437a1524c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1037,8 +1037,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } - _Py_DEC_REFTOTAL; +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif +#ifdef Py_TRACE_REFS _Py_ForgetReference(unicode); +#endif new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); if (new_unicode == NULL) { From webhook-mailer at python.org Mon Feb 3 12:11:24 2020 From: webhook-mailer at python.org (Adorilson Bezerra) Date: Mon, 03 Feb 2020 17:11:24 -0000 Subject: [Python-checkins] bpo-38558: Link to further docs from walrus operator mention in tutorial (GH-16973) Message-ID: https://github.com/python/cpython/commit/5807efd4c396d5718325e21f5a14e324a77ff77c commit: 5807efd4c396d5718325e21f5a14e324a77ff77c branch: master author: Adorilson Bezerra committer: GitHub date: 2020-02-03T18:11:19+01:00 summary: bpo-38558: Link to further docs from walrus operator mention in tutorial (GH-16973) files: M Doc/faq/design.rst M Doc/tutorial/datastructures.rst diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 75cd20fb71ddf..df3dbf4977e01 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -148,6 +148,8 @@ variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use. +.. _why-can-t-i-use-an-assignment-in-an-expression: + Why can't I use an assignment in an expression? ----------------------------------------------- diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 2f7afb088f3bb..0edb73ad73691 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -676,9 +676,10 @@ to a variable. For example, :: 'Trondheim' Note that in Python, unlike C, assignment inside expressions must be done -explicitly with the walrus operator ``:=``. This avoids a common class of -problems encountered in C programs: typing ``=`` in an expression when ``==`` -was intended. +explicitly with the +:ref:`walrus operator ` ``:=``. +This avoids a common class of problems encountered in C programs: typing ``=`` +in an expression when ``==`` was intended. .. _tut-comparing: From webhook-mailer at python.org Mon Feb 3 12:17:25 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 03 Feb 2020 17:17:25 -0000 Subject: [Python-checkins] bpo-38558: Link to further docs from walrus operator mention in tutorial (GH-16973) Message-ID: https://github.com/python/cpython/commit/d01ae1b22330992eadc7b2a0842ead544f7e507d commit: d01ae1b22330992eadc7b2a0842ead544f7e507d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T09:17:17-08:00 summary: bpo-38558: Link to further docs from walrus operator mention in tutorial (GH-16973) (cherry picked from commit 5807efd4c396d5718325e21f5a14e324a77ff77c) Co-authored-by: Adorilson Bezerra files: M Doc/faq/design.rst M Doc/tutorial/datastructures.rst diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 81c0f474ac162..e7921baf242f5 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -146,6 +146,8 @@ variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use. +.. _why-can-t-i-use-an-assignment-in-an-expression: + Why can't I use an assignment in an expression? ----------------------------------------------- diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 2f7afb088f3bb..0edb73ad73691 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -676,9 +676,10 @@ to a variable. For example, :: 'Trondheim' Note that in Python, unlike C, assignment inside expressions must be done -explicitly with the walrus operator ``:=``. This avoids a common class of -problems encountered in C programs: typing ``=`` in an expression when ``==`` -was intended. +explicitly with the +:ref:`walrus operator ` ``:=``. +This avoids a common class of problems encountered in C programs: typing ``=`` +in an expression when ``==`` was intended. .. _tut-comparing: From webhook-mailer at python.org Mon Feb 3 19:30:58 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 00:30:58 -0000 Subject: [Python-checkins] Fixes in sorting descriptions (GH-18317) Message-ID: https://github.com/python/cpython/commit/fda6593f926be274225dc4bcfdc3f96d9f40258f commit: fda6593f926be274225dc4bcfdc3f96d9f40258f branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T16:30:44-08:00 summary: Fixes in sorting descriptions (GH-18317) Improvements in listsort.txt and a comment in sortperf.py. Automerge-Triggered-By: @csabella (cherry picked from commit 24e5ad4689de9adc8e4a7d8c08fe400dcea668e6) Co-authored-by: Stefan Pochmann files: M Lib/test/sortperf.py M Objects/listsort.txt diff --git a/Lib/test/sortperf.py b/Lib/test/sortperf.py index 171e5cef5e29f..14a9d827ed57c 100644 --- a/Lib/test/sortperf.py +++ b/Lib/test/sortperf.py @@ -134,7 +134,7 @@ def tabulate(r): L = list(range(half - 1, -1, -1)) L.extend(range(half)) # Force to float, so that the timings are comparable. This is - # significantly faster if we leave tham as ints. + # significantly faster if we leave them as ints. L = list(map(float, L)) doit(L) # !sort print() diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 8c877515c72e8..dc0b273d12632 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -319,13 +319,13 @@ So merging is always done on two consecutive runs at a time, and in-place, although this may require some temp memory (more on that later). When a run is identified, its base address and length are pushed on a stack -in the MergeState struct. merge_collapse() is then called to see whether it -should merge it with preceding run(s). We would like to delay merging as -long as possible in order to exploit patterns that may come up later, but we -like even more to do merging as soon as possible to exploit that the run just -found is still high in the memory hierarchy. We also can't delay merging -"too long" because it consumes memory to remember the runs that are still -unmerged, and the stack has a fixed size. +in the MergeState struct. merge_collapse() is then called to potentially +merge runs on that stack. We would like to delay merging as long as possible +in order to exploit patterns that may come up later, but we like even more to +do merging as soon as possible to exploit that the run just found is still +high in the memory hierarchy. We also can't delay merging "too long" because +it consumes memory to remember the runs that are still unmerged, and the +stack has a fixed size. What turned out to be a good compromise maintains two invariants on the stack entries, where A, B and C are the lengths of the three righmost not-yet @@ -739,7 +739,7 @@ slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1 inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has (2**k-1)-1 - 2**(k-1) + 1 = 2**k-1 - 2**(k-1) = - 2*2**k-1 - 2**(k-1) = + 2*2**(k-1)-1 - 2**(k-1) = (2-1)*2**(k-1) - 1 = 2**(k-1) - 1 elements. From webhook-mailer at python.org Mon Feb 3 19:50:36 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 00:50:36 -0000 Subject: [Python-checkins] Fixes in sorting descriptions (GH-18317) Message-ID: https://github.com/python/cpython/commit/a0389ba84bb2dbee7a59e25163e514059afc166d commit: a0389ba84bb2dbee7a59e25163e514059afc166d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-03T16:50:29-08:00 summary: Fixes in sorting descriptions (GH-18317) Improvements in listsort.txt and a comment in sortperf.py. Automerge-Triggered-By: @csabella (cherry picked from commit 24e5ad4689de9adc8e4a7d8c08fe400dcea668e6) Co-authored-by: Stefan Pochmann files: M Lib/test/sortperf.py M Objects/listsort.txt diff --git a/Lib/test/sortperf.py b/Lib/test/sortperf.py index 171e5cef5e29f..14a9d827ed57c 100644 --- a/Lib/test/sortperf.py +++ b/Lib/test/sortperf.py @@ -134,7 +134,7 @@ def tabulate(r): L = list(range(half - 1, -1, -1)) L.extend(range(half)) # Force to float, so that the timings are comparable. This is - # significantly faster if we leave tham as ints. + # significantly faster if we leave them as ints. L = list(map(float, L)) doit(L) # !sort print() diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 43fe1574c3239..174777a2658dc 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -319,13 +319,13 @@ So merging is always done on two consecutive runs at a time, and in-place, although this may require some temp memory (more on that later). When a run is identified, its base address and length are pushed on a stack -in the MergeState struct. merge_collapse() is then called to see whether it -should merge it with preceding run(s). We would like to delay merging as -long as possible in order to exploit patterns that may come up later, but we -like even more to do merging as soon as possible to exploit that the run just -found is still high in the memory hierarchy. We also can't delay merging -"too long" because it consumes memory to remember the runs that are still -unmerged, and the stack has a fixed size. +in the MergeState struct. merge_collapse() is then called to potentially +merge runs on that stack. We would like to delay merging as long as possible +in order to exploit patterns that may come up later, but we like even more to +do merging as soon as possible to exploit that the run just found is still +high in the memory hierarchy. We also can't delay merging "too long" because +it consumes memory to remember the runs that are still unmerged, and the +stack has a fixed size. What turned out to be a good compromise maintains two invariants on the stack entries, where A, B and C are the lengths of the three rightmost not-yet @@ -739,7 +739,7 @@ slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1 inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has (2**k-1)-1 - 2**(k-1) + 1 = 2**k-1 - 2**(k-1) = - 2*2**k-1 - 2**(k-1) = + 2*2**(k-1)-1 - 2**(k-1) = (2-1)*2**(k-1) - 1 = 2**(k-1) - 1 elements. From webhook-mailer at python.org Tue Feb 4 03:05:47 2020 From: webhook-mailer at python.org (Chris Withers) Date: Tue, 04 Feb 2020 08:05:47 -0000 Subject: [Python-checkins] add whatsnew that was missed from 31d6de5aba009914efa8f0f3c3d7da35217578eb (#18344) Message-ID: https://github.com/python/cpython/commit/b6999e5690c7006b0ba4049cfd638513c982a90c commit: b6999e5690c7006b0ba4049cfd638513c982a90c branch: master author: Chris Withers committer: GitHub date: 2020-02-04T08:05:25Z summary: add whatsnew that was missed from 31d6de5aba009914efa8f0f3c3d7da35217578eb (#18344) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 3b7a9d105d059..6e080c7033c7e 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -398,6 +398,8 @@ Deprecated Removed ======= +* The erroneous version at :data:`unittest.mock.__version__` has been removed. + * :class:`nntplib.NNTP`: ``xpath()`` and ``xgtitle()`` methods have been removed. These methods are deprecated since Python 3.3. Generally, these extensions are not supported or not enabled by NNTP server administrators. From webhook-mailer at python.org Tue Feb 4 05:29:50 2020 From: webhook-mailer at python.org (Eddie Elizondo) Date: Tue, 04 Feb 2020 10:29:50 -0000 Subject: [Python-checkins] bpo-38076 Clear the interpreter state only after clearing module globals (GH-18039) Message-ID: https://github.com/python/cpython/commit/4590f72259ecbcea66e12a28af14d867255d2e66 commit: 4590f72259ecbcea66e12a28af14d867255d2e66 branch: master author: Eddie Elizondo committer: GitHub date: 2020-02-04T02:29:25-08:00 summary: bpo-38076 Clear the interpreter state only after clearing module globals (GH-18039) Currently, during runtime destruction, `_PyImport_Cleanup` is clearing the interpreter state before clearing out the modules themselves. This leads to a segfault on modules that rely on the module state to clear themselves up. For example, let's take the small snippet added in the issue by @DinoV : ``` import _struct class C: def __init__(self): self.pack = _struct.pack def __del__(self): self.pack('I', -42) _struct.x = C() ``` The module `_struct` uses the module state to run `pack`. Therefore, the module state has to be alive until after the module has been cleared out to successfully run `C.__del__`. This happens at line 606, when `_PyImport_Cleanup` calls `_PyModule_Clear`. In fact, the loop that calls `_PyModule_Clear` has in its comments: > Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end up here, since they are kept alive in the interpreter state. That means that we can't clear the module state (which is used by C Extensions) before we run that loop. Moving `_PyInterpreterState_ClearModules` until after it, fixes the segfault in the code snippet. Finally, this updates a test in `io` to correctly assert the error that it now throws (since it now finds the io module state). The test that uses this is: `test_create_at_shutdown_without_encoding`. Given this test is now working is a proof that the module state now stays alive even when `__del__` is called at module destruction time. Thus, I didn't add a new tests for this. https://bugs.python.org/issue38076 files: A Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst M Lib/test/test_io.py M Lib/test/test_struct.py M Lib/test/test_sys.py M Python/import.c diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 8a123fa1dc07a..a66726e9a790a 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3683,7 +3683,7 @@ def _to_memoryview(buf): class CTextIOWrapperTest(TextIOWrapperTest): io = io - shutdown_error = "RuntimeError: could not find io module state" + shutdown_error = "LookupError: unknown encoding: ascii" def test_initialization(self): r = self.BytesIO(b"\xc3\xa9\n\n") diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 157efa1347a9b..4829fbe1b975c 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -7,6 +7,7 @@ import sys from test import support +from test.support.script_helper import assert_python_ok ISBIGENDIAN = sys.byteorder == "big" @@ -652,6 +653,23 @@ def test_format_attr(self): s2 = struct.Struct(s.format.encode()) self.assertEqual(s2.format, s.format) + def test_struct_cleans_up_at_runtime_shutdown(self): + code = """if 1: + import struct + + class C: + def __init__(self): + self.pack = struct.pack + def __del__(self): + self.pack('I', -42) + + struct.x = C() + """ + rc, stdout, stderr = assert_python_ok("-c", code) + self.assertEqual(rc, 0) + self.assertEqual(stdout.rstrip(), b"") + self.assertIn(b"Exception ignored in:", stderr) + self.assertIn(b"C.__del__", stderr) class UnpackIteratorTest(unittest.TestCase): """ diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 58701a11f919c..c5bd8a4b1ff96 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -855,6 +855,23 @@ def __del__(self, sys=sys): self.assertIn(b'sys.flags', out[0]) self.assertIn(b'sys.float_info', out[1]) + def test_sys_ignores_cleaning_up_user_data(self): + code = """if 1: + import struct, sys + + class C: + def __init__(self): + self.pack = struct.pack + def __del__(self): + self.pack('I', -42) + + sys.x = C() + """ + rc, stdout, stderr = assert_python_ok('-c', code) + self.assertEqual(rc, 0) + self.assertEqual(stdout.rstrip(), b"") + self.assertEqual(stderr.rstrip(), b"") + @unittest.skipUnless(hasattr(sys, 'getandroidapilevel'), 'need sys.getandroidapilevel()') def test_getandroidapilevel(self): diff --git a/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst b/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst new file mode 100644 index 0000000000000..d9f6dc31efd8d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst @@ -0,0 +1,2 @@ +Fix to clear the interpreter state only after clearing module globals to +guarantee module state access from C Extensions during runtime destruction diff --git a/Python/import.c b/Python/import.c index 9838c3fa04538..8bf044827c6e9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -568,8 +568,6 @@ _PyImport_Cleanup(PyThreadState *tstate) _PyErr_Clear(tstate); } Py_XDECREF(dict); - /* Clear module dict copies stored in the interpreter state */ - _PyInterpreterState_ClearModules(interp); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings @@ -621,6 +619,9 @@ _PyImport_Cleanup(PyThreadState *tstate) } _PyModule_ClearDict(interp->builtins); + /* Clear module dict copies stored in the interpreter state */ + _PyInterpreterState_ClearModules(interp); + /* Clear and delete the modules directory. Actual modules will still be there only if imported during the execution of some destructor. */ From webhook-mailer at python.org Tue Feb 4 07:42:36 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 04 Feb 2020 12:42:36 -0000 Subject: [Python-checkins] Restore PyObject_IsInstance() comment (GH-18345) Message-ID: https://github.com/python/cpython/commit/850a4bd839ca11b59439e21dda2a3ebe917a9a16 commit: 850a4bd839ca11b59439e21dda2a3ebe917a9a16 branch: master author: Victor Stinner committer: GitHub date: 2020-02-04T13:42:13+01:00 summary: Restore PyObject_IsInstance() comment (GH-18345) Restore PyObject_IsInstance() comment explaining why only tuples of types are accepted, but not general sequence. Comment written by Guido van Rossum in commit 03290ecbf1661c0192e6abdbe00ae163af461d77 which implements isinstance(x, (A, B, ...)). The comment was lost in a PyObject_IsInstance() optimization: commit ec569b794737be248671d0dfac11b664fc930eef. Cleanup also the code. recursive_isinstance() is no longer recursive, so rename it to object_isinstance(), whereas object_isinstance() is recursive and so rename it to object_recursive_isinstance(). files: M Objects/abstract.c diff --git a/Objects/abstract.c b/Objects/abstract.c index dc8ba10762de6..aca1a4e518919 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2423,7 +2423,7 @@ check_class(PyObject *cls, const char *error) } static int -recursive_isinstance(PyObject *inst, PyObject *cls) +object_isinstance(PyObject *inst, PyObject *cls) { PyObject *icls; int retval; @@ -2461,21 +2461,23 @@ recursive_isinstance(PyObject *inst, PyObject *cls) } static int -object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) +object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) { _Py_IDENTIFIER(__instancecheck__); - PyObject *checker; /* Quick test for an exact match */ - if (Py_TYPE(inst) == (PyTypeObject *)cls) + if (Py_TYPE(inst) == (PyTypeObject *)cls) { return 1; + } /* We know what type's __instancecheck__ does. */ if (PyType_CheckExact(cls)) { - return recursive_isinstance(inst, cls); + return object_isinstance(inst, cls); } if (PyTuple_Check(cls)) { + /* Not a general sequence -- that opens up the road to + recursion and stack overflow. */ if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { return -1; } @@ -2483,37 +2485,41 @@ object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) int r = 0; for (Py_ssize_t i = 0; i < n; ++i) { PyObject *item = PyTuple_GET_ITEM(cls, i); - r = object_isinstance(tstate, inst, item); - if (r != 0) + r = object_recursive_isinstance(tstate, inst, item); + if (r != 0) { /* either found it, or got an error */ break; + } } _Py_LeaveRecursiveCall(tstate); return r; } - checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); + PyObject *checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); if (checker != NULL) { - int ok = -1; if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { Py_DECREF(checker); - return ok; + return -1; } + PyObject *res = _PyObject_CallOneArg(checker, inst); _Py_LeaveRecursiveCall(tstate); Py_DECREF(checker); - if (res != NULL) { - ok = PyObject_IsTrue(res); - Py_DECREF(res); + + if (res == NULL) { + return -1; } + int ok = PyObject_IsTrue(res); + Py_DECREF(res); + return ok; } else if (_PyErr_Occurred(tstate)) { return -1; } - /* Probably never reached anymore. */ - return recursive_isinstance(inst, cls); + /* cls has no __instancecheck__() method */ + return object_isinstance(inst, cls); } @@ -2521,7 +2527,7 @@ int PyObject_IsInstance(PyObject *inst, PyObject *cls) { PyThreadState *tstate = _PyThreadState_GET(); - return object_isinstance(tstate, inst, cls); + return object_recursive_isinstance(tstate, inst, cls); } @@ -2611,7 +2617,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls) { - return recursive_isinstance(inst, cls); + return object_isinstance(inst, cls); } int From webhook-mailer at python.org Tue Feb 4 10:24:39 2020 From: webhook-mailer at python.org (Stefan Behnel) Date: Tue, 04 Feb 2020 15:24:39 -0000 Subject: [Python-checkins] bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150) Message-ID: https://github.com/python/cpython/commit/9538bc9185e934bee2bd5ae2cda2b2e92a61906d commit: 9538bc9185e934bee2bd5ae2cda2b2e92a61906d branch: master author: Stefan Behnel committer: GitHub date: 2020-02-04T07:24:30-08:00 summary: bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150) Make it export the correct init symbol also on Windows. https://bugs.python.org/issue39432 files: A Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst M Lib/distutils/command/build_ext.py M Lib/distutils/tests/test_build_ext.py diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 38bb8fd93c278..1a9bd1200f823 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -689,7 +689,15 @@ def get_export_symbols(self, ext): provided, "PyInit_" + module_name. Only relevant on Windows, where the .pyd file (DLL) must export the module "PyInit_" function. """ - initfunc_name = "PyInit_" + ext.name.split('.')[-1] + suffix = '_' + ext.name.split('.')[-1] + try: + # Unicode module name support as defined in PEP-489 + # https://www.python.org/dev/peps/pep-0489/#export-hook-name + suffix.encode('ascii') + except UnicodeEncodeError: + suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') + + initfunc_name = "PyInit" + suffix if initfunc_name not in ext.export_symbols: ext.export_symbols.append(initfunc_name) return ext.export_symbols diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 52d36b2484f41..7e3eafa8ef231 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -304,6 +304,19 @@ def test_get_source_files(self): cmd.ensure_finalized() self.assertEqual(cmd.get_source_files(), ['xxx']) + def test_unicode_module_names(self): + modules = [ + Extension('foo', ['aaa'], optional=False), + Extension('f??', ['uuu'], optional=False), + ] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = self.build_ext(dist) + cmd.ensure_finalized() + self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo\..*') + self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??\..*') + self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) + self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) + def test_compiler_option(self): # cmd.compiler is an option and # should not be overridden by a compiler instance diff --git a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst new file mode 100644 index 0000000000000..21c4ba8620755 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst @@ -0,0 +1 @@ +Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in distutils to make it export the correct init symbol also on Windows. From webhook-mailer at python.org Tue Feb 4 10:31:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 15:31:24 -0000 Subject: [Python-checkins] bpo-37224: Improve test__xxsubinterpreters.DestroyTests (GH-18058) Message-ID: https://github.com/python/cpython/commit/9a740b6c7e7a88185d79128b8a1993ac387d5091 commit: 9a740b6c7e7a88185d79128b8a1993ac387d5091 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T07:31:19-08:00 summary: bpo-37224: Improve test__xxsubinterpreters.DestroyTests (GH-18058) Adds an additional assertion check based on a race condition for `test__xxsubinterpreters.DestroyTests.test_still_running` discovered in the bpo issue. https://bugs.python.org/issue37224 (cherry picked from commit f03a8f8d5001963ad5b5b28dbd95497e9cc15596) Co-authored-by: Kyle Stanley files: M Lib/test/test__xxsubinterpreters.py diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index 207b5db5d8fb9..30f8f98acc9dd 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -759,7 +759,11 @@ def test_still_running(self): main, = interpreters.list_all() interp = interpreters.create() with _running(interp): - with self.assertRaises(RuntimeError): + self.assertTrue(interpreters.is_running(interp), + msg=f"Interp {interp} should be running before destruction.") + + with self.assertRaises(RuntimeError, + msg=f"Should not be able to destroy interp {interp} while it's still running."): interpreters.destroy(interp) self.assertTrue(interpreters.is_running(interp)) From webhook-mailer at python.org Tue Feb 4 16:25:26 2020 From: webhook-mailer at python.org (Philipp Gesang) Date: Tue, 04 Feb 2020 21:25:26 -0000 Subject: [Python-checkins] closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) Message-ID: https://github.com/python/cpython/commit/cb1c0746f277052e45a60d6c436a765e34722821 commit: cb1c0746f277052e45a60d6c436a765e34722821 branch: master author: Philipp Gesang committer: GitHub date: 2020-02-04T13:25:16-08:00 summary: closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) When called on a closed object, readinto() segfaults on account of a write to a freed buffer: ==220553== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==220553== Access not within mapped region at address 0x2A ==220553== at 0x48408A0: memmove (vg_replace_strmem.c:1272) ==220553== by 0x58DB0C: _buffered_readinto_generic (bufferedio.c:972) ==220553== by 0x58DCBA: _io__Buffered_readinto_impl (bufferedio.c:1053) ==220553== by 0x58DCBA: _io__Buffered_readinto (bufferedio.c.h:253) Reproducer: reader = open ("/dev/zero", "rb") _void = reader.read (42) reader.close () reader.readinto (bytearray (42)) ### BANG! The problem exists since 2012 when commit dc469454ec added code to free the read buffer on close(). Signed-off-by: Philipp Gesang files: A Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst M Lib/test/test_io.py M Modules/_io/bufferedio.c diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index a66726e9a790a..0bfa4d249e9a6 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -737,6 +737,11 @@ def test_read_closed(self): file.seek(0) file.close() self.assertRaises(ValueError, file.read) + with self.open(support.TESTFN, "rb") as f: + file = self.open(f.fileno(), "rb", closefd=False) + self.assertEqual(file.read()[:3], b"egg") + file.close() + self.assertRaises(ValueError, file.readinto, bytearray(1)) def test_no_closefd_with_filename(self): # can't use closefd in combination with a file name diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst new file mode 100644 index 0000000000000..9a38e4ab76228 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst @@ -0,0 +1 @@ +Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 586e93f25e28f..ddd17a2863c24 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -965,6 +965,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) PyObject *res = NULL; CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "readinto of closed file") n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { From webhook-mailer at python.org Tue Feb 4 16:42:02 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 21:42:02 -0000 Subject: [Python-checkins] closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) Message-ID: https://github.com/python/cpython/commit/30e769382dfb67a68fe8e6bfe8509addb4aa9514 commit: 30e769382dfb67a68fe8e6bfe8509addb4aa9514 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T13:41:55-08:00 summary: closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) When called on a closed object, readinto() segfaults on account of a write to a freed buffer: ==220553== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==220553== Access not within mapped region at address 0x2A ==220553== at 0x48408A0: memmove (vg_replace_strmem.c:1272) ==220553== by 0x58DB0C: _buffered_readinto_generic (bufferedio.c:972) ==220553== by 0x58DCBA: _io__Buffered_readinto_impl (bufferedio.c:1053) ==220553== by 0x58DCBA: _io__Buffered_readinto (bufferedio.c.h:253) Reproducer: reader = open ("/dev/zero", "rb") _void = reader.read (42) reader.close () reader.readinto (bytearray (42)) GH-GH-GH- BANG! The problem exists since 2012 when commit dc469454ec added code to free the read buffer on close(). Signed-off-by: Philipp Gesang (cherry picked from commit cb1c0746f277052e45a60d6c436a765e34722821) Co-authored-by: Philipp Gesang files: A Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst M Lib/test/test_io.py M Modules/_io/bufferedio.c diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 50459e0792962..bea4342e7f0f9 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -735,6 +735,11 @@ def test_read_closed(self): file.seek(0) file.close() self.assertRaises(ValueError, file.read) + with self.open(support.TESTFN, "rb") as f: + file = self.open(f.fileno(), "rb", closefd=False) + self.assertEqual(file.read()[:3], b"egg") + file.close() + self.assertRaises(ValueError, file.readinto, bytearray(1)) def test_no_closefd_with_filename(self): # can't use closefd in combination with a file name diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst new file mode 100644 index 0000000000000..9a38e4ab76228 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst @@ -0,0 +1 @@ +Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 8e8ff97ff8c67..ad7a8c9d26427 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -965,6 +965,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) PyObject *res = NULL; CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "readinto of closed file") n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { From webhook-mailer at python.org Tue Feb 4 16:43:12 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 21:43:12 -0000 Subject: [Python-checkins] closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) Message-ID: https://github.com/python/cpython/commit/97d2a9832494e4c85da124ceab18802eed9a4ab1 commit: 97d2a9832494e4c85da124ceab18802eed9a4ab1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T13:43:07-08:00 summary: closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18295) When called on a closed object, readinto() segfaults on account of a write to a freed buffer: ==220553== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==220553== Access not within mapped region at address 0x2A ==220553== at 0x48408A0: memmove (vg_replace_strmem.c:1272) ==220553== by 0x58DB0C: _buffered_readinto_generic (bufferedio.c:972) ==220553== by 0x58DCBA: _io__Buffered_readinto_impl (bufferedio.c:1053) ==220553== by 0x58DCBA: _io__Buffered_readinto (bufferedio.c.h:253) Reproducer: reader = open ("/dev/zero", "rb") _void = reader.read (42) reader.close () reader.readinto (bytearray (42)) GH-GH-GH- BANG! The problem exists since 2012 when commit dc469454ec added code to free the read buffer on close(). Signed-off-by: Philipp Gesang (cherry picked from commit cb1c0746f277052e45a60d6c436a765e34722821) Co-authored-by: Philipp Gesang files: A Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst M Lib/test/test_io.py M Modules/_io/bufferedio.c diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 42002b9acfb76..7d50037bd7e0c 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -726,6 +726,11 @@ def test_read_closed(self): file.seek(0) file.close() self.assertRaises(ValueError, file.read) + with self.open(support.TESTFN, "rb") as f: + file = self.open(f.fileno(), "rb", closefd=False) + self.assertEqual(file.read()[:3], b"egg") + file.close() + self.assertRaises(ValueError, file.readinto, bytearray(1)) def test_no_closefd_with_filename(self): # can't use closefd in combination with a file name diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst new file mode 100644 index 0000000000000..9a38e4ab76228 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst @@ -0,0 +1 @@ +Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 358a654a98ca5..9c814c342cd81 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -974,6 +974,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) PyObject *res = NULL; CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "readinto of closed file") n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { From webhook-mailer at python.org Tue Feb 4 17:06:50 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 04 Feb 2020 22:06:50 -0000 Subject: [Python-checkins] closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18350) Message-ID: https://github.com/python/cpython/commit/c352e6c7446c894b13643f538db312092b351789 commit: c352e6c7446c894b13643f538db312092b351789 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T14:06:42-08:00 summary: closes bpo-39510: Fix use-after-free in BufferedReader.readinto() (GH-18350) When called on a closed object, readinto() segfaults on account of a write to a freed buffer: ==220553== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==220553== Access not within mapped region at address 0x2A ==220553== at 0x48408A0: memmove (vg_replace_strmem.c:1272) ==220553== by 0x58DB0C: _buffered_readinto_generic (bufferedio.c:972) ==220553== by 0x58DCBA: _io__Buffered_readinto_impl (bufferedio.c:1053) ==220553== by 0x58DCBA: _io__Buffered_readinto (bufferedio.c.h:253) Reproducer: reader = open ("/dev/zero", "rb") _void = reader.read (42) reader.close () reader.readinto (bytearray (42)) GH-GH-GH- BANG! The problem exists since 2012 when commit dc469454ec added code to free the read buffer on close(). Signed-off-by: Philipp Gesang (cherry picked from commit cb1c0746f277052e45a60d6c436a765e34722821) Co-authored-by: Philipp Gesang Co-authored-by: Philipp Gesang files: A Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst M Lib/test/test_io.py M Modules/_io/bufferedio.c diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index f29c16cb47c56..4ba46563b9908 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -707,6 +707,11 @@ def test_read_closed(self): file.seek(0) file.close() self.assertRaises(ValueError, file.read) + with self.open(support.TESTFN, "rb") as f: + file = self.open(f.fileno(), "rb", closefd=False) + self.assertEqual(file.read()[:3], b"egg") + file.close() + self.assertRaises(ValueError, file.readinto, bytearray(1)) def test_no_closefd_with_filename(self): # can't use closefd in combination with a file name diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst new file mode 100644 index 0000000000000..9a38e4ab76228 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst @@ -0,0 +1 @@ +Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 32355813e88df..3e463098881fd 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -993,6 +993,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) PyObject *res = NULL; CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "readinto of closed file") n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { From webhook-mailer at python.org Tue Feb 4 19:10:22 2020 From: webhook-mailer at python.org (Baljak) Date: Wed, 05 Feb 2020 00:10:22 -0000 Subject: [Python-checkins] Fix MinGW library generation command (GH-17917) Message-ID: https://github.com/python/cpython/commit/2545fa87628b4caca519da8aeb0eeef368b9dc0d commit: 2545fa87628b4caca519da8aeb0eeef368b9dc0d branch: master author: Baljak committer: GitHub date: 2020-02-05T11:10:16+11:00 summary: Fix MinGW library generation command (GH-17917) To print the exports to stdout, the gendef command requires the option "-". Without this option, no output is generated. files: M Doc/whatsnew/3.8.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index fabc1c597eca7..cb4c518662d6b 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -2109,7 +2109,7 @@ Changes in the C API .. code-block:: shell - gendef python38.dll > tmp.def + gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a The location of an installed :file:`pythonXY.dll` will depend on the From webhook-mailer at python.org Tue Feb 4 19:11:14 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 00:11:14 -0000 Subject: [Python-checkins] bpo-39542: Make _Py_NewReference() opaque in C API (GH-18346) Message-ID: https://github.com/python/cpython/commit/40e547dfbb9052ca0c667b242f6825ed1c23c195 commit: 40e547dfbb9052ca0c667b242f6825ed1c23c195 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T01:11:10+01:00 summary: bpo-39542: Make _Py_NewReference() opaque in C API (GH-18346) _Py_NewReference() becomes a regular opaque function, rather than a static inline function in the C API (object.h), to better hide implementation details. Move _Py_tracemalloc_config from public pymem.h to internal pycore_pymem.h header. Make _Py_AddToAllObjects() private. files: M Include/internal/pycore_pymem.h M Include/object.h M Include/pymem.h M Modules/_tracemalloc.c M Objects/object.c diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 06d0d06c75c36..db153e0bd2d71 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -169,6 +169,40 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName( PYMEM_ALLOCATOR_NOT_SET does nothing. */ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); +/* bpo-35053: Expose _Py_tracemalloc_config for _Py_NewReference() + which access directly _Py_tracemalloc_config.tracing for best + performances. */ +struct _PyTraceMalloc_Config { + /* Module initialized? + Variable protected by the GIL */ + enum { + TRACEMALLOC_NOT_INITIALIZED, + TRACEMALLOC_INITIALIZED, + TRACEMALLOC_FINALIZED + } initialized; + + /* Is tracemalloc tracing memory allocations? + Variable protected by the GIL */ + int tracing; + + /* limit of the number of frames in a traceback, 1 by default. + Variable protected by the GIL. */ + int max_nframe; + + /* use domain in trace key? + Variable protected by the GIL. */ + int use_domain; +}; + +#define _PyTraceMalloc_Config_INIT \ + {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ + .tracing = 0, \ + .max_nframe = 1, \ + .use_domain = 0} + +PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; + + #ifdef __cplusplus } #endif diff --git a/Include/object.h b/Include/object.h index 175a208f0d2d7..8dccbf16971a7 100644 --- a/Include/object.h +++ b/Include/object.h @@ -1,8 +1,6 @@ #ifndef Py_OBJECT_H #define Py_OBJECT_H -#include "pymem.h" /* _Py_tracemalloc_config */ - #ifdef __cplusplus extern "C" { #endif @@ -390,28 +388,13 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); when a memory block is reused from a free list. */ PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); +PyAPI_FUNC(void) _Py_NewReference(PyObject *op); + #ifdef Py_TRACE_REFS /* Py_TRACE_REFS is such major surgery that we call external routines. */ PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); -PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); #endif - -static inline void _Py_NewReference(PyObject *op) -{ - if (_Py_tracemalloc_config.tracing) { - _PyTraceMalloc_NewReference(op); - } -#ifdef Py_REF_DEBUG - _Py_RefTotal++; -#endif - Py_REFCNT(op) = 1; -#ifdef Py_TRACE_REFS - _Py_AddToAllObjects(op, 1); -#endif -} - - PyAPI_FUNC(void) _Py_Dealloc(PyObject *); static inline void _Py_INCREF(PyObject *op) diff --git a/Include/pymem.h b/Include/pymem.h index 07b380aa6e7fa..607feb9484f24 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -101,41 +101,6 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); #define PyMem_Del PyMem_Free #define PyMem_DEL PyMem_FREE -/* bpo-35053: expose _Py_tracemalloc_config for performance: - _Py_NewReference() needs an efficient check to test if tracemalloc is - tracing. - - It has to be defined in pymem.h, before object.h is included. */ -struct _PyTraceMalloc_Config { - /* Module initialized? - Variable protected by the GIL */ - enum { - TRACEMALLOC_NOT_INITIALIZED, - TRACEMALLOC_INITIALIZED, - TRACEMALLOC_FINALIZED - } initialized; - - /* Is tracemalloc tracing memory allocations? - Variable protected by the GIL */ - int tracing; - - /* limit of the number of frames in a traceback, 1 by default. - Variable protected by the GIL. */ - int max_nframe; - - /* use domain in trace key? - Variable protected by the GIL. */ - int use_domain; -}; - -PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; - -#define _PyTraceMalloc_Config_INIT \ - {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ - .tracing = 0, \ - .max_nframe = 1, \ - .use_domain = 0} - #ifndef Py_LIMITED_API # define Py_CPYTHON_PYMEM_H diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 70219721b51cd..ddf6ef4e11dd4 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pymem.h" #include "pycore_traceback.h" #include "hashtable.h" #include "frameobject.h" diff --git a/Objects/object.c b/Objects/object.c index 085605ae36714..e6bfad4e7295e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -93,7 +93,7 @@ static PyObject refchain = {&refchain, &refchain}; * way, though; exceptions include statically allocated type objects, and * statically allocated singletons (like Py_True and Py_None). */ -void +static void _Py_AddToAllObjects(PyObject *op, int force) { #ifdef Py_DEBUG @@ -1805,6 +1805,22 @@ _PyTypes_Init(void) } +void +_Py_NewReference(PyObject *op) +{ + if (_Py_tracemalloc_config.tracing) { + _PyTraceMalloc_NewReference(op); + } +#ifdef Py_REF_DEBUG + _Py_RefTotal++; +#endif + Py_REFCNT(op) = 1; +#ifdef Py_TRACE_REFS + _Py_AddToAllObjects(op, 1); +#endif +} + + #ifdef Py_TRACE_REFS void _Py_ForgetReference(PyObject *op) From webhook-mailer at python.org Tue Feb 4 19:15:10 2020 From: webhook-mailer at python.org (Saiyang Gou) Date: Wed, 05 Feb 2020 00:15:10 -0000 Subject: [Python-checkins] bpo-39184: Add audit events to command execution functions in os and pty modules (GH-17824) Message-ID: https://github.com/python/cpython/commit/95f60010219e142a436fae18e1695cbc45407afe commit: 95f60010219e142a436fae18e1695cbc45407afe branch: master author: Saiyang Gou committer: GitHub date: 2020-02-05T11:15:00+11:00 summary: bpo-39184: Add audit events to command execution functions in os and pty modules (GH-17824) files: A Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst M Doc/library/os.rst M Doc/library/pty.rst M Lib/pty.py M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index f59423c6f2d4e..bfc03227e4ed2 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3314,6 +3314,8 @@ to be ignored. you can check whether or not it is available using :data:`os.supports_fd`. If it is unavailable, using it will raise a :exc:`NotImplementedError`. + .. audit-event:: os.exec path,args,env os.execl + .. availability:: Unix, Windows. .. versionadded:: 3.3 @@ -3670,6 +3672,8 @@ written in Python, such as a mail server's external command delivery program. :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` flags. + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawn + .. versionadded:: 3.8 .. availability:: Unix. @@ -3684,6 +3688,8 @@ written in Python, such as a mail server's external command delivery program. for the *executable* file in the list of directories specified by the :envvar:`PATH` environment variable (in the same way as for ``execvp(3)``). + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawnp + .. versionadded:: 3.8 .. availability:: See :func:`posix_spawn` documentation. @@ -3784,6 +3790,8 @@ written in Python, such as a mail server's external command delivery program. L = ['cp', 'index.html', '/dev/null'] os.spawnvpe(os.P_WAIT, 'cp', L, os.environ) + .. audit-event:: os.spawn mode,path,args,env os.spawnl + .. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and :func:`spawnve` are not thread-safe on Windows; we advise you to use the @@ -3853,6 +3861,8 @@ written in Python, such as a mail server's external command delivery program. function is not resolved until this function is first called. If the function cannot be resolved, :exc:`NotImplementedError` will be raised. + .. audit-event:: os.startfile path,operation os.startfile + .. availability:: Windows. diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 12268437d07e9..e85d2e239fdbd 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -69,6 +69,7 @@ The :mod:`pty` module defines the following functions: *select* throws an error on your platform when passed three empty lists. This is a bug, documented in `issue 26228 `_. + .. audit-event:: pty.spawn argv pty.spawn .. versionchanged:: 3.4 :func:`spawn` now returns the status value from :func:`os.waitpid` diff --git a/Lib/pty.py b/Lib/pty.py index e841f12f3edb9..a32432041fa1d 100644 --- a/Lib/pty.py +++ b/Lib/pty.py @@ -8,6 +8,7 @@ from select import select import os +import sys import tty __all__ = ["openpty","fork","spawn"] @@ -151,6 +152,7 @@ def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv,) + sys.audit('pty.spawn', argv) pid, master_fd = fork() if pid == CHILD: os.execlp(argv[0], *argv) diff --git a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst new file mode 100644 index 0000000000000..1ab5d4d70eec5 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst @@ -0,0 +1 @@ +Add audit events to command execution functions in os and pty modules. \ No newline at end of file diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b71eddf90b70e..ec3da4fb2fc6e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5234,6 +5234,12 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) return NULL; } + if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, + argv, Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WEXECV _wexecv(path->wide, argvlist); @@ -5277,7 +5283,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execve: argv must be a tuple or list"); - goto fail; + goto fail_0; } argc = PySequence_Size(argv); if (argc < 1) { @@ -5288,22 +5294,27 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (!PyMapping_Check(env)) { PyErr_SetString(PyExc_TypeError, "execve: environment must be a mapping object"); - goto fail; + goto fail_0; } argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { - goto fail; + goto fail_0; } if (!argvlist[0][0]) { PyErr_SetString(PyExc_ValueError, "execve: argv first element cannot be empty"); - goto fail; + goto fail_0; } envlist = parse_envlist(env, &envc); if (envlist == NULL) - goto fail; + goto fail_0; + + if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, + argv, env) < 0) { + goto fail_1; + } _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_FEXECVE @@ -5321,9 +5332,9 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) /* If we get here it's definitely an error */ posix_path_error(path); - + fail_1: free_string_array(envlist, envc); - fail: + fail_0: if (argvlist) free_string_array(argvlist, argc); return NULL; @@ -5654,6 +5665,11 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a } attrp = &attr; + if (PySys_Audit("os.posix_spawn", "OOO", + path->object ? path->object : Py_None, argv, env) < 0) { + goto exit; + } + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_POSIX_SPAWNP if (use_posix_spawnp) { @@ -5894,6 +5910,13 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) mode = _P_OVERLAY; #endif + if (PySys_Audit("os.spawn", "iOOO", mode, + path->object ? path->object : Py_None, argv, + Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV @@ -6003,6 +6026,11 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, mode = _P_OVERLAY; #endif + if (PySys_Audit("os.spawn", "iOOO", mode, + path->object ? path->object : Py_None, argv, env) < 0) { + goto fail_2; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV @@ -6021,6 +6049,7 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, else res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); + fail_2: while (--envc >= 0) PyMem_DEL(envlist[envc]); PyMem_DEL(envlist); @@ -11701,6 +11730,12 @@ os_startfile_impl(PyObject *module, path_t *filepath, "startfile not available on this platform"); } + if (PySys_Audit("os.startfile", "Ou", + filepath->object ? filepath->object : Py_None, + operation) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, NULL, NULL, SW_SHOWNORMAL); From webhook-mailer at python.org Tue Feb 4 19:30:25 2020 From: webhook-mailer at python.org (Anthony Shaw) Date: Wed, 05 Feb 2020 00:30:25 -0000 Subject: [Python-checkins] bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) Message-ID: https://github.com/python/cpython/commit/89ae20b30e4543f379ee647c965eb46200556496 commit: 89ae20b30e4543f379ee647c965eb46200556496 branch: master author: Anthony Shaw committer: GitHub date: 2020-02-05T11:30:19+11:00 summary: bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) files: A Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst M PCbuild/build.bat diff --git a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst new file mode 100644 index 0000000000000..3b84bd5217264 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst @@ -0,0 +1 @@ +The build.bat script has additional options for very-quiet output (-q) and very-verbose output (-vv) \ No newline at end of file diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 7c24e0b155578..ba7154d8cb1e5 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -27,6 +27,8 @@ echo. building externals. echo. -m Enable parallel build (enabled by default) echo. -M Disable parallel build echo. -v Increased output messages +echo. -vv Verbose output messages +echo. -q Quiet output messages (errors and warnings only) echo. -k Attempt to kill any running Pythons before building (usually done echo. automatically by the pythoncore project) echo. --pgo Build with Profile-Guided Optimization. This flag @@ -73,6 +75,8 @@ if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts +if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts From webhook-mailer at python.org Tue Feb 4 19:32:37 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 05 Feb 2020 00:32:37 -0000 Subject: [Python-checkins] bpo-39184: Add audit events to command execution functions in os and pty modules (GH-17824) Message-ID: https://github.com/python/cpython/commit/3498ac55bcfc18d698ea605424ec65a6e1457a39 commit: 3498ac55bcfc18d698ea605424ec65a6e1457a39 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T16:32:32-08:00 summary: bpo-39184: Add audit events to command execution functions in os and pty modules (GH-17824) (cherry picked from commit 95f60010219e142a436fae18e1695cbc45407afe) Co-authored-by: Saiyang Gou files: A Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst M Doc/library/os.rst M Doc/library/pty.rst M Lib/pty.py M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 7aadbcf773b6a..3a828c5e08563 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3313,6 +3313,8 @@ to be ignored. you can check whether or not it is available using :data:`os.supports_fd`. If it is unavailable, using it will raise a :exc:`NotImplementedError`. + .. audit-event:: os.exec path,args,env os.execl + .. availability:: Unix, Windows. .. versionadded:: 3.3 @@ -3656,6 +3658,8 @@ written in Python, such as a mail server's external command delivery program. :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` flags. + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawn + .. versionadded:: 3.8 .. availability:: Unix. @@ -3670,6 +3674,8 @@ written in Python, such as a mail server's external command delivery program. for the *executable* file in the list of directories specified by the :envvar:`PATH` environment variable (in the same way as for ``execvp(3)``). + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawnp + .. versionadded:: 3.8 .. availability:: See :func:`posix_spawn` documentation. @@ -3770,6 +3776,8 @@ written in Python, such as a mail server's external command delivery program. L = ['cp', 'index.html', '/dev/null'] os.spawnvpe(os.P_WAIT, 'cp', L, os.environ) + .. audit-event:: os.spawn mode,path,args,env os.spawnl + .. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and :func:`spawnve` are not thread-safe on Windows; we advise you to use the @@ -3839,6 +3847,8 @@ written in Python, such as a mail server's external command delivery program. function is not resolved until this function is first called. If the function cannot be resolved, :exc:`NotImplementedError` will be raised. + .. audit-event:: os.startfile path,operation os.startfile + .. availability:: Windows. diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 12268437d07e9..e85d2e239fdbd 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -69,6 +69,7 @@ The :mod:`pty` module defines the following functions: *select* throws an error on your platform when passed three empty lists. This is a bug, documented in `issue 26228 `_. + .. audit-event:: pty.spawn argv pty.spawn .. versionchanged:: 3.4 :func:`spawn` now returns the status value from :func:`os.waitpid` diff --git a/Lib/pty.py b/Lib/pty.py index e841f12f3edb9..a32432041fa1d 100644 --- a/Lib/pty.py +++ b/Lib/pty.py @@ -8,6 +8,7 @@ from select import select import os +import sys import tty __all__ = ["openpty","fork","spawn"] @@ -151,6 +152,7 @@ def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv,) + sys.audit('pty.spawn', argv) pid, master_fd = fork() if pid == CHILD: os.execlp(argv[0], *argv) diff --git a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst new file mode 100644 index 0000000000000..1ab5d4d70eec5 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst @@ -0,0 +1 @@ +Add audit events to command execution functions in os and pty modules. \ No newline at end of file diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 850769fd95eef..88b47164bca09 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5156,6 +5156,12 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) return NULL; } + if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, + argv, Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WEXECV _wexecv(path->wide, argvlist); @@ -5199,7 +5205,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execve: argv must be a tuple or list"); - goto fail; + goto fail_0; } argc = PySequence_Size(argv); if (argc < 1) { @@ -5210,22 +5216,27 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (!PyMapping_Check(env)) { PyErr_SetString(PyExc_TypeError, "execve: environment must be a mapping object"); - goto fail; + goto fail_0; } argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { - goto fail; + goto fail_0; } if (!argvlist[0][0]) { PyErr_SetString(PyExc_ValueError, "execve: argv first element cannot be empty"); - goto fail; + goto fail_0; } envlist = parse_envlist(env, &envc); if (envlist == NULL) - goto fail; + goto fail_0; + + if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, + argv, env) < 0) { + goto fail_1; + } _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_FEXECVE @@ -5243,9 +5254,9 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) /* If we get here it's definitely an error */ posix_path_error(path); - + fail_1: free_string_array(envlist, envc); - fail: + fail_0: if (argvlist) free_string_array(argvlist, argc); return NULL; @@ -5576,6 +5587,11 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a } attrp = &attr; + if (PySys_Audit("os.posix_spawn", "OOO", + path->object ? path->object : Py_None, argv, env) < 0) { + goto exit; + } + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_POSIX_SPAWNP if (use_posix_spawnp) { @@ -5816,6 +5832,13 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) mode = _P_OVERLAY; #endif + if (PySys_Audit("os.spawn", "iOOO", mode, + path->object ? path->object : Py_None, argv, + Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV @@ -5925,6 +5948,11 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, mode = _P_OVERLAY; #endif + if (PySys_Audit("os.spawn", "iOOO", mode, + path->object ? path->object : Py_None, argv, env) < 0) { + goto fail_2; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV @@ -5943,6 +5971,7 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, else res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); + fail_2: while (--envc >= 0) PyMem_DEL(envlist[envc]); PyMem_DEL(envlist); @@ -11608,6 +11637,12 @@ os_startfile_impl(PyObject *module, path_t *filepath, "startfile not available on this platform"); } + if (PySys_Audit("os.startfile", "Ou", + filepath->object ? filepath->object : Py_None, + operation) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, NULL, NULL, SW_SHOWNORMAL); From webhook-mailer at python.org Tue Feb 4 19:47:23 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 05 Feb 2020 00:47:23 -0000 Subject: [Python-checkins] bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) Message-ID: https://github.com/python/cpython/commit/6ba8dc6aae6fa0a7e29ba4ac18227beb38872392 commit: 6ba8dc6aae6fa0a7e29ba4ac18227beb38872392 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T16:47:18-08:00 summary: bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) (cherry picked from commit 89ae20b30e4543f379ee647c965eb46200556496) Co-authored-by: Anthony Shaw files: A Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst M PCbuild/build.bat diff --git a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst new file mode 100644 index 0000000000000..3b84bd5217264 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst @@ -0,0 +1 @@ +The build.bat script has additional options for very-quiet output (-q) and very-verbose output (-vv) \ No newline at end of file diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 759aa5221b426..69d43156c62fe 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -27,6 +27,8 @@ echo. building externals. echo. -m Enable parallel build (enabled by default) echo. -M Disable parallel build echo. -v Increased output messages +echo. -vv Verbose output messages +echo. -q Quiet output messages (errors and warnings only) echo. -k Attempt to kill any running Pythons before building (usually done echo. automatically by the pythoncore project) echo. --pgo Build with Profile-Guided Optimization. This flag @@ -71,6 +73,8 @@ if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts +if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts From webhook-mailer at python.org Tue Feb 4 19:48:06 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 05 Feb 2020 00:48:06 -0000 Subject: [Python-checkins] bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) Message-ID: https://github.com/python/cpython/commit/6470a7643018b357adcd88f77ae2a196f41cb351 commit: 6470a7643018b357adcd88f77ae2a196f41cb351 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-04T16:48:01-08:00 summary: bpo-39185 Add the d[etailed] and q[uiet] verbosity levels for msbuild (GH-17791) (cherry picked from commit 89ae20b30e4543f379ee647c965eb46200556496) Co-authored-by: Anthony Shaw files: A Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst M PCbuild/build.bat diff --git a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst new file mode 100644 index 0000000000000..3b84bd5217264 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst @@ -0,0 +1 @@ +The build.bat script has additional options for very-quiet output (-q) and very-verbose output (-vv) \ No newline at end of file diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 623409c24ec04..7f9de1f5b3f55 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -27,6 +27,8 @@ echo. building externals. echo. -m Enable parallel build (enabled by default) echo. -M Disable parallel build echo. -v Increased output messages +echo. -vv Verbose output messages +echo. -q Quiet output messages (errors and warnings only) echo. -k Attempt to kill any running Pythons before building (usually done echo. automatically by the pythoncore project) echo. --pgo Build with Profile-Guided Optimization. This flag @@ -72,6 +74,8 @@ if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts +if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts From webhook-mailer at python.org Tue Feb 4 20:10:32 2020 From: webhook-mailer at python.org (Jakub Stasiak) Date: Wed, 05 Feb 2020 01:10:32 -0000 Subject: [Python-checkins] bpo-39491: Merge PEP 593 (typing.Annotated) support (#18260) Message-ID: https://github.com/python/cpython/commit/cf5b109dbb39bcff1bc5b5d22036866d11de971b commit: cf5b109dbb39bcff1bc5b5d22036866d11de971b branch: master author: Jakub Stasiak committer: GitHub date: 2020-02-04T17:10:19-08:00 summary: bpo-39491: Merge PEP 593 (typing.Annotated) support (#18260) * bpo-39491: Merge PEP 593 (typing.Annotated) support PEP 593 has been accepted some time ago. I got a green light for merging this from Till, so I went ahead and combined the code contributed to typing_extensions[1] and the documentation from the PEP 593 text[2]. My changes were limited to: * removing code designed for typing_extensions to run on older Python versions * removing some irrelevant parts of the PEP text when copying it over as documentation and otherwise changing few small bits to better serve the purpose * changing the get_type_hints signature to match reality (parameter names) I wasn't entirely sure how to go about crediting the authors but I used my best judgment, let me know if something needs changing in this regard. [1] https://github.com/python/typing/blob/8280de241fd8c8afe727c7860254b753e383b360/typing_extensions/src_py3/typing_extensions.py [2] https://github.com/python/peps/blob/17710b879882454d55f82c2d44596e8e9f8e4bff/pep-0593.rst files: A Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst M Doc/library/typing.rst M Doc/whatsnew/3.9.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 323dac2082201..d3bab94c6dd40 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1028,7 +1028,7 @@ The module defines the following classes, functions and decorators: runtime we intentionally don't check anything (we want this to be as fast as possible). -.. function:: get_type_hints(obj[, globals[, locals]]) +.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) Return a dictionary containing type hints for a function, method, module or class object. @@ -1041,6 +1041,22 @@ The module defines the following classes, functions and decorators: a dictionary constructed by merging all the ``__annotations__`` along ``C.__mro__`` in reverse order. + The function recursively replaces all ``Annotated[T, ...]`` with ``T``, + unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for + more information). For example:: + + class Student(NamedTuple): + name: Annotated[str, 'some marker'] + + get_type_hints(Student) == {'name': str} + get_type_hints(Student, include_extras=False) == {'name': str} + get_type_hints(Student, include_extras=True) == { + 'name': Annotated[str, 'some marker'] + } + + .. versionchanged:: 3.9 + Added ``include_extras`` parameter as part of :pep:`593`. + .. function:: get_origin(tp) .. function:: get_args(tp) @@ -1372,3 +1388,87 @@ The module defines the following classes, functions and decorators: evaluated, so the second annotation does not need to be enclosed in quotes. .. versionadded:: 3.5.2 + +.. data:: Annotated + + A type, introduced in :pep:`593` (``Flexible function and variable + annotations``), to decorate existing types with context-specific metadata + (possibly multiple pieces of it, as ``Annotated`` is variadic). + Specifically, a type ``T`` can be annotated with metadata ``x`` via the + typehint ``Annotated[T, x]``. This metadata can be used for either static + analysis or at runtime. If a library (or tool) encounters a typehint + ``Annotated[T, x]`` and has no special logic for metadata ``x``, it + should ignore it and simply treat the type as ``T``. Unlike the + ``no_type_check`` functionality that currently exists in the ``typing`` + module which completely disables typechecking annotations on a function + or a class, the ``Annotated`` type allows for both static typechecking + of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) + together with runtime access to ``x`` within a specific application. + + Ultimately, the responsibility of how to interpret the annotations (if + at all) is the responsibility of the tool or library encountering the + ``Annotated`` type. A tool or library encountering an ``Annotated`` type + can scan through the annotations to determine if they are of interest + (e.g., using ``isinstance()``). + + When a tool or a library does not support annotations or encounters an + unknown annotation it should just ignore it and treat annotated type as + the underlying type. + + It's up to the tool consuming the annotations to decide whether the + client is allowed to have several annotations on one type and how to + merge those annotations. + + Since the ``Annotated`` type allows you to put several annotations of + the same (or different) type(s) on any node, the tools or libraries + consuming those annotations are in charge of dealing with potential + duplicates. For example, if you are doing value range analysis you might + allow this:: + + T1 = Annotated[int, ValueRange(-10, 5)] + T2 = Annotated[T1, ValueRange(-20, 3)] + + Passing ``include_extras=True`` to :func:`get_type_hints` lets one + access the extra annotations at runtime. + + The details of the syntax: + + * The first argument to ``Annotated`` must be a valid type + + * Multiple type annotations are supported (``Annotated`` supports variadic + arguments):: + + Annotated[int, ValueRange(3, 10), ctype("char")] + + * ``Annotated`` must be called with at least two arguments ( + ``Annotated[int]`` is not valid) + + * The order of the annotations is preserved and matters for equality + checks:: + + Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ + int, ctype("char"), ValueRange(3, 10) + ] + + * Nested ``Annotated`` types are flattened, with metadata ordered + starting with the innermost annotation:: + + Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ + int, ValueRange(3, 10), ctype("char") + ] + + * Duplicated annotations are not removed:: + + Annotated[int, ValueRange(3, 10)] != Annotated[ + int, ValueRange(3, 10), ValueRange(3, 10) + ] + + * ``Annotated`` can be used with nested and generic aliases:: + + T = TypeVar('T') + Vec = Annotated[List[Tuple[T, T]], MaxLen(10)] + V = Vec[int] + + V == Annotated[List[Tuple[int, int]], MaxLen(10)] + + .. versionadded:: 3.9 diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 6e080c7033c7e..66caf3f6f8213 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -303,6 +303,14 @@ 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`) +typing +------ + +:pep:`593` introduced an :data:`typing.Annotated` type to decorate existing +types with context-specific metadata and new ``include_extras`` parameter to +:func:`typing.get_type_hints` to access the metadata at runtime. (Contributed +by Till Varoquaux and Konstantin Kashin.) + Optimizations ============= diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 5b4916f9c3260..bc6a3db4e0064 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -22,6 +22,7 @@ from typing import NamedTuple, TypedDict from typing import IO, TextIO, BinaryIO from typing import Pattern, Match +from typing import Annotated import abc import typing import weakref @@ -2891,6 +2892,64 @@ def test_get_type_hints_wrapped_decoratored_func(self): self.assertEqual(gth(ForRefExample.func), expects) self.assertEqual(gth(ForRefExample.nested), expects) + def test_get_type_hints_annotated(self): + def foobar(x: List['X']): ... + X = Annotated[int, (1, 10)] + self.assertEqual( + get_type_hints(foobar, globals(), locals()), + {'x': List[int]} + ) + self.assertEqual( + get_type_hints(foobar, globals(), locals(), include_extras=True), + {'x': List[Annotated[int, (1, 10)]]} + ) + BA = Tuple[Annotated[T, (1, 0)], ...] + def barfoo(x: BA): ... + self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) + self.assertIs( + get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], + BA + ) + def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]], + y: typing.Union[int, Annotated[T, "mutable"]]): ... + self.assertEqual( + get_type_hints(barfoo2, globals(), locals()), + {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]} + ) + BA2 = typing.Callable[..., List[T]] + def barfoo3(x: BA2): ... + self.assertIs( + get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"], + BA2 + ) + + def test_get_type_hints_annotated_refs(self): + + Const = Annotated[T, "Const"] + + class MySet(Generic[T]): + + def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]": + ... + + def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]": + ... + + self.assertEqual( + get_type_hints(MySet.__iand__, globals(), locals()), + {'other': MySet[T], 'return': MySet[T]} + ) + + self.assertEqual( + get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True), + {'other': Const[MySet[T]], 'return': MySet[T]} + ) + + self.assertEqual( + get_type_hints(MySet.__ior__, globals(), locals()), + {'other': MySet[T], 'return': MySet[T]} + ) + class GetUtilitiesTestCase(TestCase): def test_get_origin(self): @@ -2906,6 +2965,7 @@ class C(Generic[T]): pass self.assertIs(get_origin(Generic), Generic) self.assertIs(get_origin(Generic[T]), Generic) self.assertIs(get_origin(List[Tuple[T, T]][int]), list) + self.assertIs(get_origin(Annotated[T, 'thing']), Annotated) def test_get_args(self): T = TypeVar('T') @@ -2926,6 +2986,7 @@ class C(Generic[T]): pass (int, Callable[[Tuple[T, ...]], str])) self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) self.assertEqual(get_args(Tuple[()]), ((),)) + self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) class CollectionsAbcTests(BaseTestCase): @@ -3844,6 +3905,179 @@ class A(typing.Match): "type 're.Match' is not an acceptable base type") +class AnnotatedTests(BaseTestCase): + + def test_repr(self): + self.assertEqual( + repr(Annotated[int, 4, 5]), + "typing.Annotated[int, 4, 5]" + ) + self.assertEqual( + repr(Annotated[List[int], 4, 5]), + "typing.Annotated[typing.List[int], 4, 5]" + ) + + def test_flatten(self): + A = Annotated[Annotated[int, 4], 5] + self.assertEqual(A, Annotated[int, 4, 5]) + self.assertEqual(A.__metadata__, (4, 5)) + self.assertEqual(A.__origin__, int) + + def test_specialize(self): + L = Annotated[List[T], "my decoration"] + LI = Annotated[List[int], "my decoration"] + self.assertEqual(L[int], Annotated[List[int], "my decoration"]) + self.assertEqual(L[int].__metadata__, ("my decoration",)) + self.assertEqual(L[int].__origin__, List[int]) + with self.assertRaises(TypeError): + LI[int] + with self.assertRaises(TypeError): + L[int, float] + + def test_hash_eq(self): + self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) + self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) + self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) + self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) + self.assertEqual( + {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, + {Annotated[int, 4, 5], Annotated[T, 4, 5]} + ) + + def test_instantiate(self): + class C: + classvar = 4 + + def __init__(self, x): + self.x = x + + def __eq__(self, other): + if not isinstance(other, C): + return NotImplemented + return other.x == self.x + + A = Annotated[C, "a decoration"] + a = A(5) + c = C(5) + self.assertEqual(a, c) + self.assertEqual(a.x, c.x) + self.assertEqual(a.classvar, c.classvar) + + def test_instantiate_generic(self): + MyCount = Annotated[typing.Counter[T], "my decoration"] + self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1}) + self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1}) + + def test_cannot_instantiate_forward(self): + A = Annotated["int", (5, 6)] + with self.assertRaises(TypeError): + A(5) + + def test_cannot_instantiate_type_var(self): + A = Annotated[T, (5, 6)] + with self.assertRaises(TypeError): + A(5) + + def test_cannot_getattr_typevar(self): + with self.assertRaises(AttributeError): + Annotated[T, (5, 7)].x + + def test_attr_passthrough(self): + class C: + classvar = 4 + + A = Annotated[C, "a decoration"] + self.assertEqual(A.classvar, 4) + A.x = 5 + self.assertEqual(C.x, 5) + + def test_hash_eq(self): + self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) + self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) + self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) + self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) + self.assertEqual( + {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, + {Annotated[int, 4, 5], Annotated[T, 4, 5]} + ) + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"): + class C(Annotated): + pass + + def test_cannot_check_instance(self): + with self.assertRaises(TypeError): + isinstance(5, Annotated[int, "positive"]) + + def test_cannot_check_subclass(self): + with self.assertRaises(TypeError): + issubclass(int, Annotated[int, "positive"]) + + def test_pickle(self): + samples = [typing.Any, typing.Union[int, str], + typing.Optional[str], Tuple[int, ...], + typing.Callable[[str], bytes]] + + for t in samples: + x = Annotated[t, "a"] + + for prot in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=prot, type=t): + pickled = pickle.dumps(x, prot) + restored = pickle.loads(pickled) + self.assertEqual(x, restored) + + global _Annotated_test_G + + class _Annotated_test_G(Generic[T]): + x = 1 + + G = Annotated[_Annotated_test_G[int], "A decoration"] + G.foo = 42 + G.bar = 'abc' + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(G, proto) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.x, 1) + + def test_subst(self): + dec = "a decoration" + dec2 = "another decoration" + + S = Annotated[T, dec2] + self.assertEqual(S[int], Annotated[int, dec2]) + + self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2]) + L = Annotated[List[T], dec] + + self.assertEqual(L[int], Annotated[List[int], dec]) + with self.assertRaises(TypeError): + L[int, int] + + self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2]) + + D = Annotated[typing.Dict[KT, VT], dec] + self.assertEqual(D[str, int], Annotated[typing.Dict[str, int], dec]) + with self.assertRaises(TypeError): + D[int] + + It = Annotated[int, dec] + with self.assertRaises(TypeError): + It[None] + + LI = L[int] + with self.assertRaises(TypeError): + LI[None] + + def test_annotated_in_other_types(self): + X = List[Annotated[T, 5]] + self.assertEqual(X[int], List[Annotated[int, 5]]) + + class AllTests(BaseTestCase): """Tests for __all__.""" diff --git a/Lib/typing.py b/Lib/typing.py index 28c887ed35e0b..5a7077c27c42a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -31,6 +31,7 @@ # Please keep __all__ alphabetized within each category. __all__ = [ # Super-special typing primitives. + 'Annotated', 'Any', 'Callable', 'ClassVar', @@ -1118,6 +1119,101 @@ def _proto_hook(other): cls.__init__ = _no_init +class _AnnotatedAlias(_GenericAlias, _root=True): + """Runtime representation of an annotated type. + + At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' + with extra annotations. The alias behaves like a normal typing alias, + instantiating is the same as instantiating the underlying type, binding + it to types is also the same. + """ + def __init__(self, origin, metadata): + if isinstance(origin, _AnnotatedAlias): + metadata = origin.__metadata__ + metadata + origin = origin.__origin__ + super().__init__(origin, origin) + self.__metadata__ = metadata + + def copy_with(self, params): + assert len(params) == 1 + new_type = params[0] + return _AnnotatedAlias(new_type, self.__metadata__) + + def __repr__(self): + return "typing.Annotated[{}, {}]".format( + _type_repr(self.__origin__), + ", ".join(repr(a) for a in self.__metadata__) + ) + + def __reduce__(self): + return operator.getitem, ( + Annotated, (self.__origin__,) + self.__metadata__ + ) + + def __eq__(self, other): + if not isinstance(other, _AnnotatedAlias): + return NotImplemented + if self.__origin__ != other.__origin__: + return False + return self.__metadata__ == other.__metadata__ + + def __hash__(self): + return hash((self.__origin__, self.__metadata__)) + + +class Annotated: + """Add context specific metadata to a type. + + Example: Annotated[int, runtime_check.Unsigned] indicates to the + hypothetical runtime_check module that this type is an unsigned int. + Every other consumer of this type can ignore this metadata and treat + this type as int. + + The first argument to Annotated must be a valid type. + + Details: + + - It's an error to call `Annotated` with less than two arguments. + - Nested Annotated are flattened:: + + Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] + + - Instantiating an annotated type is equivalent to instantiating the + underlying type:: + + Annotated[C, Ann1](5) == C(5) + + - Annotated can be used as a generic type alias:: + + Optimized = Annotated[T, runtime.Optimize()] + Optimized[int] == Annotated[int, runtime.Optimize()] + + OptimizedList = Annotated[List[T], runtime.Optimize()] + OptimizedList[int] == Annotated[List[int], runtime.Optimize()] + """ + + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise TypeError("Type Annotated cannot be instantiated.") + + @_tp_cache + def __class_getitem__(cls, params): + if not isinstance(params, tuple) or len(params) < 2: + raise TypeError("Annotated[...] should be used " + "with at least two arguments (a type and an " + "annotation).") + msg = "Annotated[t, ...]: t must be a type." + origin = _type_check(params[0], msg) + metadata = tuple(params[1:]) + return _AnnotatedAlias(origin, metadata) + + def __init_subclass__(cls, *args, **kwargs): + raise TypeError( + "Cannot subclass {}.Annotated".format(cls.__module__) + ) + + def runtime_checkable(cls): """Mark a protocol class as a runtime protocol. @@ -1179,12 +1275,13 @@ def _get_defaults(func): WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) -def get_type_hints(obj, globalns=None, localns=None): +def get_type_hints(obj, globalns=None, localns=None, include_extras=False): """Return type hints for an object. This is often the same as obj.__annotations__, but it handles - forward references encoded as string literals, and if necessary - adds Optional[t] if a default value equal to None is set. + forward references encoded as string literals, adds Optional[t] if a + default value equal to None is set and recursively replaces all + 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). The argument may be a module, class, method, or function. The annotations are returned as a dictionary. For classes, annotations include also @@ -1228,7 +1325,7 @@ def get_type_hints(obj, globalns=None, localns=None): value = ForwardRef(value, is_argument=False) value = _eval_type(value, base_globals, localns) hints[name] = value - return hints + return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} if globalns is None: if isinstance(obj, types.ModuleType): @@ -1262,7 +1359,22 @@ def get_type_hints(obj, globalns=None, localns=None): if name in defaults and defaults[name] is None: value = Optional[value] hints[name] = value - return hints + return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} + + +def _strip_annotations(t): + """Strips the annotations from a given type. + """ + if isinstance(t, _AnnotatedAlias): + return _strip_annotations(t.__origin__) + if isinstance(t, _GenericAlias): + stripped_args = tuple(_strip_annotations(a) for a in t.__args__) + if stripped_args == t.__args__: + return t + res = t.copy_with(stripped_args) + res._special = t._special + return res + return t def get_origin(tp): @@ -1279,6 +1391,8 @@ def get_origin(tp): get_origin(Union[T, int]) is Union get_origin(List[Tuple[T, T]][int]) == list """ + if isinstance(tp, _AnnotatedAlias): + return Annotated if isinstance(tp, _GenericAlias): return tp.__origin__ if tp is Generic: @@ -1297,6 +1411,8 @@ def get_args(tp): get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) get_args(Callable[[], T][int]) == ([], int) """ + if isinstance(tp, _AnnotatedAlias): + return (tp.__origin__,) + tp.__metadata__ if isinstance(tp, _GenericAlias): res = tp.__args__ if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: diff --git a/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst b/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst new file mode 100644 index 0000000000000..1dd36454dc243 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst @@ -0,0 +1,3 @@ +Add :data:`typing.Annotated` and ``include_extras`` parameter to +:func:`typing.get_type_hints` as part of :pep:`593`. Patch by Till +Varoquaux, documentation by Till Varoquaux and Konstantin Kashin. From webhook-mailer at python.org Tue Feb 4 22:13:08 2020 From: webhook-mailer at python.org (Zackery Spytz) Date: Wed, 05 Feb 2020 03:13:08 -0000 Subject: [Python-checkins] bpo-39553: Delete HAVE_SXS protected code (GH-18356) Message-ID: https://github.com/python/cpython/commit/b439a715cb75e2663df32588fd004c7528b9f83b commit: b439a715cb75e2663df32588fd004c7528b9f83b branch: master author: Zackery Spytz committer: GitHub date: 2020-02-04T19:13:00-08:00 summary: bpo-39553: Delete HAVE_SXS protected code (GH-18356) https://bugs.python.org/issue39553 Automerge-Triggered-By: @zooba files: A Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst M PC/dl_nt.c M PC/pyconfig.h M Python/dynload_win.c diff --git a/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst b/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst new file mode 100644 index 0000000000000..bf6496fa561db --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst @@ -0,0 +1 @@ +Delete unused code related to SxS manifests. diff --git a/PC/dl_nt.c b/PC/dl_nt.c index c87c51eb559f9..0bf04f1bf3d79 100644 --- a/PC/dl_nt.c +++ b/PC/dl_nt.c @@ -23,68 +23,6 @@ char dllVersionBuffer[16] = ""; // a private buffer HMODULE PyWin_DLLhModule = NULL; const char *PyWin_DLLVersionString = dllVersionBuffer; -#if HAVE_SXS -// Windows "Activation Context" work. -// Our .pyd extension modules are generally built without a manifest (ie, -// those included with Python and those built with a default distutils. -// This requires we perform some "activation context" magic when loading our -// extensions. In summary: -// * As our DLL loads we save the context being used. -// * Before loading our extensions we re-activate our saved context. -// * After extension load is complete we restore the old context. -// As an added complication, this magic only works on XP or later - we simply -// use the existence (or not) of the relevant function pointers from kernel32. -// See bug 4566 (http://python.org/sf/4566) for more details. -// In Visual Studio 2010, side by side assemblies are no longer used by -// default. - -typedef BOOL (WINAPI * PFN_GETCURRENTACTCTX)(HANDLE *); -typedef BOOL (WINAPI * PFN_ACTIVATEACTCTX)(HANDLE, ULONG_PTR *); -typedef BOOL (WINAPI * PFN_DEACTIVATEACTCTX)(DWORD, ULONG_PTR); -typedef BOOL (WINAPI * PFN_ADDREFACTCTX)(HANDLE); -typedef BOOL (WINAPI * PFN_RELEASEACTCTX)(HANDLE); - -// locals and function pointers for this activation context magic. -static HANDLE PyWin_DLLhActivationContext = NULL; // one day it might be public -static PFN_GETCURRENTACTCTX pfnGetCurrentActCtx = NULL; -static PFN_ACTIVATEACTCTX pfnActivateActCtx = NULL; -static PFN_DEACTIVATEACTCTX pfnDeactivateActCtx = NULL; -static PFN_ADDREFACTCTX pfnAddRefActCtx = NULL; -static PFN_RELEASEACTCTX pfnReleaseActCtx = NULL; - -void _LoadActCtxPointers() -{ - HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - if (hKernel32) - pfnGetCurrentActCtx = (PFN_GETCURRENTACTCTX) GetProcAddress(hKernel32, "GetCurrentActCtx"); - // If we can't load GetCurrentActCtx (ie, pre XP) , don't bother with the rest. - if (pfnGetCurrentActCtx) { - pfnActivateActCtx = (PFN_ACTIVATEACTCTX) GetProcAddress(hKernel32, "ActivateActCtx"); - pfnDeactivateActCtx = (PFN_DEACTIVATEACTCTX) GetProcAddress(hKernel32, "DeactivateActCtx"); - pfnAddRefActCtx = (PFN_ADDREFACTCTX) GetProcAddress(hKernel32, "AddRefActCtx"); - pfnReleaseActCtx = (PFN_RELEASEACTCTX) GetProcAddress(hKernel32, "ReleaseActCtx"); - } -} - -ULONG_PTR _Py_ActivateActCtx() -{ - ULONG_PTR ret = 0; - if (PyWin_DLLhActivationContext && pfnActivateActCtx) - if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) { - OutputDebugString("Python failed to activate the activation context before loading a DLL\n"); - ret = 0; // no promise the failing function didn't change it! - } - return ret; -} - -void _Py_DeactivateActCtx(ULONG_PTR cookie) -{ - if (cookie && pfnDeactivateActCtx) - if (!(*pfnDeactivateActCtx)(0, cookie)) - OutputDebugString("Python failed to de-activate the activation context\n"); -} -#endif /* HAVE_SXS */ - BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) @@ -98,22 +36,9 @@ BOOL WINAPI DllMain (HANDLE hInst, // 1000 is a magic number I picked out of the air. Could do with a #define, I spose... LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer)); #endif - -#if HAVE_SXS - // and capture our activation context for use when loading extensions. - _LoadActCtxPointers(); - if (pfnGetCurrentActCtx && pfnAddRefActCtx) - if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) - if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext)) - OutputDebugString("Python failed to load the default activation context\n"); -#endif break; case DLL_PROCESS_DETACH: -#if HAVE_SXS - if (pfnReleaseActCtx) - (*pfnReleaseActCtx)(PyWin_DLLhActivationContext); -#endif break; } return TRUE; diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 6a437ce24bb3d..424c5be370927 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -195,11 +195,6 @@ typedef int pid_t; #define Py_IS_FINITE(X) _finite(X) #define copysign _copysign -/* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/ -#if _MSC_VER >= 1400 && _MSC_VER < 1600 -#define HAVE_SXS 1 -#endif - /* define some ANSI types that are not defined in earlier Win headers */ #if _MSC_VER >= 1200 /* This file only exists in VC 6.0 or higher */ diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 6deba1134e2a4..2bf3384b9eb5e 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -12,12 +12,6 @@ #include "patchlevel.h" #include -// "activation context" magic - see dl_nt.c... -#if HAVE_SXS -extern ULONG_PTR _Py_ActivateActCtx(); -void _Py_DeactivateActCtx(ULONG_PTR cookie); -#endif - #ifdef _DEBUG #define PYD_DEBUG_SUFFIX "_d" #else @@ -187,16 +181,10 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { HINSTANCE hDLL = NULL; unsigned int old_mode; -#if HAVE_SXS - ULONG_PTR cookie = 0; -#endif /* Don't display a message box when Python can't load a DLL */ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); -#if HAVE_SXS - cookie = _Py_ActivateActCtx(); -#endif /* bpo-36085: We use LoadLibraryEx with restricted search paths to avoid DLL preloading attacks and enable use of the AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to @@ -206,9 +194,6 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); Py_END_ALLOW_THREADS -#if HAVE_SXS - _Py_DeactivateActCtx(cookie); -#endif /* restore old error mode settings */ SetErrorMode(old_mode); From webhook-mailer at python.org Wed Feb 5 03:17:07 2020 From: webhook-mailer at python.org (schwarzichet) Date: Wed, 05 Feb 2020 08:17:07 -0000 Subject: [Python-checkins] bpo-39505: delete the redundant '/' in $env:VIRTUAL_ENV (GH-18290) Message-ID: https://github.com/python/cpython/commit/787b6d548c250f36df6d3f3179f60d754c8aa5e3 commit: 787b6d548c250f36df6d3f3179f60d754c8aa5e3 branch: master author: schwarzichet <15522755+schwarzichet at users.noreply.github.com> committer: GitHub date: 2020-02-05T08:16:58Z summary: bpo-39505: delete the redundant '/' in $env:VIRTUAL_ENV (GH-18290) files: M Lib/venv/scripts/common/Activate.ps1 diff --git a/Lib/venv/scripts/common/Activate.ps1 b/Lib/venv/scripts/common/Activate.ps1 index 699c84097f1ac..98cb1b85d11c6 100644 --- a/Lib/venv/scripts/common/Activate.ps1 +++ b/Lib/venv/scripts/common/Activate.ps1 @@ -168,7 +168,6 @@ if ($VenvDir) { } else { Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - $VenvDir = $VenvDir.Insert($VenvDir.Length, "/") Write-Verbose "VenvDir=$VenvDir" } From webhook-mailer at python.org Wed Feb 5 03:39:41 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 05 Feb 2020 08:39:41 -0000 Subject: [Python-checkins] bpo-39505: delete the redundant '/' in $env:VIRTUAL_ENV (GH-18290) (GH-18359) Message-ID: https://github.com/python/cpython/commit/927d3aab1c7874b5705fcc8269ea608315434e66 commit: 927d3aab1c7874b5705fcc8269ea608315434e66 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-05T08:39:36Z summary: bpo-39505: delete the redundant '/' in $env:VIRTUAL_ENV (GH-18290) (GH-18359) (cherry picked from commit 787b6d548c250f36df6d3f3179f60d754c8aa5e3) Co-authored-by: schwarzichet <15522755+schwarzichet at users.noreply.github.com> files: M Lib/venv/scripts/common/Activate.ps1 diff --git a/Lib/venv/scripts/common/Activate.ps1 b/Lib/venv/scripts/common/Activate.ps1 index 699c84097f1ac..98cb1b85d11c6 100644 --- a/Lib/venv/scripts/common/Activate.ps1 +++ b/Lib/venv/scripts/common/Activate.ps1 @@ -168,7 +168,6 @@ if ($VenvDir) { } else { Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - $VenvDir = $VenvDir.Insert($VenvDir.Length, "/") Write-Verbose "VenvDir=$VenvDir" } From webhook-mailer at python.org Wed Feb 5 06:19:00 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 11:19:00 -0000 Subject: [Python-checkins] bpo-39543: Remove unused _Py_Dealloc() macro (GH-18361) Message-ID: https://github.com/python/cpython/commit/f16433a73138f279642e581074135694ddcfe965 commit: f16433a73138f279642e581074135694ddcfe965 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T12:18:28+01:00 summary: bpo-39543: Remove unused _Py_Dealloc() macro (GH-18361) The macro is defined after Py_DECREF() and so is no longer used by Py_DECREF(). Moving _Py_Dealloc() macro back from cpython/object.h to object.h would require to move a lot of definitions as well: PyTypeObject and many related types used by PyTypeObject. Keep _Py_Dealloc() as an opaque function call to avoid leaking implementation details in the limited C API (object.h): remove _Py_Dealloc() macro from cpython/object.h. files: M Include/cpython/object.h M Objects/object.c diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 5fcad55c5c960..70f189c85698f 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -327,16 +327,6 @@ _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, #define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) -static inline void _Py_Dealloc_inline(PyObject *op) -{ - destructor dealloc = Py_TYPE(op)->tp_dealloc; -#ifdef Py_TRACE_REFS - _Py_ForgetReference(op); -#endif - (*dealloc)(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/Objects/object.c b/Objects/object.c index e6bfad4e7295e..1884819b982c4 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2162,8 +2162,6 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, } -#undef _Py_Dealloc - void _Py_Dealloc(PyObject *op) { From webhook-mailer at python.org Wed Feb 5 06:23:33 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 11:23:33 -0000 Subject: [Python-checkins] bpo-39542: Exclude trashcan from the limited C API (GH-18362) Message-ID: https://github.com/python/cpython/commit/0fa4f43db086ac3459811cca4ec5201ffbee694a commit: 0fa4f43db086ac3459811cca4ec5201ffbee694a branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T12:23:27+01:00 summary: bpo-39542: Exclude trashcan from the limited C API (GH-18362) Exclude trashcan mechanism from the limited C API: it requires access to PyTypeObject and PyThreadState structure fields, whereas these structures are opaque in the limited C API. The trashcan mechanism never worked with the limited C API. Move it from object.h to cpython/object.h. files: A Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst M Include/cpython/object.h M Include/object.h diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 70f189c85698f..3c4bf5bb5949a 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -445,6 +445,92 @@ PyAPI_FUNC(int) _PyObject_CheckConsistency( PyObject *op, int check_content); + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack overflows, +especially in threads (which typically have less stack space to work with). + +A container object can avoid this by bracketing the body of its tp_dealloc +function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_BEGIN(p, mytype_dealloc) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_END // there should be no code after this +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into (N-1)/(PyTrash_UNWIND_LEVEL-1) pieces, +with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. + +Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base +class, we need to ensure that the trashcan is only triggered on the tp_dealloc +of the actual class being deallocated. Otherwise we might end up with a +partially-deallocated object. To check this, the tp_dealloc function must be +passed as second argument to Py_TRASHCAN_BEGIN(). +*/ + +/* The new thread-safe private API, invoked by the macros below. */ +PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); + +#define PyTrash_UNWIND_LEVEL 50 + +#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \ + do { \ + PyThreadState *_tstate = NULL; \ + /* If "cond" is false, then _tstate remains NULL and the deallocator \ + * is run normally without involving the trashcan */ \ + if (cond) { \ + _tstate = PyThreadState_GET(); \ + if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \ + /* Store the object (to be deallocated later) and jump past \ + * Py_TRASHCAN_END, skipping the body of the deallocator */ \ + _PyTrash_thread_deposit_object(_PyObject_CAST(op)); \ + break; \ + } \ + ++_tstate->trash_delete_nesting; \ + } + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_END \ + if (_tstate) { \ + --_tstate->trash_delete_nesting; \ + if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \ + _PyTrash_thread_destroy_chain(); \ + } \ + } while (0); + +#define Py_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN_CONDITION(op, \ + Py_TYPE(op)->tp_dealloc == (destructor)(dealloc)) + +/* For backwards compatibility, these macros enable the trashcan + * unconditionally */ +#define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1) +#define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END + #ifdef __cplusplus } #endif diff --git a/Include/object.h b/Include/object.h index 8dccbf16971a7..4506757d2dc8b 100644 --- a/Include/object.h +++ b/Include/object.h @@ -607,93 +607,6 @@ it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at times. */ - -/* Trashcan mechanism, thanks to Christian Tismer. - -When deallocating a container object, it's possible to trigger an unbounded -chain of deallocations, as each Py_DECREF in turn drops the refcount on "the -next" object in the chain to 0. This can easily lead to stack overflows, -especially in threads (which typically have less stack space to work with). - -A container object can avoid this by bracketing the body of its tp_dealloc -function with a pair of macros: - -static void -mytype_dealloc(mytype *p) -{ - ... declarations go here ... - - PyObject_GC_UnTrack(p); // must untrack first - Py_TRASHCAN_BEGIN(p, mytype_dealloc) - ... The body of the deallocator goes here, including all calls ... - ... to Py_DECREF on contained objects. ... - Py_TRASHCAN_END // there should be no code after this -} - -CAUTION: Never return from the middle of the body! If the body needs to -"get out early", put a label immediately before the Py_TRASHCAN_END -call, and goto it. Else the call-depth counter (see below) will stay -above 0 forever, and the trashcan will never get emptied. - -How it works: The BEGIN macro increments a call-depth counter. So long -as this counter is small, the body of the deallocator is run directly without -further ado. But if the counter gets large, it instead adds p to a list of -objects to be deallocated later, skips the body of the deallocator, and -resumes execution after the END macro. The tp_dealloc routine then returns -without deallocating anything (and so unbounded call-stack depth is avoided). - -When the call stack finishes unwinding again, code generated by the END macro -notices this, and calls another routine to deallocate all the objects that -may have been added to the list of deferred deallocations. In effect, a -chain of N deallocations is broken into (N-1)/(PyTrash_UNWIND_LEVEL-1) pieces, -with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. - -Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base -class, we need to ensure that the trashcan is only triggered on the tp_dealloc -of the actual class being deallocated. Otherwise we might end up with a -partially-deallocated object. To check this, the tp_dealloc function must be -passed as second argument to Py_TRASHCAN_BEGIN(). -*/ - -/* The new thread-safe private API, invoked by the macros below. */ -PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*); -PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); - -#define PyTrash_UNWIND_LEVEL 50 - -#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \ - do { \ - PyThreadState *_tstate = NULL; \ - /* If "cond" is false, then _tstate remains NULL and the deallocator \ - * is run normally without involving the trashcan */ \ - if (cond) { \ - _tstate = PyThreadState_GET(); \ - if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \ - /* Store the object (to be deallocated later) and jump past \ - * Py_TRASHCAN_END, skipping the body of the deallocator */ \ - _PyTrash_thread_deposit_object(_PyObject_CAST(op)); \ - break; \ - } \ - ++_tstate->trash_delete_nesting; \ - } - /* The body of the deallocator is here. */ -#define Py_TRASHCAN_END \ - if (_tstate) { \ - --_tstate->trash_delete_nesting; \ - if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \ - _PyTrash_thread_destroy_chain(); \ - } \ - } while (0); - -#define Py_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN_CONDITION(op, \ - Py_TYPE(op)->tp_dealloc == (destructor)(dealloc)) - -/* For backwards compatibility, these macros enable the trashcan - * unconditionally */ -#define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1) -#define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END - - #ifndef Py_LIMITED_API # define Py_CPYTHON_OBJECT_H # include "cpython/object.h" diff --git a/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst b/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst new file mode 100644 index 0000000000000..5829d6e97480e --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst @@ -0,0 +1,3 @@ +Exclude trashcan mechanism from the limited C API: it requires access to +PyTypeObject and PyThreadState structure fields, whereas these structures +are opaque in the limited C API. From webhook-mailer at python.org Wed Feb 5 07:12:27 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 12:12:27 -0000 Subject: [Python-checkins] bpo-39542: Make PyObject_INIT() opaque in limited C API (GH-18363) Message-ID: https://github.com/python/cpython/commit/f58bd7c1693fe041f7296a5778d0a11287895648 commit: f58bd7c1693fe041f7296a5778d0a11287895648 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T13:12:19+01:00 summary: bpo-39542: Make PyObject_INIT() opaque in limited C API (GH-18363) In the limited C API, PyObject_INIT() and PyObject_INIT_VAR() are now defined as aliases to PyObject_Init() and PyObject_InitVar() to make their implementation opaque. It avoids to leak implementation details in the limited C API. Exclude the following functions from the limited C API, move them from object.h to cpython/object.h: * _Py_NewReference() * _Py_ForgetReference() * _PyTraceMalloc_NewReference() * _Py_GetRefTotal() files: A Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst M Include/cpython/object.h M Include/cpython/objimpl.h M Include/object.h M Include/objimpl.h M Objects/object.c diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 3c4bf5bb5949a..e36f824eeb356 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -6,6 +6,22 @@ extern "C" { #endif +PyAPI_FUNC(void) _Py_NewReference(PyObject *op); + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +#endif + +/* Update the Python traceback of an object. This function must be called + when a memory block is reused from a free list. */ +PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); + +#ifdef Py_REF_DEBUG +PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +#endif + + /********************* String Literals ****************************************/ /* This structure helps managing static strings. The basic usage goes like this: Instead of doing diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index f121922bc42ce..3f148146f67a4 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -6,6 +6,39 @@ extern "C" { #endif +/* Inline functions trading binary compatibility for speed: + PyObject_INIT() is the fast version of PyObject_Init(), and + PyObject_INIT_VAR() is the fast version of PyObject_InitVar(). + + These inline functions must not be called with op=NULL. */ +static inline PyObject* +_PyObject_INIT(PyObject *op, PyTypeObject *typeobj) +{ + assert(op != NULL); + Py_TYPE(op) = typeobj; + if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(typeobj); + } + _Py_NewReference(op); + return op; +} + +#define PyObject_INIT(op, typeobj) \ + _PyObject_INIT(_PyObject_CAST(op), (typeobj)) + +static inline PyVarObject* +_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) +{ + assert(op != NULL); + Py_SIZE(op) = size; + PyObject_INIT((PyObject *)op, typeobj); + return op; +} + +#define PyObject_INIT_VAR(op, typeobj, size) \ + _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size)) + + /* This function returns the number of allocated memory blocks, regardless of size */ PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); diff --git a/Include/object.h b/Include/object.h index 4506757d2dc8b..91855d0aa8ae1 100644 --- a/Include/object.h +++ b/Include/object.h @@ -233,8 +233,7 @@ PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); -PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, - PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(int) PyObject_GenericSetDict(PyObject *, PyObject *, void *); #endif @@ -381,20 +380,8 @@ you can count such references to the type object.) PyAPI_DATA(Py_ssize_t) _Py_RefTotal; PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op); -PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); #endif /* Py_REF_DEBUG */ -/* Update the Python traceback of an object. This function must be called - when a memory block is reused from a free list. */ -PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); - -PyAPI_FUNC(void) _Py_NewReference(PyObject *op); - -#ifdef Py_TRACE_REFS -/* Py_TRACE_REFS is such major surgery that we call external routines. */ -PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); -#endif - PyAPI_FUNC(void) _Py_Dealloc(PyObject *); static inline void _Py_INCREF(PyObject *op) diff --git a/Include/objimpl.h b/Include/objimpl.h index 2337d8a56c774..45919251f43a5 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -127,40 +127,21 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) -/* Inline functions trading binary compatibility for speed: - PyObject_INIT() is the fast version of PyObject_Init(), and - PyObject_INIT_VAR() is the fast version of PyObject_InitVar. - See also pymem.h. - - These inline functions expect non-NULL object pointers. */ -static inline PyObject* -_PyObject_INIT(PyObject *op, PyTypeObject *typeobj) -{ - assert(op != NULL); - Py_TYPE(op) = typeobj; - if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { - Py_INCREF(typeobj); - } - _Py_NewReference(op); - return op; -} - -#define PyObject_INIT(op, typeobj) \ - _PyObject_INIT(_PyObject_CAST(op), (typeobj)) +#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) -static inline PyVarObject* -_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) -{ - assert(op != NULL); - Py_SIZE(op) = size; - PyObject_INIT((PyObject *)op, typeobj); - return op; -} -#define PyObject_INIT_VAR(op, typeobj, size) \ - _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size)) +#ifdef Py_LIMITED_API +/* Define PyObject_INIT() and PyObject_INIT_VAR() as aliases to PyObject_Init() + and PyObject_InitVar() in the limited C API for compatibility with the + CPython C API. */ +# define PyObject_INIT(op, typeobj) \ + PyObject_Init(_PyObject_CAST(op), (typeobj)) +# define PyObject_INIT_VAR(op, typeobj, size) \ + PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size)) +#else +/* PyObject_INIT() and PyObject_INIT_VAR() are defined in cpython/objimpl.h */ +#endif -#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a vrbl-size object with nitems items, exclusive of gc overhead (if any). The diff --git a/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst b/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst new file mode 100644 index 0000000000000..7473577b0a943 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst @@ -0,0 +1,7 @@ +In the limited C API, ``PyObject_INIT()`` and ``PyObject_INIT_VAR()`` are +now defined as aliases to :c:func:`PyObject_Init` and +:c:func:`PyObject_InitVar` to make their implementation opaque. It avoids to +leak implementation details in the limited C API. Exclude the following +functions from the limited C API: ``_Py_NewReference()``, +``_Py_ForgetReference()``, ``_PyTraceMalloc_NewReference()`` and +``_Py_GetRefTotal()``. diff --git a/Objects/object.c b/Objects/object.c index 1884819b982c4..43b838adff20c 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -139,9 +139,11 @@ Py_DecRef(PyObject *o) PyObject * PyObject_Init(PyObject *op, PyTypeObject *tp) { - if (op == NULL) + /* Any changes should be reflected in PyObject_INIT() macro */ + if (op == NULL) { return PyErr_NoMemory(); - /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ + } + Py_TYPE(op) = tp; if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(tp); @@ -153,9 +155,11 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) PyVarObject * PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) { - if (op == NULL) + /* Any changes should be reflected in PyObject_INIT_VAR() macro */ + if (op == NULL) { return (PyVarObject *) PyErr_NoMemory(); - /* Any changes should be reflected in PyObject_INIT_VAR */ + } + Py_SIZE(op) = size; PyObject_Init((PyObject *)op, tp); return op; From webhook-mailer at python.org Wed Feb 5 08:24:47 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 13:24:47 -0000 Subject: [Python-checkins] bpo-39542: Convert PyType_Check() to static inline function (GH-18364) Message-ID: https://github.com/python/cpython/commit/509dd90f4684e40af3105dd3e754fa4b9c1530c1 commit: 509dd90f4684e40af3105dd3e754fa4b9c1530c1 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T14:24:17+01:00 summary: bpo-39542: Convert PyType_Check() to static inline function (GH-18364) Convert PyType_HasFeature(), PyType_Check() and PyType_CheckExact() macros to static inline functions. files: A Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst M Doc/c-api/type.rst M Include/cpython/object.h M Include/object.h diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 41956b7dca503..f774ca35edab9 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -21,14 +21,14 @@ Type Objects .. c:function:: int PyType_Check(PyObject *o) - Return true if the object *o* is a type object, including instances of types - derived from the standard type object. Return false in all other cases. + Return non-zero if the object *o* is a type object, including instances of + types derived from the standard type object. Return 0 in all other cases. .. c:function:: int PyType_CheckExact(PyObject *o) - Return true if the object *o* is a type object, but not a subtype of the - standard type object. Return false in all other cases. + Return non-zero if the object *o* is a type object, but not a subtype of the + standard type object. Return 0 in all other cases. .. c:function:: unsigned int PyType_ClearCache() @@ -57,8 +57,8 @@ Type Objects .. c:function:: int PyType_HasFeature(PyTypeObject *o, int feature) - Return true if the type object *o* sets the feature *feature*. Type features - are denoted by single bit flags. + Return non-zero if the type object *o* sets the feature *feature*. + Type features are denoted by single bit flags. .. c:function:: int PyType_IS_GC(PyTypeObject *o) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index e36f824eeb356..0b5260eda7d8a 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -341,8 +341,6 @@ PyAPI_FUNC(int) _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, PyObject *, PyObject *); -#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) - PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); /* Safely decref `op` and set `op` to `op2`. diff --git a/Include/object.h b/Include/object.h index 91855d0aa8ae1..3a20e666202d5 100644 --- a/Include/object.h +++ b/Include/object.h @@ -207,10 +207,6 @@ PyAPI_DATA(struct _typeobject) PySuper_Type; /* built-in 'super' */ PyAPI_FUNC(unsigned long) PyType_GetFlags(struct _typeobject*); -#define PyType_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) -#define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type) - PyAPI_FUNC(int) PyType_Ready(struct _typeobject *); PyAPI_FUNC(PyObject *) PyType_GenericAlloc(struct _typeobject *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyType_GenericNew(struct _typeobject *, @@ -342,11 +338,6 @@ given type object has a specified feature. /* Type structure has tp_finalize member (3.4) */ #define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) -#ifdef Py_LIMITED_API -# define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0) -#endif -#define PyType_FastSubclass(t,f) PyType_HasFeature(t,f) - /* The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement @@ -600,6 +591,28 @@ times. # undef Py_CPYTHON_OBJECT_H #endif + +static inline int +PyType_HasFeature(PyTypeObject *type, unsigned long feature) { +#ifdef Py_LIMITED_API + return ((PyType_GetFlags(type) & feature) != 0); +#else + return ((type->tp_flags & feature) != 0); +#endif +} + +#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag) + +static inline int _PyType_Check(PyObject *op) { + return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS); +} +#define PyType_Check(op) _PyType_Check(_PyObject_CAST(op)) + +static inline int _PyType_CheckExact(PyObject *op) { + return (Py_TYPE(op) == &PyType_Type); +} +#define PyType_CheckExact(op) _PyType_CheckExact(_PyObject_CAST(op)) + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst b/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst new file mode 100644 index 0000000000000..46fb1d257e8e9 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst @@ -0,0 +1,2 @@ +Convert :c:func:`PyType_HasFeature`, :c:func:`PyType_Check` and +:c:func:`PyType_CheckExact` macros to static inline functions. From webhook-mailer at python.org Wed Feb 5 09:10:57 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 14:10:57 -0000 Subject: [Python-checkins] bpo-39542: Define PyTypeObject earlier in object.h (GH-18366) Message-ID: https://github.com/python/cpython/commit/0e4e735d06967145b49fd00693627f3624991dbc commit: 0e4e735d06967145b49fd00693627f3624991dbc branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T15:10:39+01:00 summary: bpo-39542: Define PyTypeObject earlier in object.h (GH-18366) Replace "struct _typeobject" with PyTypeObject in object.h. files: M Include/object.h diff --git a/Include/object.h b/Include/object.h index 3a20e666202d5..e7e9c1b8ed752 100644 --- a/Include/object.h +++ b/Include/object.h @@ -61,6 +61,9 @@ whose size is determined when the object is allocated. #error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG #endif +/* PyTypeObject structure is defined in cpython/object.h. + In Py_LIMITED_API, PyTypeObject is an opaque structure. */ +typedef struct _typeobject PyTypeObject; #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ @@ -102,7 +105,7 @@ whose size is determined when the object is allocated. typedef struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; - struct _typeobject *ob_type; + PyTypeObject *ob_type; } PyObject; /* Cast argument to PyObject* type. */ @@ -165,15 +168,8 @@ typedef PyObject *(*iternextfunc) (PyObject *); typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); -typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); -typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); - -#ifdef Py_LIMITED_API -/* In Py_LIMITED_API, PyTypeObject is an opaque structure. */ -typedef struct _typeobject PyTypeObject; -#else -/* PyTypeObject is defined in cpython/object.h */ -#endif +typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); typedef struct{ int slot; /* slot id, see below */ @@ -193,26 +189,26 @@ PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 -PyAPI_FUNC(void*) PyType_GetSlot(struct _typeobject*, int); +PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); #endif /* Generic type check */ -PyAPI_FUNC(int) PyType_IsSubtype(struct _typeobject *, struct _typeobject *); +PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) -PyAPI_DATA(struct _typeobject) PyType_Type; /* built-in 'type' */ -PyAPI_DATA(struct _typeobject) PyBaseObject_Type; /* built-in 'object' */ -PyAPI_DATA(struct _typeobject) PySuper_Type; /* built-in 'super' */ +PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ +PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ -PyAPI_FUNC(unsigned long) PyType_GetFlags(struct _typeobject*); +PyAPI_FUNC(unsigned long) PyType_GetFlags(PyTypeObject*); -PyAPI_FUNC(int) PyType_Ready(struct _typeobject *); -PyAPI_FUNC(PyObject *) PyType_GenericAlloc(struct _typeobject *, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyType_GenericNew(struct _typeobject *, +PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); +PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); PyAPI_FUNC(unsigned int) PyType_ClearCache(void); -PyAPI_FUNC(void) PyType_Modified(struct _typeobject *); +PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); /* Generic operations on objects */ PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); From webhook-mailer at python.org Wed Feb 5 11:40:14 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 16:40:14 -0000 Subject: [Python-checkins] Add PyInterpreterState.fs_codec.utf8 (GH-18367) Message-ID: https://github.com/python/cpython/commit/bf305cc6f05948f264349a6a6c6fd7d49c1839d3 commit: bf305cc6f05948f264349a6a6c6fd7d49c1839d3 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T17:39:57+01:00 summary: Add PyInterpreterState.fs_codec.utf8 (GH-18367) Add a fast-path for UTF-8 encoding in PyUnicode_EncodeFSDefault() and PyUnicode_DecodeFSDefaultAndSize(). Add _PyUnicode_FiniEncodings() helper function for _PyUnicode_Fini(). files: M Include/internal/pycore_pystate.h M Objects/unicodeobject.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index b78ed69042527..405efb9f46060 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -102,6 +102,7 @@ struct _is { Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ struct { char *encoding; /* Filesystem encoding (encoded to UTF-8) */ + int utf8; /* encoding=="utf-8"? */ char *errors; /* Filesystem errors (encoded to UTF-8) */ _Py_error_handler error_handler; } fs_codec; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5f10437a1524c..7c8bc06252a1e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3615,39 +3615,32 @@ PyObject * PyUnicode_EncodeFSDefault(PyObject *unicode) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); -#ifdef _Py_FORCE_UTF8_FS_ENCODING - if (interp->fs_codec.encoding) { + if (interp->fs_codec.utf8) { return unicode_encode_utf8(unicode, interp->fs_codec.error_handler, interp->fs_codec.errors); } - else { - const wchar_t *filesystem_errors = interp->config.filesystem_errors; - _Py_error_handler errors; - errors = get_error_handler_wide(filesystem_errors); - assert(errors != _Py_ERROR_UNKNOWN); - return unicode_encode_utf8(unicode, errors, NULL); - } -#else - /* Bootstrap check: if the filesystem codec is implemented in Python, we - cannot use it to encode and decode filenames before it is loaded. Load - the Python codec requires to encode at least its own filename. Use the C - implementation of the locale codec until the codec registry is - initialized and the Python codec is loaded. - See _PyUnicode_InitEncodings(). */ - if (interp->fs_codec.encoding) { +#ifndef _Py_FORCE_UTF8_FS_ENCODING + else if (interp->fs_codec.encoding) { return PyUnicode_AsEncodedString(unicode, interp->fs_codec.encoding, interp->fs_codec.errors); } +#endif else { + /* Before _PyUnicode_InitEncodings() is called, the Python codec + machinery is not ready and so cannot be used: + use wcstombs() in this case. */ const wchar_t *filesystem_errors = interp->config.filesystem_errors; - _Py_error_handler errors; - errors = get_error_handler_wide(filesystem_errors); + assert(filesystem_errors != NULL); + _Py_error_handler errors = get_error_handler_wide(filesystem_errors); assert(errors != _Py_ERROR_UNKNOWN); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + return unicode_encode_utf8(unicode, errors, NULL); +#else return unicode_encode_locale(unicode, errors, 0); - } #endif + } } PyObject * @@ -3857,39 +3850,33 @@ PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); -#ifdef _Py_FORCE_UTF8_FS_ENCODING - if (interp->fs_codec.encoding) { + if (interp->fs_codec.utf8) { return unicode_decode_utf8(s, size, interp->fs_codec.error_handler, interp->fs_codec.errors, NULL); } - else { - const wchar_t *filesystem_errors = interp->config.filesystem_errors; - _Py_error_handler errors; - errors = get_error_handler_wide(filesystem_errors); - assert(errors != _Py_ERROR_UNKNOWN); - return unicode_decode_utf8(s, size, errors, NULL, NULL); - } -#else - /* Bootstrap check: if the filesystem codec is implemented in Python, we - cannot use it to encode and decode filenames before it is loaded. Load - the Python codec requires to encode at least its own filename. Use the C - implementation of the locale codec until the codec registry is - initialized and the Python codec is loaded. - See _PyUnicode_InitEncodings(). */ - if (interp->fs_codec.encoding) { +#ifndef _Py_FORCE_UTF8_FS_ENCODING + else if (interp->fs_codec.encoding) { return PyUnicode_Decode(s, size, interp->fs_codec.encoding, interp->fs_codec.errors); } +#endif else { + /* Before _PyUnicode_InitEncodings() is called, the Python codec + machinery is not ready and so cannot be used: + use mbstowcs() in this case. */ const wchar_t *filesystem_errors = interp->config.filesystem_errors; - _Py_error_handler errors; - errors = get_error_handler_wide(filesystem_errors); + assert(filesystem_errors != NULL); + _Py_error_handler errors = get_error_handler_wide(filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + return unicode_decode_utf8(s, size, errors, NULL, NULL); +#else return unicode_decode_locale(s, size, errors, 0); - } #endif + } } @@ -15849,10 +15836,16 @@ init_fs_codec(PyInterpreterState *interp) PyMem_RawFree(interp->fs_codec.encoding); interp->fs_codec.encoding = encoding; + /* encoding has been normalized by init_fs_encoding() */ + interp->fs_codec.utf8 = (strcmp(encoding, "utf-8") == 0); PyMem_RawFree(interp->fs_codec.errors); interp->fs_codec.errors = errors; interp->fs_codec.error_handler = error_handler; +#ifdef _Py_FORCE_UTF8_FS_ENCODING + assert(interp->fs_codec.utf8 == 1); +#endif + /* At this point, PyUnicode_EncodeFSDefault() and PyUnicode_DecodeFSDefault() can now use the Python codec rather than the C implementation of the filesystem encoding. */ @@ -15902,6 +15895,19 @@ _PyUnicode_InitEncodings(PyThreadState *tstate) } +static void +_PyUnicode_FiniEncodings(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + PyMem_RawFree(interp->fs_codec.encoding); + interp->fs_codec.encoding = NULL; + interp->fs_codec.utf8 = 0; + PyMem_RawFree(interp->fs_codec.errors); + interp->fs_codec.errors = NULL; + interp->fs_codec.error_handler = _Py_ERROR_UNKNOWN; +} + + #ifdef MS_WINDOWS int _PyUnicode_EnableLegacyWindowsFSEncoding(void) @@ -15954,12 +15960,7 @@ _PyUnicode_Fini(PyThreadState *tstate) _PyUnicode_ClearStaticStrings(); } - 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 = (wchar_t *)_Py_ERROR_UNKNOWN; + _PyUnicode_FiniEncodings(tstate); } From webhook-mailer at python.org Wed Feb 5 12:21:02 2020 From: webhook-mailer at python.org (Giampaolo Rodola) Date: Wed, 05 Feb 2020 17:21:02 -0000 Subject: [Python-checkins] bpo-39488: Skip test_largefile tests if not enough disk space (GH-18261) Message-ID: https://github.com/python/cpython/commit/b39fb8e847ac59b539ad7e93df91c1709815180e commit: b39fb8e847ac59b539ad7e93df91c1709815180e branch: master author: Giampaolo Rodola committer: GitHub date: 2020-02-05T18:20:52+01:00 summary: bpo-39488: Skip test_largefile tests if not enough disk space (GH-18261) files: M Lib/test/test_largefile.py diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index e309282d73e2a..c254b047e1ec5 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -151,9 +151,24 @@ def test_seekable(self): self.assertTrue(f.seekable()) +def skip_no_disk_space(path, required): + def decorator(fun): + def wrapper(*args, **kwargs): + if shutil.disk_usage(os.path.realpath(path)).free < required: + hsize = int(required / 1024 / 1024) + raise unittest.SkipTest( + f"required {hsize} MiB of free disk space") + return fun(*args, **kwargs) + return wrapper + return decorator + + class TestCopyfile(LargeFileTest, unittest.TestCase): open = staticmethod(io.open) + # Exact required disk space would be (size * 2), but let's give it a + # bit more tolerance. + @skip_no_disk_space(TESTFN, size * 2.5) def test_it(self): # Internally shutil.copyfile() can use "fast copy" methods like # os.sendfile(). @@ -200,6 +215,9 @@ def run(sock): self.thread.start() event.set() + # Exact required disk space would be (size * 2), but let's give it a + # bit more tolerance. + @skip_no_disk_space(TESTFN, size * 2.5) def test_it(self): port = find_unused_port() with socket.create_server(("", port)) as sock: From webhook-mailer at python.org Wed Feb 5 12:24:42 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 05 Feb 2020 17:24:42 -0000 Subject: [Python-checkins] bpo-39542: Declare _Py_AddToAllObjects() in pycore_object.h (GH-18368) Message-ID: https://github.com/python/cpython/commit/58f4e1a6ee4c6ea82f3f5075d9d9d344ce6b8a56 commit: 58f4e1a6ee4c6ea82f3f5075d9d9d344ce6b8a56 branch: master author: Victor Stinner committer: GitHub date: 2020-02-05T18:24:33+01:00 summary: bpo-39542: Declare _Py_AddToAllObjects() in pycore_object.h (GH-18368) _Py_AddToAllObjects() is used in bltinmodule.c and typeobject.c when Py_TRACE_REFS is defined. Fix Py_TRACE_REFS build. files: M Include/internal/pycore_object.h M Objects/object.c M Python/bltinmodule.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index eac39c8a3fccc..10a5746997ec7 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -82,6 +82,7 @@ extern void _PyDebug_PrintTotalRefs(void); #endif #ifdef Py_TRACE_REFS +extern void _Py_AddToAllObjects(PyObject *op, int force); extern void _Py_PrintReferences(FILE *); extern void _Py_PrintReferenceAddresses(FILE *); #endif diff --git a/Objects/object.c b/Objects/object.c index 43b838adff20c..9eaa163bdfd1f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -93,7 +93,7 @@ static PyObject refchain = {&refchain, &refchain}; * way, though; exceptions include statically allocated type objects, and * statically allocated singletons (like Py_True and Py_None). */ -static void +void _Py_AddToAllObjects(PyObject *op, int force) { #ifdef Py_DEBUG diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5818eb9e38f6a..cdb1eaaff01de 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_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" @@ -2443,7 +2444,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) would change the value of empty. In fact, using in-place addition rather that binary addition for any of the steps introduces subtle behavior changes: - + https://bugs.python.org/issue18305 */ temp = PyNumber_Add(result, item); Py_DECREF(result); From webhook-mailer at python.org Wed Feb 5 15:43:19 2020 From: webhook-mailer at python.org (Shantanu) Date: Wed, 05 Feb 2020 20:43:19 -0000 Subject: [Python-checkins] bpo-39559: Remove unused, undocumented argument from uuid.getnode (GH-18369) Message-ID: https://github.com/python/cpython/commit/8b6f6526f857bb7523b0fcff09b45bc6471289e9 commit: 8b6f6526f857bb7523b0fcff09b45bc6471289e9 branch: master author: Shantanu committer: GitHub date: 2020-02-05T22:43:09+02:00 summary: bpo-39559: Remove unused, undocumented argument from uuid.getnode (GH-18369) files: A Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst M Lib/uuid.py diff --git a/Lib/uuid.py b/Lib/uuid.py index 6a436d371a3fd..224a766ff2297 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -757,7 +757,7 @@ def _random_getnode(): _node = None -def getnode(*, getters=None): +def getnode(): """Get the hardware address as a 48-bit positive integer. The first time this runs, it may launch a separate program, which could diff --git a/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst b/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst new file mode 100644 index 0000000000000..881f26bdb7bac --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst @@ -0,0 +1 @@ +Remove unused, undocumented argument ``getters`` from :func:`uuid.getnode` \ No newline at end of file From webhook-mailer at python.org Wed Feb 5 16:10:05 2020 From: webhook-mailer at python.org (Andy Lester) Date: Wed, 05 Feb 2020 21:10:05 -0000 Subject: [Python-checkins] bpo-39127: Make _Py_HashPointer's argument be const (GH-17690) Message-ID: https://github.com/python/cpython/commit/3d06953c34fd6421dd1dfdb615578cde676ee0eb commit: 3d06953c34fd6421dd1dfdb615578cde676ee0eb branch: master author: Andy Lester committer: GitHub date: 2020-02-05T23:09:57+02:00 summary: bpo-39127: Make _Py_HashPointer's argument be const (GH-17690) files: M Include/pyhash.h M Python/pyhash.c diff --git a/Include/pyhash.h b/Include/pyhash.h index dbcc9744be35a..2f398589cee7e 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -8,7 +8,7 @@ extern "C" { /* Helpers for hash functions */ #ifndef Py_LIMITED_API PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); -PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*); +PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); #endif diff --git a/Python/pyhash.c b/Python/pyhash.c index 4c0b929586fc1..d381dc0230c5b 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -129,7 +129,7 @@ _Py_HashDouble(double v) } Py_hash_t -_Py_HashPointer(void *p) +_Py_HashPointer(const void *p) { Py_hash_t x; size_t y = (size_t)p; From webhook-mailer at python.org Wed Feb 5 23:48:18 2020 From: webhook-mailer at python.org (Steve Dower) Date: Thu, 06 Feb 2020 04:48:18 -0000 Subject: [Python-checkins] bpo-39555: Fix distutils test to handle _d suffix on Windows debug build (GH-18357) Message-ID: https://github.com/python/cpython/commit/ab0d892288f3058856a8213333e8c3e4ed8a562b commit: ab0d892288f3058856a8213333e8c3e4ed8a562b branch: master author: Steve Dower committer: GitHub date: 2020-02-06T15:48:10+11:00 summary: bpo-39555: Fix distutils test to handle _d suffix on Windows debug build (GH-18357) files: M Lib/distutils/tests/test_build_ext.py diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 7e3eafa8ef231..5e47e0773a964 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -312,8 +312,8 @@ def test_unicode_module_names(self): dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = self.build_ext(dist) cmd.ensure_finalized() - self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo\..*') - self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??\..*') + self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo(_d)?\..*') + self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??(_d)?\..*') self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) From webhook-mailer at python.org Thu Feb 6 03:26:42 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 06 Feb 2020 08:26:42 -0000 Subject: [Python-checkins] bpo-38149: Call sys.audit() only once per call for glob.glob(). (GH-18360) Message-ID: https://github.com/python/cpython/commit/54b4f14712b9350f11c983f1c8ac47a3716958a7 commit: 54b4f14712b9350f11c983f1c8ac47a3716958a7 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-06T10:26:37+02:00 summary: bpo-38149: Call sys.audit() only once per call for glob.glob(). (GH-18360) files: A Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst M Lib/glob.py diff --git a/Lib/glob.py b/Lib/glob.py index 0b3fcc6bbb9af..0dd2f8be66109 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -31,6 +31,7 @@ def iglob(pathname, *, recursive=False): If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ + sys.audit("glob.glob", pathname, recursive) it = _iglob(pathname, recursive, False) if recursive and _isrecursive(pathname): s = next(it) # skip empty string @@ -38,7 +39,6 @@ def iglob(pathname, *, recursive=False): return it def _iglob(pathname, recursive, dironly): - sys.audit("glob.glob", pathname, recursive) dirname, basename = os.path.split(pathname) if not has_magic(pathname): assert not dironly diff --git a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst new file mode 100644 index 0000000000000..b4ec60b2abad1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst @@ -0,0 +1,2 @@ +:func:`sys.audit` is now called only once per call of :func:`glob.glob` and +:func:`glob.iglob`. From webhook-mailer at python.org Thu Feb 6 03:45:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 08:45:24 -0000 Subject: [Python-checkins] bpo-38149: Call sys.audit() only once per call for glob.glob(). (GH-18360) Message-ID: https://github.com/python/cpython/commit/708f472dd92f4f46c27ace710492da65da4a3319 commit: 708f472dd92f4f46c27ace710492da65da4a3319 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T00:45:18-08:00 summary: bpo-38149: Call sys.audit() only once per call for glob.glob(). (GH-18360) (cherry picked from commit 54b4f14712b9350f11c983f1c8ac47a3716958a7) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst M Lib/glob.py diff --git a/Lib/glob.py b/Lib/glob.py index 0b3fcc6bbb9af..0dd2f8be66109 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -31,6 +31,7 @@ def iglob(pathname, *, recursive=False): If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ + sys.audit("glob.glob", pathname, recursive) it = _iglob(pathname, recursive, False) if recursive and _isrecursive(pathname): s = next(it) # skip empty string @@ -38,7 +39,6 @@ def iglob(pathname, *, recursive=False): return it def _iglob(pathname, recursive, dironly): - sys.audit("glob.glob", pathname, recursive) dirname, basename = os.path.split(pathname) if not has_magic(pathname): assert not dironly diff --git a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst new file mode 100644 index 0000000000000..b4ec60b2abad1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst @@ -0,0 +1,2 @@ +:func:`sys.audit` is now called only once per call of :func:`glob.glob` and +:func:`glob.iglob`. From webhook-mailer at python.org Thu Feb 6 09:46:02 2020 From: webhook-mailer at python.org (Brandt Bucher) Date: Thu, 06 Feb 2020 14:46:02 -0000 Subject: [Python-checkins] bpo-38823: Fix refleaks in _ast initialization error path (GH-17276) Message-ID: https://github.com/python/cpython/commit/d2f96672642cc51b92f61b951ca1b11d615c12d1 commit: d2f96672642cc51b92f61b951ca1b11d615c12d1 branch: master author: Brandt Bucher committer: GitHub date: 2020-02-06T15:45:46+01:00 summary: bpo-38823: Fix refleaks in _ast initialization error path (GH-17276) files: M Parser/asdl_c.py M Python/Python-ast.c diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index daac0966f564a..e81506cc9a62d 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -998,17 +998,25 @@ def visitModule(self, mod): self.emit("if (!init_types()) return NULL;", 1) self.emit('m = PyState_FindModule(&_astmodule);', 1) self.emit("if (!m) return NULL;", 1) + self.emit('if (PyModule_AddObject(m, "AST", astmodulestate_global->AST_type) < 0) {', 1) + self.emit('goto error;', 2) + self.emit('}', 1) self.emit('Py_INCREF(astmodulestate(m)->AST_type);', 1) - self.emit('if (PyModule_AddObject(m, "AST", astmodulestate_global->AST_type) < 0) return NULL;', 1) - self.emit('if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0)', 1) - self.emit("return NULL;", 2) - self.emit('if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)', 1) - self.emit("return NULL;", 2) - self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)', 1) - self.emit("return NULL;", 2) + self.emit('if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) {', 1) + self.emit("goto error;", 2) + self.emit('}', 1) + self.emit('if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) {', 1) + self.emit("goto error;", 2) + self.emit('}', 1) + self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) {', 1) + self.emit("goto error;", 2) + self.emit('}', 1) for dfn in mod.dfns: self.visit(dfn) self.emit("return m;", 1) + self.emit("error:", 0) + self.emit("Py_DECREF(m);", 1) + self.emit("return NULL;", 1) self.emit("}", 0) def visitProduct(self, prod, name): @@ -1024,7 +1032,9 @@ def visitConstructor(self, cons, name): def addObj(self, name): self.emit("if (PyModule_AddObject(m, \"%s\", " - "astmodulestate_global->%s_type) < 0) return NULL;" % (name, name), 1) + "astmodulestate_global->%s_type) < 0) {" % (name, name), 1) + self.emit("goto error;", 2) + self.emit('}', 1) self.emit("Py_INCREF(astmodulestate(m)->%s_type);" % name, 1) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index d5465d795cfa4..e9925e742e733 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -9887,355 +9887,533 @@ PyInit__ast(void) if (!init_types()) return NULL; m = PyState_FindModule(&_astmodule); if (!m) return NULL; + if (PyModule_AddObject(m, "AST", astmodulestate_global->AST_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AST_type); - if (PyModule_AddObject(m, "AST", astmodulestate_global->AST_type) < 0) - return NULL; - if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) - return NULL; - if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) - return NULL; - if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) - return NULL; - if (PyModule_AddObject(m, "mod", astmodulestate_global->mod_type) < 0) - return NULL; + if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) { + goto error; + } + if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) { + goto error; + } + if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) { + goto error; + } + if (PyModule_AddObject(m, "mod", astmodulestate_global->mod_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->mod_type); if (PyModule_AddObject(m, "Module", astmodulestate_global->Module_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Module_type); if (PyModule_AddObject(m, "Interactive", - astmodulestate_global->Interactive_type) < 0) return NULL; + astmodulestate_global->Interactive_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Interactive_type); if (PyModule_AddObject(m, "Expression", - astmodulestate_global->Expression_type) < 0) return NULL; + astmodulestate_global->Expression_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Expression_type); if (PyModule_AddObject(m, "FunctionType", - astmodulestate_global->FunctionType_type) < 0) return NULL; + astmodulestate_global->FunctionType_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->FunctionType_type); - if (PyModule_AddObject(m, "Suite", astmodulestate_global->Suite_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Suite", astmodulestate_global->Suite_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Suite_type); - if (PyModule_AddObject(m, "stmt", astmodulestate_global->stmt_type) < 0) - return NULL; + if (PyModule_AddObject(m, "stmt", astmodulestate_global->stmt_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->stmt_type); if (PyModule_AddObject(m, "FunctionDef", - astmodulestate_global->FunctionDef_type) < 0) return NULL; + astmodulestate_global->FunctionDef_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->FunctionDef_type); if (PyModule_AddObject(m, "AsyncFunctionDef", - astmodulestate_global->AsyncFunctionDef_type) < 0) return NULL; + astmodulestate_global->AsyncFunctionDef_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AsyncFunctionDef_type); if (PyModule_AddObject(m, "ClassDef", astmodulestate_global->ClassDef_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->ClassDef_type); if (PyModule_AddObject(m, "Return", astmodulestate_global->Return_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Return_type); if (PyModule_AddObject(m, "Delete", astmodulestate_global->Delete_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Delete_type); if (PyModule_AddObject(m, "Assign", astmodulestate_global->Assign_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Assign_type); if (PyModule_AddObject(m, "AugAssign", - astmodulestate_global->AugAssign_type) < 0) return NULL; + astmodulestate_global->AugAssign_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AugAssign_type); if (PyModule_AddObject(m, "AnnAssign", - astmodulestate_global->AnnAssign_type) < 0) return NULL; + astmodulestate_global->AnnAssign_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AnnAssign_type); - if (PyModule_AddObject(m, "For", astmodulestate_global->For_type) < 0) - return NULL; + if (PyModule_AddObject(m, "For", astmodulestate_global->For_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->For_type); if (PyModule_AddObject(m, "AsyncFor", astmodulestate_global->AsyncFor_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AsyncFor_type); - if (PyModule_AddObject(m, "While", astmodulestate_global->While_type) < 0) - return NULL; + if (PyModule_AddObject(m, "While", astmodulestate_global->While_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->While_type); - if (PyModule_AddObject(m, "If", astmodulestate_global->If_type) < 0) return - NULL; + if (PyModule_AddObject(m, "If", astmodulestate_global->If_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->If_type); - if (PyModule_AddObject(m, "With", astmodulestate_global->With_type) < 0) - return NULL; + if (PyModule_AddObject(m, "With", astmodulestate_global->With_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->With_type); if (PyModule_AddObject(m, "AsyncWith", - astmodulestate_global->AsyncWith_type) < 0) return NULL; + astmodulestate_global->AsyncWith_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AsyncWith_type); - if (PyModule_AddObject(m, "Raise", astmodulestate_global->Raise_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Raise", astmodulestate_global->Raise_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Raise_type); - if (PyModule_AddObject(m, "Try", astmodulestate_global->Try_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Try", astmodulestate_global->Try_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Try_type); if (PyModule_AddObject(m, "Assert", astmodulestate_global->Assert_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Assert_type); if (PyModule_AddObject(m, "Import", astmodulestate_global->Import_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Import_type); if (PyModule_AddObject(m, "ImportFrom", - astmodulestate_global->ImportFrom_type) < 0) return NULL; + astmodulestate_global->ImportFrom_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->ImportFrom_type); if (PyModule_AddObject(m, "Global", astmodulestate_global->Global_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Global_type); if (PyModule_AddObject(m, "Nonlocal", astmodulestate_global->Nonlocal_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Nonlocal_type); - if (PyModule_AddObject(m, "Expr", astmodulestate_global->Expr_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Expr", astmodulestate_global->Expr_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Expr_type); - if (PyModule_AddObject(m, "Pass", astmodulestate_global->Pass_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Pass", astmodulestate_global->Pass_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Pass_type); - if (PyModule_AddObject(m, "Break", astmodulestate_global->Break_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Break", astmodulestate_global->Break_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Break_type); if (PyModule_AddObject(m, "Continue", astmodulestate_global->Continue_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Continue_type); - if (PyModule_AddObject(m, "expr", astmodulestate_global->expr_type) < 0) - return NULL; + if (PyModule_AddObject(m, "expr", astmodulestate_global->expr_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->expr_type); if (PyModule_AddObject(m, "BoolOp", astmodulestate_global->BoolOp_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->BoolOp_type); if (PyModule_AddObject(m, "NamedExpr", - astmodulestate_global->NamedExpr_type) < 0) return NULL; + astmodulestate_global->NamedExpr_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->NamedExpr_type); - if (PyModule_AddObject(m, "BinOp", astmodulestate_global->BinOp_type) < 0) - return NULL; + if (PyModule_AddObject(m, "BinOp", astmodulestate_global->BinOp_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->BinOp_type); if (PyModule_AddObject(m, "UnaryOp", astmodulestate_global->UnaryOp_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->UnaryOp_type); if (PyModule_AddObject(m, "Lambda", astmodulestate_global->Lambda_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Lambda_type); - if (PyModule_AddObject(m, "IfExp", astmodulestate_global->IfExp_type) < 0) - return NULL; + if (PyModule_AddObject(m, "IfExp", astmodulestate_global->IfExp_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->IfExp_type); - if (PyModule_AddObject(m, "Dict", astmodulestate_global->Dict_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Dict", astmodulestate_global->Dict_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Dict_type); - if (PyModule_AddObject(m, "Set", astmodulestate_global->Set_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Set", astmodulestate_global->Set_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Set_type); if (PyModule_AddObject(m, "ListComp", astmodulestate_global->ListComp_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->ListComp_type); if (PyModule_AddObject(m, "SetComp", astmodulestate_global->SetComp_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->SetComp_type); if (PyModule_AddObject(m, "DictComp", astmodulestate_global->DictComp_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->DictComp_type); if (PyModule_AddObject(m, "GeneratorExp", - astmodulestate_global->GeneratorExp_type) < 0) return NULL; + astmodulestate_global->GeneratorExp_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->GeneratorExp_type); - if (PyModule_AddObject(m, "Await", astmodulestate_global->Await_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Await", astmodulestate_global->Await_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Await_type); - if (PyModule_AddObject(m, "Yield", astmodulestate_global->Yield_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Yield", astmodulestate_global->Yield_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Yield_type); if (PyModule_AddObject(m, "YieldFrom", - astmodulestate_global->YieldFrom_type) < 0) return NULL; + astmodulestate_global->YieldFrom_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->YieldFrom_type); if (PyModule_AddObject(m, "Compare", astmodulestate_global->Compare_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Compare_type); - if (PyModule_AddObject(m, "Call", astmodulestate_global->Call_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Call", astmodulestate_global->Call_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Call_type); if (PyModule_AddObject(m, "FormattedValue", - astmodulestate_global->FormattedValue_type) < 0) return NULL; + astmodulestate_global->FormattedValue_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->FormattedValue_type); if (PyModule_AddObject(m, "JoinedStr", - astmodulestate_global->JoinedStr_type) < 0) return NULL; + astmodulestate_global->JoinedStr_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->JoinedStr_type); if (PyModule_AddObject(m, "Constant", astmodulestate_global->Constant_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Constant_type); if (PyModule_AddObject(m, "Attribute", - astmodulestate_global->Attribute_type) < 0) return NULL; + astmodulestate_global->Attribute_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Attribute_type); if (PyModule_AddObject(m, "Subscript", - astmodulestate_global->Subscript_type) < 0) return NULL; + astmodulestate_global->Subscript_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Subscript_type); if (PyModule_AddObject(m, "Starred", astmodulestate_global->Starred_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Starred_type); - if (PyModule_AddObject(m, "Name", astmodulestate_global->Name_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Name", astmodulestate_global->Name_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Name_type); - if (PyModule_AddObject(m, "List", astmodulestate_global->List_type) < 0) - return NULL; + if (PyModule_AddObject(m, "List", astmodulestate_global->List_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->List_type); - if (PyModule_AddObject(m, "Tuple", astmodulestate_global->Tuple_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Tuple", astmodulestate_global->Tuple_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Tuple_type); if (PyModule_AddObject(m, "expr_context", - astmodulestate_global->expr_context_type) < 0) return NULL; + astmodulestate_global->expr_context_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->expr_context_type); - if (PyModule_AddObject(m, "Load", astmodulestate_global->Load_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Load", astmodulestate_global->Load_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Load_type); - if (PyModule_AddObject(m, "Store", astmodulestate_global->Store_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Store", astmodulestate_global->Store_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Store_type); - if (PyModule_AddObject(m, "Del", astmodulestate_global->Del_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Del", astmodulestate_global->Del_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Del_type); if (PyModule_AddObject(m, "AugLoad", astmodulestate_global->AugLoad_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AugLoad_type); if (PyModule_AddObject(m, "AugStore", astmodulestate_global->AugStore_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->AugStore_type); - if (PyModule_AddObject(m, "Param", astmodulestate_global->Param_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Param", astmodulestate_global->Param_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Param_type); - if (PyModule_AddObject(m, "slice", astmodulestate_global->slice_type) < 0) - return NULL; + if (PyModule_AddObject(m, "slice", astmodulestate_global->slice_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->slice_type); - if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Slice_type); if (PyModule_AddObject(m, "ExtSlice", astmodulestate_global->ExtSlice_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->ExtSlice_type); - if (PyModule_AddObject(m, "Index", astmodulestate_global->Index_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Index", astmodulestate_global->Index_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Index_type); if (PyModule_AddObject(m, "boolop", astmodulestate_global->boolop_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->boolop_type); - if (PyModule_AddObject(m, "And", astmodulestate_global->And_type) < 0) - return NULL; + if (PyModule_AddObject(m, "And", astmodulestate_global->And_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->And_type); - if (PyModule_AddObject(m, "Or", astmodulestate_global->Or_type) < 0) return - NULL; + if (PyModule_AddObject(m, "Or", astmodulestate_global->Or_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Or_type); if (PyModule_AddObject(m, "operator", astmodulestate_global->operator_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->operator_type); - if (PyModule_AddObject(m, "Add", astmodulestate_global->Add_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Add", astmodulestate_global->Add_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Add_type); - if (PyModule_AddObject(m, "Sub", astmodulestate_global->Sub_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Sub", astmodulestate_global->Sub_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Sub_type); - if (PyModule_AddObject(m, "Mult", astmodulestate_global->Mult_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Mult", astmodulestate_global->Mult_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Mult_type); if (PyModule_AddObject(m, "MatMult", astmodulestate_global->MatMult_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->MatMult_type); - if (PyModule_AddObject(m, "Div", astmodulestate_global->Div_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Div", astmodulestate_global->Div_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Div_type); - if (PyModule_AddObject(m, "Mod", astmodulestate_global->Mod_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Mod", astmodulestate_global->Mod_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Mod_type); - if (PyModule_AddObject(m, "Pow", astmodulestate_global->Pow_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Pow", astmodulestate_global->Pow_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Pow_type); if (PyModule_AddObject(m, "LShift", astmodulestate_global->LShift_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->LShift_type); if (PyModule_AddObject(m, "RShift", astmodulestate_global->RShift_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->RShift_type); - if (PyModule_AddObject(m, "BitOr", astmodulestate_global->BitOr_type) < 0) - return NULL; + if (PyModule_AddObject(m, "BitOr", astmodulestate_global->BitOr_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->BitOr_type); if (PyModule_AddObject(m, "BitXor", astmodulestate_global->BitXor_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->BitXor_type); if (PyModule_AddObject(m, "BitAnd", astmodulestate_global->BitAnd_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->BitAnd_type); if (PyModule_AddObject(m, "FloorDiv", astmodulestate_global->FloorDiv_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->FloorDiv_type); if (PyModule_AddObject(m, "unaryop", astmodulestate_global->unaryop_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->unaryop_type); if (PyModule_AddObject(m, "Invert", astmodulestate_global->Invert_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Invert_type); - if (PyModule_AddObject(m, "Not", astmodulestate_global->Not_type) < 0) - return NULL; + if (PyModule_AddObject(m, "Not", astmodulestate_global->Not_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Not_type); - if (PyModule_AddObject(m, "UAdd", astmodulestate_global->UAdd_type) < 0) - return NULL; + if (PyModule_AddObject(m, "UAdd", astmodulestate_global->UAdd_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->UAdd_type); - if (PyModule_AddObject(m, "USub", astmodulestate_global->USub_type) < 0) - return NULL; + if (PyModule_AddObject(m, "USub", astmodulestate_global->USub_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->USub_type); - if (PyModule_AddObject(m, "cmpop", astmodulestate_global->cmpop_type) < 0) - return NULL; + if (PyModule_AddObject(m, "cmpop", astmodulestate_global->cmpop_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->cmpop_type); - if (PyModule_AddObject(m, "Eq", astmodulestate_global->Eq_type) < 0) return - NULL; + if (PyModule_AddObject(m, "Eq", astmodulestate_global->Eq_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Eq_type); - if (PyModule_AddObject(m, "NotEq", astmodulestate_global->NotEq_type) < 0) - return NULL; + if (PyModule_AddObject(m, "NotEq", astmodulestate_global->NotEq_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->NotEq_type); - if (PyModule_AddObject(m, "Lt", astmodulestate_global->Lt_type) < 0) return - NULL; + if (PyModule_AddObject(m, "Lt", astmodulestate_global->Lt_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Lt_type); - if (PyModule_AddObject(m, "LtE", astmodulestate_global->LtE_type) < 0) - return NULL; + if (PyModule_AddObject(m, "LtE", astmodulestate_global->LtE_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->LtE_type); - if (PyModule_AddObject(m, "Gt", astmodulestate_global->Gt_type) < 0) return - NULL; + if (PyModule_AddObject(m, "Gt", astmodulestate_global->Gt_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Gt_type); - if (PyModule_AddObject(m, "GtE", astmodulestate_global->GtE_type) < 0) - return NULL; + if (PyModule_AddObject(m, "GtE", astmodulestate_global->GtE_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->GtE_type); - if (PyModule_AddObject(m, "Is", astmodulestate_global->Is_type) < 0) return - NULL; + if (PyModule_AddObject(m, "Is", astmodulestate_global->Is_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->Is_type); - if (PyModule_AddObject(m, "IsNot", astmodulestate_global->IsNot_type) < 0) - return NULL; + if (PyModule_AddObject(m, "IsNot", astmodulestate_global->IsNot_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->IsNot_type); - if (PyModule_AddObject(m, "In", astmodulestate_global->In_type) < 0) return - NULL; + if (PyModule_AddObject(m, "In", astmodulestate_global->In_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->In_type); - if (PyModule_AddObject(m, "NotIn", astmodulestate_global->NotIn_type) < 0) - return NULL; + if (PyModule_AddObject(m, "NotIn", astmodulestate_global->NotIn_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->NotIn_type); if (PyModule_AddObject(m, "comprehension", - astmodulestate_global->comprehension_type) < 0) return NULL; + astmodulestate_global->comprehension_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->comprehension_type); if (PyModule_AddObject(m, "excepthandler", - astmodulestate_global->excepthandler_type) < 0) return NULL; + astmodulestate_global->excepthandler_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->excepthandler_type); if (PyModule_AddObject(m, "ExceptHandler", - astmodulestate_global->ExceptHandler_type) < 0) return NULL; + astmodulestate_global->ExceptHandler_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->ExceptHandler_type); if (PyModule_AddObject(m, "arguments", - astmodulestate_global->arguments_type) < 0) return NULL; + astmodulestate_global->arguments_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->arguments_type); - if (PyModule_AddObject(m, "arg", astmodulestate_global->arg_type) < 0) - return NULL; + if (PyModule_AddObject(m, "arg", astmodulestate_global->arg_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->arg_type); if (PyModule_AddObject(m, "keyword", astmodulestate_global->keyword_type) < - 0) return NULL; + 0) { + goto error; + } Py_INCREF(astmodulestate(m)->keyword_type); - if (PyModule_AddObject(m, "alias", astmodulestate_global->alias_type) < 0) - return NULL; + if (PyModule_AddObject(m, "alias", astmodulestate_global->alias_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->alias_type); if (PyModule_AddObject(m, "withitem", astmodulestate_global->withitem_type) - < 0) return NULL; + < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->withitem_type); if (PyModule_AddObject(m, "type_ignore", - astmodulestate_global->type_ignore_type) < 0) return NULL; + astmodulestate_global->type_ignore_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->type_ignore_type); if (PyModule_AddObject(m, "TypeIgnore", - astmodulestate_global->TypeIgnore_type) < 0) return NULL; + astmodulestate_global->TypeIgnore_type) < 0) { + goto error; + } Py_INCREF(astmodulestate(m)->TypeIgnore_type); return m; +error: + Py_DECREF(m); + return NULL; } From webhook-mailer at python.org Thu Feb 6 09:48:34 2020 From: webhook-mailer at python.org (Petr Viktorin) Date: Thu, 06 Feb 2020 14:48:34 -0000 Subject: [Python-checkins] bpo-39245: Make Vectorcall C API public (GH-17893) Message-ID: https://github.com/python/cpython/commit/3f563cea567fbfed9db539ecbbacfee2d86f7735 commit: 3f563cea567fbfed9db539ecbbacfee2d86f7735 branch: master author: Petr Viktorin committer: GitHub date: 2020-02-06T15:48:27+01:00 summary: bpo-39245: Make Vectorcall C API public (GH-17893) * Add backcompat defines and move non-limited API declaration to cpython/ This partially reverts commit 2ff58a24e8a1c7e290d025d69ebaea0bbead3b8c which added PyObject_CallNoArgs to the 3.9+ stable ABI. This should not be done; there are enough other call APIs in the stable ABI to choose from. * Adjust documentation Mark all newly public functions as added in 3.9. Add a note about the 3.8 provisional names. Add notes on public API. * Put PyObject_CallNoArgs back in the limited API * Rename PyObject_FastCallDict to PyObject_VectorcallDict files: A Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst M Doc/c-api/call.rst M Doc/c-api/typeobj.rst M Include/cpython/abstract.h M Include/object.h diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 0833531b1d5ee..06db12666d787 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -35,17 +35,11 @@ To call an object, use :c:func:`PyObject_Call` or other The Vectorcall Protocol ----------------------- -.. versionadded:: 3.8 +.. versionadded:: 3.9 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 @@ -69,7 +63,7 @@ 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 +: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: @@ -97,7 +91,7 @@ This is a pointer to a function with the following signature: 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 + 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 @@ -107,7 +101,20 @@ This is a pointer to a function with the following signature: 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. +:c:func:`PyObject_Vectorcall` will usually be most efficient. + + +.. note:: + + In CPython 3.8, the vectorcall API and related functions were available + provisionally under names with a leading underscore: + ``_PyObject_Vectorcall``, ``_Py_TPFLAGS_HAVE_VECTORCALL``, + ``_PyObject_VectorcallMethod``, ``_PyVectorcall_Function``, + ``_PyObject_CallOneArg``, ``_PyObject_CallMethodNoArgs``, + ``_PyObject_CallMethodOneArg``. + Additionally, ``PyObject_VectorcallDict`` was available as + ``_PyObject_FastCallDict``. + The old names are still defined as aliases of the new, non-underscored names. Recursion Control @@ -137,9 +144,11 @@ Vectorcall Support API However, the function ``PyVectorcall_NARGS`` should be used to allow for future extensions. + This function is not part of the `limited API `_. + .. versionadded:: 3.8 -.. c:function:: vectorcallfunc _PyVectorcall_Function(PyObject *op) +.. 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*. @@ -147,7 +156,9 @@ Vectorcall Support API 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``. + which can be done by checking ``PyVectorcall_Function(op) != NULL``. + + This function is not part of the `limited API `_. .. versionadded:: 3.8 @@ -158,9 +169,11 @@ Vectorcall Support API 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 + It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag and it does not fall back to ``tp_call``. + This function is not part of the `limited API `_. + .. versionadded:: 3.8 @@ -185,7 +198,7 @@ please see individual documentation for details. +------------------------------------------+------------------+--------------------+---------------+ | :c:func:`PyObject_CallNoArgs` | ``PyObject *`` | --- | --- | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_CallOneArg` | ``PyObject *`` | 1 object | --- | +| :c:func:`PyObject_CallOneArg` | ``PyObject *`` | 1 object | --- | +------------------------------------------+------------------+--------------------+---------------+ | :c:func:`PyObject_CallObject` | ``PyObject *`` | tuple/``NULL`` | --- | +------------------------------------------+------------------+--------------------+---------------+ @@ -197,15 +210,15 @@ please see individual documentation for details. +------------------------------------------+------------------+--------------------+---------------+ | :c:func:`PyObject_CallMethodObjArgs` | obj + name | variadic | --- | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_CallMethodNoArgs` | obj + name | --- | --- | +| :c:func:`PyObject_CallMethodNoArgs` | obj + name | --- | --- | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_CallMethodOneArg` | obj + name | 1 object | --- | +| :c:func:`PyObject_CallMethodOneArg` | obj + name | 1 object | --- | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_Vectorcall` | ``PyObject *`` | vectorcall | vectorcall | +| :c:func:`PyObject_Vectorcall` | ``PyObject *`` | vectorcall | vectorcall | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_FastCallDict` | ``PyObject *`` | vectorcall | dict/``NULL`` | +| :c:func:`PyObject_VectorcallDict` | ``PyObject *`` | vectorcall | dict/``NULL`` | +------------------------------------------+------------------+--------------------+---------------+ -| :c:func:`_PyObject_VectorcallMethod` | arg + name | vectorcall | vectorcall | +| :c:func:`PyObject_VectorcallMethod` | arg + name | vectorcall | vectorcall | +------------------------------------------+------------------+--------------------+---------------+ @@ -235,7 +248,7 @@ please see individual documentation for details. .. versionadded:: 3.9 -.. c:function:: PyObject* _PyObject_CallOneArg(PyObject *callable, PyObject *arg) +.. 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. @@ -243,6 +256,8 @@ please see individual documentation for details. Return the result of the call on success, or raise an exception and return *NULL* on failure. + This function is not part of the `limited API `_. + .. versionadded:: 3.9 @@ -320,7 +335,7 @@ please see individual documentation for details. *NULL* on failure. -.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name) +.. 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*. @@ -328,10 +343,12 @@ please see individual documentation for details. Return the result of the call on success, or raise an exception and return *NULL* on failure. + This function is not part of the `limited API `_. + .. versionadded:: 3.9 -.. c:function:: PyObject* _PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg) +.. 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 @@ -340,10 +357,12 @@ please see individual documentation for details. Return the result of the call on success, or raise an exception and return *NULL* on failure. + This function is not part of the `limited API `_. + .. versionadded:: 3.9 -.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) +.. 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`. @@ -353,15 +372,11 @@ please see individual documentation for details. 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. + This function is not part of the `limited API `_. - .. versionadded:: 3.8 + .. versionadded:: 3.9 -.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict) +.. c:function:: PyObject* PyObject_VectorcallDict(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*. @@ -373,15 +388,11 @@ please see individual documentation for details. already has a dictionary ready to use for the keyword arguments, but not a tuple for the positional arguments. - .. note:: + This function is not part of the `limited API `_. - 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 + .. versionadded:: 3.9 -.. c:function:: PyObject* _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) +.. 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 @@ -390,7 +401,7 @@ please see individual documentation for details. *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`. + :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 @@ -399,6 +410,8 @@ please see individual documentation for details. Return the result of the call on success, or raise an exception and return *NULL* on failure. + This function is not part of the `limited API `_. + .. versionadded:: 3.9 diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index a8a779ef6165a..ff0e70e6e52e2 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -684,15 +684,15 @@ and :c:type:`PyType_Type` effectively act as defaults.) 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` + 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 *vectorcallfunc* pointer may be ``NULL``, in which case the instance behaves - as if :const:`_Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance + 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 + 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 :c:func:`PyVectorcall_Call`. @@ -719,7 +719,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** This field is always inherited. - However, the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag is not + 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. @@ -1153,7 +1153,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) type structure. - .. data:: _Py_TPFLAGS_HAVE_VECTORCALL + .. data:: Py_TPFLAGS_HAVE_VECTORCALL This bit is set when the class implements the :ref:`vectorcall protocol `. @@ -1163,15 +1163,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) 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``. + `Heap types`_ do not inherit ``Py_TPFLAGS_HAVE_VECTORCALL``. - .. note:: - - This flag is provisional and expected to become public in Python 3.9, - with a different name and, possibly, changed semantics. - If you use vectorcall, plan for updating your code for Python 3.9. - - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. c:member:: const char* PyTypeObject.tp_doc diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 2c4eae70b9690..4bd7b1a61a532 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -29,7 +29,7 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict( /* Suggested size (number of positional arguments) for arrays of PyObject* allocated on a C stack to avoid allocating memory on the heap memory. Such array is used to pass positional arguments to call functions of the - _PyObject_Vectorcall() family. + PyObject_Vectorcall() family. The size is chosen to not abuse the C stack and so limit the risk of stack overflow. The size is also chosen to allow using the small stack for most @@ -45,8 +45,8 @@ PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( /* === Vectorcall protocol (PEP 590) ============================= */ -/* Call callable using tp_call. Arguments are like _PyObject_Vectorcall() - or _PyObject_FastCallDict() (both forms are supported), +/* Call callable using tp_call. Arguments are like PyObject_Vectorcall() + 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, @@ -63,7 +63,7 @@ PyVectorcall_NARGS(size_t n) } static inline vectorcallfunc -_PyVectorcall_Function(PyObject *callable) +PyVectorcall_Function(PyObject *callable) { assert(callable != NULL); PyTypeObject *tp = Py_TYPE(callable); @@ -103,7 +103,7 @@ _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, assert(kwnames == NULL || PyTuple_Check(kwnames)); assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); - vectorcallfunc func = _PyVectorcall_Function(callable); + vectorcallfunc func = PyVectorcall_Function(callable); if (func == NULL) { Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); @@ -113,7 +113,7 @@ _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, } static inline PyObject * -_PyObject_Vectorcall(PyObject *callable, PyObject *const *args, +PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) { PyThreadState *tstate = PyThreadState_GET(); @@ -121,9 +121,18 @@ _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, args, nargsf, kwnames); } -/* Same as _PyObject_Vectorcall except that keyword arguments are passed as +// Backwards compatibility aliases for API that was provisional in Python 3.8 +#define _PyObject_Vectorcall PyObject_Vectorcall +#define _PyObject_VectorcallMethod PyObject_VectorcallMethod +#define _PyObject_FastCallDict PyObject_VectorcallDict +#define _PyVectorcall_Function PyVectorcall_Function +#define _PyObject_CallOneArg PyObject_CallOneArg +#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs +#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg + +/* 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( +PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( PyObject *callable, PyObject *const *args, size_t nargsf, @@ -133,7 +142,7 @@ PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( "tuple" and keyword arguments "dict". "dict" may also be NULL */ PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); -/* Same as _PyObject_Vectorcall except without keyword arguments */ +/* Same as PyObject_Vectorcall except without keyword arguments */ static inline PyObject * _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) { @@ -151,7 +160,7 @@ _PyObject_CallNoArg(PyObject *func) { } static inline PyObject * -_PyObject_CallOneArg(PyObject *func, PyObject *arg) +PyObject_CallOneArg(PyObject *func, PyObject *arg) { assert(arg != NULL); PyObject *_args[2]; @@ -162,19 +171,19 @@ _PyObject_CallOneArg(PyObject *func, PyObject *arg) return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } -PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod( +PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); static inline PyObject * -_PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) +PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) { return _PyObject_VectorcallMethod(name, &self, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } static inline PyObject * -_PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) +PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) { assert(arg != NULL); PyObject *args[2] = {self, arg}; @@ -207,7 +216,7 @@ _PyObject_VectorcallMethodId( if (!oname) { return NULL; } - return _PyObject_VectorcallMethod(oname, args, nargsf, kwnames); + return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); } static inline PyObject * diff --git a/Include/object.h b/Include/object.h index e7e9c1b8ed752..38794a0e98cea 100644 --- a/Include/object.h +++ b/Include/object.h @@ -279,7 +279,9 @@ given type object has a specified feature. /* Set if the type implements the vectorcall protocol (PEP 590) */ #ifndef Py_LIMITED_API -#define _Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +// Backwards compatibility alias for API that was provisional in Python 3.8 +#define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #endif /* Set if the type is 'ready' -- fully initialized */ diff --git a/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst b/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst new file mode 100644 index 0000000000000..e5836b5255d3d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst @@ -0,0 +1,5 @@ +The Vectorcall API (PEP 590) was made public, adding the functions +``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``, +``PyVectorcall_Function``, ``PyObject_CallOneArg``, +``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``, +``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``. From webhook-mailer at python.org Thu Feb 6 09:54:12 2020 From: webhook-mailer at python.org (Sebastian Berg) Date: Thu, 06 Feb 2020 14:54:12 -0000 Subject: [Python-checkins] bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Message-ID: https://github.com/python/cpython/commit/427c84f13f7719e6014a21bd1b81efdc02a046fb commit: 427c84f13f7719e6014a21bd1b81efdc02a046fb branch: master author: Sebastian Berg committer: GitHub date: 2020-02-06T15:54:05+01:00 summary: bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Some numerator types used (specifically NumPy) decides to not return a Python boolean for the "a != b" operation. Using the equivalent call to bool() guarantees a bool return also for such types. files: A Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst M Lib/fractions.py M Lib/test/test_fractions.py diff --git a/Lib/fractions.py b/Lib/fractions.py index 501f4b74a0b7a..f5a854414c166 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -625,7 +625,9 @@ def __ge__(a, b): def __bool__(a): """a != 0""" - return a._numerator != 0 + # bpo-39274: Use bool() because (a._numerator != 0) can return an + # object which is not a bool. + return bool(a._numerator) # support for pickling, copy, and deepcopy diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 7cf7899932b34..4649a34bcc1f1 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -6,6 +6,7 @@ import numbers import operator import fractions +import functools import sys import unittest import warnings @@ -322,6 +323,42 @@ def testConversions(self): self.assertTypedEquals(0.1+0j, complex(F(1,10))) + def testBoolGuarateesBoolReturn(self): + # Ensure that __bool__ is used on numerator which guarantees a bool + # return. See also bpo-39274. + @functools.total_ordering + class CustomValue: + denominator = 1 + + def __init__(self, value): + self.value = value + + def __bool__(self): + return bool(self.value) + + @property + def numerator(self): + # required to preserve `self` during instantiation + return self + + def __eq__(self, other): + raise AssertionError("Avoid comparisons in Fraction.__bool__") + + __lt__ = __eq__ + + # We did not implement all abstract methods, so register: + numbers.Rational.register(CustomValue) + + numerator = CustomValue(1) + r = F(numerator) + # ensure the numerator was not lost during instantiation: + self.assertIs(r.numerator, numerator) + self.assertIs(bool(r), True) + + numerator = CustomValue(0) + r = F(numerator) + self.assertIs(bool(r), False) + def testRound(self): self.assertTypedEquals(F(-200), round(F(-150), -2)) self.assertTypedEquals(F(-200), round(F(-250), -2)) diff --git a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst new file mode 100644 index 0000000000000..4c398682b98ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst @@ -0,0 +1 @@ +``bool(fraction.Fraction)`` now returns a boolean even if (numerator != 0) does not return a boolean (ex: numpy number). From webhook-mailer at python.org Thu Feb 6 10:13:44 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 15:13:44 -0000 Subject: [Python-checkins] bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Message-ID: https://github.com/python/cpython/commit/0d03a1028200646479ef9bb0ad8973d0e73f9525 commit: 0d03a1028200646479ef9bb0ad8973d0e73f9525 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T07:13:38-08:00 summary: bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Some numerator types used (specifically NumPy) decides to not return a Python boolean for the "a != b" operation. Using the equivalent call to bool() guarantees a bool return also for such types. (cherry picked from commit 427c84f13f7719e6014a21bd1b81efdc02a046fb) Co-authored-by: Sebastian Berg files: A Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst M Lib/fractions.py M Lib/test/test_fractions.py diff --git a/Lib/fractions.py b/Lib/fractions.py index e774d58e40353..e4fcc8901bbf4 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -636,7 +636,9 @@ def __ge__(a, b): def __bool__(a): """a != 0""" - return a._numerator != 0 + # bpo-39274: Use bool() because (a._numerator != 0) can return an + # object which is not a bool. + return bool(a._numerator) # support for pickling, copy, and deepcopy diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 18ab28cfebe0c..86b49f30f549f 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -6,6 +6,7 @@ import numbers import operator import fractions +import functools import sys import unittest import warnings @@ -346,6 +347,42 @@ def testConversions(self): self.assertTypedEquals(0.1+0j, complex(F(1,10))) + def testBoolGuarateesBoolReturn(self): + # Ensure that __bool__ is used on numerator which guarantees a bool + # return. See also bpo-39274. + @functools.total_ordering + class CustomValue: + denominator = 1 + + def __init__(self, value): + self.value = value + + def __bool__(self): + return bool(self.value) + + @property + def numerator(self): + # required to preserve `self` during instantiation + return self + + def __eq__(self, other): + raise AssertionError("Avoid comparisons in Fraction.__bool__") + + __lt__ = __eq__ + + # We did not implement all abstract methods, so register: + numbers.Rational.register(CustomValue) + + numerator = CustomValue(1) + r = F(numerator) + # ensure the numerator was not lost during instantiation: + self.assertIs(r.numerator, numerator) + self.assertIs(bool(r), True) + + numerator = CustomValue(0) + r = F(numerator) + self.assertIs(bool(r), False) + def testRound(self): self.assertTypedEquals(F(-200), round(F(-150), -2)) self.assertTypedEquals(F(-200), round(F(-250), -2)) diff --git a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst new file mode 100644 index 0000000000000..4c398682b98ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst @@ -0,0 +1 @@ +``bool(fraction.Fraction)`` now returns a boolean even if (numerator != 0) does not return a boolean (ex: numpy number). From webhook-mailer at python.org Thu Feb 6 10:14:43 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 15:14:43 -0000 Subject: [Python-checkins] bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Message-ID: https://github.com/python/cpython/commit/705d271d553b77fd170d27ab8d0f11f638c7f145 commit: 705d271d553b77fd170d27ab8d0f11f638c7f145 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T07:14:37-08:00 summary: bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Some numerator types used (specifically NumPy) decides to not return a Python boolean for the "a != b" operation. Using the equivalent call to bool() guarantees a bool return also for such types. (cherry picked from commit 427c84f13f7719e6014a21bd1b81efdc02a046fb) Co-authored-by: Sebastian Berg files: A Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst M Lib/fractions.py M Lib/test/test_fractions.py diff --git a/Lib/fractions.py b/Lib/fractions.py index 8330202d7037b..64bff70060eb8 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -625,7 +625,9 @@ def __ge__(a, b): def __bool__(a): """a != 0""" - return a._numerator != 0 + # bpo-39274: Use bool() because (a._numerator != 0) can return an + # object which is not a bool. + return bool(a._numerator) # support for pickling, copy, and deepcopy diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 7905c367ba9dd..d1a43870ea88a 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -6,6 +6,7 @@ import numbers import operator import fractions +import functools import sys import unittest import warnings @@ -335,6 +336,42 @@ def testConversions(self): self.assertTypedEquals(0.1+0j, complex(F(1,10))) + def testBoolGuarateesBoolReturn(self): + # Ensure that __bool__ is used on numerator which guarantees a bool + # return. See also bpo-39274. + @functools.total_ordering + class CustomValue: + denominator = 1 + + def __init__(self, value): + self.value = value + + def __bool__(self): + return bool(self.value) + + @property + def numerator(self): + # required to preserve `self` during instantiation + return self + + def __eq__(self, other): + raise AssertionError("Avoid comparisons in Fraction.__bool__") + + __lt__ = __eq__ + + # We did not implement all abstract methods, so register: + numbers.Rational.register(CustomValue) + + numerator = CustomValue(1) + r = F(numerator) + # ensure the numerator was not lost during instantiation: + self.assertIs(r.numerator, numerator) + self.assertIs(bool(r), True) + + numerator = CustomValue(0) + r = F(numerator) + self.assertIs(bool(r), False) + def testRound(self): self.assertTypedEquals(F(-200), round(F(-150), -2)) self.assertTypedEquals(F(-200), round(F(-250), -2)) diff --git a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst new file mode 100644 index 0000000000000..4c398682b98ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst @@ -0,0 +1 @@ +``bool(fraction.Fraction)`` now returns a boolean even if (numerator != 0) does not return a boolean (ex: numpy number). From webhook-mailer at python.org Thu Feb 6 16:41:49 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 06 Feb 2020 21:41:49 -0000 Subject: [Python-checkins] bpo-39542: Document limited C API changes (GH-18378) Message-ID: https://github.com/python/cpython/commit/2844336e6bb0dc932d710be5f4d8c126d0768d03 commit: 2844336e6bb0dc932d710be5f4d8c126d0768d03 branch: master author: Victor Stinner committer: GitHub date: 2020-02-06T22:41:34+01:00 summary: bpo-39542: Document limited C API changes (GH-18378) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 66caf3f6f8213..d127e0a4a94fc 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -319,13 +319,6 @@ 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. @@ -359,6 +352,48 @@ Build and C API Changes * The ``COUNT_ALLOCS`` special build macro has been removed. (Contributed by Victor Stinner in :issue:`39489`.) +* Changes in the limited C API (if ``Py_LIMITED_API`` macro is defined): + + * 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. + + * Exclude the following functions from the limited C API: + + * ``_Py_CheckRecursionLimit`` + * ``_Py_NewReference()`` + * ``_Py_ForgetReference()`` + * ``_PyTraceMalloc_NewReference()`` + * ``_Py_GetRefTotal()`` + * The trashcan mechanism which never worked in the limited C API. + * ``PyTrash_UNWIND_LEVEL`` + * ``Py_TRASHCAN_BEGIN_CONDITION`` + * ``Py_TRASHCAN_BEGIN`` + * ``Py_TRASHCAN_END`` + * ``Py_TRASHCAN_SAFE_BEGIN`` + * ``Py_TRASHCAN_SAFE_END`` + + * The following static inline functions or macros become regular "opaque" + function to hide implementation details: + + * ``_Py_NewReference()`` + * ``PyObject_INIT()`` and ``PyObject_INIT_VAR()`` become aliases to + :c:func:`PyObject_Init` and :c:func:`PyObject_InitVar` in the limited C + API, but are overriden with static inline function otherwise. Thanks to + that, it was possible to exclude ``_Py_NewReference()`` from the limited + C API. + + * Move following functions and definitions to the internal C API: + + * ``_PyDebug_PrintTotalRefs()`` + * ``_Py_PrintReferences()`` + * ``_Py_PrintReferenceAddresses()`` + * ``_Py_tracemalloc_config`` + * ``_Py_AddToAllObjects()`` (specific to ``Py_TRACE_REFS`` build) + + (Contributed by Victor Stinner in :issue:`38644` and :issue:`39542`.) + Deprecated ========== From webhook-mailer at python.org Thu Feb 6 16:54:59 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 21:54:59 -0000 Subject: [Python-checkins] Fix MinGW library generation command (GH-17917) Message-ID: https://github.com/python/cpython/commit/30096c9365fcb7cc3c38c4d161eaf8f61ae5cfea commit: 30096c9365fcb7cc3c38c4d161eaf8f61ae5cfea branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T22:54:54+01:00 summary: Fix MinGW library generation command (GH-17917) To print the exports to stdout, the gendef command requires the option "-". Without this option, no output is generated. (cherry picked from commit 2545fa87628b4caca519da8aeb0eeef368b9dc0d) Co-authored-by: Baljak files: M Doc/whatsnew/3.8.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 007e3228f9ae6..9b61e1f05542d 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -2111,7 +2111,7 @@ Changes in the C API .. code-block:: shell - gendef python38.dll > tmp.def + gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a The location of an installed :file:`pythonXY.dll` will depend on the From webhook-mailer at python.org Thu Feb 6 17:03:06 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 06 Feb 2020 22:03:06 -0000 Subject: [Python-checkins] What's New in Python 3.9: sort improved modules (GH-18383) Message-ID: https://github.com/python/cpython/commit/227af8e21725958ad7d92a7910e70d678bb8a0a6 commit: 227af8e21725958ad7d92a7910e70d678bb8a0a6 branch: master author: Victor Stinner committer: GitHub date: 2020-02-06T23:03:01+01:00 summary: What's New in Python 3.9: sort improved modules (GH-18383) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index d127e0a4a94fc..4991e56759b1c 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -205,6 +205,14 @@ with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. (Contributed by Dong-hee Na in :issue:`38615`.) +importlib +--------- + +To improve consistency with import statements, :func:`importlib.util.resolve_name` +now raises :exc:`ImportError` instead of :exc:`ValueError` for invalid relative +import attempts. +(Contributed by Ngalim Siregar in :issue:`37444`.) + math ---- @@ -240,32 +248,6 @@ The :func:`os.putenv` and :func:`os.unsetenv` functions are now always available. (Contributed by Victor Stinner in :issue:`39395`.) -poplib ------- - -:class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` -if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) - -threading ---------- - -In a subinterpreter, spawning a daemon thread now raises a :exc:`RuntimeError`. Daemon -threads were never supported in subinterpreters. Previously, the subinterpreter -finalization crashed with a Python fatal error if a daemon thread was still -running. -(Contributed by Victor Stinner in :issue:`37266`.) - -venv ----- - -The activation scripts provided by :mod:`venv` now all specify their prompt -customization consistently by always using the value specified by -``__VENV_PROMPT__``. Previously some scripts unconditionally used -``__VENV_PROMPT__``, others only if it happened to be set (which was the default -case), and one used ``__VENV_NAME__`` instead. -(Contributed by Brett Cannon in :issue:`37663`.) - pathlib ------- @@ -273,19 +255,24 @@ Added :meth:`pathlib.Path.readlink()` which acts similarly to :func:`os.readlink`. (Contributed by Girts Folkmanis in :issue:`30618`) +poplib +------ + +:class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` +if the given timeout for their constructor is zero to prevent the creation of +a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) + pprint ------ :mod:`pprint` can now pretty-print :class:`types.SimpleNamespace`. (Contributed by Carl Bordum Hansen in :issue:`37376`.) -importlib ---------- +signal +------ -To improve consistency with import statements, :func:`importlib.util.resolve_name` -now raises :exc:`ImportError` instead of :exc:`ValueError` for invalid relative -import attempts. -(Contributed by Ngalim Siregar in :issue:`37444`.) +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`) smtplib ------- @@ -297,11 +284,14 @@ a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) :class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. (Contributed by Dong-hee Na in :issue:`39329`.) -signal ------- +threading +--------- -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`) +In a subinterpreter, spawning a daemon thread now raises a :exc:`RuntimeError`. Daemon +threads were never supported in subinterpreters. Previously, the subinterpreter +finalization crashed with a Python fatal error if a daemon thread was still +running. +(Contributed by Victor Stinner in :issue:`37266`.) typing ------ @@ -311,6 +301,16 @@ types with context-specific metadata and new ``include_extras`` parameter to :func:`typing.get_type_hints` to access the metadata at runtime. (Contributed by Till Varoquaux and Konstantin Kashin.) +venv +---- + +The activation scripts provided by :mod:`venv` now all specify their prompt +customization consistently by always using the value specified by +``__VENV_PROMPT__``. Previously some scripts unconditionally used +``__VENV_PROMPT__``, others only if it happened to be set (which was the default +case), and one used ``__VENV_NAME__`` instead. +(Contributed by Brett Cannon in :issue:`37663`.) + Optimizations ============= From webhook-mailer at python.org Thu Feb 6 17:16:57 2020 From: webhook-mailer at python.org (Julien Palard) Date: Thu, 06 Feb 2020 22:16:57 -0000 Subject: [Python-checkins] bpo-39534: Doc: Clarify return in finally (GH-18324) Message-ID: https://github.com/python/cpython/commit/446463f8dbce0556be8020914f37089b63bb8ab6 commit: 446463f8dbce0556be8020914f37089b63bb8ab6 branch: master author: Julien Palard committer: GitHub date: 2020-02-06T23:16:48+01:00 summary: bpo-39534: Doc: Clarify return in finally (GH-18324) files: M Doc/tutorial/errors.rst diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 8f86eca02483a..ab23df9f3ff9a 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -388,15 +388,33 @@ example:: File "", line 2, in KeyboardInterrupt -If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs: - -* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution. - -* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause. +If a :keyword:`finally` clause is present, the :keyword:`!finally` +clause will execute as the last task before the :keyword:`try` +statement completes. The :keyword:`!finally` clause runs whether or +not the :keyword:`!try` statement produces an exception. The following +points discuss more complex cases when an exception occurs: + +* If an exception occurs during execution of the :keyword:`!try` + clause, the exception may be handled by an :keyword:`except` + clause. If the exception is not handled by an :keyword:`!except` + clause, the exception is re-raised after the :keyword:`!finally` + clause has been executed. + +* An exception could occur during execution of an :keyword:`!except` + or :keyword:`!else` clause. Again, the exception is re-raised after + the :keyword:`!finally` clause has been executed. + +* If the :keyword:`!try` statement reaches a :keyword:`break`, + :keyword:`continue` or :keyword:`return` statement, the + :keyword:`!finally` clause will execute just prior to the + :keyword:`!break`, :keyword:`!continue` or :keyword:`!return` + statement's execution. + +* If a :keyword:`!finally` clause includes a :keyword:`!return` + statement, the returned value will be the one from the + :keyword:`!finally` clause's :keyword:`!return` statement, not the + value from the :keyword:`!try` clause's :keyword:`!return` + statement. For example:: From webhook-mailer at python.org Thu Feb 6 17:22:20 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 22:22:20 -0000 Subject: [Python-checkins] bpo-39534: Doc: Clarify return in finally (GH-18324) Message-ID: https://github.com/python/cpython/commit/83efed9eba9e50ed2395bd3366c31628b9555b1e commit: 83efed9eba9e50ed2395bd3366c31628b9555b1e branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T14:22:11-08:00 summary: bpo-39534: Doc: Clarify return in finally (GH-18324) (cherry picked from commit 446463f8dbce0556be8020914f37089b63bb8ab6) Co-authored-by: Julien Palard files: M Doc/tutorial/errors.rst diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 4bc7184d1078c..27c67c6e015af 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -341,15 +341,33 @@ example:: File "", line 2, in KeyboardInterrupt -If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs: - -* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution. - -* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause. +If a :keyword:`finally` clause is present, the :keyword:`!finally` +clause will execute as the last task before the :keyword:`try` +statement completes. The :keyword:`!finally` clause runs whether or +not the :keyword:`!try` statement produces an exception. The following +points discuss more complex cases when an exception occurs: + +* If an exception occurs during execution of the :keyword:`!try` + clause, the exception may be handled by an :keyword:`except` + clause. If the exception is not handled by an :keyword:`!except` + clause, the exception is re-raised after the :keyword:`!finally` + clause has been executed. + +* An exception could occur during execution of an :keyword:`!except` + or :keyword:`!else` clause. Again, the exception is re-raised after + the :keyword:`!finally` clause has been executed. + +* If the :keyword:`!try` statement reaches a :keyword:`break`, + :keyword:`continue` or :keyword:`return` statement, the + :keyword:`!finally` clause will execute just prior to the + :keyword:`!break`, :keyword:`!continue` or :keyword:`!return` + statement's execution. + +* If a :keyword:`!finally` clause includes a :keyword:`!return` + statement, the returned value will be the one from the + :keyword:`!finally` clause's :keyword:`!return` statement, not the + value from the :keyword:`!try` clause's :keyword:`!return` + statement. For example:: From webhook-mailer at python.org Thu Feb 6 17:23:12 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 06 Feb 2020 22:23:12 -0000 Subject: [Python-checkins] bpo-39534: Doc: Clarify return in finally (GH-18324) Message-ID: https://github.com/python/cpython/commit/97e00b3c52796cb54dd0a50548760579b9cb7b3a commit: 97e00b3c52796cb54dd0a50548760579b9cb7b3a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-06T14:23:04-08:00 summary: bpo-39534: Doc: Clarify return in finally (GH-18324) (cherry picked from commit 446463f8dbce0556be8020914f37089b63bb8ab6) Co-authored-by: Julien Palard files: M Doc/tutorial/errors.rst diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 4bc7184d1078c..27c67c6e015af 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -341,15 +341,33 @@ example:: File "", line 2, in KeyboardInterrupt -If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs: - -* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution. - -* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause. +If a :keyword:`finally` clause is present, the :keyword:`!finally` +clause will execute as the last task before the :keyword:`try` +statement completes. The :keyword:`!finally` clause runs whether or +not the :keyword:`!try` statement produces an exception. The following +points discuss more complex cases when an exception occurs: + +* If an exception occurs during execution of the :keyword:`!try` + clause, the exception may be handled by an :keyword:`except` + clause. If the exception is not handled by an :keyword:`!except` + clause, the exception is re-raised after the :keyword:`!finally` + clause has been executed. + +* An exception could occur during execution of an :keyword:`!except` + or :keyword:`!else` clause. Again, the exception is re-raised after + the :keyword:`!finally` clause has been executed. + +* If the :keyword:`!try` statement reaches a :keyword:`break`, + :keyword:`continue` or :keyword:`return` statement, the + :keyword:`!finally` clause will execute just prior to the + :keyword:`!break`, :keyword:`!continue` or :keyword:`!return` + statement's execution. + +* If a :keyword:`!finally` clause includes a :keyword:`!return` + statement, the returned value will be the one from the + :keyword:`!finally` clause's :keyword:`!return` statement, not the + value from the :keyword:`!try` clause's :keyword:`!return` + statement. For example:: From webhook-mailer at python.org Thu Feb 6 18:39:13 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 06 Feb 2020 23:39:13 -0000 Subject: [Python-checkins] bpo-39573: Use Py_REFCNT() macro (GH-18388) Message-ID: https://github.com/python/cpython/commit/a93c51e3a8e15f1a486d11d5b55a64f3381babe0 commit: a93c51e3a8e15f1a486d11d5b55a64f3381babe0 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T00:38:59+01:00 summary: bpo-39573: Use Py_REFCNT() macro (GH-18388) Replace direct acccess to PyObject.ob_refcnt with usage of the Py_REFCNT() macro. files: M Modules/_functoolsmodule.c M Modules/_testcapimodule.c M Objects/enumobject.c M Objects/fileobject.c M Objects/object.c M Objects/tupleobject.c M Objects/typeobject.c M Objects/weakrefobject.c M Python/sysmodule.c diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 987087b1ac97b..50d8c58e954f8 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -649,7 +649,7 @@ functools_reduce(PyObject *self, PyObject *args) for (;;) { PyObject *op2; - if (args->ob_refcnt > 1) { + if (Py_REFCNT(args) > 1) { Py_DECREF(args); if ((args = PyTuple_New(2)) == NULL) goto Fail; @@ -666,7 +666,7 @@ functools_reduce(PyObject *self, PyObject *args) result = op2; else { /* Update the args tuple in-place */ - assert(args->ob_refcnt == 1); + assert(Py_REFCNT(args) == 1); Py_XSETREF(_PyTuple_ITEMS(args)[0], result); Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); if ((result = PyObject_Call(func, args, NULL)) == NULL) { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c5812f827dfeb..27db86a70b9d5 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3550,8 +3550,8 @@ slot_tp_del(PyObject *self) PyObject *error_type, *error_value, *error_traceback; /* Temporarily resurrect the object. */ - assert(self->ob_refcnt == 0); - self->ob_refcnt = 1; + assert(Py_REFCNT(self) == 0); + Py_REFCNT(self) = 1; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); @@ -3573,17 +3573,19 @@ slot_tp_del(PyObject *self) /* Undo the temporary resurrection; can't use DECREF here, it would * cause a recursive call. */ - assert(self->ob_refcnt > 0); - if (--self->ob_refcnt == 0) - return; /* this is the normal path out */ + assert(Py_REFCNT(self) > 0); + if (--Py_REFCNT(self) == 0) { + /* this is the normal path out */ + return; + } /* __del__ resurrected it! Make it look like the original Py_DECREF * never happened. */ { - Py_ssize_t refcnt = self->ob_refcnt; + Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - self->ob_refcnt = refcnt; + Py_REFCNT(self) = refcnt; } assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 4786297c41ace..75703be5fcfc5 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -122,7 +122,7 @@ enum_next_long(enumobject *en, PyObject* next_item) } en->en_longindex = stepped_up; - if (result->ob_refcnt == 1) { + if (Py_REFCNT(result) == 1) { Py_INCREF(result); old_index = PyTuple_GET_ITEM(result, 0); old_item = PyTuple_GET_ITEM(result, 1); @@ -167,7 +167,7 @@ enum_next(enumobject *en) } en->en_index++; - if (result->ob_refcnt == 1) { + if (Py_REFCNT(result) == 1) { Py_INCREF(result); old_index = PyTuple_GET_ITEM(result, 0); old_item = PyTuple_GET_ITEM(result, 1); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 527693c80998f..c0eff8bed5136 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -85,7 +85,7 @@ PyFile_GetLine(PyObject *f, int n) "EOF when reading a line"); } else if (s[len-1] == '\n') { - if (result->ob_refcnt == 1) + if (Py_REFCNT(result) == 1) _PyBytes_Resize(&result, len-1); else { PyObject *v; diff --git a/Objects/object.c b/Objects/object.c index 9eaa163bdfd1f..f9682fe5b1f52 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -58,7 +58,7 @@ _Py_GetRefTotal(void) Py_ssize_t total = _Py_RefTotal; o = _PySet_Dummy; if (o != NULL) - total -= o->ob_refcnt; + total -= Py_REFCNT(o); return total; } @@ -206,32 +206,32 @@ PyObject_CallFinalizer(PyObject *self) int PyObject_CallFinalizerFromDealloc(PyObject *self) { - if (self->ob_refcnt != 0) { + if (Py_REFCNT(self) != 0) { _PyObject_ASSERT_FAILED_MSG(self, "PyObject_CallFinalizerFromDealloc called " "on object with a non-zero refcount"); } /* Temporarily resurrect the object. */ - self->ob_refcnt = 1; + Py_REFCNT(self) = 1; PyObject_CallFinalizer(self); _PyObject_ASSERT_WITH_MSG(self, - self->ob_refcnt > 0, + Py_REFCNT(self) > 0, "refcount is too small"); /* Undo the temporary resurrection; can't use DECREF here, it would * cause a recursive call. */ - if (--self->ob_refcnt == 0) { + if (--Py_REFCNT(self) == 0) { return 0; /* this is the normal path out */ } /* tp_finalize resurrected it! Make it look like the original Py_DECREF * never happened. */ - Py_ssize_t refcnt = self->ob_refcnt; + Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - self->ob_refcnt = refcnt; + Py_REFCNT(self) = refcnt; _PyObject_ASSERT(self, (!PyType_IS_GC(Py_TYPE(self)) @@ -263,12 +263,12 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) Py_END_ALLOW_THREADS } else { - if (op->ob_refcnt <= 0) { + if (Py_REFCNT(op) <= 0) { /* XXX(twouters) cast refcount to long until %zd is universally available */ Py_BEGIN_ALLOW_THREADS fprintf(fp, "", - (long)op->ob_refcnt, (void *)op); + (long)Py_REFCNT(op), (void *)op); Py_END_ALLOW_THREADS } else { @@ -363,7 +363,7 @@ _PyObject_Dump(PyObject* op) fprintf(stderr, "object address : %p\n", (void *)op); /* XXX(twouters) cast refcount to long until %zd is universally available */ - fprintf(stderr, "object refcount : %ld\n", (long)op->ob_refcnt); + fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); fflush(stderr); PyTypeObject *type = Py_TYPE(op); @@ -1010,7 +1010,7 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) return err; } Py_DECREF(name); - _PyObject_ASSERT(name, name->ob_refcnt >= 1); + _PyObject_ASSERT(name, Py_REFCNT(name) >= 1); if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) PyErr_Format(PyExc_TypeError, "'%.100s' object has no attributes " @@ -1829,7 +1829,7 @@ _Py_NewReference(PyObject *op) void _Py_ForgetReference(PyObject *op) { - if (op->ob_refcnt < 0) { + if (Py_REFCNT(op) < 0) { _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); } @@ -1867,7 +1867,7 @@ _Py_PrintReferences(FILE *fp) PyObject *op; fprintf(fp, "Remaining objects:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, op->ob_refcnt); + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, Py_REFCNT(op)); if (PyObject_Print(op, fp, 0) != 0) PyErr_Clear(); putc('\n', fp); @@ -1884,7 +1884,7 @@ _Py_PrintReferenceAddresses(FILE *fp) fprintf(fp, "Remaining object addresses:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, - op->ob_refcnt, Py_TYPE(op)->tp_name); + Py_REFCNT(op), Py_TYPE(op)->tp_name); } PyObject * @@ -2025,7 +2025,7 @@ _PyTrash_deposit_object(PyObject *op) _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later); gcstate->trash_delete_later = op; } @@ -2037,7 +2037,7 @@ _PyTrash_thread_deposit_object(PyObject *op) PyThreadState *tstate = _PyThreadState_GET(); _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); tstate->trash_delete_later = op; } @@ -2064,7 +2064,7 @@ _PyTrash_destroy_chain(void) * assorted non-release builds calling Py_DECREF again ends * up distorting allocation statistics. */ - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); ++gcstate->trash_delete_nesting; (*dealloc)(op); --gcstate->trash_delete_nesting; @@ -2102,7 +2102,7 @@ _PyTrash_thread_destroy_chain(void) * assorted non-release builds calling Py_DECREF again ends * up distorting allocation statistics. */ - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); assert(tstate->trash_delete_nesting == 1); } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 8c8c66f266f9d..d114bd640964c 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -153,7 +153,7 @@ int PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) { PyObject **p; - if (!PyTuple_Check(op) || op->ob_refcnt != 1) { + if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) { Py_XDECREF(newitem); PyErr_BadInternalCall(); return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 01def837803d2..d85ff3ce56993 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1173,8 +1173,9 @@ subtype_dealloc(PyObject *self) } if (type->tp_del) { type->tp_del(self); - if (self->ob_refcnt > 0) + if (Py_REFCNT(self) > 0) { return; + } } /* Find the nearest base with a different tp_dealloc */ @@ -1239,7 +1240,7 @@ subtype_dealloc(PyObject *self) if (type->tp_del) { _PyObject_GC_TRACK(self); type->tp_del(self); - if (self->ob_refcnt > 0) { + if (Py_REFCNT(self) > 0) { /* Resurrected */ goto endlabel; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index bf79e0c7ecbcc..d104b646f0181 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -952,7 +952,8 @@ PyObject_ClearWeakRefs(PyObject *object) if (object == NULL || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) - || object->ob_refcnt != 0) { + || Py_REFCNT(object) != 0) + { PyErr_BadInternalCall(); return; } @@ -975,8 +976,9 @@ PyObject_ClearWeakRefs(PyObject *object) current->wr_callback = NULL; clear_weakref(current); if (callback != NULL) { - if (((PyObject *)current)->ob_refcnt > 0) + if (Py_REFCNT((PyObject *)current) > 0) { handle_callback(current, callback); + } Py_DECREF(callback); } } @@ -993,8 +995,7 @@ PyObject_ClearWeakRefs(PyObject *object) for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; - if (((PyObject *)current)->ob_refcnt > 0) - { + if (Py_REFCNT((PyObject *)current) > 0) { Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1cb10300d7758..d8d1874745483 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1656,7 +1656,7 @@ static Py_ssize_t sys_getrefcount_impl(PyObject *module, PyObject *object) /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ { - return object->ob_refcnt; + return Py_REFCNT(object); } #ifdef Py_REF_DEBUG From webhook-mailer at python.org Thu Feb 6 19:24:37 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 00:24:37 -0000 Subject: [Python-checkins] bpo-39573: Add Py_SET_REFCNT() function (GH-18389) Message-ID: https://github.com/python/cpython/commit/c86a11221df7e37da389f9c6ce6e47ea22dc44ff commit: c86a11221df7e37da389f9c6ce6e47ea22dc44ff branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T01:24:29+01:00 summary: bpo-39573: Add Py_SET_REFCNT() function (GH-18389) Add a Py_SET_REFCNT() function to set the reference counter of an object. files: A Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst M Doc/c-api/structures.rst M Include/object.h M Modules/_testcapimodule.c M Objects/moduleobject.c M Objects/object.c M Objects/unicodeobject.c diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 0c661389021ef..100573c5693fc 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -79,6 +79,13 @@ the definition of all other Python objects. (((PyObject*)(o))->ob_refcnt) +.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt) + + Set the object *o* reference counter to *refcnt*. + + .. versionadded:: 3.9 + + .. c:macro:: Py_SIZE(o) This macro is used to access the :attr:`ob_size` member of a Python object. diff --git a/Include/object.h b/Include/object.h index 38794a0e98cea..0b630513375d3 100644 --- a/Include/object.h +++ b/Include/object.h @@ -123,6 +123,11 @@ typedef struct { #define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type) #define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size) +static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { + ob->ob_refcnt = refcnt; +} +#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) + /* Type objects contain a string containing the type name (to help somewhat in debugging), the allocation parameters (see PyObject_New() and diff --git a/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst b/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst new file mode 100644 index 0000000000000..310933a6d4076 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst @@ -0,0 +1,2 @@ +Add a :c:func:`Py_SET_REFCNT` function to set the reference counter of an +object. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 27db86a70b9d5..d8bf3735046c1 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3551,7 +3551,7 @@ slot_tp_del(PyObject *self) /* Temporarily resurrect the object. */ assert(Py_REFCNT(self) == 0); - Py_REFCNT(self) = 1; + Py_SET_REFCNT(self, 1); /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); @@ -3574,7 +3574,8 @@ slot_tp_del(PyObject *self) * cause a recursive call. */ assert(Py_REFCNT(self) > 0); - if (--Py_REFCNT(self) == 0) { + Py_SET_REFCNT(self, Py_REFCNT(self) - 1); + if (Py_REFCNT(self) == 0) { /* this is the normal path out */ return; } @@ -3585,7 +3586,7 @@ slot_tp_del(PyObject *self) { Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - Py_REFCNT(self) = refcnt; + Py_SET_REFCNT(self, refcnt); } assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased @@ -4621,7 +4622,7 @@ check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) return NULL; } /* Initialize reference count to avoid early crash in ceval or GC */ - Py_REFCNT(op) = 1; + Py_SET_REFCNT(op, 1); /* object fields like ob_type are uninitialized! */ return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); } @@ -4636,7 +4637,7 @@ check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args return NULL; } /* Initialize reference count to avoid early crash in ceval or GC */ - Py_REFCNT(op) = 1; + Py_SET_REFCNT(op, 1); /* ob_type field is after the memory block: part of "forbidden bytes" when using debug hooks on memory allocators! */ return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); @@ -4652,7 +4653,7 @@ check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) } Py_TYPE(op)->tp_dealloc(op); /* Reset reference count to avoid early crash in ceval or GC */ - Py_REFCNT(op) = 1; + Py_SET_REFCNT(op, 1); /* object memory is freed! */ return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); } @@ -5134,7 +5135,7 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) } assert(Py_REFCNT(obj) == 1); - Py_REFCNT(obj) = 0; + Py_SET_REFCNT(obj, 0); /* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */ Py_DECREF(obj); diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 49cfd574d5664..da329b4fbac8b 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -51,7 +51,7 @@ PyModuleDef_Init(struct PyModuleDef* def) return NULL; if (def->m_base.m_index == 0) { max_module_number++; - Py_REFCNT(def) = 1; + Py_SET_REFCNT(def, 1); Py_TYPE(def) = &PyModuleDef_Type; def->m_base.m_index = max_module_number; } diff --git a/Objects/object.c b/Objects/object.c index f9682fe5b1f52..aca20e8d096f8 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -213,7 +213,7 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) } /* Temporarily resurrect the object. */ - Py_REFCNT(self) = 1; + Py_SET_REFCNT(self, 1); PyObject_CallFinalizer(self); @@ -223,7 +223,8 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) /* Undo the temporary resurrection; can't use DECREF here, it would * cause a recursive call. */ - if (--Py_REFCNT(self) == 0) { + Py_SET_REFCNT(self, Py_REFCNT(self) - 1); + if (Py_REFCNT(self) == 0) { return 0; /* this is the normal path out */ } @@ -231,7 +232,7 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) * never happened. */ Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - Py_REFCNT(self) = refcnt; + Py_SET_REFCNT(self, refcnt); _PyObject_ASSERT(self, (!PyType_IS_GC(Py_TYPE(self)) @@ -1818,7 +1819,7 @@ _Py_NewReference(PyObject *op) #ifdef Py_REF_DEBUG _Py_RefTotal++; #endif - Py_REFCNT(op) = 1; + Py_SET_REFCNT(op, 1); #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op, 1); #endif diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7c8bc06252a1e..fa48ee1ac78f0 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1903,7 +1903,7 @@ unicode_dealloc(PyObject *unicode) case SSTATE_INTERNED_MORTAL: /* revive dead object temporarily for DelItem */ - Py_REFCNT(unicode) = 3; + Py_SET_REFCNT(unicode, 3); if (PyDict_DelItem(interned, unicode) != 0) { _PyErr_WriteUnraisableMsg("deletion of interned string failed", NULL); @@ -15367,7 +15367,7 @@ PyUnicode_InternInPlace(PyObject **p) } /* The two references in interned are not counted by refcnt. The deallocator will take care of this */ - Py_REFCNT(s) -= 2; + Py_SET_REFCNT(s, Py_REFCNT(s) - 2); _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; } From webhook-mailer at python.org Thu Feb 6 19:43:38 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 00:43:38 -0000 Subject: [Python-checkins] bpo-39571: Fix clang warning on PyTypeObject typedef (GH-18385) Message-ID: https://github.com/python/cpython/commit/f95cd199b4bc16775c8c48641bd85416b17742e7 commit: f95cd199b4bc16775c8c48641bd85416b17742e7 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T01:43:25+01:00 summary: bpo-39571: Fix clang warning on PyTypeObject typedef (GH-18385) Only define PyTypeObject type once. files: M Include/cpython/object.h diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 0b5260eda7d8a..4600f942ee766 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -190,7 +190,7 @@ typedef struct { * backwards-compatibility */ typedef Py_ssize_t printfunc; -typedef struct _typeobject { +struct _typeobject { PyObject_VAR_HEAD const char *tp_name; /* For printing, in format "." */ Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ @@ -271,7 +271,7 @@ typedef struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; -} PyTypeObject; +}; /* The *real* layout of a type object when allocated on the heap */ typedef struct _heaptypeobject { From webhook-mailer at python.org Thu Feb 6 19:53:28 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 00:53:28 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() in abstract.c (GH-18390) Message-ID: https://github.com/python/cpython/commit/0d76d2bd28ac815dabae8b07240ed002ac8fce2d commit: 0d76d2bd28ac815dabae8b07240ed002ac8fce2d branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T01:53:23+01:00 summary: bpo-39573: Use Py_TYPE() in abstract.c (GH-18390) Replace direct access to PyObject.ob_type with Py_TYPE(). files: M Objects/abstract.c diff --git a/Objects/abstract.c b/Objects/abstract.c index aca1a4e518919..7ab58a8bd52c3 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -14,7 +14,7 @@ static PyObject * type_error(const char *msg, PyObject *obj) { - PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, msg, Py_TYPE(obj)->tp_name); return NULL; } @@ -38,7 +38,7 @@ PyObject_Type(PyObject *o) return null_error(); } - v = (PyObject *)o->ob_type; + v = (PyObject *)Py_TYPE(o); Py_INCREF(v); return v; } @@ -53,7 +53,7 @@ PyObject_Size(PyObject *o) return -1; } - m = o->ob_type->tp_as_sequence; + m = Py_TYPE(o)->tp_as_sequence; if (m && m->sq_length) { Py_ssize_t len = m->sq_length(o); assert(len >= 0 || PyErr_Occurred()); @@ -150,14 +150,14 @@ PyObject_GetItem(PyObject *o, PyObject *key) return null_error(); } - m = o->ob_type->tp_as_mapping; + m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_subscript) { PyObject *item = m->mp_subscript(o, key); assert((item != NULL) ^ (PyErr_Occurred() != NULL)); return item; } - ms = o->ob_type->tp_as_sequence; + ms = Py_TYPE(o)->tp_as_sequence; if (ms && ms->sq_item) { if (PyIndex_Check(key)) { Py_ssize_t key_value; @@ -197,11 +197,11 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) null_error(); return -1; } - m = o->ob_type->tp_as_mapping; + m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_ass_subscript) return m->mp_ass_subscript(o, key, value); - if (o->ob_type->tp_as_sequence) { + if (Py_TYPE(o)->tp_as_sequence) { if (PyIndex_Check(key)) { Py_ssize_t key_value; key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); @@ -209,7 +209,7 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) return -1; return PySequence_SetItem(o, key_value, value); } - else if (o->ob_type->tp_as_sequence->sq_ass_item) { + else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { type_error("sequence index must be " "integer, not '%.200s'", key); return -1; @@ -229,11 +229,11 @@ PyObject_DelItem(PyObject *o, PyObject *key) null_error(); return -1; } - m = o->ob_type->tp_as_mapping; + m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_ass_subscript) return m->mp_ass_subscript(o, key, (PyObject*)NULL); - if (o->ob_type->tp_as_sequence) { + if (Py_TYPE(o)->tp_as_sequence) { if (PyIndex_Check(key)) { Py_ssize_t key_value; key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); @@ -241,7 +241,7 @@ PyObject_DelItem(PyObject *o, PyObject *key) return -1; return PySequence_DelItem(o, key_value); } - else if (o->ob_type->tp_as_sequence->sq_ass_item) { + else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { type_error("sequence index must be " "integer, not '%.200s'", key); return -1; @@ -276,7 +276,7 @@ PyObject_DelItemString(PyObject *o, const char *key) int PyObject_CheckReadBuffer(PyObject *obj) { - PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; Py_buffer view; if (pb == NULL || @@ -334,7 +334,7 @@ int PyObject_AsWriteBuffer(PyObject *obj, null_error(); return -1; } - pb = obj->ob_type->tp_as_buffer; + pb = Py_TYPE(obj)->tp_as_buffer; if (pb == NULL || pb->bf_getbuffer == NULL || ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { @@ -354,7 +354,7 @@ int PyObject_AsWriteBuffer(PyObject *obj, int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_Format(PyExc_TypeError, @@ -801,10 +801,10 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) int PyNumber_Check(PyObject *o) { - return o && o->ob_type->tp_as_number && - (o->ob_type->tp_as_number->nb_index || - o->ob_type->tp_as_number->nb_int || - o->ob_type->tp_as_number->nb_float); + return o && Py_TYPE(o)->tp_as_number && + (Py_TYPE(o)->tp_as_number->nb_index || + Py_TYPE(o)->tp_as_number->nb_int || + Py_TYPE(o)->tp_as_number->nb_float); } /* Binary operators */ @@ -821,8 +821,8 @@ PyNumber_Check(PyObject *o) Order operations are tried until either a valid result or error: w.op(v,w)[*], v.op(v,w), w.op(v,w) - [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of - v->ob_type + [*] only when Py_TYPE(v) != Py_TYPE(w) && Py_TYPE(w) is a subclass of + Py_TYPE(v) */ static PyObject * @@ -832,16 +832,16 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot) binaryfunc slotv = NULL; binaryfunc slotw = NULL; - if (v->ob_type->tp_as_number != NULL) - slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot); - if (w->ob_type != v->ob_type && - w->ob_type->tp_as_number != NULL) { - slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot); + if (Py_TYPE(v)->tp_as_number != NULL) + slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot); + if (Py_TYPE(w) != Py_TYPE(v) && + Py_TYPE(w)->tp_as_number != NULL) { + slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot); if (slotw == slotv) slotw = NULL; } if (slotv) { - if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { x = slotw(v, w); if (x != Py_NotImplemented) return x; @@ -869,8 +869,8 @@ binop_type_error(PyObject *v, PyObject *w, const char *op_name) "unsupported operand type(s) for %.100s: " "'%.100s' and '%.100s'", op_name, - v->ob_type->tp_name, - w->ob_type->tp_name); + Py_TYPE(v)->tp_name, + Py_TYPE(w)->tp_name); return NULL; } @@ -890,8 +890,8 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) "'%.100s' and '%.100s'. Did you mean \"print(, " "file=)\"?", op_name, - v->ob_type->tp_name, - w->ob_type->tp_name); + Py_TYPE(v)->tp_name, + Py_TYPE(w)->tp_name); return NULL; } @@ -921,18 +921,18 @@ ternary_op(PyObject *v, ternaryfunc slotw = NULL; ternaryfunc slotz = NULL; - mv = v->ob_type->tp_as_number; - mw = w->ob_type->tp_as_number; + mv = Py_TYPE(v)->tp_as_number; + mw = Py_TYPE(w)->tp_as_number; if (mv != NULL) slotv = NB_TERNOP(mv, op_slot); - if (w->ob_type != v->ob_type && + if (Py_TYPE(w) != Py_TYPE(v) && mw != NULL) { slotw = NB_TERNOP(mw, op_slot); if (slotw == slotv) slotw = NULL; } if (slotv) { - if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { x = slotw(v, w, z); if (x != Py_NotImplemented) return x; @@ -950,7 +950,7 @@ ternary_op(PyObject *v, return x; Py_DECREF(x); /* can't do it */ } - mz = z->ob_type->tp_as_number; + mz = Py_TYPE(z)->tp_as_number; if (mz != NULL) { slotz = NB_TERNOP(mz, op_slot); if (slotz == slotv || slotz == slotw) @@ -968,16 +968,16 @@ ternary_op(PyObject *v, PyExc_TypeError, "unsupported operand type(s) for ** or pow(): " "'%.100s' and '%.100s'", - v->ob_type->tp_name, - w->ob_type->tp_name); + Py_TYPE(v)->tp_name, + Py_TYPE(w)->tp_name); else PyErr_Format( PyExc_TypeError, "unsupported operand type(s) for pow(): " "'%.100s', '%.100s', '%.100s'", - v->ob_type->tp_name, - w->ob_type->tp_name, - z->ob_type->tp_name); + Py_TYPE(v)->tp_name, + Py_TYPE(w)->tp_name, + Py_TYPE(z)->tp_name); return NULL; } @@ -1000,7 +1000,7 @@ PyNumber_Add(PyObject *v, PyObject *w) { PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); if (result == Py_NotImplemented) { - PySequenceMethods *m = v->ob_type->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; Py_DECREF(result); if (m && m->sq_concat) { return (*m->sq_concat)(v, w); @@ -1031,8 +1031,8 @@ PyNumber_Multiply(PyObject *v, PyObject *w) { PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply)); if (result == Py_NotImplemented) { - PySequenceMethods *mv = v->ob_type->tp_as_sequence; - PySequenceMethods *mw = w->ob_type->tp_as_sequence; + PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; + PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; Py_DECREF(result); if (mv && mv->sq_repeat) { return sequence_repeat(mv->sq_repeat, v, w); @@ -1094,7 +1094,7 @@ PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) static PyObject * binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot) { - PyNumberMethods *mv = v->ob_type->tp_as_number; + PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; if (mv != NULL) { binaryfunc slot = NB_BINOP(mv, iop_slot); if (slot) { @@ -1154,7 +1154,7 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w) PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), NB_SLOT(nb_add)); if (result == Py_NotImplemented) { - PySequenceMethods *m = v->ob_type->tp_as_sequence; + PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; Py_DECREF(result); if (m != NULL) { binaryfunc f = NULL; @@ -1176,8 +1176,8 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) NB_SLOT(nb_multiply)); if (result == Py_NotImplemented) { ssizeargfunc f = NULL; - PySequenceMethods *mv = v->ob_type->tp_as_sequence; - PySequenceMethods *mw = w->ob_type->tp_as_sequence; + PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; + PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; Py_DECREF(result); if (mv != NULL) { f = mv->sq_inplace_repeat; @@ -1215,8 +1215,8 @@ PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { - if (v->ob_type->tp_as_number && - v->ob_type->tp_as_number->nb_inplace_power != NULL) { + if (Py_TYPE(v)->tp_as_number && + Py_TYPE(v)->tp_as_number->nb_inplace_power != NULL) { return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); } else { @@ -1236,7 +1236,7 @@ PyNumber_Negative(PyObject *o) return null_error(); } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_negative) return (*m->nb_negative)(o); @@ -1252,7 +1252,7 @@ PyNumber_Positive(PyObject *o) return null_error(); } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_positive) return (*m->nb_positive)(o); @@ -1268,7 +1268,7 @@ PyNumber_Invert(PyObject *o) return null_error(); } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_invert) return (*m->nb_invert)(o); @@ -1284,7 +1284,7 @@ PyNumber_Absolute(PyObject *o) return null_error(); } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_absolute) return m->nb_absolute(o); @@ -1296,8 +1296,8 @@ PyNumber_Absolute(PyObject *o) int PyIndex_Check(PyObject *obj) { - return obj->ob_type->tp_as_number != NULL && - obj->ob_type->tp_as_number->nb_index != NULL; + return Py_TYPE(obj)->tp_as_number != NULL && + Py_TYPE(obj)->tp_as_number->nb_index != NULL; } /* Return a Python int from the object item. @@ -1319,16 +1319,16 @@ PyNumber_Index(PyObject *item) if (!PyIndex_Check(item)) { PyErr_Format(PyExc_TypeError, "'%.200s' object cannot be interpreted " - "as an integer", item->ob_type->tp_name); + "as an integer", Py_TYPE(item)->tp_name); return NULL; } - result = item->ob_type->tp_as_number->nb_index(item); + result = Py_TYPE(item)->tp_as_number->nb_index(item); if (!result || PyLong_CheckExact(result)) return result; if (!PyLong_Check(result)) { PyErr_Format(PyExc_TypeError, "__index__ returned non-int (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } @@ -1337,7 +1337,7 @@ PyNumber_Index(PyObject *item) "__index__ returned non-int (type %.200s). " "The ability to return an instance of a strict subclass of int " "is deprecated, and may be removed in a future version of Python.", - result->ob_type->tp_name)) { + Py_TYPE(result)->tp_name)) { Py_DECREF(result); return NULL; } @@ -1382,7 +1382,7 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) /* Otherwise replace the error with caller's error object. */ PyErr_Format(err, "cannot fit '%.200s' into an index-sized integer", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); } finish: @@ -1408,7 +1408,7 @@ PyNumber_Long(PyObject *o) Py_INCREF(o); return o; } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ result = _PyLong_FromNbInt(o); if (result != NULL && !PyLong_CheckExact(result)) { @@ -1436,12 +1436,12 @@ PyNumber_Long(PyObject *o) } /* __trunc__ is specified to return an Integral type, but int() needs to return an int. */ - m = result->ob_type->tp_as_number; + m = Py_TYPE(result)->tp_as_number; if (m == NULL || (m->nb_index == NULL && m->nb_int == NULL)) { PyErr_Format( PyExc_TypeError, "__trunc__ returned non-Integral (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } @@ -1503,7 +1503,7 @@ PyNumber_Float(PyObject *o) Py_INCREF(o); return o; } - m = o->ob_type->tp_as_number; + m = Py_TYPE(o)->tp_as_number; if (m && m->nb_float) { /* This should include subclasses of float */ PyObject *res = m->nb_float(o); double val; @@ -1513,7 +1513,7 @@ PyNumber_Float(PyObject *o) if (!PyFloat_Check(res)) { PyErr_Format(PyExc_TypeError, "%.50s.__float__ returned non-float (type %.50s)", - o->ob_type->tp_name, res->ob_type->tp_name); + Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } @@ -1522,7 +1522,7 @@ PyNumber_Float(PyObject *o) "%.50s.__float__ returned non-float (type %.50s). " "The ability to return an instance of a strict subclass of float " "is deprecated, and may be removed in a future version of Python.", - o->ob_type->tp_name, res->ob_type->tp_name)) { + Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name)) { Py_DECREF(res); return NULL; } @@ -1576,8 +1576,8 @@ PySequence_Check(PyObject *s) { if (PyDict_Check(s)) return 0; - return s->ob_type->tp_as_sequence && - s->ob_type->tp_as_sequence->sq_item != NULL; + return Py_TYPE(s)->tp_as_sequence && + Py_TYPE(s)->tp_as_sequence->sq_item != NULL; } Py_ssize_t @@ -1590,14 +1590,14 @@ PySequence_Size(PyObject *s) return -1; } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_length) { Py_ssize_t len = m->sq_length(s); assert(len >= 0 || PyErr_Occurred()); return len; } - if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_length) { + if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_length) { type_error("%.200s is not a sequence", s); return -1; } @@ -1622,7 +1622,7 @@ PySequence_Concat(PyObject *s, PyObject *o) return null_error(); } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_concat) return m->sq_concat(s, o); @@ -1647,7 +1647,7 @@ PySequence_Repeat(PyObject *o, Py_ssize_t count) return null_error(); } - m = o->ob_type->tp_as_sequence; + m = Py_TYPE(o)->tp_as_sequence; if (m && m->sq_repeat) return m->sq_repeat(o, count); @@ -1677,7 +1677,7 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o) return null_error(); } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_inplace_concat) return m->sq_inplace_concat(s, o); if (m && m->sq_concat) @@ -1702,7 +1702,7 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) return null_error(); } - m = o->ob_type->tp_as_sequence; + m = Py_TYPE(o)->tp_as_sequence; if (m && m->sq_inplace_repeat) return m->sq_inplace_repeat(o, count); if (m && m->sq_repeat) @@ -1732,7 +1732,7 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) return null_error(); } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_item) { if (i < 0) { if (m->sq_length) { @@ -1747,7 +1747,7 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) return m->sq_item(s, i); } - if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_subscript) { + if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_subscript) { return type_error("%.200s is not a sequence", s); } return type_error("'%.200s' object does not support indexing", s); @@ -1762,7 +1762,7 @@ PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) return null_error(); } - mp = s->ob_type->tp_as_mapping; + mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_subscript) { PyObject *res; PyObject *slice = _PySlice_FromIndices(i1, i2); @@ -1786,7 +1786,7 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) return -1; } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_ass_item) { if (i < 0) { if (m->sq_length) { @@ -1801,7 +1801,7 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) return m->sq_ass_item(s, i, o); } - if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_ass_subscript) { + if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { type_error("%.200s is not a sequence", s); return -1; } @@ -1819,7 +1819,7 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) return -1; } - m = s->ob_type->tp_as_sequence; + m = Py_TYPE(s)->tp_as_sequence; if (m && m->sq_ass_item) { if (i < 0) { if (m->sq_length) { @@ -1834,7 +1834,7 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) return m->sq_ass_item(s, i, (PyObject *)NULL); } - if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_ass_subscript) { + if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { type_error("%.200s is not a sequence", s); return -1; } @@ -1852,7 +1852,7 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) return -1; } - mp = s->ob_type->tp_as_mapping; + mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_ass_subscript) { int res; PyObject *slice = _PySlice_FromIndices(i1, i2); @@ -1877,7 +1877,7 @@ PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) return -1; } - mp = s->ob_type->tp_as_mapping; + mp = Py_TYPE(s)->tp_as_mapping; if (mp && mp->mp_ass_subscript) { int res; PyObject *slice = _PySlice_FromIndices(i1, i2); @@ -2127,7 +2127,7 @@ int PySequence_Contains(PyObject *seq, PyObject *ob) { Py_ssize_t result; - PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; + PySequenceMethods *sqm = Py_TYPE(seq)->tp_as_sequence; if (sqm != NULL && sqm->sq_contains != NULL) return (*sqm->sq_contains)(seq, ob); result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); @@ -2153,8 +2153,8 @@ PySequence_Index(PyObject *s, PyObject *o) int PyMapping_Check(PyObject *o) { - return o && o->ob_type->tp_as_mapping && - o->ob_type->tp_as_mapping->mp_subscript; + return o && Py_TYPE(o)->tp_as_mapping && + Py_TYPE(o)->tp_as_mapping->mp_subscript; } Py_ssize_t @@ -2167,14 +2167,14 @@ PyMapping_Size(PyObject *o) return -1; } - m = o->ob_type->tp_as_mapping; + m = Py_TYPE(o)->tp_as_mapping; if (m && m->mp_length) { Py_ssize_t len = m->mp_length(o); assert(len >= 0 || PyErr_Occurred()); return len; } - if (o->ob_type->tp_as_sequence && o->ob_type->tp_as_sequence->sq_length) { + if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) { type_error("%.200s is not a mapping", o); return -1; } @@ -2434,7 +2434,7 @@ object_isinstance(PyObject *inst, PyObject *cls) if (retval == 0) { retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); if (icls != NULL) { - if (icls != (PyObject *)(inst->ob_type) && PyType_Check(icls)) { + if (icls != (PyObject *)(Py_TYPE(inst)) && PyType_Check(icls)) { retval = PyType_IsSubtype( (PyTypeObject *)icls, (PyTypeObject *)cls); @@ -2630,7 +2630,7 @@ _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls) PyObject * PyObject_GetIter(PyObject *o) { - PyTypeObject *t = o->ob_type; + PyTypeObject *t = Py_TYPE(o); getiterfunc f; f = t->tp_iter; @@ -2645,7 +2645,7 @@ PyObject_GetIter(PyObject *o) PyErr_Format(PyExc_TypeError, "iter() returned non-iterator " "of type '%.100s'", - res->ob_type->tp_name); + Py_TYPE(res)->tp_name); Py_DECREF(res); res = NULL; } @@ -2657,8 +2657,8 @@ PyObject_GetIter(PyObject *o) int PyIter_Check(PyObject *obj) { - return obj->ob_type->tp_iternext != NULL && - obj->ob_type->tp_iternext != &_PyObject_NextNotImplemented; + return Py_TYPE(obj)->tp_iternext != NULL && + Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented; } /* Return next item. @@ -2672,7 +2672,7 @@ PyObject * PyIter_Next(PyObject *iter) { PyObject *result; - result = (*iter->ob_type->tp_iternext)(iter); + result = (*Py_TYPE(iter)->tp_iternext)(iter); if (result == NULL && PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) From webhook-mailer at python.org Thu Feb 6 20:15:20 2020 From: webhook-mailer at python.org (Jakub Stasiak) Date: Fri, 07 Feb 2020 01:15:20 -0000 Subject: [Python-checkins] bpo-39491: Mention Annotated in get_origin() docstring (GH-18379) Message-ID: https://github.com/python/cpython/commit/38aaaaac805fa30870e2d093e52a900dddde3b34 commit: 38aaaaac805fa30870e2d093e52a900dddde3b34 branch: master author: Jakub Stasiak committer: GitHub date: 2020-02-06T17:15:12-08:00 summary: bpo-39491: Mention Annotated in get_origin() docstring (GH-18379) I forgot to do it in https://github.com/python/cpython/pull/18260. files: M Lib/typing.py diff --git a/Lib/typing.py b/Lib/typing.py index 5a7077c27c42a..8886b08c2ec6f 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1380,8 +1380,8 @@ def _strip_annotations(t): def get_origin(tp): """Get the unsubscripted version of a type. - This supports generic types, Callable, Tuple, Union, Literal, Final and ClassVar. - Return None for unsupported types. Examples:: + This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar + and Annotated. Return None for unsupported types. Examples:: get_origin(Literal[42]) is Literal get_origin(int) is None From webhook-mailer at python.org Thu Feb 6 20:24:56 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 01:24:56 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() macro in Python and Include directories (GH-18391) Message-ID: https://github.com/python/cpython/commit/a102ed7d2f0e7e05438f14d5fb72ca0358602249 commit: a102ed7d2f0e7e05438f14d5fb72ca0358602249 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T02:24:48+01:00 summary: bpo-39573: Use Py_TYPE() macro in Python and Include directories (GH-18391) Replace direct access to PyObject.ob_type with Py_TYPE(). files: M Include/classobject.h M Include/cpython/abstract.h M Include/pyerrors.h M Python/_warnings.c M Python/bltinmodule.c M Python/ceval.c M Python/codecs.c M Python/compile.c M Python/formatter_unicode.c M Python/getargs.c M Python/marshal.c M Python/sysmodule.c diff --git a/Include/classobject.h b/Include/classobject.h index 840431a127691..8742720720550 100644 --- a/Include/classobject.h +++ b/Include/classobject.h @@ -19,7 +19,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyMethod_Type; -#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type) +#define PyMethod_Check(op) (Py_TYPE(op)== &PyMethod_Type) PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); @@ -40,7 +40,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; -#define PyInstanceMethod_Check(op) ((op)->ob_type == &PyInstanceMethod_Type) +#define PyInstanceMethod_Check(op) (Py_TYPE(op) == &PyInstanceMethod_Type) PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 4bd7b1a61a532..76eaedfc4b72b 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -246,8 +246,8 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); /* Return 1 if the getbuffer function is available, otherwise return 0. */ #define PyObject_CheckBuffer(obj) \ - (((obj)->ob_type->tp_as_buffer != NULL) && \ - ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL)) + ((Py_TYPE(obj)->tp_as_buffer != NULL) && \ + (Py_TYPE(obj)->tp_as_buffer->bf_getbuffer != NULL)) /* This is a C-API version of the getbuffer function call. It checks to make sure object has the required function pointer and issues the @@ -315,14 +315,14 @@ PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); /* ==== Iterators ================================================ */ #define PyIter_Check(obj) \ - ((obj)->ob_type->tp_iternext != NULL && \ - (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented) + (Py_TYPE(obj)->tp_iternext != NULL && \ + Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented) /* === Number Protocol ================================================== */ #define PyIndex_Check(obj) \ - ((obj)->ob_type->tp_as_number != NULL && \ - (obj)->ob_type->tp_as_number->nb_index != NULL) + (Py_TYPE(obj)->tp_as_number != NULL && \ + Py_TYPE(obj)->tp_as_number->nb_index != NULL) /* === Sequence protocol ================================================ */ diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 5125a51ec1aa1..3fd133c57de30 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -54,11 +54,11 @@ PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS)) #define PyExceptionInstance_Check(x) \ - PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS) + PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); -#define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type)) +#define PyExceptionInstance_Class(x) ((PyObject*)Py_TYPE(x)) /* Predefined exceptions */ diff --git a/Python/_warnings.c b/Python/_warnings.c index 602211c02efa0..9e8b52d353dab 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -650,7 +650,7 @@ warn_explicit(PyObject *category, PyObject *message, text = PyObject_Str(message); if (text == NULL) goto cleanup; - category = (PyObject*)message->ob_type; + category = (PyObject*)Py_TYPE(message); } else { text = message; @@ -906,7 +906,7 @@ get_category(PyObject *message, PyObject *category) return NULL; if (rc == 1) - category = (PyObject*)message->ob_type; + category = (PyObject*)Py_TYPE(message); else if (category == NULL || category == Py_None) category = PyExc_UserWarning; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index cdb1eaaff01de..980b81041b4f9 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -170,7 +170,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, /* else get the type of the first base */ else { PyObject *base0 = PyTuple_GET_ITEM(bases, 0); - meta = (PyObject *) (base0->ob_type); + meta = (PyObject *)Py_TYPE(base0); } Py_INCREF(meta); isclass = 1; /* meta is really a class */ @@ -1002,13 +1002,13 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, if (!PyDict_Check(globals)) { PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", - globals->ob_type->tp_name); + Py_TYPE(globals)->tp_name); return NULL; } if (!PyMapping_Check(locals)) { PyErr_Format(PyExc_TypeError, "locals must be a mapping or None, not %.100s", - locals->ob_type->tp_name); + Py_TYPE(locals)->tp_name); return NULL; } if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) { @@ -1383,11 +1383,11 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) if (!PyIter_Check(it)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an iterator", - it->ob_type->tp_name); + Py_TYPE(it)->tp_name); return NULL; } - res = (*it->ob_type->tp_iternext)(it); + res = (*Py_TYPE(it)->tp_iternext)(it); if (res != NULL) { return res; } else if (nargs > 1) { @@ -1788,7 +1788,7 @@ builtin_ord(PyObject *module, PyObject *c) else { PyErr_Format(PyExc_TypeError, "ord() expected string of length 1, but " \ - "%.200s found", c->ob_type->tp_name); + "%.200s found", Py_TYPE(c)->tp_name); return NULL; } @@ -1856,7 +1856,7 @@ builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject else if (sep && !PyUnicode_Check(sep)) { PyErr_Format(PyExc_TypeError, "sep must be None or a string, not %.200s", - sep->ob_type->tp_name); + Py_TYPE(sep)->tp_name); return NULL; } if (end == Py_None) { @@ -1865,7 +1865,7 @@ builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject else if (end && !PyUnicode_Check(end)) { PyErr_Format(PyExc_TypeError, "end must be None or a string, not %.200s", - end->ob_type->tp_name); + Py_TYPE(end)->tp_name); return NULL; } diff --git a/Python/ceval.c b/Python/ceval.c index 892d668816ab9..c36a38e21139d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2633,7 +2633,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - (iterable->ob_type->tp_iter == NULL && !PySequence_Check(iterable))) + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) { _PyErr_Clear(tstate); _PyErr_Format(tstate, PyExc_TypeError, @@ -2803,7 +2803,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not a mapping", - update->ob_type->tp_name); + Py_TYPE(update)->tp_name); } Py_DECREF(update); goto error; @@ -3158,7 +3158,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PREDICTED(FOR_ITER); /* before: [iter]; after: [iter, iter()] *or* [] */ PyObject *iter = TOP(); - PyObject *next = (*iter->ob_type->tp_iternext)(iter); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); if (next != NULL) { PUSH(next); PREDICT(STORE_FAST); @@ -4369,11 +4369,11 @@ unpack_iterable(PyThreadState *tstate, PyObject *v, it = PyObject_GetIter(v); if (it == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - v->ob_type->tp_iter == NULL && !PySequence_Check(v)) + Py_TYPE(v)->tp_iter == NULL && !PySequence_Check(v)) { _PyErr_Format(tstate, PyExc_TypeError, "cannot unpack non-iterable %.200s object", - v->ob_type->tp_name); + Py_TYPE(v)->tp_name); } return 0; } @@ -4790,7 +4790,7 @@ PyEval_GetFuncName(PyObject *func) else if (PyCFunction_Check(func)) return ((PyCFunctionObject*)func)->m_ml->ml_name; else - return func->ob_type->tp_name; + return Py_TYPE(func)->tp_name; } const char * @@ -5197,7 +5197,7 @@ import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) static int check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) { - if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { + if (Py_TYPE(args)->tp_iter == NULL && !PySequence_Check(args)) { /* check_args_iterable() may be called with a live exception: * clear it to prevent calling _PyObject_FunctionStr() with an * exception set. */ diff --git a/Python/codecs.c b/Python/codecs.c index 10d76969a519d..ee2758c5fbe91 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -658,7 +658,7 @@ static void wrong_exception_type(PyObject *exc) { PyErr_Format(PyExc_TypeError, "don't know how to handle %.200s in error callback", - exc->ob_type->tp_name); + Py_TYPE(exc)->tp_name); } PyObject *PyCodec_StrictErrors(PyObject *exc) diff --git a/Python/compile.c b/Python/compile.c index 6776df54d47d0..04b8fe46e194d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3988,7 +3988,7 @@ infer_type(expr_ty e) case FormattedValue_kind: return &PyUnicode_Type; case Constant_kind: - return e->v.Constant.value->ob_type; + return Py_TYPE(e->v.Constant.value); default: return NULL; } diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 7c4ecf0b3e2cb..41a2478e0a817 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -1447,7 +1447,7 @@ _PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer, return format_string_internal(obj, &format, writer); default: /* unknown */ - unknown_presentation_type(format.type, obj->ob_type->tp_name); + unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); return -1; } } @@ -1505,7 +1505,7 @@ _PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer, default: /* unknown */ - unknown_presentation_type(format.type, obj->ob_type->tp_name); + unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); goto done; } @@ -1549,7 +1549,7 @@ _PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer, default: /* unknown */ - unknown_presentation_type(format.type, obj->ob_type->tp_name); + unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); return -1; } } @@ -1587,7 +1587,7 @@ _PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer, default: /* unknown */ - unknown_presentation_type(format.type, obj->ob_type->tp_name); + unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); return -1; } } diff --git a/Python/getargs.c b/Python/getargs.c index d5caf47a02838..d644aea5207ac 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -531,7 +531,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, toplevel ? "expected %d arguments, not %.50s" : "must be %d-item sequence, not %.50s", n, - arg == Py_None ? "None" : arg->ob_type->tp_name); + arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); return msgbuf; } @@ -621,7 +621,7 @@ _PyArg_BadArgument(const char *fname, const char *displayname, PyErr_Format(PyExc_TypeError, "%.200s() %.200s must be %.50s, not %.50s", fname, displayname, expected, - arg == Py_None ? "None" : arg->ob_type->tp_name); + arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); } static const char * @@ -636,7 +636,7 @@ converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) else { PyOS_snprintf(msgbuf, bufsize, "must be %.50s, not %.50s", expected, - arg == Py_None ? "None" : arg->ob_type->tp_name); + arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); } return msgbuf; } @@ -1331,7 +1331,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, type = va_arg(*p_va, PyTypeObject*); p = va_arg(*p_va, PyObject **); format++; - if (PyType_IsSubtype(arg->ob_type, type)) + if (PyType_IsSubtype(Py_TYPE(arg), type)) *p = arg; else return converterr(type->tp_name, arg, msgbuf, bufsize); diff --git a/Python/marshal.c b/Python/marshal.c index ec6b3dadc02ca..8d441a4f08196 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1696,7 +1696,7 @@ marshal_load(PyObject *module, PyObject *file) if (!PyBytes_Check(data)) { PyErr_Format(PyExc_TypeError, "file.read() returned not bytes but %.100s", - data->ob_type->tp_name); + Py_TYPE(data)->tp_name); result = NULL; } else { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index d8d1874745483..707a08e7f4996 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -840,7 +840,7 @@ sys_intern_impl(PyObject *module, PyObject *s) } else { _PyErr_Format(tstate, PyExc_TypeError, - "can't intern %.400s", s->ob_type->tp_name); + "can't intern %.400s", Py_TYPE(s)->tp_name); return NULL; } } From webhook-mailer at python.org Thu Feb 6 21:04:31 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 02:04:31 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() macro in Objects directory (GH-18392) Message-ID: https://github.com/python/cpython/commit/58ac700fb09497df14d4492b6f820109490b2b88 commit: 58ac700fb09497df14d4492b6f820109490b2b88 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T03:04:21+01:00 summary: bpo-39573: Use Py_TYPE() macro in Objects directory (GH-18392) Replace direct access to PyObject.ob_type with Py_TYPE(). files: M Objects/bytearrayobject.c M Objects/bytesobject.c M Objects/call.c M Objects/cellobject.c M Objects/classobject.c M Objects/codeobject.c M Objects/complexobject.c M Objects/descrobject.c M Objects/dictobject.c M Objects/floatobject.c M Objects/funcobject.c M Objects/interpreteridobject.c M Objects/listobject.c M Objects/longobject.c M Objects/methodobject.c M Objects/namespaceobject.c M Objects/object.c M Objects/rangeobject.c M Objects/typeobject.c M Objects/unicodeobject.c diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c9bf11bba1dd2..a019b4905a898 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -856,7 +856,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Format(PyExc_TypeError, "cannot convert '%.200s' object to bytearray", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); } return -1; } @@ -1630,7 +1630,7 @@ bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Format(PyExc_TypeError, "can't extend bytearray with %.100s", - iterable_of_ints->ob_type->tp_name); + Py_TYPE(iterable_of_ints)->tp_name); } return NULL; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 5334eca7f33e6..4edd93d4b8ddb 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2762,7 +2762,7 @@ PyBytes_FromObject(PyObject *x) PyErr_Format(PyExc_TypeError, "cannot convert '%.200s' object to bytes", - x->ob_type->tp_name); + Py_TYPE(x)->tp_name); return NULL; } diff --git a/Objects/call.c b/Objects/call.c index 0f8cb5aa246b0..d1d50b647f365 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -263,11 +263,11 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, return PyVectorcall_Call(callable, args, kwargs); } else { - call = callable->ob_type->tp_call; + call = Py_TYPE(callable)->tp_call; if (call == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not callable", - callable->ob_type->tp_name); + Py_TYPE(callable)->tp_name); return NULL; } diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 911cf527a4348..e97feefbf6d04 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -112,7 +112,7 @@ cell_repr(PyCellObject *op) return PyUnicode_FromFormat("", op); return PyUnicode_FromFormat("", - op, op->ob_ref->ob_type->tp_name, + op, Py_TYPE(op->ob_ref)->tp_name, op->ob_ref); } diff --git a/Objects/classobject.c b/Objects/classobject.c index db53f04862cd6..fb89b8aa69324 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -178,7 +178,7 @@ static PyObject * method_getattro(PyObject *obj, PyObject *name) { PyMethodObject *im = (PyMethodObject *)obj; - PyTypeObject *tp = obj->ob_type; + PyTypeObject *tp = Py_TYPE(obj); PyObject *descr = NULL; { @@ -190,9 +190,9 @@ method_getattro(PyObject *obj, PyObject *name) } if (descr != NULL) { - descrgetfunc f = TP_DESCR_GET(descr->ob_type); + descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); if (f != NULL) - return f(descr, obj, (PyObject *)obj->ob_type); + return f(descr, obj, (PyObject *)Py_TYPE(obj)); else { Py_INCREF(descr); return descr; @@ -425,7 +425,7 @@ static PyGetSetDef instancemethod_getset[] = { static PyObject * instancemethod_getattro(PyObject *self, PyObject *name) { - PyTypeObject *tp = self->ob_type; + PyTypeObject *tp = Py_TYPE(self); PyObject *descr = NULL; if (tp->tp_dict == NULL) { @@ -435,9 +435,9 @@ instancemethod_getattro(PyObject *self, PyObject *name) descr = _PyType_Lookup(tp, name); if (descr != NULL) { - descrgetfunc f = TP_DESCR_GET(descr->ob_type); + descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); if (f != NULL) - return f(descr, self, (PyObject *)self->ob_type); + return f(descr, self, (PyObject *)Py_TYPE(self)); else { Py_INCREF(descr); return descr; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c6759c9be22f6..fd64393c235c5 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -416,7 +416,7 @@ validate_and_copy_tuple(PyObject *tup) PyExc_TypeError, "name tuples must contain only " "strings, not '%.500s'", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); Py_DECREF(newtuple); return NULL; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index f1b76673efd4c..8d1461b29b488 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -296,7 +296,7 @@ try_complex_special_method(PyObject *op) if (!PyComplex_Check(res)) { PyErr_Format(PyExc_TypeError, "__complex__ returned non-complex (type %.200s)", - res->ob_type->tp_name); + Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } @@ -305,7 +305,7 @@ try_complex_special_method(PyObject *op) "__complex__ returned non-complex (type %.200s). " "The ability to return an instance of a strict subclass of complex " "is deprecated, and may be removed in a future version of Python.", - res->ob_type->tp_name)) { + Py_TYPE(res)->tp_name)) { Py_DECREF(res); return NULL; } @@ -958,7 +958,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) return NULL; } - nbr = r->ob_type->tp_as_number; + nbr = Py_TYPE(r)->tp_as_number; if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " @@ -970,7 +970,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) return NULL; } if (i != NULL) { - nbi = i->ob_type->tp_as_number; + nbi = Py_TYPE(i)->tp_as_number; if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " diff --git a/Objects/descrobject.c b/Objects/descrobject.c index b9b16d6d0a37d..49c26eb069233 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -84,7 +84,7 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) "doesn't apply to a '%.100s' object", descr_name((PyDescrObject *)descr), "?", descr->d_type->tp_name, - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); *pres = NULL; return 1; } @@ -97,7 +97,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) /* Ensure a valid type. Class methods ignore obj. */ if (type == NULL) { if (obj != NULL) - type = (PyObject *)obj->ob_type; + type = (PyObject *)Py_TYPE(obj); else { /* Wot - no type?! */ PyErr_Format(PyExc_TypeError, @@ -114,7 +114,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) "needs a type, not a '%.100s' as arg 2", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, - type->ob_type->tp_name); + Py_TYPE(type)->tp_name); return NULL; } if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { @@ -194,7 +194,7 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, "doesn't apply to a '%.100s' object", descr_name(descr), "?", descr->d_type->tp_name, - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); *pres = -1; return 1; } @@ -506,7 +506,7 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, - self->ob_type->tp_name); + Py_TYPE(self)->tp_name); return NULL; } @@ -1234,7 +1234,7 @@ wrapper_repr(wrapperobject *wp) { return PyUnicode_FromFormat("", wp->descr->d_base->name, - wp->self->ob_type->tp_name, + Py_TYPE(wp->self)->tp_name, wp->self); } @@ -1476,7 +1476,7 @@ property_dealloc(PyObject *self) Py_XDECREF(gs->prop_set); Py_XDECREF(gs->prop_del); Py_XDECREF(gs->prop_doc); - self->ob_type->tp_free(self); + Py_TYPE(self)->tp_free(self); } static PyObject * diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ae6b50ff27245..164104ed7e151 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4015,7 +4015,7 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) /* XXX Get rid of this restriction later */ PyErr_Format(PyExc_TypeError, "%s() requires a dict argument, not '%s'", - type->tp_name, dict->ob_type->tp_name); + type->tp_name, Py_TYPE(dict)->tp_name); return NULL; } dv = PyObject_GC_New(_PyDictViewObject, type); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index ab486d4ee3d2e..26e238cf05ad3 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -256,7 +256,7 @@ PyFloat_AsDouble(PyObject *op) return val; } PyErr_Format(PyExc_TypeError, "must be real number, not %.50s", - op->ob_type->tp_name); + Py_TYPE(op)->tp_name); return -1; } @@ -268,7 +268,7 @@ PyFloat_AsDouble(PyObject *op) if (!PyFloat_Check(res)) { PyErr_Format(PyExc_TypeError, "%.50s.__float__ returned non-float (type %.50s)", - op->ob_type->tp_name, res->ob_type->tp_name); + Py_TYPE(op)->tp_name, Py_TYPE(res)->tp_name); Py_DECREF(res); return -1; } @@ -276,7 +276,7 @@ PyFloat_AsDouble(PyObject *op) "%.50s.__float__ returned non-float (type %.50s). " "The ability to return an instance of a strict subclass of float " "is deprecated, and may be removed in a future version of Python.", - op->ob_type->tp_name, res->ob_type->tp_name)) { + Py_TYPE(op)->tp_name, Py_TYPE(res)->tp_name)) { Py_DECREF(res); return -1; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index b6ffc2a184c99..ebe68adc3362e 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -196,7 +196,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure) else { PyErr_Format(PyExc_SystemError, "expected tuple for closure, got '%.100s'", - closure->ob_type->tp_name); + Py_TYPE(closure)->tp_name); return -1; } Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure); @@ -541,7 +541,7 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, if (!PyCell_Check(o)) { return PyErr_Format(PyExc_TypeError, "arg 5 (closure) expected cell, found %s", - o->ob_type->tp_name); + Py_TYPE(o)->tp_name); } } } diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 94f5dd709bbda..57748e8139fb8 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -56,7 +56,7 @@ interp_id_converter(PyObject *arg, void *ptr) else { PyErr_Format(PyExc_TypeError, "interpreter ID must be an int, got %.100s", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); return 0; } *(int64_t *)ptr = id; diff --git a/Objects/listobject.c b/Objects/listobject.c index c93a0feaf3695..d83e3cfcf1af5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -493,7 +493,7 @@ list_concat(PyListObject *a, PyObject *bb) if (!PyList_Check(bb)) { PyErr_Format(PyExc_TypeError, "can only concatenate list (not \"%.200s\") to list", - bb->ob_type->tp_name); + Py_TYPE(bb)->tp_name); return NULL; } #define b ((PyListObject *)bb) @@ -892,7 +892,7 @@ list_extend(PyListObject *self, PyObject *iterable) it = PyObject_GetIter(iterable); if (it == NULL) return NULL; - iternext = *it->ob_type->tp_iternext; + iternext = *Py_TYPE(it)->tp_iternext; /* Guess a result list size. */ n = PyObject_LengthHint(iterable, 8); @@ -1179,7 +1179,7 @@ struct s_MergeState { /* This function is used by unsafe_object_compare to optimize comparisons * when we know our list is type-homogeneous but we can't assume anything else. - * In the pre-sort check it is set equal to key->ob_type->tp_richcompare */ + * In the pre-sort check it is set equal to Py_TYPE(key)->tp_richcompare */ PyObject *(*key_richcompare)(PyObject *, PyObject *, int); /* This function is used by unsafe_tuple_compare to compare the first elements @@ -2015,7 +2015,7 @@ unsafe_object_compare(PyObject *v, PyObject *w, MergeState *ms) PyObject *res_obj; int res; /* No assumptions, because we check first: */ - if (v->ob_type->tp_richcompare != ms->key_richcompare) + if (Py_TYPE(v)->tp_richcompare != ms->key_richcompare) return PyObject_RichCompareBool(v, w, Py_LT); assert(ms->key_richcompare != NULL); @@ -2052,8 +2052,8 @@ unsafe_latin_compare(PyObject *v, PyObject *w, MergeState *ms) int res; /* Modified from Objects/unicodeobject.c:unicode_compare, assuming: */ - assert(v->ob_type == w->ob_type); - assert(v->ob_type == &PyUnicode_Type); + assert(Py_TYPE(v) == Py_TYPE(w)); + assert(Py_TYPE(v) == &PyUnicode_Type); assert(PyUnicode_KIND(v) == PyUnicode_KIND(w)); assert(PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND); @@ -2075,8 +2075,8 @@ unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms) PyLongObject *vl, *wl; sdigit v0, w0; int res; /* Modified from Objects/longobject.c:long_compare, assuming: */ - assert(v->ob_type == w->ob_type); - assert(v->ob_type == &PyLong_Type); + assert(Py_TYPE(v) == Py_TYPE(w)); + assert(Py_TYPE(v) == &PyLong_Type); assert(Py_ABS(Py_SIZE(v)) <= 1); assert(Py_ABS(Py_SIZE(w)) <= 1); @@ -2103,8 +2103,8 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms) int res; /* Modified from Objects/floatobject.c:float_richcompare, assuming: */ - assert(v->ob_type == w->ob_type); - assert(v->ob_type == &PyFloat_Type); + assert(Py_TYPE(v) == Py_TYPE(w)); + assert(Py_TYPE(v) == &PyFloat_Type); res = PyFloat_AS_DOUBLE(v) < PyFloat_AS_DOUBLE(w); assert(res == PyObject_RichCompareBool(v, w, Py_LT)); @@ -2125,8 +2125,8 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms) int k; /* Modified from Objects/tupleobject.c:tuplerichcompare, assuming: */ - assert(v->ob_type == w->ob_type); - assert(v->ob_type == &PyTuple_Type); + assert(Py_TYPE(v) == Py_TYPE(w)); + assert(Py_TYPE(v) == &PyTuple_Type); assert(Py_SIZE(v) > 0); assert(Py_SIZE(w) > 0); @@ -2247,12 +2247,12 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) * set ms appropriately. */ if (saved_ob_size > 1) { /* Assume the first element is representative of the whole list. */ - int keys_are_in_tuples = (lo.keys[0]->ob_type == &PyTuple_Type && + int keys_are_in_tuples = (Py_TYPE(lo.keys[0]) == &PyTuple_Type && Py_SIZE(lo.keys[0]) > 0); PyTypeObject* key_type = (keys_are_in_tuples ? - PyTuple_GET_ITEM(lo.keys[0], 0)->ob_type : - lo.keys[0]->ob_type); + Py_TYPE(PyTuple_GET_ITEM(lo.keys[0], 0)) : + Py_TYPE(lo.keys[0])); int keys_are_all_same_type = 1; int strings_are_latin = 1; @@ -2262,7 +2262,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) for (i=0; i < saved_ob_size; i++) { if (keys_are_in_tuples && - !(lo.keys[i]->ob_type == &PyTuple_Type && Py_SIZE(lo.keys[i]) != 0)) { + !(Py_TYPE(lo.keys[i]) == &PyTuple_Type && Py_SIZE(lo.keys[i]) != 0)) { keys_are_in_tuples = 0; keys_are_all_same_type = 0; break; @@ -2275,7 +2275,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) PyTuple_GET_ITEM(lo.keys[i], 0) : lo.keys[i]); - if (key->ob_type != key_type) { + if (Py_TYPE(key) != key_type) { keys_are_all_same_type = 0; /* If keys are in tuple we must loop over the whole list to make sure all items are tuples */ @@ -2818,7 +2818,7 @@ list_subscript(PyListObject* self, PyObject* item) else { PyErr_Format(PyExc_TypeError, "list indices must be integers or slices, not %.200s", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); return NULL; } } @@ -2981,7 +2981,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) else { PyErr_Format(PyExc_TypeError, "list indices must be integers or slices, not %.200s", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); return -1; } } diff --git a/Objects/longobject.c b/Objects/longobject.c index 9115fa184f37e..67cbc7b27e3d3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -150,7 +150,7 @@ _PyLong_FromNbInt(PyObject *integral) if (!PyLong_Check(result)) { PyErr_Format(PyExc_TypeError, "__int__ returned non-int (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } @@ -159,7 +159,7 @@ _PyLong_FromNbInt(PyObject *integral) "__int__ returned non-int (type %.200s). " "The ability to return an instance of a strict subclass of int " "is deprecated, and may be removed in a future version of Python.", - result->ob_type->tp_name)) { + Py_TYPE(result)->tp_name)) { Py_DECREF(result); return NULL; } @@ -203,7 +203,7 @@ _PyLong_FromNbIndexOrNbInt(PyObject *integral) if (!PyLong_Check(result)) { PyErr_Format(PyExc_TypeError, "__index__ returned non-int (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } @@ -212,7 +212,7 @@ _PyLong_FromNbIndexOrNbInt(PyObject *integral) "__index__ returned non-int (type %.200s). " "The ability to return an instance of a strict subclass of int " "is deprecated, and may be removed in a future version of Python.", - result->ob_type->tp_name)) + Py_TYPE(result)->tp_name)) { Py_DECREF(result); return NULL; diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 6a37238d86d8d..2a8111fea1c61 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -234,7 +234,7 @@ meth_repr(PyCFunctionObject *m) m->m_ml->ml_name); return PyUnicode_FromFormat("", m->m_ml->ml_name, - m->m_self->ob_type->tp_name, + Py_TYPE(m->m_self)->tp_name, m->m_self); } diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index ddad39a910762..5c7163f36dc32 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -73,7 +73,7 @@ namespace_repr(PyObject *ns) const char * name; name = (Py_TYPE(ns) == &_PyNamespace_Type) ? "namespace" - : ns->ob_type->tp_name; + : Py_TYPE(ns)->tp_name; i = Py_ReprEnter(ns); if (i != 0) { diff --git a/Objects/object.c b/Objects/object.c index aca20e8d096f8..5806542488115 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -33,8 +33,8 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) CHECK(!_PyObject_IsFreed(op)); CHECK(Py_REFCNT(op) >= 1); - CHECK(op->ob_type != NULL); - _PyType_CheckConsistency(op->ob_type); + CHECK(Py_TYPE(op) != NULL); + _PyType_CheckConsistency(Py_TYPE(op)); if (PyUnicode_Check(op)) { _PyUnicode_CheckConsistency(op, check_content); @@ -299,7 +299,7 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) else { PyErr_Format(PyExc_TypeError, "str() or repr() returned '%.100s'", - s->ob_type->tp_name); + Py_TYPE(s)->tp_name); ret = -1; } Py_XDECREF(s); @@ -331,7 +331,7 @@ _Py_BreakPoint(void) int _PyObject_IsFreed(PyObject *op) { - if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(op->ob_type)) { + if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(Py_TYPE(op))) { return 1; } /* ignore op->ob_ref: its value can have be modified @@ -406,7 +406,7 @@ PyObject_Repr(PyObject *v) return PyUnicode_FromString(""); if (Py_TYPE(v)->tp_repr == NULL) return PyUnicode_FromFormat("<%s object at %p>", - v->ob_type->tp_name, v); + Py_TYPE(v)->tp_name, v); PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG @@ -422,7 +422,7 @@ PyObject_Repr(PyObject *v) " while getting the repr of an object")) { return NULL; } - res = (*v->ob_type->tp_repr)(v); + res = (*Py_TYPE(v)->tp_repr)(v); _Py_LeaveRecursiveCall(tstate); if (res == NULL) { @@ -431,7 +431,7 @@ PyObject_Repr(PyObject *v) if (!PyUnicode_Check(res)) { _PyErr_Format(tstate, PyExc_TypeError, "__repr__ returned non-string (type %.200s)", - res->ob_type->tp_name); + Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } @@ -665,22 +665,22 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) PyObject *res; int checked_reverse_op = 0; - if (v->ob_type != w->ob_type && - PyType_IsSubtype(w->ob_type, v->ob_type) && - (f = w->ob_type->tp_richcompare) != NULL) { + if (Py_TYPE(v) != Py_TYPE(w) && + PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) && + (f = Py_TYPE(w)->tp_richcompare) != NULL) { checked_reverse_op = 1; res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; Py_DECREF(res); } - if ((f = v->ob_type->tp_richcompare) != NULL) { + if ((f = Py_TYPE(v)->tp_richcompare) != NULL) { res = (*f)(v, w, op); if (res != Py_NotImplemented) return res; Py_DECREF(res); } - if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { + if (!checked_reverse_op && (f = Py_TYPE(w)->tp_richcompare) != NULL) { res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; @@ -699,8 +699,8 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) _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); + Py_TYPE(v)->tp_name, + Py_TYPE(w)->tp_name); return NULL; } Py_INCREF(res); @@ -888,7 +888,7 @@ PyObject_GetAttr(PyObject *v, PyObject *name) if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); return NULL; } if (tp->tp_getattro != NULL) @@ -913,7 +913,7 @@ _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); *result = NULL; return -1; } @@ -989,7 +989,7 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); return -1; } Py_INCREF(name); @@ -1115,9 +1115,9 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) if (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { meth_found = 1; } else { - f = descr->ob_type->tp_descr_get; + f = Py_TYPE(descr)->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) { - *method = f(descr, obj, (PyObject *)obj->ob_type); + *method = f(descr, obj, (PyObject *)Py_TYPE(obj)); Py_DECREF(descr); return 0; } @@ -1188,7 +1188,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); return NULL; } Py_INCREF(name); @@ -1203,9 +1203,9 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, f = NULL; if (descr != NULL) { Py_INCREF(descr); - f = descr->ob_type->tp_descr_get; + f = Py_TYPE(descr)->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) { - res = f(descr, obj, (PyObject *)obj->ob_type); + res = f(descr, obj, (PyObject *)Py_TYPE(obj)); if (res == NULL && suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -1302,7 +1302,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); return -1; } @@ -1315,7 +1315,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, if (descr != NULL) { Py_INCREF(descr); - f = descr->ob_type->tp_descr_set; + f = Py_TYPE(descr)->tp_descr_set; if (f != NULL) { res = f(descr, obj, value); goto done; @@ -1408,15 +1408,15 @@ PyObject_IsTrue(PyObject *v) return 0; if (v == Py_None) return 0; - else if (v->ob_type->tp_as_number != NULL && - v->ob_type->tp_as_number->nb_bool != NULL) - res = (*v->ob_type->tp_as_number->nb_bool)(v); - else if (v->ob_type->tp_as_mapping != NULL && - v->ob_type->tp_as_mapping->mp_length != NULL) - res = (*v->ob_type->tp_as_mapping->mp_length)(v); - else if (v->ob_type->tp_as_sequence != NULL && - v->ob_type->tp_as_sequence->sq_length != NULL) - res = (*v->ob_type->tp_as_sequence->sq_length)(v); + else if (Py_TYPE(v)->tp_as_number != NULL && + Py_TYPE(v)->tp_as_number->nb_bool != NULL) + res = (*Py_TYPE(v)->tp_as_number->nb_bool)(v); + else if (Py_TYPE(v)->tp_as_mapping != NULL && + Py_TYPE(v)->tp_as_mapping->mp_length != NULL) + res = (*Py_TYPE(v)->tp_as_mapping->mp_length)(v); + else if (Py_TYPE(v)->tp_as_sequence != NULL && + Py_TYPE(v)->tp_as_sequence->sq_length != NULL) + res = (*Py_TYPE(v)->tp_as_sequence->sq_length)(v); else return 1; /* if it is negative, it should be either -1 or -2 */ @@ -1443,7 +1443,7 @@ PyCallable_Check(PyObject *x) { if (x == NULL) return 0; - return x->ob_type->tp_call != NULL; + return Py_TYPE(x)->tp_call != NULL; } diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index e7168209324ed..343a80c76b0bc 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -121,7 +121,7 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) "range expected at least 1 argument, got 0"); return NULL; default: - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_TypeError, "range expected at most 3 arguments, got %zd", num_args); return NULL; @@ -631,7 +631,7 @@ range_subscript(rangeobject* self, PyObject* item) } PyErr_Format(PyExc_TypeError, "range indices must be integers or slices, not %.200s", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); return NULL; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d85ff3ce56993..5b8d5a228e5af 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2345,7 +2345,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) assert(args != NULL && PyTuple_Check(args)); assert(kwds == NULL || PyDict_Check(kwds)); - /* Special case: type(x) should return x->ob_type */ + /* Special case: type(x) should return Py_TYPE(x) */ /* We only want type itself to accept the one-argument form (#27157) Note: We don't call PyType_CheckExact as that also allows subclasses */ if (metatype == &PyType_Type) { @@ -3230,7 +3230,7 @@ type_getattro(PyTypeObject *type, PyObject *name) if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); + Py_TYPE(name)->tp_name); return NULL; } @@ -3888,12 +3888,12 @@ object_richcompare(PyObject *self, PyObject *other, int op) case Py_NE: /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ - if (self->ob_type->tp_richcompare == NULL) { + if (Py_TYPE(self)->tp_richcompare == NULL) { res = Py_NotImplemented; Py_INCREF(res); break; } - res = (*self->ob_type->tp_richcompare)(self, other, Py_EQ); + res = (*Py_TYPE(self)->tp_richcompare)(self, other, Py_EQ); if (res != NULL && res != Py_NotImplemented) { int ok = PyObject_IsTrue(res); Py_DECREF(res); @@ -4215,7 +4215,7 @@ _PyObject_GetState(PyObject *obj, int required) if (getstate == NULL) { PyObject *slotnames; - if (required && obj->ob_type->tp_itemsize) { + if (required && Py_TYPE(obj)->tp_itemsize) { PyErr_Format(PyExc_TypeError, "cannot pickle '%.200s' object", Py_TYPE(obj)->tp_name); @@ -4248,13 +4248,13 @@ _PyObject_GetState(PyObject *obj, int required) assert(slotnames == Py_None || PyList_Check(slotnames)); if (required) { Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; - if (obj->ob_type->tp_dictoffset) + if (Py_TYPE(obj)->tp_dictoffset) basicsize += sizeof(PyObject *); - if (obj->ob_type->tp_weaklistoffset) + if (Py_TYPE(obj)->tp_weaklistoffset) basicsize += sizeof(PyObject *); if (slotnames != Py_None) basicsize += sizeof(PyObject *) * PyList_GET_SIZE(slotnames); - if (obj->ob_type->tp_basicsize > basicsize) { + if (Py_TYPE(obj)->tp_basicsize > basicsize) { Py_DECREF(slotnames); Py_DECREF(state); PyErr_Format(PyExc_TypeError, @@ -4725,7 +4725,7 @@ object___format___impl(PyObject *self, PyObject *format_spec) if (PyUnicode_GET_LENGTH(format_spec) > 0) { PyErr_Format(PyExc_TypeError, "unsupported format string passed to %.200s.__format__", - self->ob_type->tp_name); + Py_TYPE(self)->tp_name); return NULL; } return PyObject_Str(self); @@ -4744,10 +4744,10 @@ object___sizeof___impl(PyObject *self) Py_ssize_t res, isize; res = 0; - isize = self->ob_type->tp_itemsize; + isize = Py_TYPE(self)->tp_itemsize; if (isize > 0) res = Py_SIZE(self) * isize; - res += self->ob_type->tp_basicsize; + res += Py_TYPE(self)->tp_basicsize; return PyLong_FromSsize_t(res); } @@ -4794,7 +4794,7 @@ object___dir___impl(PyObject *self) if (_PyObject_LookupAttrId(self, &PyId___class__, &itsclass) < 0) { goto error; } - /* XXX(tomer): Perhaps fall back to obj->ob_type if no + /* XXX(tomer): Perhaps fall back to Py_TYPE(obj) if no __class__ exists? */ if (itsclass != NULL && merge_class_dict(dict, itsclass) < 0) goto error; @@ -7537,7 +7537,7 @@ set_names(PyTypeObject *type) _PyErr_FormatFromCause(PyExc_RuntimeError, "Error calling __set_name__ on '%.100s' instance %R " "in '%.100s'", - value->ob_type->tp_name, key, type->tp_name); + Py_TYPE(value)->tp_name, key, type->tp_name); Py_DECREF(names_to_set); return -1; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fa48ee1ac78f0..fd08ddbf57434 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8401,7 +8401,7 @@ charmapencode_lookup(Py_UCS4 c, PyObject *mapping) /* wrong return value */ PyErr_Format(PyExc_TypeError, "character mapping must return integer, bytes or None, not %.400s", - x->ob_type->tp_name); + Py_TYPE(x)->tp_name); Py_DECREF(x); return NULL; } @@ -11082,8 +11082,8 @@ PyUnicode_Compare(PyObject *left, PyObject *right) } PyErr_Format(PyExc_TypeError, "Can't compare %.100s and %.100s", - left->ob_type->tp_name, - right->ob_type->tp_name); + Py_TYPE(left)->tp_name, + Py_TYPE(right)->tp_name); return -1; } @@ -11353,7 +11353,7 @@ PyUnicode_Concat(PyObject *left, PyObject *right) if (!PyUnicode_Check(right)) { PyErr_Format(PyExc_TypeError, "can only concatenate str (not \"%.200s\") to str", - right->ob_type->tp_name); + Py_TYPE(right)->tp_name); return NULL; } if (PyUnicode_READY(right) < 0) From webhook-mailer at python.org Thu Feb 6 21:37:12 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 02:37:12 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() macro in Modules directory (GH-18393) Message-ID: https://github.com/python/cpython/commit/daa9756cb6395323d6f291efe5c7d7fdc6b2e9d8 commit: daa9756cb6395323d6f291efe5c7d7fdc6b2e9d8 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T03:37:06+01:00 summary: bpo-39573: Use Py_TYPE() macro in Modules directory (GH-18393) Replace direct access to PyObject.ob_type with Py_TYPE(). files: M Modules/_collectionsmodule.c M Modules/_csv.c M Modules/_ctypes/cfield.c M Modules/_ctypes/ctypes.h M Modules/_ctypes/stgdict.c M Modules/_cursesmodule.c M Modules/_datetimemodule.c M Modules/_dbmmodule.c M Modules/_decimal/_decimal.c M Modules/_gdbmmodule.c M Modules/_io/_iomodule.c M Modules/_io/textio.c M Modules/_json.c M Modules/_pickle.c M Modules/_sqlite/microprotocols.c M Modules/_testbuffer.c M Modules/_testcapimodule.c M Modules/_tkinter.c M Modules/_xxsubinterpretersmodule.c M Modules/cjkcodecs/multibytecodec.c M Modules/cjkcodecs/multibytecodec.h M Modules/gcmodule.c M Modules/grpmodule.c M Modules/parsermodule.c M Modules/sha512module.c M Modules/socketmodule.c diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 1d23973fd0566..97d7de47d2dfa 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -539,7 +539,7 @@ deque_concat(dequeobject *deque, PyObject *other) if (rv == 0) { PyErr_Format(PyExc_TypeError, "can only concatenate deque (not \"%.200s\") to deque", - other->ob_type->tp_name); + Py_TYPE(other)->tp_name); } return NULL; } @@ -2395,7 +2395,7 @@ tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) "descriptor for index '%zd' for tuple subclasses " "doesn't apply to '%s' object", index, - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); return NULL; } diff --git a/Modules/_csv.c b/Modules/_csv.c index aaf377650c0b2..2d541bb3af8ea 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -236,7 +236,7 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) if (!PyUnicode_Check(src)) { PyErr_Format(PyExc_TypeError, "\"%s\" must be string, not %.200s", name, - src->ob_type->tp_name); + Py_TYPE(src)->tp_name); return -1; } len = PyUnicode_GetLength(src); @@ -807,7 +807,7 @@ Reader_iternext(ReaderObj *self) "iterator should return strings, " "not %.200s " "(did you open the file in text mode?)", - lineobj->ob_type->tp_name + Py_TYPE(lineobj)->tp_name ); Py_DECREF(lineobj); return NULL; @@ -1168,7 +1168,7 @@ csv_writerow(WriterObj *self, PyObject *seq) if (iter == NULL) return PyErr_Format(_csvstate_global->error_obj, "iterable expected, not %.200s", - seq->ob_type->tp_name); + Py_TYPE(seq)->tp_name); /* Join all fields in internal buffer. */ diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index e0a50fde6a07a..f860e6e51b246 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -274,7 +274,7 @@ static void PyCField_dealloc(PyObject *self) { PyCField_clear((CFieldObject *)self); - self->ob_type->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * @@ -1175,7 +1175,7 @@ u_set(void *ptr, PyObject *value, Py_ssize_t size) if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string expected instead of %s instance", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } else Py_INCREF(value); @@ -1234,7 +1234,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string expected instead of %s instance", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } @@ -1289,7 +1289,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) if(!PyBytes_Check(value)) { PyErr_Format(PyExc_TypeError, "expected bytes, %s found", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } @@ -1334,7 +1334,7 @@ z_set(void *ptr, PyObject *value, Py_ssize_t size) } PyErr_Format(PyExc_TypeError, "bytes or integer address expected instead of %s instance", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } @@ -1373,7 +1373,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string or integer address expected instead of %s instance", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } @@ -1416,7 +1416,7 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) } else if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string expected instead of %s instance", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return NULL; } diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index e58f85233cb71..351f996be05c6 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -102,7 +102,7 @@ typedef struct { } PyCFuncPtrObject; extern PyTypeObject PyCStgDict_Type; -#define PyCStgDict_CheckExact(v) ((v)->ob_type == &PyCStgDict_Type) +#define PyCStgDict_CheckExact(v) (Py_TYPE(v) == &PyCStgDict_Type) #define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); @@ -314,7 +314,7 @@ struct tagPyCArgObject { }; extern PyTypeObject PyCArg_Type; -#define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) +#define PyCArg_CheckExact(v) (Py_TYPE(v) == &PyCArg_Type) extern PyCArgObject *PyCArgObject_new(void); extern PyObject * diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 1d45ade5efd90..c8001a9781049 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -190,7 +190,7 @@ PyType_stgdict(PyObject *obj) StgDictObject * PyObject_stgdict(PyObject *self) { - PyTypeObject *type = self->ob_type; + PyTypeObject *type = Py_TYPE(self); if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index c2ce3a968faee..5b29000a24ef8 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2924,7 +2924,7 @@ _curses_getwin(PyObject *module, PyObject *file) if (!PyBytes_Check(data)) { PyErr_Format(PyExc_TypeError, "f.read() returned %.100s instead of bytes", - data->ob_type->tp_name); + Py_TYPE(data)->tp_name); Py_DECREF(data); goto error; } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 0b98cca67d4c5..bc03c504380de 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1810,7 +1810,7 @@ checked_divmod(PyObject *a, PyObject *b) if (!PyTuple_Check(result)) { PyErr_Format(PyExc_TypeError, "divmod() returned non-tuple (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index b317b57e7ae57..072e977523696 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -255,7 +255,7 @@ dbm_contains(PyObject *self, PyObject *arg) else if (!PyBytes_Check(arg)) { PyErr_Format(PyExc_TypeError, "dbm key must be bytes or string, not %.100s", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); return -1; } else { diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e2ac19800315c..75a8ddba1fe0a 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2584,7 +2584,7 @@ PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) else { PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is not supported", - v->ob_type->tp_name); + Py_TYPE(v)->tp_name); return NULL; } } @@ -2633,7 +2633,7 @@ PyDec_FromObject(PyObject *v, PyObject *context) else { PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is not supported", - v->ob_type->tp_name); + Py_TYPE(v)->tp_name); return NULL; } } @@ -2696,7 +2696,7 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) if (type_err) { PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is not supported", - v->ob_type->tp_name); + Py_TYPE(v)->tp_name); } else { Py_INCREF(Py_NotImplemented); diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index dd4a348d136c7..a815819ee90f3 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -349,7 +349,7 @@ dbm_contains(PyObject *self, PyObject *arg) else if (!PyBytes_Check(arg)) { PyErr_Format(PyExc_TypeError, "gdbm key must be bytes or string, not %.100s", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); return -1; } else { diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 5932363f3af35..d609fa4afec61 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -544,7 +544,7 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err) /* Otherwise replace the error with caller's error object. */ PyErr_Format(err, "cannot fit '%.200s' into an offset-sized integer", - item->ob_type->tp_name); + Py_TYPE(item)->tp_name); } finish: diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 5ebeb024e5793..c4c56cb04def2 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1094,7 +1094,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, PyErr_Format( PyExc_TypeError, "TextIOWrapper() argument 'errors' must be str or None, not %.50s", - errors->ob_type->tp_name); + Py_TYPE(errors)->tp_name); return -1; } else if (io_check_errors(errors)) { diff --git a/Modules/_json.c b/Modules/_json.c index 3e4fe795a0573..a70043b605f6b 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1617,7 +1617,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, else { PyErr_Format(PyExc_TypeError, "keys must be str, int, float, bool or None, " - "not %.100s", key->ob_type->tp_name); + "not %.100s", Py_TYPE(key)->tp_name); goto bail; } diff --git a/Modules/_pickle.c b/Modules/_pickle.c index fc48d6057866a..f67fb6a65c38c 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1976,7 +1976,7 @@ fast_save_enter(PicklerObject *self, PyObject *obj) PyErr_Format(PyExc_ValueError, "fast mode: can't pickle cyclic objects " "including object type %.200s at %p", - obj->ob_type->tp_name, obj); + Py_TYPE(obj)->tp_name, obj); self->fast_nesting = -1; return 0; } diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 59a5e228454ec..bdcb174be4379 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -84,7 +84,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) way to get a quotable object to be its instance */ /* look for an adapter in the registry */ - key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto); + key = Py_BuildValue("(OO)", (PyObject*)Py_TYPE(obj), proto); if (!key) { return NULL; } diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index d7d3cc8d0d53a..047e3d3974cf1 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -1854,7 +1854,7 @@ ndarray_subscript(NDArrayObject *self, PyObject *key) type_error: PyErr_Format(PyExc_TypeError, "cannot index memory using \"%.200s\"", - key->ob_type->tp_name); + Py_TYPE(key)->tp_name); err_occurred: Py_DECREF(nd); return NULL; diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index d8bf3735046c1..3bb1bf1e274ff 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -274,7 +274,7 @@ dict_hassplittable(PyObject *self, PyObject *arg) if (!PyDict_Check(arg)) { PyErr_Format(PyExc_TypeError, "dict_hassplittable() argument must be dict, not '%s'", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); return NULL; } @@ -2724,7 +2724,7 @@ test_thread_state(PyObject *self, PyObject *args) if (!PyCallable_Check(fn)) { PyErr_Format(PyExc_TypeError, "'%s' object is not callable", - fn->ob_type->tp_name); + Py_TYPE(fn)->tp_name); return NULL; } diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 4f7d1b78ebe81..87bc7ae8aeeab 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -833,7 +833,7 @@ typedef struct { } PyTclObject; static PyObject *PyTclObject_Type; -#define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type) +#define PyTclObject_Check(v) (Py_TYPE(v) == (PyTypeObject *) PyTclObject_Type) static PyObject * newPyTclObject(Tcl_Obj *arg) @@ -1734,7 +1734,7 @@ varname_converter(PyObject *in, void *_out) } PyErr_Format(PyExc_TypeError, "must be str, bytes or Tcl_Obj, not %.50s", - in->ob_type->tp_name); + Py_TYPE(in)->tp_name); return 0; } diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index fa20bc5dcec57..cc4f5d9e6dc16 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1428,7 +1428,7 @@ channel_id_converter(PyObject *arg, void *ptr) else { PyErr_Format(PyExc_TypeError, "channel ID must be an int, got %.100s", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); return 0; } *(int64_t *)ptr = cid; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index f24ec933508f1..2dd63a9531e67 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1450,7 +1450,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, PyErr_Format(PyExc_TypeError, "stream function returned a " "non-bytes object (%.100s)", - cres->ob_type->tp_name); + Py_TYPE(cres)->tp_name); goto errorexit; } diff --git a/Modules/cjkcodecs/multibytecodec.h b/Modules/cjkcodecs/multibytecodec.h index 6d34534ee685b..94670ecafefd1 100644 --- a/Modules/cjkcodecs/multibytecodec.h +++ b/Modules/cjkcodecs/multibytecodec.h @@ -65,7 +65,7 @@ typedef struct { MultibyteCodec *codec; } MultibyteCodecObject; -#define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type) +#define MultibyteCodec_Check(op) (Py_TYPE(op) == &MultibyteCodec_Type) #define _MultibyteStatefulCodec_HEAD \ PyObject_HEAD \ diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 99a6c9ed91d36..7e9eae50a8ed6 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -653,7 +653,7 @@ untrack_dicts(PyGC_Head *head) static int has_legacy_finalizer(PyObject *op) { - return op->ob_type->tp_del != NULL; + return Py_TYPE(op)->tp_del != NULL; } /* Move the objects in unreachable with tp_del slots into `finalizers`. diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 81f969c51dd00..0e2801fce5055 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -116,7 +116,7 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) PyErr_Clear(); if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "group id must be int, not %.200", - id->ob_type->tp_name) < 0) { + Py_TYPE(id)->tp_name) < 0) { return NULL; } py_int_id = PyNumber_Long(id); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index ef63ca936e91c..f00329b354182 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -256,7 +256,7 @@ PyTypeObject PyST_Type = { /* PyST_Type isn't subclassable, so just check ob_type */ -#define PyST_Object_Check(v) ((v)->ob_type == &PyST_Type) +#define PyST_Object_Check(v) (Py_TYPE(v) == &PyST_Type) static int parser_compare_nodes(node *left, node *right) diff --git a/Modules/sha512module.c b/Modules/sha512module.c index df4f9d2d7415d..4045698387faa 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -478,7 +478,7 @@ SHA512Type_copy_impl(SHAobject *self) { SHAobject *newobj; - if (((PyObject*)self)->ob_type == &SHA512type) { + if (Py_TYPE((PyObject*)self) == &SHA512type) { if ( (newobj = newSHA512object())==NULL) return NULL; } else { diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index d42fa7ce18293..e54f7a9b1c2bb 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1670,7 +1670,7 @@ idna_converter(PyObject *obj, struct maybe_idna *data) } else { PyErr_Format(PyExc_TypeError, "str, bytes or bytearray expected, not %s", - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); return 0; } if (strlen(data->buf) != len) { From webhook-mailer at python.org Fri Feb 7 03:17:12 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 08:17:12 -0000 Subject: [Python-checkins] bpo-39573: Add Py_SET_TYPE() function (GH-18394) Message-ID: https://github.com/python/cpython/commit/d2ec81a8c99796b51fb8c49b77a7fe369863226f commit: d2ec81a8c99796b51fb8c49b77a7fe369863226f branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T09:17:07+01:00 summary: bpo-39573: Add Py_SET_TYPE() function (GH-18394) Add Py_SET_TYPE() function to set the type of an object. files: A Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst M Doc/c-api/structures.rst M Include/cpython/objimpl.h M Include/object.h M Modules/_blake2/blake2module.c M Modules/_ctypes/_ctypes.c M Modules/_ctypes/ctypes.h M Modules/_sha3/sha3module.c M Modules/_sqlite/prepare_protocol.c M Modules/_testbuffer.c M Modules/_testcapimodule.c M Modules/arraymodule.c M Modules/itertoolsmodule.c M Modules/md5module.c M Modules/sha1module.c M Modules/sha256module.c M Modules/sha512module.c M Modules/socketmodule.c M Modules/unicodedata.c M Objects/floatobject.c M Objects/moduleobject.c M Objects/object.c M Objects/typeobject.c M Objects/weakrefobject.c diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 100573c5693fc..8a1431c2de7fa 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -70,6 +70,13 @@ the definition of all other Python objects. (((PyObject*)(o))->ob_type) +.. c:function:: void Py_SET_TYPE(PyObject *o, PyTypeObject *type) + + Set the object *o* type to *type*. + + .. versionadded:: 3.9 + + .. c:macro:: Py_REFCNT(o) This macro is used to access the :attr:`ob_refcnt` member of a Python diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index 3f148146f67a4..ebb3e234e36fe 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -15,7 +15,7 @@ static inline PyObject* _PyObject_INIT(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); - Py_TYPE(op) = typeobj; + Py_SET_TYPE(op, typeobj); if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(typeobj); } diff --git a/Include/object.h b/Include/object.h index 0b630513375d3..eb887f4c6eb50 100644 --- a/Include/object.h +++ b/Include/object.h @@ -128,6 +128,12 @@ static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { } #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) +static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { + ob->ob_type = type; +} +#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) + + /* Type objects contain a string containing the type name (to help somewhat in debugging), the allocation parameters (see PyObject_New() and diff --git a/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst b/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst new file mode 100644 index 0000000000000..22d3d693ac0c9 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst @@ -0,0 +1 @@ +Add :c:func:`Py_SET_TYPE` function to set the type of an object. diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index e2a3d420d4eb8..9d280a9ccd5f3 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -62,7 +62,7 @@ PyInit__blake2(void) return NULL; /* BLAKE2b */ - Py_TYPE(&PyBlake2_BLAKE2bType) = &PyType_Type; + Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); if (PyType_Ready(&PyBlake2_BLAKE2bType) < 0) { return NULL; } @@ -82,7 +82,7 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ - Py_TYPE(&PyBlake2_BLAKE2sType) = &PyType_Type; + Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); if (PyType_Ready(&PyBlake2_BLAKE2sType) < 0) { return NULL; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index cb6e03f2ca14e..4747195c2e6b2 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5758,42 +5758,42 @@ PyInit__ctypes(void) if (PyType_Ready(&PyCData_Type) < 0) return NULL; - Py_TYPE(&Struct_Type) = &PyCStructType_Type; + Py_SET_TYPE(&Struct_Type, &PyCStructType_Type); Struct_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Struct_Type) < 0) return NULL; Py_INCREF(&Struct_Type); PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); - Py_TYPE(&Union_Type) = &UnionType_Type; + Py_SET_TYPE(&Union_Type, &UnionType_Type); Union_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Union_Type) < 0) return NULL; Py_INCREF(&Union_Type); PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type; + Py_SET_TYPE(&PyCPointer_Type, &PyCPointerType_Type); PyCPointer_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCPointer_Type) < 0) return NULL; Py_INCREF(&PyCPointer_Type); PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type; + Py_SET_TYPE(&PyCArray_Type, &PyCArrayType_Type); PyCArray_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCArray_Type) < 0) return NULL; Py_INCREF(&PyCArray_Type); PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - Py_TYPE(&Simple_Type) = &PyCSimpleType_Type; + Py_SET_TYPE(&Simple_Type, &PyCSimpleType_Type); Simple_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Simple_Type) < 0) return NULL; Py_INCREF(&Simple_Type); PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type; + Py_SET_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type); PyCFuncPtr_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCFuncPtr_Type) < 0) return NULL; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 351f996be05c6..a232a4bc83206 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -68,7 +68,7 @@ typedef struct { ffi_type *atypes[1]; } CThunkObject; extern PyTypeObject PyCThunk_Type; -#define CThunk_CheckExact(v) ((v)->ob_type == &PyCThunk_Type) +#define CThunk_CheckExact(v) (Py_TYPE(v) == &PyCThunk_Type) typedef struct { /* First part identical to tagCDataObject */ diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index d4ca9a111da69..9cdee5869a271 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -713,7 +713,7 @@ PyInit__sha3(void) #define init_sha3type(name, type) \ do { \ - Py_TYPE(type) = &PyType_Type; \ + Py_SET_TYPE(type, &PyType_Type); \ if (PyType_Ready(type) < 0) { \ goto error; \ } \ diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 181c7edf96b45..05a2ca5a652f5 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -78,6 +78,6 @@ PyTypeObject pysqlite_PrepareProtocolType= { extern int pysqlite_prepare_protocol_setup_types(void) { pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; - Py_TYPE(&pysqlite_PrepareProtocolType)= &PyType_Type; + Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); return PyType_Ready(&pysqlite_PrepareProtocolType); } diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 047e3d3974cf1..600a52aa872f8 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -2835,11 +2835,11 @@ PyInit__testbuffer(void) if (m == NULL) return NULL; - Py_TYPE(&NDArray_Type) = &PyType_Type; + Py_SET_TYPE(&NDArray_Type, &PyType_Type); Py_INCREF(&NDArray_Type); PyModule_AddObject(m, "ndarray", (PyObject *)&NDArray_Type); - Py_TYPE(&StaticArray_Type) = &PyType_Type; + Py_SET_TYPE(&StaticArray_Type, &PyType_Type); Py_INCREF(&StaticArray_Type); PyModule_AddObject(m, "staticarray", (PyObject *)&StaticArray_Type); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 3bb1bf1e274ff..e6d30341cdfb1 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6605,9 +6605,9 @@ PyInit__testcapi(void) if (m == NULL) return NULL; - Py_TYPE(&_HashInheritanceTester_Type)=&PyType_Type; + Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type); - Py_TYPE(&test_structmembersType)=&PyType_Type; + Py_SET_TYPE(&test_structmembersType, &PyType_Type); Py_INCREF(&test_structmembersType); /* don't use a name starting with "test", since we don't want test_capi to automatically call this */ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index edb56ab6e1873..5065d28dafbc2 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2996,7 +2996,7 @@ array_modexec(PyObject *m) if (PyType_Ready(&Arraytype) < 0) return -1; - Py_TYPE(&PyArrayIter_Type) = &PyType_Type; + Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type); Py_INCREF((PyObject *)&Arraytype); if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 0cb472966d1f9..0dafb65c288e4 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -4750,14 +4750,16 @@ PyInit_itertools(void) NULL }; - Py_TYPE(&teedataobject_type) = &PyType_Type; + Py_SET_TYPE(&teedataobject_type, &PyType_Type); m = PyModule_Create(&itertoolsmodule); - if (m == NULL) + if (m == NULL) { return NULL; + } for (i=0 ; typelist[i] != NULL ; i++) { - if (PyType_Ready(typelist[i]) < 0) + if (PyType_Ready(typelist[i]) < 0) { return NULL; + } name = _PyType_Name(typelist[i]); Py_INCREF(typelist[i]); PyModule_AddObject(m, name, (PyObject *)typelist[i]); diff --git a/Modules/md5module.c b/Modules/md5module.c index f2c2d32cbe7df..d783ae5a765fa 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -572,13 +572,15 @@ PyInit__md5(void) { PyObject *m; - Py_TYPE(&MD5type) = &PyType_Type; - if (PyType_Ready(&MD5type) < 0) + Py_SET_TYPE(&MD5type, &PyType_Type); + if (PyType_Ready(&MD5type) < 0) { return NULL; + } m = PyModule_Create(&_md5module); - if (m == NULL) + if (m == NULL) { return NULL; + } Py_INCREF((PyObject *)&MD5type); PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 4d191c3c48885..e066b88022941 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -549,13 +549,15 @@ PyInit__sha1(void) { PyObject *m; - Py_TYPE(&SHA1type) = &PyType_Type; - if (PyType_Ready(&SHA1type) < 0) + Py_SET_TYPE(&SHA1type, &PyType_Type); + if (PyType_Ready(&SHA1type) < 0) { return NULL; + } m = PyModule_Create(&_sha1module); - if (m == NULL) + if (m == NULL) { return NULL; + } Py_INCREF((PyObject *)&SHA1type); PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 245f4c04542a7..0e0c4461880f0 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -713,12 +713,14 @@ PyInit__sha256(void) { PyObject *m; - Py_TYPE(&SHA224type) = &PyType_Type; - if (PyType_Ready(&SHA224type) < 0) + Py_SET_TYPE(&SHA224type, &PyType_Type); + if (PyType_Ready(&SHA224type) < 0) { return NULL; - Py_TYPE(&SHA256type) = &PyType_Type; - if (PyType_Ready(&SHA256type) < 0) + } + Py_SET_TYPE(&SHA256type, &PyType_Type); + if (PyType_Ready(&SHA256type) < 0) { return NULL; + } m = PyModule_Create(&_sha256module); if (m == NULL) diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 4045698387faa..07bf28351888b 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -778,16 +778,19 @@ PyInit__sha512(void) { PyObject *m; - Py_TYPE(&SHA384type) = &PyType_Type; - if (PyType_Ready(&SHA384type) < 0) + Py_SET_TYPE(&SHA384type, &PyType_Type); + if (PyType_Ready(&SHA384type) < 0) { return NULL; - Py_TYPE(&SHA512type) = &PyType_Type; - if (PyType_Ready(&SHA512type) < 0) + } + Py_SET_TYPE(&SHA512type, &PyType_Type); + if (PyType_Ready(&SHA512type) < 0) { return NULL; + } m = PyModule_Create(&_sha512module); - if (m == NULL) + if (m == NULL) { return NULL; + } Py_INCREF((PyObject *)&SHA384type); PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index e54f7a9b1c2bb..37b312396f944 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -7100,7 +7100,7 @@ PyInit__socket(void) } #endif - Py_TYPE(&sock_type) = &PyType_Type; + Py_SET_TYPE(&sock_type, &PyType_Type); m = PyModule_Create(&socketmodule); if (m == NULL) return NULL; diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index e99d914b797bf..58b1bc2d0a105 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1455,7 +1455,7 @@ PyInit_unicodedata(void) { PyObject *m, *v; - Py_TYPE(&UCD_Type) = &PyType_Type; + Py_SET_TYPE(&UCD_Type, &PyType_Type); m = PyModule_Create(&unicodedatamodule); if (!m) diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 26e238cf05ad3..dfc5b196f18e4 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -221,7 +221,7 @@ float_dealloc(PyFloatObject *op) return; } numfree++; - Py_TYPE(op) = (struct _typeobject *)free_list; + Py_SET_TYPE(op, (PyTypeObject *)free_list); free_list = op; } else diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index da329b4fbac8b..0a593261c4134 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -52,7 +52,7 @@ PyModuleDef_Init(struct PyModuleDef* def) if (def->m_base.m_index == 0) { max_module_number++; Py_SET_REFCNT(def, 1); - Py_TYPE(def) = &PyModuleDef_Type; + Py_SET_TYPE(def, &PyModuleDef_Type); def->m_base.m_index = max_module_number; } return (PyObject*)def; diff --git a/Objects/object.c b/Objects/object.c index 5806542488115..503fb867802c1 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -144,7 +144,7 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) return PyErr_NoMemory(); } - Py_TYPE(op) = tp; + Py_SET_TYPE(op, tp); if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(tp); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5b8d5a228e5af..e6a84b017aa67 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4097,9 +4097,10 @@ object_set_class(PyObject *self, PyObject *value, void *closure) } if (compatible_for_assignment(oldto, newto, "__class__")) { - if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) + if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(newto); - Py_TYPE(self) = newto; + } + Py_SET_TYPE(self, newto); if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_DECREF(oldto); return 0; @@ -5334,8 +5335,9 @@ PyType_Ready(PyTypeObject *type) NULL when type is &PyBaseObject_Type, and we know its ob_type is not NULL (it's initialized to &PyType_Type). But coverity doesn't know that. */ - if (Py_TYPE(type) == NULL && base != NULL) - Py_TYPE(type) = Py_TYPE(base); + if (Py_TYPE(type) == NULL && base != NULL) { + Py_SET_TYPE(type, Py_TYPE(base)); + } /* Initialize tp_bases */ bases = type->tp_bases; diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index d104b646f0181..18c737e7e4097 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -882,10 +882,12 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) if (result != NULL) { PyWeakReference *prev; - if (PyCallable_Check(ob)) - Py_TYPE(result) = &_PyWeakref_CallableProxyType; - else - Py_TYPE(result) = &_PyWeakref_ProxyType; + if (PyCallable_Check(ob)) { + Py_SET_TYPE(result, &_PyWeakref_CallableProxyType); + } + else { + Py_SET_TYPE(result, &_PyWeakref_ProxyType); + } get_basic_refs(*list, &ref, &proxy); if (callback == NULL) { if (proxy != NULL) { From webhook-mailer at python.org Fri Feb 7 03:20:26 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 08:20:26 -0000 Subject: [Python-checkins] bpo-35134: Create Include/cpython/listobject.h (GH-18395) Message-ID: https://github.com/python/cpython/commit/bec4186c67345f1e6cd3f8a531bc228f14d7ed7b commit: bec4186c67345f1e6cd3f8a531bc228f14d7ed7b branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T09:20:21+01:00 summary: bpo-35134: Create Include/cpython/listobject.h (GH-18395) Move listobject.h code surrounded by "#ifndef Py_LIMITED_API" to a new Include/cpython/listobject.h header file. Add cpython/ header files to Makefile.pre.in and pythoncore project of PCbuild. Add _PyList_CAST() macro. files: A Include/cpython/listobject.h M Include/listobject.h M Makefile.pre.in M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h new file mode 100644 index 0000000000000..4b6f2f7741c1a --- /dev/null +++ b/Include/cpython/listobject.h @@ -0,0 +1,44 @@ +#ifndef Py_CPYTHON_LISTOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; + +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); +PyAPI_FUNC(int) PyList_ClearFreeList(void); +PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); + +/* Macro, trading safety for speed */ + +/* Cast argument to PyTupleObject* type. */ +#define _PyList_CAST(op) (assert(PyList_Check(op)), (PyListObject *)(op)) + +#define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i]) +#define PyList_SET_ITEM(op, i, v) (_PyList_CAST(op)->ob_item[i] = (v)) +#define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op)) +#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) + +#ifdef __cplusplus +} +#endif diff --git a/Include/listobject.h b/Include/listobject.h index baf94152792ed..34dfcf92ec93a 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -1,16 +1,14 @@ +/* List object interface -/* List object interface */ + Another generally useful object type is a list of object pointers. + This is a mutable type: the list items can be changed, and items can be + added or removed. Out-of-range indices or non-list objects are ignored. -/* -Another generally useful object type is a list of object pointers. -This is a mutable type: the list items can be changed, and items can be -added or removed. Out-of-range indices or non-list objects are ignored. - -*** WARNING *** PyList_SetItem does not increment the new item's reference -count, but does decrement the reference count of the item it replaces, -if not nil. It does *decrement* the reference count if it is *not* -inserted in the list. Similarly, PyList_GetItem does not increment the -returned item's reference count. + WARNING: PyList_SetItem does not increment the new item's reference count, + but does decrement the reference count of the item it replaces, if not nil. + It does *decrement* the reference count if it is *not* inserted in the list. + Similarly, PyList_GetItem does not increment the returned item's reference + count. */ #ifndef Py_LISTOBJECT_H @@ -19,27 +17,6 @@ returned item's reference count. extern "C" { #endif -#ifndef Py_LIMITED_API -typedef struct { - PyObject_VAR_HEAD - /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ - PyObject **ob_item; - - /* ob_item contains space for 'allocated' elements. The number - * currently in use is ob_size. - * Invariants: - * 0 <= ob_size <= allocated - * len(list) == ob_size - * ob_item == NULL implies ob_size == allocated == 0 - * list.sort() temporarily sets allocated to -1 to detect mutations. - * - * Items must normally not be NULL, except during construction when - * the list is not yet visible outside the function that builds it. - */ - Py_ssize_t allocated; -} PyListObject; -#endif - PyAPI_DATA(PyTypeObject) PyList_Type; PyAPI_DATA(PyTypeObject) PyListIter_Type; PyAPI_DATA(PyTypeObject) PyListRevIter_Type; @@ -50,28 +27,23 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); + PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); + PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); + PyAPI_FUNC(int) PyList_Sort(PyObject *); PyAPI_FUNC(int) PyList_Reverse(PyObject *); PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); - -PyAPI_FUNC(int) PyList_ClearFreeList(void); -PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); -#endif -/* Macro, trading safety for speed */ #ifndef Py_LIMITED_API -#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) -#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) -#define PyList_GET_SIZE(op) (assert(PyList_Check(op)),Py_SIZE(op)) -#define _PyList_ITEMS(op) (((PyListObject *)(op))->ob_item) +# define Py_CPYTHON_LISTOBJECT_H +# include "cpython/listobject.h" +# undef Py_CPYTHON_LISTOBJECT_H #endif #ifdef __cplusplus diff --git a/Makefile.pre.in b/Makefile.pre.in index d430dc30bb6de..510f227ed4df3 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1063,6 +1063,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/import.h \ $(srcdir)/Include/cpython/initconfig.h \ $(srcdir)/Include/cpython/interpreteridobject.h \ + $(srcdir)/Include/cpython/listobject.h \ $(srcdir)/Include/cpython/object.h \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/pyerrors.h \ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index cfab2fa4e189c..36a27f467405d 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -132,6 +132,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index ba1839f8a3814..0301557b3e50d 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -99,6 +99,9 @@ Include + + Include + Include From webhook-mailer at python.org Fri Feb 7 05:18:43 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 10:18:43 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() macro in object.c (GH-18398) Message-ID: https://github.com/python/cpython/commit/c65b320a95784d2b2133926921d67ac439259e9f commit: c65b320a95784d2b2133926921d67ac439259e9f branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T11:18:33+01:00 summary: bpo-39573: Use Py_TYPE() macro in object.c (GH-18398) Replace direct acccess to PyVarObject.ob_size with usage of the Py_SIZE() macro. files: M Objects/object.c diff --git a/Objects/object.c b/Objects/object.c index 503fb867802c1..ff6c497900cf2 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1041,13 +1041,11 @@ _PyObject_GetDictPtr(PyObject *obj) if (dictoffset == 0) return NULL; if (dictoffset < 0) { - Py_ssize_t tsize; - size_t size; - - tsize = ((PyVarObject *)obj)->ob_size; - if (tsize < 0) + Py_ssize_t tsize = Py_SIZE(obj); + if (tsize < 0) { tsize = -tsize; - size = _PyObject_VAR_SIZE(tp, tsize); + } + size_t size = _PyObject_VAR_SIZE(tp, tsize); dictoffset += (long)size; _PyObject_ASSERT(obj, dictoffset > 0); @@ -1219,13 +1217,11 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, dictoffset = tp->tp_dictoffset; if (dictoffset != 0) { if (dictoffset < 0) { - Py_ssize_t tsize; - size_t size; - - tsize = ((PyVarObject *)obj)->ob_size; - if (tsize < 0) + Py_ssize_t tsize = Py_SIZE(obj); + if (tsize < 0) { tsize = -tsize; - size = _PyObject_VAR_SIZE(tp, tsize); + } + size_t size = _PyObject_VAR_SIZE(tp, tsize); _PyObject_ASSERT(obj, size <= PY_SSIZE_T_MAX); dictoffset += (Py_ssize_t)size; From webhook-mailer at python.org Fri Feb 7 05:23:01 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 10:23:01 -0000 Subject: [Python-checkins] bpo-38644: Add Py_EnterRecursiveCall() to python3.def (GH-18399) Message-ID: https://github.com/python/cpython/commit/877ea88934a5164be4d9f15207694fad4173d87d commit: 877ea88934a5164be4d9f15207694fad4173d87d branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T11:22:54+01:00 summary: bpo-38644: Add Py_EnterRecursiveCall() to python3.def (GH-18399) Add Py_EnterRecursiveCall and Py_LeaveRecursiveCall functions to python3.def. files: M PC/python3.def diff --git a/PC/python3.def b/PC/python3.def index 4689b777a6933..c7aed8789cfaa 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -727,6 +727,7 @@ EXPORTS Py_DecodeLocale=python39.Py_DecodeLocale Py_EncodeLocale=python39.Py_EncodeLocale Py_EndInterpreter=python39.Py_EndInterpreter + Py_EnterRecursiveCall=python39.Py_EnterRecursiveCall Py_Exit=python39.Py_Exit Py_FatalError=python39.Py_FatalError Py_FileSystemDefaultEncodeErrors=python39.Py_FileSystemDefaultEncodeErrors DATA @@ -750,6 +751,7 @@ EXPORTS Py_Initialize=python39.Py_Initialize Py_InitializeEx=python39.Py_InitializeEx Py_IsInitialized=python39.Py_IsInitialized + Py_LeaveRecursiveCall=python39.Py_LeaveRecursiveCall Py_Main=python39.Py_Main Py_MakePendingCalls=python39.Py_MakePendingCalls Py_NewInterpreter=python39.Py_NewInterpreter From webhook-mailer at python.org Fri Feb 7 06:05:17 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 11:05:17 -0000 Subject: [Python-checkins] bpo-39573: Add Py_SET_SIZE() function (GH-18400) Message-ID: https://github.com/python/cpython/commit/b10dc3e7a11fcdb97e285882eba6da92594f90f9 commit: b10dc3e7a11fcdb97e285882eba6da92594f90f9 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T12:05:12+01:00 summary: bpo-39573: Add Py_SET_SIZE() function (GH-18400) Add Py_SET_SIZE() function to set the size of an object. files: A Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst M Doc/c-api/structures.rst M Include/cpython/objimpl.h M Include/object.h M Objects/object.c diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 8a1431c2de7fa..75e2383beb216 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -101,6 +101,13 @@ the definition of all other Python objects. (((PyVarObject*)(o))->ob_size) +.. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size) + + Set the object *o* size of *size*. + + .. versionadded:: 3.9 + + .. c:macro:: PyObject_HEAD_INIT(type) This is a macro which expands to initialization values for a new diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index ebb3e234e36fe..8e3c964cf44e7 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -30,7 +30,7 @@ static inline PyVarObject* _PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) { assert(op != NULL); - Py_SIZE(op) = size; + Py_SET_SIZE(op, size); PyObject_INIT((PyObject *)op, typeobj); return op; } diff --git a/Include/object.h b/Include/object.h index eb887f4c6eb50..68200f7666f17 100644 --- a/Include/object.h +++ b/Include/object.h @@ -133,6 +133,11 @@ static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) +static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t refcnt) { + ob->ob_size = refcnt; +} +#define Py_SET_SIZE(ob, refcnt) _Py_SET_SIZE(_PyVarObject_CAST(ob), refcnt) + /* Type objects contain a string containing the type name (to help somewhat diff --git a/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst b/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst new file mode 100644 index 0000000000000..d84cddc57636b --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst @@ -0,0 +1 @@ +Add :c:func:`Py_SET_SIZE` function to set the size of an object. diff --git a/Objects/object.c b/Objects/object.c index ff6c497900cf2..81de3b8253040 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -160,7 +160,7 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) return (PyVarObject *) PyErr_NoMemory(); } - Py_SIZE(op) = size; + Py_SET_SIZE(op, size); PyObject_Init((PyObject *)op, tp); return op; } From webhook-mailer at python.org Fri Feb 7 12:56:21 2020 From: webhook-mailer at python.org (Michael Felt) Date: Fri, 07 Feb 2020 17:56:21 -0000 Subject: [Python-checkins] bpo-39502: Fix 64-bit Python PyTime_localtime() on AIX (GH-18285) Message-ID: https://github.com/python/cpython/commit/de6f38db4859f7b8fe4da4556f06c52675fff24a commit: de6f38db4859f7b8fe4da4556f06c52675fff24a branch: master author: Michael Felt committer: GitHub date: 2020-02-07T18:56:16+01:00 summary: bpo-39502: Fix 64-bit Python PyTime_localtime() on AIX (GH-18285) Fix time.localtime() on 64-bit AIX to support years before 1902 and after 2038. files: A Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl.rst M Python/pytime.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl.rst new file mode 100644 index 0000000000000..93b3639c80c5b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl.rst @@ -0,0 +1,2 @@ +Fix :func:`time.localtime` on 64-bit AIX to support years before 1902 and after 2038. +Patch by M Felt. diff --git a/Python/pytime.c b/Python/pytime.c index 54ddfc952b817..9b2b74af5c043 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -1059,7 +1059,7 @@ _PyTime_localtime(time_t t, struct tm *tm) return 0; #else /* !MS_WINDOWS */ -#ifdef _AIX +#if defined(_AIX) && (SIZEOF_TIME_T < 8) /* bpo-34373: AIX does not return NULL if t is too small or too large */ if (t < -2145916800 /* 1902-01-01 */ || t > 2145916800 /* 2038-01-01 */) { From webhook-mailer at python.org Fri Feb 7 17:18:31 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 22:18:31 -0000 Subject: [Python-checkins] bpo-39573: Use Py_SET_SIZE() function (GH-18402) Message-ID: https://github.com/python/cpython/commit/60ac6ed5579f6666130fc264d3b748ee9575e3aa commit: 60ac6ed5579f6666130fc264d3b748ee9575e3aa branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T23:18:08+01:00 summary: bpo-39573: Use Py_SET_SIZE() function (GH-18402) Replace direct acccess to PyVarObject.ob_size with usage of the Py_SET_SIZE() function. files: M Modules/_asynciomodule.c M Modules/_collectionsmodule.c M Modules/_decimal/_decimal.c M Modules/_pickle.c M Modules/arraymodule.c M Modules/gcmodule.c M Objects/bytearrayobject.c M Objects/bytesobject.c M Objects/listobject.c M Objects/longobject.c M Objects/odictobject.c M Objects/stringlib/split.h M Objects/structseq.c M Python/ceval.c M Python/hamt.c M Python/marshal.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 70da40a8a3b86..2e293757fb731 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1007,7 +1007,7 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) } if (j < len) { - Py_SIZE(newlist) = j; + Py_SET_SIZE(newlist, j); } j = PyList_GET_SIZE(newlist); len = PyList_GET_SIZE(self->fut_callbacks); diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 97d7de47d2dfa..10030606711e0 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -172,7 +172,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) MARK_END(b->rightlink); assert(BLOCKLEN >= 2); - Py_SIZE(deque) = 0; + Py_SET_SIZE(deque, 0); deque->leftblock = b; deque->rightblock = b; deque->leftindex = CENTER + 1; @@ -196,7 +196,7 @@ deque_pop(dequeobject *deque, PyObject *unused) } item = deque->rightblock->data[deque->rightindex]; deque->rightindex--; - Py_SIZE(deque)--; + Py_SET_SIZE(deque, Py_SIZE(deque) - 1); deque->state++; if (deque->rightindex < 0) { @@ -234,7 +234,7 @@ deque_popleft(dequeobject *deque, PyObject *unused) assert(deque->leftblock != NULL); item = deque->leftblock->data[deque->leftindex]; deque->leftindex++; - Py_SIZE(deque)--; + Py_SET_SIZE(deque, Py_SIZE(deque) - 1); deque->state++; if (deque->leftindex == BLOCKLEN) { @@ -287,7 +287,7 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) MARK_END(b->rightlink); deque->rightindex = -1; } - Py_SIZE(deque)++; + Py_SET_SIZE(deque, Py_SIZE(deque) + 1); deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; if (NEEDS_TRIM(deque, maxlen)) { @@ -324,7 +324,7 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) MARK_END(b->leftlink); deque->leftindex = BLOCKLEN; } - Py_SIZE(deque)++; + Py_SET_SIZE(deque, Py_SIZE(deque) + 1); deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; if (NEEDS_TRIM(deque, deque->maxlen)) { @@ -597,7 +597,7 @@ deque_clear(dequeobject *deque) /* Set the deque to be empty using the newly allocated block */ MARK_END(b->leftlink); MARK_END(b->rightlink); - Py_SIZE(deque) = 0; + Py_SET_SIZE(deque, 0); deque->leftblock = b; deque->rightblock = b; deque->leftindex = CENTER + 1; @@ -680,7 +680,7 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) if (deque->rightindex == BLOCKLEN - 1) { block *b = newblock(); if (b == NULL) { - Py_SIZE(deque) += i; + Py_SET_SIZE(deque, Py_SIZE(deque) + i); return NULL; } b->leftlink = deque->rightblock; @@ -700,7 +700,7 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) deque->rightblock->data[deque->rightindex] = item; } } - Py_SIZE(deque) += i; + Py_SET_SIZE(deque, Py_SIZE(deque) + i); Py_INCREF(deque); return (PyObject *)deque; } diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 75a8ddba1fe0a..0fbbb73a6bdec 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3253,9 +3253,9 @@ dec_as_long(PyObject *dec, PyObject *context, int round) i--; } - Py_SIZE(pylong) = i; + Py_SET_SIZE(pylong, i); if (mpd_isnegative(x) && !mpd_iszero(x)) { - Py_SIZE(pylong) = -i; + Py_SET_SIZE(pylong, -i); } mpd_del(x); diff --git a/Modules/_pickle.c b/Modules/_pickle.c index f67fb6a65c38c..5f11fe5c88c2b 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -461,7 +461,7 @@ Pdata_New(void) if (!(self = PyObject_New(Pdata, &Pdata_Type))) return NULL; - Py_SIZE(self) = 0; + Py_SET_SIZE(self, 0); self->mark_set = 0; self->fence = 0; self->allocated = 8; @@ -488,7 +488,7 @@ Pdata_clear(Pdata *self, Py_ssize_t clearto) while (--i >= clearto) { Py_CLEAR(self->data[i]); } - Py_SIZE(self) = clearto; + Py_SET_SIZE(self, clearto); return 0; } @@ -539,7 +539,8 @@ Pdata_pop(Pdata *self) Pdata_stack_underflow(self); return NULL; } - return self->data[--Py_SIZE(self)]; + Py_SET_SIZE(self, Py_SIZE(self) - 1); + return self->data[Py_SIZE(self)]; } #define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0) @@ -549,7 +550,8 @@ Pdata_push(Pdata *self, PyObject *obj) if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) { return -1; } - self->data[Py_SIZE(self)++] = obj; + self->data[Py_SIZE(self)] = obj; + Py_SET_SIZE(self, Py_SIZE(self) + 1); return 0; } @@ -579,7 +581,7 @@ Pdata_poptuple(Pdata *self, Py_ssize_t start) for (i = start, j = 0; j < len; i++, j++) PyTuple_SET_ITEM(tuple, j, self->data[i]); - Py_SIZE(self) = start; + Py_SET_SIZE(self, start); return tuple; } @@ -596,7 +598,7 @@ Pdata_poplist(Pdata *self, Py_ssize_t start) for (i = start, j = 0; j < len; i++, j++) PyList_SET_ITEM(list, j, self->data[i]); - Py_SIZE(self) = start; + Py_SET_SIZE(self, start); return list; } @@ -6134,7 +6136,7 @@ load_pop(UnpicklerObject *self) else { len--; Py_DECREF(self->stack->data[len]); - Py_SIZE(self->stack) = len; + Py_SET_SIZE(self->stack, len); } return 0; } @@ -6495,13 +6497,13 @@ do_append(UnpicklerObject *self, Py_ssize_t x) result = _Pickle_FastCall(append_func, value); if (result == NULL) { Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = x; + Py_SET_SIZE(self->stack, x); Py_DECREF(append_func); return -1; } Py_DECREF(result); } - Py_SIZE(self->stack) = x; + Py_SET_SIZE(self->stack, x); Py_DECREF(append_func); } } @@ -6623,12 +6625,12 @@ load_additems(UnpicklerObject *self) result = _Pickle_FastCall(add_func, item); if (result == NULL) { Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = mark; + Py_SET_SIZE(self->stack, mark); return -1; } Py_DECREF(result); } - Py_SIZE(self->stack) = mark; + Py_SET_SIZE(self->stack, mark); } return 0; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 5065d28dafbc2..eeda714d6a935 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -128,14 +128,14 @@ array_resize(arrayobject *self, Py_ssize_t newsize) if (self->allocated >= newsize && Py_SIZE(self) < newsize + 16 && self->ob_item != NULL) { - Py_SIZE(self) = newsize; + Py_SET_SIZE(self, newsize); return 0; } if (newsize == 0) { PyMem_FREE(self->ob_item); self->ob_item = NULL; - Py_SIZE(self) = 0; + Py_SET_SIZE(self, 0); self->allocated = 0; return 0; } @@ -165,7 +165,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize) return -1; } self->ob_item = items; - Py_SIZE(self) = newsize; + Py_SET_SIZE(self, newsize); self->allocated = _new_size; return 0; } @@ -593,7 +593,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des op->ob_descr = descr; op->allocated = size; op->weakreflist = NULL; - Py_SIZE(op) = size; + Py_SET_SIZE(op, size); if (size <= 0) { op->ob_item = NULL; } @@ -2696,7 +2696,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } self->ob_item = item; - Py_SIZE(self) = n / sizeof(Py_UNICODE); + Py_SET_SIZE(self, n / sizeof(Py_UNICODE)); memcpy(item, ustr, n); self->allocated = Py_SIZE(self); } diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 7e9eae50a8ed6..5673f6028372f 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -2294,7 +2294,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) if (g == NULL) return (PyVarObject *)PyErr_NoMemory(); op = (PyVarObject *) FROM_GC(g); - Py_SIZE(op) = nitems; + Py_SET_SIZE(op, nitems); return op; } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index a019b4905a898..b2808c05b40ca 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -148,7 +148,7 @@ PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) memcpy(new->ob_bytes, bytes, size); new->ob_bytes[size] = '\0'; /* Trailing null byte */ } - Py_SIZE(new) = size; + Py_SET_SIZE(new, size); new->ob_alloc = alloc; new->ob_start = new->ob_bytes; new->ob_exports = 0; @@ -206,7 +206,7 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) } else { /* Minor downsize; quick exit */ - Py_SIZE(self) = size; + Py_SET_SIZE(self, size); PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */ return 0; } @@ -246,7 +246,7 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) } obj->ob_bytes = obj->ob_start = sval; - Py_SIZE(self) = size; + Py_SET_SIZE(self, size); obj->ob_alloc = alloc; obj->ob_bytes[size] = '\0'; /* Trailing null byte */ @@ -498,7 +498,7 @@ bytearray_setslice_linear(PyByteArrayObject *self, } /* memmove() removed bytes, the bytearray object cannot be restored in its previous state. */ - Py_SIZE(self) += growth; + Py_SET_SIZE(self, Py_SIZE(self) + growth); res = -1; } buf = PyByteArray_AS_STRING(self); @@ -886,7 +886,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) /* Append the byte */ if (Py_SIZE(self) + 1 < self->ob_alloc) { - Py_SIZE(self)++; + Py_SET_SIZE(self, Py_SIZE(self) + 1); PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; } else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 4edd93d4b8ddb..e139bed71bf6d 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2963,7 +2963,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) } _Py_NewReference(*pv); sv = (PyBytesObject *) *pv; - Py_SIZE(sv) = newsize; + Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; sv->ob_shash = -1; /* invalidate cached hash value */ return 0; diff --git a/Objects/listobject.c b/Objects/listobject.c index d83e3cfcf1af5..a406e70694a69 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -45,7 +45,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) */ if (allocated >= newsize && newsize >= (allocated >> 1)) { assert(self->ob_item != NULL || newsize == 0); - Py_SIZE(self) = newsize; + Py_SET_SIZE(self, newsize); return 0; } @@ -73,7 +73,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) return -1; } self->ob_item = items; - Py_SIZE(self) = newsize; + Py_SET_SIZE(self, newsize); self->allocated = new_allocated; return 0; } @@ -156,7 +156,7 @@ PyList_New(Py_ssize_t size) return PyErr_NoMemory(); } } - Py_SIZE(op) = size; + Py_SET_SIZE(op, size); op->allocated = size; _PyObject_GC_TRACK(op); return (PyObject *) op; @@ -457,7 +457,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) Py_INCREF(v); dest[i] = v; } - Py_SIZE(np) = len; + Py_SET_SIZE(np, len); return (PyObject *)np; } @@ -518,7 +518,7 @@ list_concat(PyListObject *a, PyObject *bb) Py_INCREF(v); dest[i] = v; } - Py_SIZE(np) = size; + Py_SET_SIZE(np, size); return (PyObject *)np; #undef b } @@ -561,7 +561,7 @@ list_repeat(PyListObject *a, Py_ssize_t n) } } } - Py_SIZE(np) = size; + Py_SET_SIZE(np, size); return (PyObject *) np; } @@ -574,7 +574,7 @@ _list_clear(PyListObject *a) /* Because XDECREF can recursively invoke operations on this list, we make it empty first. */ i = Py_SIZE(a); - Py_SIZE(a) = 0; + Py_SET_SIZE(a, 0); a->ob_item = NULL; a->allocated = 0; while (--i >= 0) { @@ -913,7 +913,7 @@ list_extend(PyListObject *self, PyObject *iterable) if (list_resize(self, mn) < 0) goto error; /* Make the list sane again. */ - Py_SIZE(self) = m; + Py_SET_SIZE(self, m); } /* Run iterator to exhaustion. */ @@ -931,7 +931,7 @@ list_extend(PyListObject *self, PyObject *iterable) if (Py_SIZE(self) < self->allocated) { /* steals ref */ PyList_SET_ITEM(self, Py_SIZE(self), item); - ++Py_SIZE(self); + Py_SET_SIZE(self, Py_SIZE(self) + 1); } else { int status = app1(self, item); @@ -2204,7 +2204,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) saved_ob_size = Py_SIZE(self); saved_ob_item = self->ob_item; saved_allocated = self->allocated; - Py_SIZE(self) = 0; + Py_SET_SIZE(self, 0); self->ob_item = NULL; self->allocated = -1; /* any operation will reset it to >= 0 */ @@ -2421,7 +2421,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) keyfunc_fail: final_ob_item = self->ob_item; i = Py_SIZE(self); - Py_SIZE(self) = saved_ob_size; + Py_SET_SIZE(self, saved_ob_size); self->ob_item = saved_ob_item; self->allocated = saved_allocated; if (final_ob_item != NULL) { @@ -2811,7 +2811,7 @@ list_subscript(PyListObject* self, PyObject* item) Py_INCREF(it); dest[i] = it; } - Py_SIZE(result) = slicelength; + Py_SET_SIZE(result, slicelength); return result; } } @@ -2904,7 +2904,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) sizeof(PyObject *)); } - Py_SIZE(self) -= slicelength; + Py_SET_SIZE(self, Py_SIZE(self) - slicelength); res = list_resize(self, Py_SIZE(self)); for (i = 0; i < slicelength; i++) { diff --git a/Objects/longobject.c b/Objects/longobject.c index 67cbc7b27e3d3..b4d0b0575bcf6 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -73,7 +73,7 @@ _PyLong_Negate(PyLongObject **x_p) x = (PyLongObject *)*x_p; if (Py_REFCNT(x) == 1) { - Py_SIZE(x) = -Py_SIZE(x); + Py_SET_SIZE(x, -Py_SIZE(x)); return; } @@ -112,8 +112,9 @@ long_normalize(PyLongObject *v) while (i > 0 && v->ob_digit[i-1] == 0) --i; - if (i != j) - Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; + if (i != j) { + Py_SET_SIZE(v, (Py_SIZE(v) < 0) ? -(i) : i); + } return v; } @@ -281,9 +282,10 @@ _PyLong_Copy(PyLongObject *src) } result = _PyLong_New(i); if (result != NULL) { - Py_SIZE(result) = Py_SIZE(src); - while (--i >= 0) + Py_SET_SIZE(result, Py_SIZE(src)); + while (--i >= 0) { result->ob_digit[i] = src->ob_digit[i]; + } } return (PyObject *)result; } @@ -318,7 +320,7 @@ PyLong_FromLong(long ival) if (!(abs_ival >> PyLong_SHIFT)) { v = _PyLong_New(1); if (v) { - Py_SIZE(v) = sign; + Py_SET_SIZE(v, sign); v->ob_digit[0] = Py_SAFE_DOWNCAST( abs_ival, unsigned long, digit); } @@ -330,7 +332,7 @@ PyLong_FromLong(long ival) if (!(abs_ival >> 2*PyLong_SHIFT)) { v = _PyLong_New(2); if (v) { - Py_SIZE(v) = 2*sign; + Py_SET_SIZE(v, 2 * sign); v->ob_digit[0] = Py_SAFE_DOWNCAST( abs_ival & PyLong_MASK, unsigned long, digit); v->ob_digit[1] = Py_SAFE_DOWNCAST( @@ -349,7 +351,7 @@ PyLong_FromLong(long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = ndigits*sign; + Py_SET_SIZE(v, ndigits * sign); t = abs_ival; while (t) { *p++ = Py_SAFE_DOWNCAST( @@ -445,8 +447,9 @@ PyLong_FromDouble(double dval) frac = frac - (double)bits; frac = ldexp(frac, PyLong_SHIFT); } - if (neg) - Py_SIZE(v) = -(Py_SIZE(v)); + if (neg) { + Py_SET_SIZE(v, -(Py_SIZE(v))); + } return (PyObject *)v; } @@ -930,7 +933,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, } } - Py_SIZE(v) = is_signed ? -idigit : idigit; + Py_SET_SIZE(v, is_signed ? -idigit : idigit); return (PyObject *)long_normalize(v); } @@ -1158,7 +1161,7 @@ PyLong_FromLongLong(long long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; + Py_SET_SIZE(v, negative ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1201,7 +1204,7 @@ PyLong_FromSsize_t(Py_ssize_t ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; + Py_SET_SIZE(v, negative ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -2443,7 +2446,7 @@ digit beyond the first. if (z == NULL) { return NULL; } - Py_SIZE(z) = 0; + Py_SET_SIZE(z, 0); /* `convwidth` consecutive input digits are treated as a single * digit in base `convmultmax`. @@ -2493,7 +2496,7 @@ digit beyond the first. assert(c < PyLong_BASE); if (Py_SIZE(z) < size_z) { *pz = (digit)c; - ++Py_SIZE(z); + Py_SET_SIZE(z, Py_SIZE(z) + 1); } else { PyLongObject *tmp; @@ -2532,7 +2535,7 @@ digit beyond the first. goto onError; } if (sign < 0) { - Py_SIZE(z) = -(Py_SIZE(z)); + Py_SET_SIZE(z, -(Py_SIZE(z))); } while (*str && Py_ISSPACE(*str)) { str++; @@ -3165,7 +3168,7 @@ x_sub(PyLongObject *a, PyLongObject *b) } assert(borrow == 0); if (sign < 0) { - Py_SIZE(z) = -Py_SIZE(z); + Py_SET_SIZE(z, -Py_SIZE(z)); } return maybe_small_long(long_normalize(z)); } @@ -3189,7 +3192,7 @@ long_add(PyLongObject *a, PyLongObject *b) That also means z is not an element of small_ints, so negating it in-place is safe. */ assert(Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); + Py_SET_SIZE(z, -(Py_SIZE(z))); } } else @@ -3222,7 +3225,7 @@ long_sub(PyLongObject *a, PyLongObject *b) z = x_add(a, b); if (z != NULL) { assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); + Py_SET_SIZE(z, -(Py_SIZE(z))); } } } @@ -3615,7 +3618,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) /* Multiply the next slice of b by a. */ memcpy(bslice->ob_digit, b->ob_digit + nbdone, nbtouse * sizeof(digit)); - Py_SIZE(bslice) = nbtouse; + Py_SET_SIZE(bslice, nbtouse); product = k_mul(a, bslice); if (product == NULL) goto fail; @@ -4431,7 +4434,7 @@ long_neg(PyLongObject *v) return PyLong_FromLong(-MEDIUM_VALUE(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) - Py_SIZE(z) = -(Py_SIZE(v)); + Py_SET_SIZE(z, -(Py_SIZE(v))); return (PyObject *)z; } @@ -4576,7 +4579,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) return NULL; if (Py_SIZE(a) < 0) { assert(Py_REFCNT(z) == 1); - Py_SIZE(z) = -Py_SIZE(z); + Py_SET_SIZE(z, -Py_SIZE(z)); } for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; @@ -4760,7 +4763,7 @@ long_bitwise(PyLongObject *a, /* Complement result if negative. */ if (negz) { - Py_SIZE(z) = -(Py_SIZE(z)); + Py_SET_SIZE(z, -(Py_SIZE(z))); z->ob_digit[size_z] = PyLong_MASK; v_complement(z->ob_digit, z->ob_digit, size_z+1); } @@ -4907,8 +4910,9 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) T = -A; A = -B; B = T; T = -C; C = -D; D = T; } - if (c != NULL) - Py_SIZE(c) = size_a; + if (c != NULL) { + Py_SET_SIZE(c, size_a); + } else if (Py_REFCNT(a) == 1) { Py_INCREF(a); c = a; @@ -4920,12 +4924,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) goto error; } - if (d != NULL) - Py_SIZE(d) = size_a; + if (d != NULL) { + Py_SET_SIZE(d, size_a); + } else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { Py_INCREF(b); d = b; - Py_SIZE(d) = size_a; + Py_SET_SIZE(d, size_a); } else { alloc_b = size_a; @@ -5105,9 +5110,10 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) return NULL; } assert(PyLong_Check(newobj)); - Py_SIZE(newobj) = Py_SIZE(tmp); - for (i = 0; i < n; i++) + Py_SET_SIZE(newobj, Py_SIZE(tmp)); + for (i = 0; i < n; i++) { newobj->ob_digit[i] = tmp->ob_digit[i]; + } Py_DECREF(tmp); return (PyObject *)newobj; } @@ -5744,7 +5750,7 @@ _PyLong_Init(PyThreadState *tstate) return -1; } - Py_SIZE(v) = size; + Py_SET_SIZE(v, size); v->ob_digit[0] = (digit)abs(ival); tstate->interp->small_ints[i] = v; diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 45e089be2871e..f412220e8cc02 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1417,8 +1417,9 @@ odict_repr(PyODictObject *self) } count++; } - if (count < PyList_GET_SIZE(pieces)) - Py_SIZE(pieces) = count; + if (count < PyList_GET_SIZE(pieces)) { + Py_SET_SIZE(pieces, count); + } } else { PyObject *items = _PyObject_CallMethodIdNoArgs((PyObject *)self, diff --git a/Objects/stringlib/split.h b/Objects/stringlib/split.h index 31f77a77243ea..068047f9874a0 100644 --- a/Objects/stringlib/split.h +++ b/Objects/stringlib/split.h @@ -48,7 +48,7 @@ /* Always force the list to the expected size. */ -#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count +#define FIX_PREALLOC_SIZE(list) Py_SET_SIZE(list, count) Py_LOCAL_INLINE(PyObject *) STRINGLIB(split_whitespace)(PyObject* str_obj, diff --git a/Objects/structseq.c b/Objects/structseq.c index c86fbe50b972c..1865e2461a2f4 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -47,7 +47,7 @@ PyStructSequence_New(PyTypeObject *type) return NULL; /* Hack the size of the variable object, so invisible fields don't appear to Python code. */ - Py_SIZE(obj) = VISIBLE_SIZE_TP(type); + Py_SET_SIZE(obj, VISIBLE_SIZE_TP(type)); for (i = 0; i < size; i++) obj->ob_item[i] = NULL; diff --git a/Python/ceval.c b/Python/ceval.c index c36a38e21139d..deba99ed7ace2 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4436,7 +4436,7 @@ unpack_iterable(PyThreadState *tstate, PyObject *v, *--sp = PyList_GET_ITEM(l, ll - j); } /* Resize the list. */ - Py_SIZE(l) = ll - argcntafter; + Py_SET_SIZE(l, ll - argcntafter); Py_DECREF(it); return 1; diff --git a/Python/hamt.c b/Python/hamt.c index f5586eec5b076..a0fee4c7a63de 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -551,7 +551,7 @@ hamt_node_bitmap_new(Py_ssize_t size) return NULL; } - Py_SIZE(node) = size; + Py_SET_SIZE(node, size); for (i = 0; i < size; i++) { node->b_array[i] = NULL; @@ -1288,7 +1288,7 @@ hamt_node_collision_new(int32_t hash, Py_ssize_t size) node->c_array[i] = NULL; } - Py_SIZE(node) = size; + Py_SET_SIZE(node, size); node->c_hash = hash; _PyObject_GC_TRACK(node); diff --git a/Python/marshal.c b/Python/marshal.c index 8d441a4f08196..04a8dc598988a 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -813,7 +813,7 @@ r_PyLong(RFILE *p) if (ob == NULL) return NULL; - Py_SIZE(ob) = n > 0 ? size : -size; + Py_SET_SIZE(ob, n > 0 ? size : -size); for (i = 0; i < size-1; i++) { d = 0; From webhook-mailer at python.org Fri Feb 7 17:42:56 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 07 Feb 2020 22:42:56 -0000 Subject: [Python-checkins] bpo-39350: Fix fractions for int subclasses (GH-18375) Message-ID: https://github.com/python/cpython/commit/dc7a50d73a3d16918529669ff7b8783c08cff090 commit: dc7a50d73a3d16918529669ff7b8783c08cff090 branch: master author: Victor Stinner committer: GitHub date: 2020-02-07T23:42:51+01:00 summary: bpo-39350: Fix fractions for int subclasses (GH-18375) Fix regression in fractions.Fraction if the numerator and/or the denominator is an int subclass. The math.gcd() function is now used to normalize the numerator and denominator. math.gcd() always return a int type. Previously, the GCD type depended on numerator and denominator. files: A Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst M Doc/library/fractions.rst M Lib/fractions.py M Lib/test/test_fractions.py diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index d3a42762e3ff8..a4d006eb58ffe 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -84,6 +84,10 @@ another rational number, or from a string. The :class:`Fraction` constructor now accepts :class:`float` and :class:`decimal.Decimal` instances. + .. versionchanged:: 3.9 + The :func:`math.gcd` function is now used to normalize the *numerator* + and *denominator*. :func:`math.gcd` always return a :class:`int` type. + Previously, the GCD type depended on *numerator* and *denominator*. .. attribute:: numerator diff --git a/Lib/fractions.py b/Lib/fractions.py index f5a854414c166..de3e23b759227 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -155,13 +155,9 @@ def __new__(cls, numerator=0, denominator=None, *, _normalize=True): if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) if _normalize: - if type(numerator) is int is type(denominator): - # *very* normal case - g = math.gcd(numerator, denominator) - if denominator < 0: - g = -g - else: - g = _gcd(numerator, denominator) + g = math.gcd(numerator, denominator) + if denominator < 0: + g = -g numerator //= g denominator //= g self._numerator = numerator diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 4649a34bcc1f1..c748533c79129 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -703,6 +703,28 @@ def test_slots(self): r = F(13, 7) self.assertRaises(AttributeError, setattr, r, 'a', 10) + def test_int_subclass(self): + class myint(int): + def __mul__(self, other): + return type(self)(int(self) * int(other)) + def __floordiv__(self, other): + return type(self)(int(self) // int(other)) + def __mod__(self, other): + x = type(self)(int(self) % int(other)) + return x + @property + def numerator(self): + return type(self)(int(self)) + @property + def denominator(self): + return type(self)(1) + + f = fractions.Fraction(myint(1 * 3), myint(2 * 3)) + self.assertEqual(f.numerator, 1) + self.assertEqual(f.denominator, 2) + self.assertEqual(type(f.numerator), myint) + self.assertEqual(type(f.denominator), myint) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst b/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst new file mode 100644 index 0000000000000..1a09358082ef6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst @@ -0,0 +1,5 @@ +Fix regression in :class:`fractions.Fraction` if the numerator and/or the +denominator is an :class:`int` subclass. The :func:`math.gcd` function is now +used to normalize the *numerator* and *denominator*. :func:`math.gcd` always +return a :class:`int` type. Previously, the GCD type depended on *numerator* +and *denominator*. From webhook-mailer at python.org Fri Feb 7 18:36:36 2020 From: webhook-mailer at python.org (Lysandros Nikolaou) Date: Fri, 07 Feb 2020 23:36:36 -0000 Subject: [Python-checkins] bpo-39579: Fix Attribute end_col_offset to point at the current node (GH-18405) Message-ID: https://github.com/python/cpython/commit/d2e1098641f98594702ef29049c3c4a3f394786f commit: d2e1098641f98594702ef29049c3c4a3f394786f branch: master author: Lysandros Nikolaou committer: GitHub date: 2020-02-07T15:36:32-08:00 summary: bpo-39579: Fix Attribute end_col_offset to point at the current node (GH-18405) files: A Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index aa0d214b8a606..6d1e419932261 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -142,6 +142,8 @@ def to_tuple(t): "@deco1\n at deco2()\n at deco3(1)\nclass C: pass", # Decorator with generator argument "@deco(a for a in b)\ndef f(): pass", + # Decorator with attribute + "@a.b.c\ndef f(): pass", # Simple assignment expression "(a := 1)", # Positional-only arguments @@ -616,6 +618,11 @@ def test_issue18374_binop_col_offset(self): self.assertEqual(grandchild_binop.end_col_offset, 3) self.assertEqual(grandchild_binop.end_lineno, 1) + def test_issue39579_dotted_name_end_col_offset(self): + tree = ast.parse('@a.b.c\ndef f(): pass') + attr_b = tree.body[0].decorator_list[0].value + self.assertEqual(attr_b.end_col_offset, 4) + class ASTHelpers_Test(unittest.TestCase): maxDiff = None @@ -1903,6 +1910,7 @@ def main(): ('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []), ('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []), ('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []), +('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []), ('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []), ('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []), diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst new file mode 100644 index 0000000000000..36d5c425670c2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst @@ -0,0 +1 @@ +Change the ending column offset of `Attribute` nodes constructed in `ast_for_dotted_name` to point at the end of the current node and not at the end of the last `NAME` node. \ No newline at end of file diff --git a/Python/ast.c b/Python/ast.c index 9c48d71d154fc..bab672b29589f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1715,11 +1715,12 @@ ast_for_dotted_name(struct compiling *c, const node *n) return NULL; for (i = 2; i < NCH(n); i+=2) { - id = NEW_IDENTIFIER(CHILD(n, i)); + const node *child = CHILD(n, i); + id = NEW_IDENTIFIER(child); if (!id) return NULL; e = Attribute(e, id, Load, lineno, col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); + child->n_end_lineno, child->n_end_col_offset, c->c_arena); if (!e) return NULL; } From webhook-mailer at python.org Fri Feb 7 18:46:34 2020 From: webhook-mailer at python.org (Fangrui Song) Date: Fri, 07 Feb 2020 23:46:34 -0000 Subject: [Python-checkins] closes bpo-39575: Change -lgcov to --coverage. (GH-18382) Message-ID: https://github.com/python/cpython/commit/9a978ddb93bf5eaa519916d9a40c4fa4edf5d854 commit: 9a978ddb93bf5eaa519916d9a40c4fa4edf5d854 branch: master author: Fangrui Song committer: GitHub date: 2020-02-07T15:46:29-08:00 summary: closes bpo-39575: Change -lgcov to --coverage. (GH-18382) This allows clang to get rid of the dependency on libgcov. When linking, GCC passes -lgcov while clang passes the path to libclang_rt.profile-$arch.a files: M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index 510f227ed4df3..3da104bac87d0 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -513,7 +513,7 @@ profile-opt: profile-run-stamp coverage: @echo "Building with support for coverage checking:" $(MAKE) clean - $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg -fprofile-arcs -ftest-coverage" LIBS="$(LIBS) -lgcov" + $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LIBS="$(LIBS) --coverage" coverage-lcov: @echo "Creating Coverage HTML report with LCOV:" From webhook-mailer at python.org Fri Feb 7 19:21:48 2020 From: webhook-mailer at python.org (Lysandros Nikolaou) Date: Sat, 08 Feb 2020 00:21:48 -0000 Subject: [Python-checkins] [3.8] bpo-39579: Fix Attribute end_col_offset to point at the current node (GH-18405) (GH-18408) Message-ID: https://github.com/python/cpython/commit/8b9cebce09cb6919fdb97d8e608288a503681d13 commit: 8b9cebce09cb6919fdb97d8e608288a503681d13 branch: 3.8 author: Lysandros Nikolaou committer: GitHub date: 2020-02-07T16:21:38-08:00 summary: [3.8] bpo-39579: Fix Attribute end_col_offset to point at the current node (GH-18405) (GH-18408) (cherry picked from commit d2e1098641f98594702ef29049c3c4a3f394786f) https://bugs.python.org/issue39579 Automerge-Triggered-By: @gvanrossum files: A Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 69ed83cd8b68b..e843d53781d25 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -140,6 +140,8 @@ def to_tuple(t): "@deco1\n at deco2()\n at deco3(1)\nclass C: pass", # Decorator with generator argument "@deco(a for a in b)\ndef f(): pass", + # Decorator with attribute + "@a.b.c\ndef f(): pass", # Simple assignment expression "(a := 1)", # Positional-only arguments @@ -614,6 +616,11 @@ def test_issue18374_binop_col_offset(self): self.assertEqual(grandchild_binop.end_col_offset, 3) self.assertEqual(grandchild_binop.end_lineno, 1) + def test_issue39579_dotted_name_end_col_offset(self): + tree = ast.parse('@a.b.c\ndef f(): pass') + attr_b = tree.body[0].decorator_list[0].value + self.assertEqual(attr_b.end_col_offset, 4) + class ASTHelpers_Test(unittest.TestCase): maxDiff = None @@ -1838,6 +1845,7 @@ def main(): ('Module', [('AsyncFunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []), ('Module', [('ClassDef', (4, 0), 'C', [], [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])])], []), ('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []), +('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Attribute', (1, 1), ('Attribute', (1, 1), ('Name', (1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []), ('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []), diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst new file mode 100644 index 0000000000000..36d5c425670c2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst @@ -0,0 +1 @@ +Change the ending column offset of `Attribute` nodes constructed in `ast_for_dotted_name` to point at the end of the current node and not at the end of the last `NAME` node. \ No newline at end of file diff --git a/Python/ast.c b/Python/ast.c index f3263c1e3fcdc..12f24f2c22ab9 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1715,11 +1715,12 @@ ast_for_dotted_name(struct compiling *c, const node *n) return NULL; for (i = 2; i < NCH(n); i+=2) { - id = NEW_IDENTIFIER(CHILD(n, i)); + const node *child = CHILD(n, i); + id = NEW_IDENTIFIER(child); if (!id) return NULL; e = Attribute(e, id, Load, lineno, col_offset, - n->n_end_lineno, n->n_end_col_offset, c->c_arena); + child->n_end_lineno, child->n_end_col_offset, c->c_arena); if (!e) return NULL; } From webhook-mailer at python.org Fri Feb 7 19:48:10 2020 From: webhook-mailer at python.org (Saiyang Gou) Date: Sat, 08 Feb 2020 00:48:10 -0000 Subject: [Python-checkins] Doc: sys.__unraisablehook__ and bytearray.hex separators are new in 3.8 (GH-17884) Message-ID: https://github.com/python/cpython/commit/0edc2c7678266c39a7ceb2df885cb050f887e32b commit: 0edc2c7678266c39a7ceb2df885cb050f887e32b branch: master author: Saiyang Gou committer: GitHub date: 2020-02-07T16:48:06-08:00 summary: Doc: sys.__unraisablehook__ and bytearray.hex separators are new in 3.8 (GH-17884) Minor fix in documentation: - `sys.__unraisablehook__` is new in version 3.8 - Optional `sep` and `bytes_per_sep` parameters for `bytearray.hex` is also supported in Python 3.8 (just like `bytes.hex`) files: M Doc/library/stdtypes.rst M Doc/library/sys.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index fd3401fd18a09..47d64f1e8d65f 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2416,7 +2416,7 @@ data and are closely related to string objects in a variety of other ways. A reverse conversion function exists to transform a bytes object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2510,7 +2510,7 @@ objects. A reverse conversion function exists to transform a bytearray object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2520,6 +2520,11 @@ objects. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`bytearray.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + Since bytearray objects are sequences of integers (akin to a list), for a bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytearray object of length 1. (This contrasts with text strings, where @@ -3673,7 +3678,7 @@ copying. in-memory Fortran order is preserved. For non-contiguous views, the data is converted to C first. *order=None* is the same as *order='C'*. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the buffer. :: @@ -3684,6 +3689,11 @@ copying. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`memoryview.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + .. method:: tolist() Return the data in the buffer as a list of elements. :: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index d28b3565c1c63..f67bf630ff8f3 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -343,6 +343,8 @@ always available. .. versionadded:: 3.7 __breakpointhook__ + .. versionadded:: 3.8 + __unraisablehook__ .. function:: exc_info() From webhook-mailer at python.org Fri Feb 7 19:54:10 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 08 Feb 2020 00:54:10 -0000 Subject: [Python-checkins] Doc: sys.__unraisablehook__ and bytearray.hex separators are new in 3.8 (GH-17884) Message-ID: https://github.com/python/cpython/commit/0c915e620d049558bacc78cf25c1560f55d1fb82 commit: 0c915e620d049558bacc78cf25c1560f55d1fb82 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-07T16:54:06-08:00 summary: Doc: sys.__unraisablehook__ and bytearray.hex separators are new in 3.8 (GH-17884) Minor fix in documentation: - `sys.__unraisablehook__` is new in version 3.8 - Optional `sep` and `bytes_per_sep` parameters for `bytearray.hex` is also supported in Python 3.8 (just like `bytes.hex`) (cherry picked from commit 0edc2c7678266c39a7ceb2df885cb050f887e32b) Co-authored-by: Saiyang Gou files: M Doc/library/stdtypes.rst M Doc/library/sys.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index d6db9b5411d8a..d369b38b31bc9 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2399,7 +2399,7 @@ data and are closely related to string objects in a variety of other ways. A reverse conversion function exists to transform a bytes object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2493,7 +2493,7 @@ objects. A reverse conversion function exists to transform a bytearray object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2503,6 +2503,11 @@ objects. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`bytearray.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + Since bytearray objects are sequences of integers (akin to a list), for a bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytearray object of length 1. (This contrasts with text strings, where @@ -3649,7 +3654,7 @@ copying. in-memory Fortran order is preserved. For non-contiguous views, the data is converted to C first. *order=None* is the same as *order='C'*. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the buffer. :: @@ -3660,6 +3665,11 @@ copying. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`memoryview.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + .. method:: tolist() Return the data in the buffer as a list of elements. :: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index e1d93f85bd407..d3473de1292ea 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -343,6 +343,8 @@ always available. .. versionadded:: 3.7 __breakpointhook__ + .. versionadded:: 3.8 + __unraisablehook__ .. function:: exc_info() From webhook-mailer at python.org Sat Feb 8 18:46:05 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Sat, 08 Feb 2020 23:46:05 -0000 Subject: [Python-checkins] bpo-39573: Use Py_TYPE() macro in ctypes.h (GH-18411) Message-ID: https://github.com/python/cpython/commit/7f6f7eef5206858030cbe4f80a7c04b02781cc9a commit: 7f6f7eef5206858030cbe4f80a7c04b02781cc9a branch: master author: Dong-hee Na committer: GitHub date: 2020-02-09T00:45:52+01:00 summary: bpo-39573: Use Py_TYPE() macro in ctypes.h (GH-18411) files: M Modules/_ctypes/ctypes.h diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index a232a4bc83206..a93d573b72b2d 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -112,12 +112,12 @@ extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palig extern PyTypeObject PyCData_Type; -#define CDataObject_CheckExact(v) ((v)->ob_type == &PyCData_Type) +#define CDataObject_CheckExact(v) (Py_TYPE(v) == &PyCData_Type) #define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) #define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) extern PyTypeObject PyCSimpleType_Type; -#define PyCSimpleTypeObject_CheckExact(v) ((v)->ob_type == &PyCSimpleType_Type) +#define PyCSimpleTypeObject_CheckExact(v) (Py_TYPE(v) == &PyCSimpleType_Type) #define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) extern PyTypeObject PyCField_Type; From webhook-mailer at python.org Sun Feb 9 03:16:57 2020 From: webhook-mailer at python.org (sweeneyde) Date: Sun, 09 Feb 2020 08:16:57 -0000 Subject: [Python-checkins] bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) Message-ID: https://github.com/python/cpython/commit/c6dedde160a9fce5d049e860f586ad8f93aec822 commit: c6dedde160a9fce5d049e860f586ad8f93aec822 branch: master author: sweeneyde <36520290+sweeneyde at users.noreply.github.com> committer: GitHub date: 2020-02-09T00:16:43-08:00 summary: bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) files: A Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst M Lib/test/test_deque.py M Modules/_collectionsmodule.c diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 51b66b76aca91..c0f7138254f3f 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -183,6 +183,18 @@ def test_contains(self): with self.assertRaises(RuntimeError): n in d + def test_contains_count_stop_crashes(self): + class A: + def __eq__(self, other): + d.clear() + return NotImplemented + d = deque([A(), A()]) + with self.assertRaises(RuntimeError): + _ = 3 in d + d = deque([A(), A()]) + with self.assertRaises(RuntimeError): + _ = d.count(3) + def test_extend(self): d = deque('a') self.assertRaises(TypeError, d.extend, 1) diff --git a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst new file mode 100644 index 0000000000000..68625028fb7af --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst @@ -0,0 +1 @@ +Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes. \ No newline at end of file diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 10030606711e0..25e4c96943e46 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -965,7 +965,9 @@ deque_count(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); item = b->data[index]; + Py_INCREF(item); cmp = PyObject_RichCompareBool(item, v, Py_EQ); + Py_DECREF(item); if (cmp < 0) return NULL; count += cmp; @@ -1002,7 +1004,9 @@ deque_contains(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); item = b->data[index]; + Py_INCREF(item); cmp = PyObject_RichCompareBool(item, v, Py_EQ); + Py_DECREF(item); if (cmp) { return cmp; } From webhook-mailer at python.org Sun Feb 9 03:39:40 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 09 Feb 2020 08:39:40 -0000 Subject: [Python-checkins] bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) (GH-18423) Message-ID: https://github.com/python/cpython/commit/dc56f5f48866bf3c5412642bba00890d9a090cfb commit: dc56f5f48866bf3c5412642bba00890d9a090cfb branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-09T00:39:28-08:00 summary: bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) (GH-18423) (cherry picked from commit c6dedde160a9fce5d049e860f586ad8f93aec822) Co-authored-by: sweeneyde <36520290+sweeneyde at users.noreply.github.com> Co-authored-by: sweeneyde <36520290+sweeneyde at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst M Lib/test/test_deque.py M Modules/_collectionsmodule.c diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 51b66b76aca91..c0f7138254f3f 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -183,6 +183,18 @@ def test_contains(self): with self.assertRaises(RuntimeError): n in d + def test_contains_count_stop_crashes(self): + class A: + def __eq__(self, other): + d.clear() + return NotImplemented + d = deque([A(), A()]) + with self.assertRaises(RuntimeError): + _ = 3 in d + d = deque([A(), A()]) + with self.assertRaises(RuntimeError): + _ = d.count(3) + def test_extend(self): d = deque('a') self.assertRaises(TypeError, d.extend, 1) diff --git a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst new file mode 100644 index 0000000000000..68625028fb7af --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst @@ -0,0 +1 @@ +Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes. \ No newline at end of file diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 45169ecd11af0..cc2b90eaa283e 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -966,7 +966,9 @@ deque_count(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); item = b->data[index]; + Py_INCREF(item); cmp = PyObject_RichCompareBool(item, v, Py_EQ); + Py_DECREF(item); if (cmp < 0) return NULL; count += cmp; @@ -1003,7 +1005,9 @@ deque_contains(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); item = b->data[index]; + Py_INCREF(item); cmp = PyObject_RichCompareBool(item, v, Py_EQ); + Py_DECREF(item); if (cmp) { return cmp; } From webhook-mailer at python.org Sun Feb 9 19:57:51 2020 From: webhook-mailer at python.org (Don Kirkby) Date: Mon, 10 Feb 2020 00:57:51 -0000 Subject: [Python-checkins] Grammar fix in tutorial (GH-18425) Message-ID: https://github.com/python/cpython/commit/3ed4d251587c36c3853daf42602eaad121b59bba commit: 3ed4d251587c36c3853daf42602eaad121b59bba branch: master author: Don Kirkby committer: GitHub date: 2020-02-09T19:57:46-05:00 summary: Grammar fix in tutorial (GH-18425) files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 7dfd33af25886..f05f5edd5ccc4 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -142,7 +142,7 @@ the list, thus saving space. We say such an object is :term:`iterable`, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that -the :keyword:`for` statement is such a construct, while an example of function +the :keyword:`for` statement is such a construct, while an example of a function that takes an iterable is :func:`sum`:: >>> sum(range(4)) # 0 + 1 + 2 + 3 From webhook-mailer at python.org Mon Feb 10 04:49:12 2020 From: webhook-mailer at python.org (idomic) Date: Mon, 10 Feb 2020 09:49:12 -0000 Subject: [Python-checkins] bpo-39128: Added happy_eyeballs_delay, interleave to function signature (GH-18315) Message-ID: https://github.com/python/cpython/commit/5305cc9dbfe8a5a0ab666511f3ba7f026c8983f8 commit: 5305cc9dbfe8a5a0ab666511f3ba7f026c8983f8 branch: master author: idomic committer: GitHub date: 2020-02-10T10:48:40+01:00 summary: bpo-39128: Added happy_eyeballs_delay, interleave to function signature (GH-18315) files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 0029d94f0b598..3acd79d283580 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -359,7 +359,8 @@ Opening network connections host=None, port=None, \*, ssl=None, \ family=0, proto=0, flags=0, sock=None, \ local_addr=None, server_hostname=None, \ - ssl_handshake_timeout=None) + ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Open a streaming transport connection to a given address specified by *host* and *port*. @@ -448,7 +449,7 @@ Opening network connections .. versionadded:: 3.8 - The *happy_eyeballs_delay* and *interleave* parameters. + Added the *happy_eyeballs_delay* and *interleave* parameters. .. versionadded:: 3.7 From webhook-mailer at python.org Mon Feb 10 04:54:43 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 09:54:43 -0000 Subject: [Python-checkins] bpo-39128: Added happy_eyeballs_delay, interleave to function signature (GH-18315) Message-ID: https://github.com/python/cpython/commit/af95d790a86fc46739badfa9edbaeb264ee96600 commit: af95d790a86fc46739badfa9edbaeb264ee96600 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T01:54:38-08:00 summary: bpo-39128: Added happy_eyeballs_delay, interleave to function signature (GH-18315) (cherry picked from commit 5305cc9dbfe8a5a0ab666511f3ba7f026c8983f8) Co-authored-by: idomic files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 24f621e2d9fff..4ea8521eb0bf3 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -347,7 +347,8 @@ Opening network connections host=None, port=None, \*, ssl=None, \ family=0, proto=0, flags=0, sock=None, \ local_addr=None, server_hostname=None, \ - ssl_handshake_timeout=None) + ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Open a streaming transport connection to a given address specified by *host* and *port*. @@ -436,7 +437,7 @@ Opening network connections .. versionadded:: 3.8 - The *happy_eyeballs_delay* and *interleave* parameters. + Added the *happy_eyeballs_delay* and *interleave* parameters. .. versionadded:: 3.7 From webhook-mailer at python.org Mon Feb 10 06:40:20 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 11:40:20 -0000 Subject: [Python-checkins] Grammar fix in tutorial (GH-18425) (GH-18426) Message-ID: https://github.com/python/cpython/commit/b086ea5edc44cf64ecfb645d578927aa96e8c355 commit: b086ea5edc44cf64ecfb645d578927aa96e8c355 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T06:40:15-05:00 summary: Grammar fix in tutorial (GH-18425) (GH-18426) (cherry picked from commit 3ed4d251587c36c3853daf42602eaad121b59bba) Co-authored-by: Don Kirkby files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 7dfd33af25886..f05f5edd5ccc4 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -142,7 +142,7 @@ the list, thus saving space. We say such an object is :term:`iterable`, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that -the :keyword:`for` statement is such a construct, while an example of function +the :keyword:`for` statement is such a construct, while an example of a function that takes an iterable is :func:`sum`:: >>> sum(range(4)) # 0 + 1 + 2 + 3 From webhook-mailer at python.org Mon Feb 10 08:27:07 2020 From: webhook-mailer at python.org (Hugo van Kemenade) Date: Mon, 10 Feb 2020 13:27:07 -0000 Subject: [Python-checkins] bpo-39586: Deprecate distutils bdist_msi command (GH-18415) Message-ID: https://github.com/python/cpython/commit/29b3fc0a18f105de666fdd586b537f34e349766d commit: 29b3fc0a18f105de666fdd586b537f34e349766d branch: master author: Hugo van Kemenade committer: GitHub date: 2020-02-10T14:26:40+01:00 summary: bpo-39586: Deprecate distutils bdist_msi command (GH-18415) files: A Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst M Doc/distutils/apiref.rst M Doc/distutils/builtdist.rst M Doc/whatsnew/3.9.rst M Lib/distutils/command/bdist_msi.py M Lib/distutils/tests/test_bdist_msi.py M Misc/ACKS diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 12e0c0b2c9757..b14197c2f94db 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1855,6 +1855,9 @@ Subclasses of :class:`Command` must define the following methods. .. class:: bdist_msi +.. deprecated:: 3.9 + Use bdist_wheel (wheel packages) instead. + Builds a `Windows Installer`_ (.msi) binary package. .. _Windows Installer: https://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst index b814f2e9508c9..e032c03e229a5 100644 --- a/Doc/distutils/builtdist.rst +++ b/Doc/distutils/builtdist.rst @@ -149,6 +149,9 @@ generated by each, are: .. note:: bdist_wininst is deprecated since Python 3.8. +.. note:: + bdist_msi is deprecated since Python 3.9. + The following sections give details on the individual :command:`bdist_\*` commands. @@ -304,6 +307,9 @@ Creating Windows Installers .. warning:: bdist_wininst is deprecated since Python 3.8. +.. warning:: + bdist_msi is deprecated since Python 3.9. + Executable installers are the natural format for binary distributions on Windows. They display a nice graphical user interface, display some information about the module distribution to be installed taken from the metadata in the @@ -468,3 +474,6 @@ installed for all users) and 'force' (meaning always prompt for elevation). .. note:: bdist_wininst is deprecated since Python 3.8. + +.. note:: + bdist_msi is deprecated since Python 3.9. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 4991e56759b1c..4f4c7f2808d01 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -398,6 +398,10 @@ Build and C API Changes Deprecated ========== +* The distutils ``bdist_msi`` command is now deprecated, use + ``bdist_wheel`` (wheel packages) instead. + (Contributed by Hugo van Kemenade in :issue:`39586`.) + * Currently :func:`math.factorial` accepts :class:`float` instances with non-negative integer values (like ``5.0``). It raises a :exc:`ValueError` for non-integral and negative floats. It is now deprecated. In future diff --git a/Lib/distutils/command/bdist_msi.py b/Lib/distutils/command/bdist_msi.py index f335a34898620..0863a1883e720 100644 --- a/Lib/distutils/command/bdist_msi.py +++ b/Lib/distutils/command/bdist_msi.py @@ -6,7 +6,9 @@ Implements the bdist_msi command. """ -import sys, os +import os +import sys +import warnings from distutils.core import Command from distutils.dir_util import remove_tree from distutils.sysconfig import get_python_version @@ -122,6 +124,12 @@ class bdist_msi(Command): '3.5', '3.6', '3.7', '3.8', '3.9'] other_version = 'X' + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + warnings.warn("bdist_msi command is deprecated since Python 3.9, " + "use bdist_wheel (wheel packages) instead", + DeprecationWarning, 2) + def initialize_options(self): self.bdist_dir = None self.plat_name = None diff --git a/Lib/distutils/tests/test_bdist_msi.py b/Lib/distutils/tests/test_bdist_msi.py index 15d8bdff2b4f5..418e60ec72977 100644 --- a/Lib/distutils/tests/test_bdist_msi.py +++ b/Lib/distutils/tests/test_bdist_msi.py @@ -1,7 +1,7 @@ """Tests for distutils.command.bdist_msi.""" import sys import unittest -from test.support import run_unittest +from test.support import run_unittest, check_warnings from distutils.tests import support @@ -14,7 +14,8 @@ def test_minimal(self): # minimal test XXX need more tests from distutils.command.bdist_msi import bdist_msi project_dir, dist = self.create_dist() - cmd = bdist_msi(dist) + with check_warnings(("", DeprecationWarning)): + cmd = bdist_msi(dist) cmd.ensure_finalized() diff --git a/Misc/ACKS b/Misc/ACKS index f3e368078124d..5a779833e68be 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -843,6 +843,7 @@ Dmitry Kazakov Brian Kearns Sebastien Keim Ryan Kelly +Hugo van Kemenade Dan Kenigsberg Randall Kern Robert Kern diff --git a/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst b/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst new file mode 100644 index 0000000000000..5189f131afd98 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst @@ -0,0 +1,2 @@ +The distutils ``bdist_msi`` command is deprecated in Python 3.9, use +``bdist_wheel`` (wheel packages) instead. \ No newline at end of file From webhook-mailer at python.org Mon Feb 10 12:47:25 2020 From: webhook-mailer at python.org (Brian Curtin) Date: Mon, 10 Feb 2020 17:47:25 -0000 Subject: [Python-checkins] Remove note saying patch is straightforward (#18431) Message-ID: https://github.com/python/cpython/commit/e00c1d0c45975c0e9367f05f8c68bb32d68c2fbf commit: e00c1d0c45975c0e9367f05f8c68bb32d68c2fbf branch: master author: Brian Curtin committer: GitHub date: 2020-02-10T10:47:17-07:00 summary: Remove note saying patch is straightforward (#18431) While `unittest.mock.patch` is a great thing, it is not straightforward. If it were straightforward there wouldn't be such a huge amount of documentation for it, and frankly, when myself and others who I've read about often struggle to figure out what on earth `patch()` wants, coming to the docs to read that it's straightforward is not helpful. files: M Doc/library/unittest.mock.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 515bdd060a198..3643d1ad96ed1 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1327,8 +1327,7 @@ patch .. note:: - :func:`patch` is straightforward to use. The key is to do the patching in the - right namespace. See the section `where to patch`_. + The key is to do the patching in the right namespace. See the section `where to patch`_. .. function:: patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) From webhook-mailer at python.org Mon Feb 10 14:41:41 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 10 Feb 2020 19:41:41 -0000 Subject: [Python-checkins] bpo-39600, IDLE: Remove duplicated font names (GH-18430) Message-ID: https://github.com/python/cpython/commit/ed335cf53b5d4bca9a08c9b83ba684ba17be0f10 commit: ed335cf53b5d4bca9a08c9b83ba684ba17be0f10 branch: master author: Victor Stinner committer: GitHub date: 2020-02-10T11:41:26-08:00 summary: bpo-39600, IDLE: Remove duplicated font names (GH-18430) In the font configuration window, remove duplicated font names. files: A Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 22359735874d1..7b844f00e7736 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -607,8 +607,9 @@ def load_font_cfg(self): font_bold = configured_font[2]=='bold' # Set editor font selection list and font_name. - fonts = list(tkFont.families(self)) - fonts.sort() + fonts = tkFont.families(self) + # remove duplicated names and sort + fonts = sorted(set(fonts)) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) diff --git a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst new file mode 100644 index 0000000000000..102aa75f5813e --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst @@ -0,0 +1 @@ +In the font configuration window, remove duplicated font names. From webhook-mailer at python.org Mon Feb 10 15:13:46 2020 From: webhook-mailer at python.org (Wellington Pardim) Date: Mon, 10 Feb 2020 20:13:46 -0000 Subject: [Python-checkins] bpo-39369 Doc: Update mmap readline method documentation (GH-17957) Message-ID: https://github.com/python/cpython/commit/6c9974e12c50150149b989aaef68be1fe46ea670 commit: 6c9974e12c50150149b989aaef68be1fe46ea670 branch: master author: Wellington Pardim committer: GitHub date: 2020-02-10T12:13:41-08:00 summary: bpo-39369 Doc: Update mmap readline method documentation (GH-17957) * Update mmap readline method documentation Update mmap `readline` method description. The fact that the `readline` method does update the file position should not be ignored since this might give the impression for the programmer that it doesn't update it. * ?? Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst M Doc/library/mmap.rst diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 12b14d69332d7..1f3fbc340fc26 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -244,7 +244,8 @@ To map anonymous memory, -1 should be passed as the fileno along with the length .. method:: readline() Returns a single line, starting at the current file position and up to the - next newline. + next newline. The file position is updated to point after the bytes that were + returned. .. method:: resize(newsize) diff --git a/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst b/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst new file mode 100644 index 0000000000000..7f41735b9d3e3 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst @@ -0,0 +1 @@ +Update mmap readline method description. The fact that the readline method does update the file position should not be ignored since this might give the impression for the programmer that it doesn't update it. \ No newline at end of file From webhook-mailer at python.org Mon Feb 10 15:17:58 2020 From: webhook-mailer at python.org (Christophe Nanteuil) Date: Mon, 10 Feb 2020 20:17:58 -0000 Subject: [Python-checkins] Remove redundant references in struct doc (GH-18053) Message-ID: https://github.com/python/cpython/commit/3c5dec65e99ab7b641f1663c88e3332fff944881 commit: 3c5dec65e99ab7b641f1663c88e3332fff944881 branch: master author: Christophe Nanteuil <35002064+christopheNan at users.noreply.github.com> committer: GitHub date: 2020-02-10T12:17:54-08:00 summary: Remove redundant references in struct doc (GH-18053) files: M Doc/library/struct.rst diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 1f90e3d1ba855..856b6da8bb255 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -259,7 +259,7 @@ Notes: called to convert the argument to an integer before packing. .. versionchanged:: 3.2 - Use of the :meth:`__index__` method for non-integers is new in 3.2. + Added use of the :meth:`__index__` method for non-integers. (3) The ``'n'`` and ``'N'`` conversion codes are only available for the native @@ -312,7 +312,7 @@ When packing a value ``x`` using one of the integer formats (``'b'``, then :exc:`struct.error` is raised. .. versionchanged:: 3.1 - In 3.0, some of the integer formats wrapped out-of-range values and + Previously, some of the integer formats wrapped out-of-range values and raised :exc:`DeprecationWarning` instead of :exc:`struct.error`. The ``'p'`` format character encodes a "Pascal string", meaning a short From webhook-mailer at python.org Mon Feb 10 15:28:19 2020 From: webhook-mailer at python.org (Elena Oat) Date: Mon, 10 Feb 2020 20:28:19 -0000 Subject: [Python-checkins] bpo-39545: docs: do not use await in f-strings (GH-18434) Message-ID: https://github.com/python/cpython/commit/a2963f09629a0a8c63e9acef79c1dcc0a040ddb6 commit: a2963f09629a0a8c63e9acef79c1dcc0a040ddb6 branch: 3.6 author: Elena Oat committer: GitHub date: 2020-02-10T15:28:11-05:00 summary: bpo-39545: docs: do not use await in f-strings (GH-18434) files: M Doc/reference/compound_stmts.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 8d050a69a931d..b4e95b90dbc70 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -730,7 +730,7 @@ Functions defined with ``async def`` syntax are always coroutine functions, even if they do not contain ``await`` or ``async`` keywords. It is a :exc:`SyntaxError` to use ``yield from`` expressions in -``async def`` coroutines. +``async def`` coroutines. Using ``await`` in :keyword:`f-strings` will also produce a :exc:`SyntaxError`. An example of a coroutine function:: From webhook-mailer at python.org Mon Feb 10 16:15:39 2020 From: webhook-mailer at python.org (Carl) Date: Mon, 10 Feb 2020 21:15:39 -0000 Subject: [Python-checkins] Issue3950: Fix docs for default locale used by gettext to match implementation (#18435) Message-ID: https://github.com/python/cpython/commit/d68e0a8a165761604e820c8cb4f20abc735e717f commit: d68e0a8a165761604e820c8cb4f20abc735e717f branch: master author: Carl committer: GitHub date: 2020-02-10T13:15:34-08:00 summary: Issue3950: Fix docs for default locale used by gettext to match implementation (#18435) documentation for default locale directory Doc/library/gettext.rst changed to match gettext implementation line 63. files: M Doc/library/gettext.rst diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 937330bb201b0..ec2c12806b416 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -724,8 +724,8 @@ implementations, and valuable experience to the creation of this module: .. [#] The default locale directory is system dependent; for example, on RedHat Linux it is :file:`/usr/share/locale`, but on Solaris it is :file:`/usr/lib/locale`. The :mod:`gettext` module does not try to support these system dependent - defaults; instead its default is :file:`{sys.prefix}/share/locale` (see - :data:`sys.prefix`). For this reason, it is always best to call + defaults; instead its default is :file:`{sys.base_prefix}/share/locale` (see + :data:`sys.base_prefix`). For this reason, it is always best to call :func:`bindtextdomain` with an explicit absolute path at the start of your application. From webhook-mailer at python.org Mon Feb 10 16:25:01 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 21:25:01 -0000 Subject: [Python-checkins] Issue3950: Fix docs for default locale used by gettext to match implementation (GH-18435) Message-ID: https://github.com/python/cpython/commit/a83d9108066a7a22605ba7ee962a755f4bec1ab1 commit: a83d9108066a7a22605ba7ee962a755f4bec1ab1 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T13:24:53-08:00 summary: Issue3950: Fix docs for default locale used by gettext to match implementation (GH-18435) documentation for default locale directory Doc/library/gettext.rst changed to match gettext implementation line 63. (cherry picked from commit d68e0a8a165761604e820c8cb4f20abc735e717f) Co-authored-by: Carl files: M Doc/library/gettext.rst diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 937330bb201b0..ec2c12806b416 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -724,8 +724,8 @@ implementations, and valuable experience to the creation of this module: .. [#] The default locale directory is system dependent; for example, on RedHat Linux it is :file:`/usr/share/locale`, but on Solaris it is :file:`/usr/lib/locale`. The :mod:`gettext` module does not try to support these system dependent - defaults; instead its default is :file:`{sys.prefix}/share/locale` (see - :data:`sys.prefix`). For this reason, it is always best to call + defaults; instead its default is :file:`{sys.base_prefix}/share/locale` (see + :data:`sys.base_prefix`). For this reason, it is always best to call :func:`bindtextdomain` with an explicit absolute path at the start of your application. From webhook-mailer at python.org Mon Feb 10 16:34:32 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 21:34:32 -0000 Subject: [Python-checkins] [3.7] bpo-3950: Fix docs for default locale used by gettext to match implementation (GH-18435) (GH-18439) Message-ID: https://github.com/python/cpython/commit/3b888ad70aaed39df1985b38b4987feb5bee7981 commit: 3b888ad70aaed39df1985b38b4987feb5bee7981 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T13:34:22-08:00 summary: [3.7] bpo-3950: Fix docs for default locale used by gettext to match implementation (GH-18435) (GH-18439) documentation for default locale directory Doc/library/gettext.rst changed to match gettext implementation line 63. (cherry picked from commit d68e0a8a165761604e820c8cb4f20abc735e717f) Co-authored-by: Carl https://bugs.python.org/issue3950 Automerge-Triggered-By: @gvanrossum files: M Doc/library/gettext.rst diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 94ed340a22f20..c4e04832ed5f9 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -652,8 +652,8 @@ implementations, and valuable experience to the creation of this module: .. [#] The default locale directory is system dependent; for example, on RedHat Linux it is :file:`/usr/share/locale`, but on Solaris it is :file:`/usr/lib/locale`. The :mod:`gettext` module does not try to support these system dependent - defaults; instead its default is :file:`{sys.prefix}/share/locale` (see - :data:`sys.prefix`). For this reason, it is always best to call + defaults; instead its default is :file:`{sys.base_prefix}/share/locale` (see + :data:`sys.base_prefix`). For this reason, it is always best to call :func:`bindtextdomain` with an explicit absolute path at the start of your application. From webhook-mailer at python.org Mon Feb 10 16:38:38 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 21:38:38 -0000 Subject: [Python-checkins] bpo-39600, IDLE: Remove duplicated font names (GH-18430) Message-ID: https://github.com/python/cpython/commit/021a5694ede9d7be119f9ceb3ee7e8e518ec5002 commit: 021a5694ede9d7be119f9ceb3ee7e8e518ec5002 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T13:38:30-08:00 summary: bpo-39600, IDLE: Remove duplicated font names (GH-18430) In the font configuration window, remove duplicated font names. (cherry picked from commit ed335cf53b5d4bca9a08c9b83ba684ba17be0f10) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 22359735874d1..7b844f00e7736 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -607,8 +607,9 @@ def load_font_cfg(self): font_bold = configured_font[2]=='bold' # Set editor font selection list and font_name. - fonts = list(tkFont.families(self)) - fonts.sort() + fonts = tkFont.families(self) + # remove duplicated names and sort + fonts = sorted(set(fonts)) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) diff --git a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst new file mode 100644 index 0000000000000..102aa75f5813e --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst @@ -0,0 +1 @@ +In the font configuration window, remove duplicated font names. From webhook-mailer at python.org Mon Feb 10 16:39:47 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 21:39:47 -0000 Subject: [Python-checkins] bpo-39600, IDLE: Remove duplicated font names (GH-18430) Message-ID: https://github.com/python/cpython/commit/2e8097d1c7c04dd96061ec1498cfa088bce9085b commit: 2e8097d1c7c04dd96061ec1498cfa088bce9085b branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T13:39:43-08:00 summary: bpo-39600, IDLE: Remove duplicated font names (GH-18430) In the font configuration window, remove duplicated font names. (cherry picked from commit ed335cf53b5d4bca9a08c9b83ba684ba17be0f10) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 22359735874d1..7b844f00e7736 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -607,8 +607,9 @@ def load_font_cfg(self): font_bold = configured_font[2]=='bold' # Set editor font selection list and font_name. - fonts = list(tkFont.families(self)) - fonts.sort() + fonts = tkFont.families(self) + # remove duplicated names and sort + fonts = sorted(set(fonts)) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) diff --git a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst new file mode 100644 index 0000000000000..102aa75f5813e --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst @@ -0,0 +1 @@ +In the font configuration window, remove duplicated font names. From webhook-mailer at python.org Mon Feb 10 17:37:06 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:37:06 -0000 Subject: [Python-checkins] Improve grammar in the import system reference documentation (GH-18209) Message-ID: https://github.com/python/cpython/commit/13657368328f4e2320e4e3c0fe5ee88f5cbbfe1d commit: 13657368328f4e2320e4e3c0fe5ee88f5cbbfe1d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:36:58-08:00 summary: Improve grammar in the import system reference documentation (GH-18209) Replaced the period with a comma. Automerge-Triggered-By: @Mariatta (cherry picked from commit d47d0c8e9f2ca0f9f5d1bf0b35006a9a4d5ca684) Co-authored-by: Bonifacio de Oliveira files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 50a7562e3ae7a..0ba04e497e5c2 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -856,7 +856,7 @@ module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). To indicate to the import machinery that the spec represents a namespace -:term:`portion`. the path entry finder sets "loader" on the spec to +:term:`portion`, the path entry finder sets "loader" on the spec to ``None`` and "submodule_search_locations" to a list containing the portion. From webhook-mailer at python.org Mon Feb 10 17:37:51 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:37:51 -0000 Subject: [Python-checkins] Improve grammar in the import system reference documentation (GH-18209) Message-ID: https://github.com/python/cpython/commit/8ef9e6d59aedfd91cbd42b421c34a6c935ef7b25 commit: 8ef9e6d59aedfd91cbd42b421c34a6c935ef7b25 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:37:45-08:00 summary: Improve grammar in the import system reference documentation (GH-18209) Replaced the period with a comma. Automerge-Triggered-By: @Mariatta (cherry picked from commit d47d0c8e9f2ca0f9f5d1bf0b35006a9a4d5ca684) Co-authored-by: Bonifacio de Oliveira files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index c6f6d030d2ac3..1c98aab7d83aa 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -855,7 +855,7 @@ module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). To indicate to the import machinery that the spec represents a namespace -:term:`portion`. the path entry finder sets "loader" on the spec to +:term:`portion`, the path entry finder sets "loader" on the spec to ``None`` and "submodule_search_locations" to a list containing the portion. From webhook-mailer at python.org Mon Feb 10 17:50:31 2020 From: webhook-mailer at python.org (Roger Hurwitz) Date: Mon, 10 Feb 2020 22:50:31 -0000 Subject: [Python-checkins] bpo-39594: Fix typo in os.times documentation (GH-18443) Message-ID: https://github.com/python/cpython/commit/37c55b2b49a3acb7c56c9f6a5062bc6e4e35bc1c commit: 37c55b2b49a3acb7c56c9f6a5062bc6e4e35bc1c branch: master author: Roger Hurwitz committer: GitHub date: 2020-02-10T14:50:19-08:00 summary: bpo-39594: Fix typo in os.times documentation (GH-18443) There was an extra space in the url markup, causing the documentation not rendered properly. https://bugs.python.org/issue39594 files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index bfc03227e4ed2..b06a318c3d79d 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3912,10 +3912,8 @@ written in Python, such as a mail server's external command delivery program. See the Unix manual page :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN - ` - _ on Windows. - On Windows, only :attr:`user` and :attr:`system` are known; the other - attributes are zero. + `_ + on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. .. availability:: Unix, Windows. From webhook-mailer at python.org Mon Feb 10 17:51:05 2020 From: webhook-mailer at python.org (Tim D. Smith) Date: Mon, 10 Feb 2020 22:51:05 -0000 Subject: [Python-checkins] bpo-13826: Clarify Popen constructor example (GH-18438) Message-ID: https://github.com/python/cpython/commit/95d024d585bd3ed627437a2f0cbc783c8a014c8a commit: 95d024d585bd3ed627437a2f0cbc783c8a014c8a branch: master author: Tim D. Smith committer: GitHub date: 2020-02-10T14:51:01-08:00 summary: bpo-13826: Clarify Popen constructor example (GH-18438) Clarifies that the use of `shlex.split` is more instructive than normative, and provides a simpler example. https://bugs.python.org/issue13826 files: M Doc/library/subprocess.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 74857480360dc..24497a2edd357 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -356,14 +356,20 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. + An example of passing some arguments to an external program + as a sequence is:: + + Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."]) + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. .. note:: - :meth:`shlex.split` can be useful when determining the correct - tokenization for *args*, especially in complex cases:: + It may not be obvious how to break a shell command into a sequence of arguments, + especially in complex cases. :meth:`shlex.split` can illustrate how to + determine the correct tokenization for *args*:: >>> import shlex, subprocess >>> command_line = input() From webhook-mailer at python.org Mon Feb 10 17:55:40 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:55:40 -0000 Subject: [Python-checkins] bpo-39594: Fix typo in os.times documentation (GH-18443) Message-ID: https://github.com/python/cpython/commit/a12effde34e7cf7ced767ca232cc2ed95e62cd46 commit: a12effde34e7cf7ced767ca232cc2ed95e62cd46 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:55:35-08:00 summary: bpo-39594: Fix typo in os.times documentation (GH-18443) There was an extra space in the url markup, causing the documentation not rendered properly. https://bugs.python.org/issue39594 (cherry picked from commit 37c55b2b49a3acb7c56c9f6a5062bc6e4e35bc1c) Co-authored-by: Roger Hurwitz files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 3a5a5f97b93a6..e23500d43391f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3603,10 +3603,8 @@ written in Python, such as a mail server's external command delivery program. See the Unix manual page :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN - ` - _ on Windows. - On Windows, only :attr:`user` and :attr:`system` are known; the other - attributes are zero. + `_ + on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. .. availability:: Unix, Windows. From webhook-mailer at python.org Mon Feb 10 17:56:19 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:56:19 -0000 Subject: [Python-checkins] bpo-13826: Clarify Popen constructor example (GH-18438) Message-ID: https://github.com/python/cpython/commit/78982f94faaa05e363d15b49ec230d11a4d8bebd commit: 78982f94faaa05e363d15b49ec230d11a4d8bebd branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:56:14-08:00 summary: bpo-13826: Clarify Popen constructor example (GH-18438) Clarifies that the use of `shlex.split` is more instructive than normative, and provides a simpler example. https://bugs.python.org/issue13826 (cherry picked from commit 95d024d585bd3ed627437a2f0cbc783c8a014c8a) Co-authored-by: Tim D. Smith files: M Doc/library/subprocess.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index f9ace66295215..69737820f37d8 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -354,14 +354,20 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. + An example of passing some arguments to an external program + as a sequence is:: + + Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."]) + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. .. note:: - :meth:`shlex.split` can be useful when determining the correct - tokenization for *args*, especially in complex cases:: + It may not be obvious how to break a shell command into a sequence of arguments, + especially in complex cases. :meth:`shlex.split` can illustrate how to + determine the correct tokenization for *args*:: >>> import shlex, subprocess >>> command_line = input() From webhook-mailer at python.org Mon Feb 10 17:57:10 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:57:10 -0000 Subject: [Python-checkins] bpo-13826: Clarify Popen constructor example (GH-18438) Message-ID: https://github.com/python/cpython/commit/e6690f6cd1b0c2bd5804bad30239a4070f79102c commit: e6690f6cd1b0c2bd5804bad30239a4070f79102c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:57:06-08:00 summary: bpo-13826: Clarify Popen constructor example (GH-18438) Clarifies that the use of `shlex.split` is more instructive than normative, and provides a simpler example. https://bugs.python.org/issue13826 (cherry picked from commit 95d024d585bd3ed627437a2f0cbc783c8a014c8a) Co-authored-by: Tim D. Smith files: M Doc/library/subprocess.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ea12cd133a6ff..cce7da1c9b166 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -355,14 +355,20 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. + An example of passing some arguments to an external program + as a sequence is:: + + Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."]) + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. .. note:: - :meth:`shlex.split` can be useful when determining the correct - tokenization for *args*, especially in complex cases:: + It may not be obvious how to break a shell command into a sequence of arguments, + especially in complex cases. :meth:`shlex.split` can illustrate how to + determine the correct tokenization for *args*:: >>> import shlex, subprocess >>> command_line = input() From webhook-mailer at python.org Mon Feb 10 17:57:18 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 10 Feb 2020 22:57:18 -0000 Subject: [Python-checkins] bpo-39594: Fix typo in os.times documentation (GH-18443) Message-ID: https://github.com/python/cpython/commit/4d4301782cbc789eedc5b76741d1028df579cfa5 commit: 4d4301782cbc789eedc5b76741d1028df579cfa5 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T14:57:14-08:00 summary: bpo-39594: Fix typo in os.times documentation (GH-18443) There was an extra space in the url markup, causing the documentation not rendered properly. https://bugs.python.org/issue39594 (cherry picked from commit 37c55b2b49a3acb7c56c9f6a5062bc6e4e35bc1c) Co-authored-by: Roger Hurwitz files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 3a828c5e08563..0d8df34c345c4 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3898,10 +3898,8 @@ written in Python, such as a mail server's external command delivery program. See the Unix manual page :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN - ` - _ on Windows. - On Windows, only :attr:`user` and :attr:`system` are known; the other - attributes are zero. + `_ + on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. .. availability:: Unix, Windows. From webhook-mailer at python.org Mon Feb 10 18:32:23 2020 From: webhook-mailer at python.org (Eric Wieser) Date: Mon, 10 Feb 2020 23:32:23 -0000 Subject: [Python-checkins] Correct the documented default encoding (GH-18429) Message-ID: https://github.com/python/cpython/commit/bf15d5b775c31e65584926998ff141edc75226d4 commit: bf15d5b775c31e65584926998ff141edc75226d4 branch: master author: Eric Wieser committer: GitHub date: 2020-02-10T15:32:18-08:00 summary: Correct the documented default encoding (GH-18429) >From the source for `PyUnicode_Decode`, the implementation is: ``` if (encoding == NULL) { return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL); } ``` which is pretty clearly not defaulting to ASCII. --- I assume this needs neither a news entry nor bpo link. files: M Doc/c-api/unicode.rst diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 77f123cf1f2c0..96d77c4084132 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -978,7 +978,7 @@ have the same semantics as the ones of the built-in :func:`str` string object constructor. Setting encoding to ``NULL`` causes the default encoding to be used -which is ASCII. The file system calls should use +which is UTF-8. The file system calls should use :c:func:`PyUnicode_FSConverter` for encoding file names. This uses the variable :c:data:`Py_FileSystemDefaultEncoding` internally. This variable should be treated as read-only: on some systems, it will be a From webhook-mailer at python.org Mon Feb 10 18:51:05 2020 From: webhook-mailer at python.org (Ogi Moore) Date: Mon, 10 Feb 2020 23:51:05 -0000 Subject: [Python-checkins] bpo-39417: Fix broken link to guide to building venvs (GH-18432) Message-ID: https://github.com/python/cpython/commit/c4a65ed7fe342bd18b5a5b0eea3470dc4fc31160 commit: c4a65ed7fe342bd18b5a5b0eea3470dc4fc31160 branch: master author: Ogi Moore committer: GitHub date: 2020-02-10T15:51:01-08:00 summary: bpo-39417: Fix broken link to guide to building venvs (GH-18432) files: M Doc/library/venv.rst diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index d778486b0a5d9..8abadc4df3cac 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -27,7 +27,7 @@ See :pep:`405` for more information about Python virtual environments. .. seealso:: `Python Packaging User Guide: Creating and using virtual environments - `__ + `__ Creating virtual environments From webhook-mailer at python.org Mon Feb 10 18:58:29 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 10 Feb 2020 23:58:29 -0000 Subject: [Python-checkins] bpo-38325: Skip non-BMP tests of test_winconsoleio (GH-18448) Message-ID: https://github.com/python/cpython/commit/038770edc4680e9a3dc39bacb35a8358034fb901 commit: 038770edc4680e9a3dc39bacb35a8358034fb901 branch: master author: Victor Stinner committer: GitHub date: 2020-02-11T00:58:23+01:00 summary: bpo-38325: Skip non-BMP tests of test_winconsoleio (GH-18448) Skip tests on non-BMP characters of test_winconsoleio. files: A Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst M Lib/test/test_winconsoleio.py diff --git a/Lib/test/test_winconsoleio.py b/Lib/test/test_winconsoleio.py index 9a61e48881d90..a44f7bbd27b70 100644 --- a/Lib/test/test_winconsoleio.py +++ b/Lib/test/test_winconsoleio.py @@ -144,6 +144,10 @@ def test_input(self): self.assertStdinRoundTrip('??????') # Combining characters self.assertStdinRoundTrip('A?B ??AA?') + + # bpo-38325 + @unittest.skipIf(True, "Handling Non-BMP characters is broken") + def test_input_nonbmp(self): # Non-BMP self.assertStdinRoundTrip('\U00100000\U0010ffff\U0010fffd') @@ -163,6 +167,8 @@ def test_partial_reads(self): self.assertEqual(actual, expected, 'stdin.read({})'.format(read_count)) + # bpo-38325 + @unittest.skipIf(True, "Handling Non-BMP characters is broken") def test_partial_surrogate_reads(self): # Test that reading less than 1 full character works when stdin # contains surrogate pairs that cannot be decoded to UTF-8 without diff --git a/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst b/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst new file mode 100644 index 0000000000000..7503379915260 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst @@ -0,0 +1 @@ +Skip tests on non-BMP characters of test_winconsoleio. From webhook-mailer at python.org Mon Feb 10 20:09:06 2020 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 11 Feb 2020 01:09:06 -0000 Subject: [Python-checkins] bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Message-ID: https://github.com/python/cpython/commit/96ce22706735779cf8cc46eaaa5ac61359364b5a commit: 96ce22706735779cf8cc46eaaa5ac61359364b5a branch: master author: Terry Jan Reedy committer: GitHub date: 2020-02-10T20:08:58-05:00 summary: bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Complete previous patch. files: M Lib/idlelib/NEWS.txt M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index d57ba7e6bac90..838120964b2d8 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2020-10-05? ====================================== +bpo-39600: Remove duplicate font names from configuration list. + bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` or shell restart occurs. Patch by Zackery Spytz. diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 7b844f00e7736..9d5c2cde04b24 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -606,10 +606,8 @@ def load_font_cfg(self): font_size = configured_font[1] font_bold = configured_font[2]=='bold' - # Set editor font selection list and font_name. - fonts = tkFont.families(self) - # remove duplicated names and sort - fonts = sorted(set(fonts)) + # Set sorted no-duplicate editor font selection list and font_name. + fonts = sorted(set(tkFont.families(self))) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) From webhook-mailer at python.org Mon Feb 10 20:27:39 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 11 Feb 2020 01:27:39 -0000 Subject: [Python-checkins] bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Message-ID: https://github.com/python/cpython/commit/c372f9b9e758a22608b8df33423b7413d224fdad commit: c372f9b9e758a22608b8df33423b7413d224fdad branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T17:27:31-08:00 summary: bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Complete previous patch. (cherry picked from commit 96ce22706735779cf8cc46eaaa5ac61359364b5a) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/NEWS.txt M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 1fc9e0f3090f6..9cf563401259d 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39600: Remove duplicate font names from configuration list. + bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` or shell restart occurs. Patch by Zackery Spytz. diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 7b844f00e7736..9d5c2cde04b24 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -606,10 +606,8 @@ def load_font_cfg(self): font_size = configured_font[1] font_bold = configured_font[2]=='bold' - # Set editor font selection list and font_name. - fonts = tkFont.families(self) - # remove duplicated names and sort - fonts = sorted(set(fonts)) + # Set sorted no-duplicate editor font selection list and font_name. + fonts = sorted(set(tkFont.families(self))) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) From webhook-mailer at python.org Mon Feb 10 20:28:08 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 11 Feb 2020 01:28:08 -0000 Subject: [Python-checkins] bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Message-ID: https://github.com/python/cpython/commit/32c88407d24a700946e1a6429cd5ca616cb3a810 commit: 32c88407d24a700946e1a6429cd5ca616cb3a810 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T17:28:03-08:00 summary: bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449) Complete previous patch. (cherry picked from commit 96ce22706735779cf8cc46eaaa5ac61359364b5a) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/NEWS.txt M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 2afbe82277ee9..3b1168693c4b5 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39600: Remove duplicate font names from configuration list. + bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` or shell restart occurs. Patch by Zackery Spytz. diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 7b844f00e7736..9d5c2cde04b24 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -606,10 +606,8 @@ def load_font_cfg(self): font_size = configured_font[1] font_bold = configured_font[2]=='bold' - # Set editor font selection list and font_name. - fonts = tkFont.families(self) - # remove duplicated names and sort - fonts = sorted(set(fonts)) + # Set sorted no-duplicate editor font selection list and font_name. + fonts = sorted(set(tkFont.families(self))) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) From webhook-mailer at python.org Tue Feb 11 01:56:17 2020 From: webhook-mailer at python.org (Roger Hurwitz) Date: Tue, 11 Feb 2020 06:56:17 -0000 Subject: [Python-checkins] bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Message-ID: https://github.com/python/cpython/commit/4eb9f4313cfaea6a9611221024a1c54f5662cc37 commit: 4eb9f4313cfaea6a9611221024a1c54f5662cc37 branch: master author: Roger Hurwitz committer: GitHub date: 2020-02-10T22:56:02-08:00 summary: bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Reflecting changes to the code, removed weakref.ReferenceError from weakref.rst and exceptions.rst. Issue submitter provided evidence that the `weakref.ReferenceError` alias for `ReferenceError` was removed from the code in 2007. Working with @gvanrossum at PyCascades CPython sprint we looked at the code and confirmed that `weakref.ReferenceError` was no longer in `weakref.py`. Based on that analysis I removed references `weakref.ReferenceError` from the two documents where it was still being referenced: `weakref.rst` and `exceptions.rst`. https://bugs.python.org/issue38374 files: M Doc/c-api/exceptions.rst M Doc/library/weakref.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 2edcbf788d2ad..b7175166a6f00 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -983,9 +983,6 @@ Notes: This is a base class for other standard exceptions. (2) - This is the same as :exc:`weakref.ReferenceError`. - -(3) Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index c3519e45beb6b..8636e76c52a42 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -327,12 +327,6 @@ objects. types. -.. exception:: ReferenceError - - Exception raised when a proxy object is used but the underlying object has been - collected. This is the same as the standard :exc:`ReferenceError` exception. - - .. seealso:: :pep:`205` - Weak References From webhook-mailer at python.org Tue Feb 11 02:01:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 11 Feb 2020 07:01:28 -0000 Subject: [Python-checkins] bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Message-ID: https://github.com/python/cpython/commit/fcfc3c8fbe3942e8deef15acc25bfa371db7766a commit: fcfc3c8fbe3942e8deef15acc25bfa371db7766a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T23:01:23-08:00 summary: bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Reflecting changes to the code, removed weakref.ReferenceError from weakref.rst and exceptions.rst. Issue submitter provided evidence that the `weakref.ReferenceError` alias for `ReferenceError` was removed from the code in 2007. Working with @gvanrossum at PyCascades CPython sprint we looked at the code and confirmed that `weakref.ReferenceError` was no longer in `weakref.py`. Based on that analysis I removed references `weakref.ReferenceError` from the two documents where it was still being referenced: `weakref.rst` and `exceptions.rst`. https://bugs.python.org/issue38374 (cherry picked from commit 4eb9f4313cfaea6a9611221024a1c54f5662cc37) Co-authored-by: Roger Hurwitz files: M Doc/c-api/exceptions.rst M Doc/library/weakref.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index a53c49a211036..2f58149c6cd14 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -968,9 +968,6 @@ Notes: This is a base class for other standard exceptions. (2) - This is the same as :exc:`weakref.ReferenceError`. - -(3) Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 8d8a0b5df2687..93efcef1501b4 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -323,12 +323,6 @@ objects. types. -.. exception:: ReferenceError - - Exception raised when a proxy object is used but the underlying object has been - collected. This is the same as the standard :exc:`ReferenceError` exception. - - .. seealso:: :pep:`205` - Weak References From webhook-mailer at python.org Tue Feb 11 02:02:06 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 11 Feb 2020 07:02:06 -0000 Subject: [Python-checkins] bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Message-ID: https://github.com/python/cpython/commit/3f8d181446aa9d87e3773896c2695161ea8f6e42 commit: 3f8d181446aa9d87e3773896c2695161ea8f6e42 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-10T23:02:01-08:00 summary: bpo-38374: Remove weakref.ReferenceError from docs (GH-18452) Reflecting changes to the code, removed weakref.ReferenceError from weakref.rst and exceptions.rst. Issue submitter provided evidence that the `weakref.ReferenceError` alias for `ReferenceError` was removed from the code in 2007. Working with @gvanrossum at PyCascades CPython sprint we looked at the code and confirmed that `weakref.ReferenceError` was no longer in `weakref.py`. Based on that analysis I removed references `weakref.ReferenceError` from the two documents where it was still being referenced: `weakref.rst` and `exceptions.rst`. https://bugs.python.org/issue38374 (cherry picked from commit 4eb9f4313cfaea6a9611221024a1c54f5662cc37) Co-authored-by: Roger Hurwitz files: M Doc/c-api/exceptions.rst M Doc/library/weakref.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c7ba74cc8d587..7300c802e0817 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -971,9 +971,6 @@ Notes: This is a base class for other standard exceptions. (2) - This is the same as :exc:`weakref.ReferenceError`. - -(3) Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index b3c8e35455331..2dbe5e33bd011 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -327,12 +327,6 @@ objects. types. -.. exception:: ReferenceError - - Exception raised when a proxy object is used but the underlying object has been - collected. This is the same as the standard :exc:`ReferenceError` exception. - - .. seealso:: :pep:`205` - Weak References From webhook-mailer at python.org Tue Feb 11 06:16:46 2020 From: webhook-mailer at python.org (Hai Shi) Date: Tue, 11 Feb 2020 11:16:46 -0000 Subject: [Python-checkins] bpo-1635741: Port _codecs extension module to multiphase initialization (PEP 489) (GH-18065) Message-ID: https://github.com/python/cpython/commit/1ea45ae257971ee7b648e3b031603a31fc059f81 commit: 1ea45ae257971ee7b648e3b031603a31fc059f81 branch: master author: Hai Shi committer: GitHub date: 2020-02-11T03:16:38-08:00 summary: bpo-1635741: Port _codecs extension module to multiphase initialization (PEP 489) (GH-18065) https://bugs.python.org/issue1635741 files: A Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjsfm.rst M Modules/_codecsmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjsfm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjsfm.rst new file mode 100644 index 0000000000000..10fc23bcfa117 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjsfm.rst @@ -0,0 +1 @@ +Port _codecs extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index a8ffb699557ab..952072102d5d8 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -1039,13 +1039,17 @@ static PyMethodDef _codecs_functions[] = { {NULL, NULL} /* sentinel */ }; +static PyModuleDef_Slot _codecs_slots[] = { + {0, NULL} +}; + static struct PyModuleDef codecsmodule = { PyModuleDef_HEAD_INIT, "_codecs", NULL, - -1, + 0, _codecs_functions, - NULL, + _codecs_slots, NULL, NULL, NULL @@ -1054,5 +1058,5 @@ static struct PyModuleDef codecsmodule = { PyMODINIT_FUNC PyInit__codecs(void) { - return PyModule_Create(&codecsmodule); + return PyModuleDef_Init(&codecsmodule); } From webhook-mailer at python.org Tue Feb 11 08:29:38 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 11 Feb 2020 13:29:38 -0000 Subject: [Python-checkins] bpo-39500: Document PyUnicode_IsIdentifier() function (GH-18397) Message-ID: https://github.com/python/cpython/commit/f3e7ea5b8c220cd63101e419d529c8563f9c6115 commit: f3e7ea5b8c220cd63101e419d529c8563f9c6115 branch: master author: Victor Stinner committer: GitHub date: 2020-02-11T14:29:33+01:00 summary: bpo-39500: Document PyUnicode_IsIdentifier() function (GH-18397) PyUnicode_IsIdentifier() does not call Py_FatalError() anymore if the string is not ready. files: A Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst M Doc/c-api/unicode.rst M Objects/unicodeobject.c M Parser/tokenizer.c diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 96d77c4084132..b1787ed1ce89c 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -240,6 +240,16 @@ access internal read-only data of Unicode objects: :c:func:`PyUnicode_nBYTE_DATA` family of macros. +.. c:function:: int PyUnicode_IsIdentifier(PyObject *o) + + Return ``1`` if the string is a valid identifier according to the language + definition, section :ref:`identifiers`. Return ``0`` otherwise. + + .. versionchanged:: 3.9 + The function does not call :c:func:`Py_FatalError` anymore if the string + is not ready. + + Unicode Character Properties """""""""""""""""""""""""""" diff --git a/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst b/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst new file mode 100644 index 0000000000000..2ca359f0ec11a --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst @@ -0,0 +1,2 @@ +:c:func:`PyUnicode_IsIdentifier` does not call :c:func:`Py_FatalError` +anymore if the string is not ready. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fd08ddbf57434..aa874f2a12d29 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -12198,22 +12198,33 @@ unicode_isnumeric_impl(PyObject *self) int PyUnicode_IsIdentifier(PyObject *self) { - int kind; - void *data; Py_ssize_t i; - Py_UCS4 first; + int ready = PyUnicode_IS_READY(self); - if (PyUnicode_READY(self) == -1) { - Py_FatalError("identifier not ready"); + Py_ssize_t len = ready ? PyUnicode_GET_LENGTH(self) : PyUnicode_GET_SIZE(self); + if (len == 0) { + /* an empty string is not a valid identifier */ return 0; } - /* Special case for empty strings */ - if (PyUnicode_GET_LENGTH(self) == 0) - return 0; - kind = PyUnicode_KIND(self); - data = PyUnicode_DATA(self); + int kind; + void *data; + wchar_t *wstr; + if (ready) { + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + } + else { + wstr = _PyUnicode_WSTR(self); + } + Py_UCS4 ch; + if (ready) { + ch = PyUnicode_READ(kind, data, 0); + } + else { + ch = wstr[0]; + } /* PEP 3131 says that the first character must be in XID_Start and subsequent characters in XID_Continue, and for the ASCII range, the 2.x rules apply (i.e @@ -12222,13 +12233,21 @@ PyUnicode_IsIdentifier(PyObject *self) definition of XID_Start and XID_Continue, it is sufficient to check just for these, except that _ must be allowed as starting an identifier. */ - first = PyUnicode_READ(kind, data, 0); - if (!_PyUnicode_IsXidStart(first) && first != 0x5F /* LOW LINE */) + if (!_PyUnicode_IsXidStart(ch) && ch != 0x5F /* LOW LINE */) { return 0; + } - for (i = 1; i < PyUnicode_GET_LENGTH(self); i++) - if (!_PyUnicode_IsXidContinue(PyUnicode_READ(kind, data, i))) + for (i = 1; i < len; i++) { + if (ready) { + ch = PyUnicode_READ(kind, data, i); + } + else { + ch = wstr[i]; + } + if (!_PyUnicode_IsXidContinue(ch)) { return 0; + } + } return 1; } diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index f73c32684c7b7..c37cd927df5a4 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1079,8 +1079,9 @@ verify_identifier(struct tok_state *tok) } result = PyUnicode_IsIdentifier(s); Py_DECREF(s); - if (result == 0) + if (result == 0) { tok->done = E_IDENTIFIER; + } return result; } From webhook-mailer at python.org Tue Feb 11 10:32:48 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 11 Feb 2020 15:32:48 -0000 Subject: [Python-checkins] bpo-39299: Add more tests for mimetypes and its cli. (GH-17949) Message-ID: https://github.com/python/cpython/commit/d3f9fb2d28ceedb0a17a703338424ff284a578c8 commit: d3f9fb2d28ceedb0a17a703338424ff284a578c8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T07:32:40-08:00 summary: bpo-39299: Add more tests for mimetypes and its cli. (GH-17949) * Add tests for case insensitive check of types and extensions as fallback. * Add tests for data url with no comma. * Add tests for read_mime_types. * Add tests for the mimetypes cli and refactor __main__ code to private function. * Restore mimetypes.knownfiles value at the end of the test. (cherry picked from commit d8efc1495194228c3a4cd472200275d6491d8e2d) Co-authored-by: Karthikeyan Singaravelan files: M Lib/mimetypes.py M Lib/test/test_mimetypes.py diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 9b42bf6dd2ca7..f33b658f10e5e 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -563,7 +563,7 @@ def _default_mime_types(): _default_mime_types() -if __name__ == '__main__': +def _main(): import getopt USAGE = """\ @@ -607,3 +607,7 @@ def usage(code, msg=''): guess, encoding = guess_type(gtype, strict) if not guess: print("I don't know anything about type", gtype) else: print('type:', guess, 'encoding:', encoding) + + +if __name__ == '__main__': + _main() diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index a5a06b189dec4..9cac6ce0225e1 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -8,10 +8,20 @@ from test import support from platform import win32_edition -# Tell it we don't know about external files: -mimetypes.knownfiles = [] -mimetypes.inited = False -mimetypes._default_mime_types() + +def setUpModule(): + global knownfiles + knownfiles = mimetypes.knownfiles + + # Tell it we don't know about external files: + mimetypes.knownfiles = [] + mimetypes.inited = False + mimetypes._default_mime_types() + + +def tearDownModule(): + # Restore knownfiles to its initial state + mimetypes.knownfiles = knownfiles class MimeTypesTestCase(unittest.TestCase): @@ -21,6 +31,7 @@ def setUp(self): def test_default_data(self): eq = self.assertEqual eq(self.db.guess_type("foo.html"), ("text/html", None)) + eq(self.db.guess_type("foo.HTML"), ("text/html", None)) eq(self.db.guess_type("foo.tgz"), ("application/x-tar", "gzip")) eq(self.db.guess_type("foo.tar.gz"), ("application/x-tar", "gzip")) eq(self.db.guess_type("foo.tar.Z"), ("application/x-tar", "compress")) @@ -30,6 +41,7 @@ def test_default_data(self): def test_data_urls(self): eq = self.assertEqual guess_type = self.db.guess_type + eq(guess_type("data:invalidDataWithoutComma"), (None, None)) eq(guess_type("data:,thisIsTextPlain"), ("text/plain", None)) eq(guess_type("data:;base64,thisIsTextPlain"), ("text/plain", None)) eq(guess_type("data:text/x-foo,thisIsTextXFoo"), ("text/x-foo", None)) @@ -42,6 +54,19 @@ def test_file_parsing(self): ("x-application/x-unittest", None)) eq(self.db.guess_extension("x-application/x-unittest"), ".pyunit") + def test_read_mime_types(self): + eq = self.assertEqual + + # Unreadable file returns None + self.assertIsNone(mimetypes.read_mime_types("non-existent")) + + with support.temp_dir() as directory: + data = "x-application/x-unittest pyunit\n" + file = pathlib.Path(directory, "sample.mimetype") + file.write_text(data) + mime_dict = mimetypes.read_mime_types(file) + eq(mime_dict[".pyunit"], "x-application/x-unittest") + def test_non_standard_types(self): eq = self.assertEqual # First try strict @@ -49,7 +74,10 @@ def test_non_standard_types(self): eq(self.db.guess_extension('image/jpg', strict=True), None) # And then non-strict eq(self.db.guess_type('foo.xul', strict=False), ('text/xul', None)) + eq(self.db.guess_type('foo.XUL', strict=False), ('text/xul', None)) + eq(self.db.guess_type('foo.invalid', strict=False), (None, None)) eq(self.db.guess_extension('image/jpg', strict=False), '.jpg') + eq(self.db.guess_extension('image/JPG', strict=False), '.jpg') def test_filename_with_url_delimiters(self): # bpo-38449: URL delimiters cases should be handled also. @@ -200,5 +228,53 @@ def test__all__(self): support.check__all__(self, mimetypes) +class MimetypesCliTestCase(unittest.TestCase): + + def mimetypes_cmd(self, *args, **kwargs): + support.patch(self, sys, "argv", [sys.executable, *args]) + with support.captured_stdout() as output: + mimetypes._main() + return output.getvalue().strip() + + def test_help_option(self): + support.patch(self, sys, "argv", [sys.executable, "-h"]) + with support.captured_stdout() as output: + with self.assertRaises(SystemExit) as cm: + mimetypes._main() + + self.assertIn("Usage: mimetypes.py", output.getvalue()) + self.assertEqual(cm.exception.code, 0) + + def test_invalid_option(self): + support.patch(self, sys, "argv", [sys.executable, "--invalid"]) + with support.captured_stdout() as output: + with self.assertRaises(SystemExit) as cm: + mimetypes._main() + + self.assertIn("Usage: mimetypes.py", output.getvalue()) + self.assertEqual(cm.exception.code, 1) + + def test_guess_extension(self): + eq = self.assertEqual + + extension = self.mimetypes_cmd("-l", "-e", "image/jpg") + eq(extension, ".jpg") + + extension = self.mimetypes_cmd("-e", "image/jpg") + eq(extension, "I don't know anything about type image/jpg") + + extension = self.mimetypes_cmd("-e", "image/jpeg") + eq(extension, ".jpg") + + def test_guess_type(self): + eq = self.assertEqual + + type_info = self.mimetypes_cmd("-l", "foo.pic") + eq(type_info, "type: image/pict encoding: None") + + type_info = self.mimetypes_cmd("foo.pic") + eq(type_info, "I don't know anything about type foo.pic") + + if __name__ == "__main__": unittest.main() From webhook-mailer at python.org Tue Feb 11 11:47:03 2020 From: webhook-mailer at python.org (Petr Viktorin) Date: Tue, 11 Feb 2020 16:47:03 -0000 Subject: [Python-checkins] bpo-39245: Switch to public API for Vectorcall (GH-18460) Message-ID: https://github.com/python/cpython/commit/ffd9753a944916ced659b2c77aebe66a6c9fbab5 commit: ffd9753a944916ced659b2c77aebe66a6c9fbab5 branch: master author: Petr Viktorin committer: GitHub date: 2020-02-11T17:46:57+01:00 summary: bpo-39245: Switch to public API for Vectorcall (GH-18460) The bulk of this patch was generated automatically with: for name in \ PyObject_Vectorcall \ Py_TPFLAGS_HAVE_VECTORCALL \ PyObject_VectorcallMethod \ PyVectorcall_Function \ PyObject_CallOneArg \ PyObject_CallMethodNoArgs \ PyObject_CallMethodOneArg \ ; do echo $name git grep -lwz _$name | xargs -0 sed -i "s/\b_$name\b/$name/g" done old=_PyObject_FastCallDict new=PyObject_VectorcallDict git grep -lwz $old | xargs -0 sed -i "s/\b$old\b/$new/g" and then cleaned up: - Revert changes to in docs & news - Revert changes to backcompat defines in headers - Nudge misaligned comments files: M Include/cpython/abstract.h M Lib/test/test_call.py M Modules/_asynciomodule.c M Modules/_collectionsmodule.c M Modules/_csv.c M Modules/_ctypes/callproc.c M Modules/_elementtree.c M Modules/_functoolsmodule.c M Modules/_io/bufferedio.c M Modules/_io/iobase.c M Modules/_io/stringio.c M Modules/_io/textio.c M Modules/_json.c M Modules/_operator.c M Modules/_pickle.c M Modules/_posixsubprocess.c M Modules/_randommodule.c M Modules/_sqlite/cache.c M Modules/_sqlite/connection.c M Modules/_sqlite/cursor.c M Modules/_sqlite/microprotocols.c M Modules/_sre.c M Modules/_struct.c M Modules/_testcapimodule.c M Modules/_xxtestfuzz/fuzzer.c M Modules/cjkcodecs/cjkcodecs.h M Modules/cjkcodecs/multibytecodec.c M Modules/gcmodule.c M Modules/itertoolsmodule.c M Modules/pyexpat.c M Objects/abstract.c M Objects/bytearrayobject.c M Objects/bytesobject.c M Objects/call.c M Objects/classobject.c M Objects/descrobject.c M Objects/dictobject.c M Objects/fileobject.c M Objects/floatobject.c M Objects/funcobject.c M Objects/genobject.c M Objects/listobject.c M Objects/longobject.c M Objects/memoryobject.c M Objects/methodobject.c M Objects/moduleobject.c M Objects/typeobject.c M Objects/unicodeobject.c M Objects/weakrefobject.c M Python/_warnings.c M Python/bltinmodule.c M Python/ceval.c M Python/codecs.c M Python/errors.c M Python/import.c M Python/sysmodule.c diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 76eaedfc4b72b..c0b0182fd5d36 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -67,7 +67,7 @@ PyVectorcall_Function(PyObject *callable) { assert(callable != NULL); PyTypeObject *tp = Py_TYPE(callable); - if (!PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { return NULL; } assert(PyCallable_Check(callable)); @@ -178,7 +178,7 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( static inline PyObject * PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) { - return _PyObject_VectorcallMethod(name, &self, + return PyObject_VectorcallMethod(name, &self, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } @@ -187,7 +187,7 @@ PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) { assert(arg != NULL); PyObject *args[2] = {self, arg}; - return _PyObject_VectorcallMethod(name, args, + return PyObject_VectorcallMethod(name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index d178aa4ec2bd2..b3077ad1d1cb8 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -468,7 +468,7 @@ def test_fastcall(self): self.check_result(result, expected) def test_vectorcall_dict(self): - # Test _PyObject_FastCallDict() + # Test PyObject_VectorcallDict() for func, args, expected in self.CALLS_POSARGS: with self.subTest(func=func, args=args): @@ -487,7 +487,7 @@ def test_vectorcall_dict(self): self.check_result(result, expected) def test_vectorcall(self): - # Test _PyObject_Vectorcall() + # Test PyObject_Vectorcall() for func, args, expected in self.CALLS_POSARGS: with self.subTest(func=func, args=args): @@ -594,7 +594,7 @@ def test_vectorcall(self): # 1. vectorcall using PyVectorcall_Call() # (only for objects that support vectorcall directly) # 2. normal call - # 3. vectorcall using _PyObject_Vectorcall() + # 3. vectorcall using PyObject_Vectorcall() # 4. call as bound method # 5. call using functools.partial diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2e293757fb731..5aea74332c5ef 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -142,7 +142,7 @@ _is_coroutine(PyObject *coro) Do this check after 'future_init()'; in case we need to raise an error, __del__ needs a properly initialized object. */ - PyObject *res = _PyObject_CallOneArg(asyncio_iscoroutine_func, coro); + PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro); if (res == NULL) { return -1; } @@ -367,7 +367,7 @@ call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) } stack[nargs] = (PyObject *)ctx; - handle = _PyObject_Vectorcall(callable, stack, nargs, context_kwname); + handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname); Py_DECREF(callable); } @@ -1287,7 +1287,7 @@ static PyObject * _asyncio_Future__repr_info_impl(FutureObj *self) /*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ { - return _PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); + return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); } static PyObject * @@ -1363,7 +1363,7 @@ FutureObj_finalize(FutureObj *fut) func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); if (func != NULL) { - PyObject *res = _PyObject_CallOneArg(func, context); + PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { PyErr_WriteUnraisable(func); } @@ -2126,13 +2126,13 @@ _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) Py_DECREF(current_task_func); return NULL; } - ret = _PyObject_CallOneArg(current_task_func, loop); + ret = PyObject_CallOneArg(current_task_func, loop); Py_DECREF(current_task_func); Py_DECREF(loop); return ret; } else { - ret = _PyObject_CallOneArg(current_task_func, loop); + ret = PyObject_CallOneArg(current_task_func, loop); Py_DECREF(current_task_func); return ret; } @@ -2168,7 +2168,7 @@ _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) return NULL; } - res = _PyObject_CallOneArg(all_tasks_func, loop); + res = PyObject_CallOneArg(all_tasks_func, loop); Py_DECREF(all_tasks_func); return res; } @@ -2181,7 +2181,7 @@ static PyObject * _asyncio_Task__repr_info_impl(TaskObj *self) /*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ { - return _PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self); + return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self); } /*[clinic input] @@ -2431,7 +2431,7 @@ TaskObj_finalize(TaskObj *task) func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); if (func != NULL) { - PyObject *res = _PyObject_CallOneArg(func, context); + PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { PyErr_WriteUnraisable(func); } @@ -2571,7 +2571,7 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) return NULL; } - PyObject *e = _PyObject_CallOneArg(et, msg); + PyObject *e = PyObject_CallOneArg(et, msg); Py_DECREF(msg); if (e == NULL) { return NULL; @@ -2841,7 +2841,7 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *stack[2]; stack[0] = wrapper; stack[1] = (PyObject *)task->task_context; - res = _PyObject_Vectorcall(add_cb, stack, 1, context_kwname); + res = PyObject_Vectorcall(add_cb, stack, 1, context_kwname); Py_DECREF(add_cb); Py_DECREF(wrapper); if (res == NULL) { diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 25e4c96943e46..057d40441835c 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -512,7 +512,7 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) return NULL; } if (old_deque->maxlen < 0) - result = _PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque); + result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque); else result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", deque, old_deque->maxlen, NULL); diff --git a/Modules/_csv.c b/Modules/_csv.c index 2d541bb3af8ea..42437728f2ed2 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -514,10 +514,10 @@ _call_dialect(PyObject *dialect_inst, PyObject *kwargs) { PyObject *type = (PyObject *)&Dialect_Type; if (dialect_inst) { - return _PyObject_FastCallDict(type, &dialect_inst, 1, kwargs); + return PyObject_VectorcallDict(type, &dialect_inst, 1, kwargs); } else { - return _PyObject_FastCallDict(type, NULL, 0, kwargs); + return PyObject_VectorcallDict(type, NULL, 0, kwargs); } } @@ -1240,7 +1240,7 @@ csv_writerow(WriterObj *self, PyObject *seq) if (line == NULL) { return NULL; } - result = _PyObject_CallOneArg(self->write, line); + result = PyObject_CallOneArg(self->write, line); Py_DECREF(line); return result; } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 65c6eb15a298b..5f29f95b128ff 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -945,7 +945,7 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) if (!checker || !retval) return retval; - v = _PyObject_CallOneArg(checker, retval); + v = PyObject_CallOneArg(checker, retval); if (v == NULL) _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); @@ -1138,7 +1138,7 @@ PyObject *_ctypes_callproc(PPROC pProc, if (argtypes && argtype_count > i) { PyObject *v; converter = PyTuple_GET_ITEM(argtypes, i); - v = _PyObject_CallOneArg(converter, arg); + v = PyObject_CallOneArg(converter, arg); if (v == NULL) { _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1); goto cleanup; @@ -1835,7 +1835,7 @@ pointer(PyObject *self, PyObject *arg) typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); if (typ) { - return _PyObject_CallOneArg(typ, arg); + return PyObject_CallOneArg(typ, arg); } else if (PyErr_Occurred()) { return NULL; @@ -1843,7 +1843,7 @@ pointer(PyObject *self, PyObject *arg) typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); if (typ == NULL) return NULL; - result = _PyObject_CallOneArg(typ, arg); + result = PyObject_CallOneArg(typ, arg); Py_DECREF(typ); return result; } diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index c096eab43ea6a..a04b295378e4f 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2671,7 +2671,7 @@ treebuilder_append_event(TreeBuilderObject *self, PyObject *action, PyObject *event = PyTuple_Pack(2, action, node); if (event == NULL) return -1; - res = _PyObject_CallOneArg(self->events_append, event); + res = PyObject_CallOneArg(self->events_append, event); Py_DECREF(event); if (res == NULL) return -1; @@ -2837,7 +2837,7 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) } if (self->comment_factory) { - comment = _PyObject_CallOneArg(self->comment_factory, text); + comment = PyObject_CallOneArg(self->comment_factory, text); if (!comment) return NULL; @@ -3179,7 +3179,7 @@ expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, if (errmsg == NULL) return; - error = _PyObject_CallOneArg(st->parseerror_obj, errmsg); + error = PyObject_CallOneArg(st->parseerror_obj, errmsg); Py_DECREF(errmsg); if (!error) return; @@ -3242,7 +3242,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, (TreeBuilderObject*) self->target, value ); else if (self->handle_data) - res = _PyObject_CallOneArg(self->handle_data, value); + res = PyObject_CallOneArg(self->handle_data, value); else res = NULL; Py_XDECREF(res); @@ -3353,7 +3353,7 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) - res = _PyObject_CallOneArg(self->handle_data, data); + res = PyObject_CallOneArg(self->handle_data, data); else res = NULL; @@ -3380,7 +3380,7 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) else if (self->handle_end) { tag = makeuniversal(self, tag_in); if (tag) { - res = _PyObject_CallOneArg(self->handle_end, tag); + res = PyObject_CallOneArg(self->handle_end, tag); Py_DECREF(tag); } } @@ -3467,7 +3467,7 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) if (!prefix) return; - res = _PyObject_CallOneArg(self->handle_end_ns, prefix); + res = PyObject_CallOneArg(self->handle_end_ns, prefix); Py_DECREF(prefix); } @@ -3499,7 +3499,7 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (!comment) return; - res = _PyObject_CallOneArg(self->handle_comment, comment); + res = PyObject_CallOneArg(self->handle_comment, comment); Py_XDECREF(res); Py_DECREF(comment); } diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 50d8c58e954f8..88c02d82dca0a 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -213,7 +213,7 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, static void partial_setvectorcall(partialobject *pto) { - if (_PyVectorcall_Function(pto->fn) == NULL) { + if (PyVectorcall_Function(pto->fn) == NULL) { /* Don't use vectorcall if the underlying function doesn't support it */ pto->vectorcall = NULL; } @@ -440,7 +440,7 @@ static PyTypeObject partial_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | - _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ partial_doc, /* tp_doc */ (traverseproc)partial_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index ddd17a2863c24..6f55577813c9f 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -461,7 +461,7 @@ static PyObject * buffered_simple_flush(buffered *self, PyObject *args) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush); } static int @@ -513,7 +513,7 @@ buffered_close(buffered *self, PyObject *args) } /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (!ENTER_BUFFERED(self)) return NULL; if (res == NULL) @@ -521,7 +521,7 @@ buffered_close(buffered *self, PyObject *args) else Py_DECREF(res); - res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close); + res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close); if (self->buffer) { PyMem_Free(self->buffer); @@ -545,7 +545,7 @@ buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) { PyObject *raw, *res; CHECK_INITIALIZED(self) - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); @@ -562,21 +562,21 @@ static PyObject * buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable); } static PyObject * buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable); } static PyObject * buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable); } static PyObject * @@ -599,14 +599,14 @@ static PyObject * buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno); } static PyObject * buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty); + return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty); } /* Forward decls */ @@ -670,7 +670,7 @@ _buffered_raw_tell(buffered *self) { Py_off_t n; PyObject *res; - res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell); + res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell); if (res == NULL) return -1; n = PyNumber_AsOff_t(res, PyExc_ValueError); @@ -1324,7 +1324,7 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos) goto end; Py_CLEAR(res); } - res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); + res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); if (res == NULL) goto end; /* Reset cached position */ @@ -1351,7 +1351,7 @@ buffered_iternext(buffered *self) line = _buffered_readline(self, -1); } else { - line = _PyObject_CallMethodNoArgs((PyObject *)self, + line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); if (line && !PyBytes_Check(line)) { PyErr_Format(PyExc_OSError, @@ -1470,7 +1470,7 @@ _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) raised (see issue #10956). */ do { - res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj); + res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj); } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); if (res == NULL) @@ -1569,7 +1569,7 @@ _bufferedreader_read_all(buffered *self) } /* Read until EOF or until read() would block. */ - data = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read); + data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read); if (data == NULL) goto cleanup; if (data != Py_None && !PyBytes_Check(data)) { @@ -1818,7 +1818,7 @@ _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len) */ do { errno = 0; - res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj); + res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj); errnum = errno; } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index d51fc944e1a62..1ff35648e550f 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -235,7 +235,7 @@ _io__IOBase_close_impl(PyObject *self) Py_RETURN_NONE; } - res = _PyObject_CallMethodNoArgs(self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs(self, _PyIO_str_flush); PyErr_Fetch(&exc, &val, &tb); rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); @@ -281,7 +281,7 @@ iobase_finalize(PyObject *self) finalization process. */ if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) PyErr_Clear(); - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close); /* Silencing I/O errors is bad, but printing spurious tracebacks is equally as bad, and potentially more frequent (because of shutdown issues). */ @@ -382,7 +382,7 @@ _io__IOBase_seekable_impl(PyObject *self) PyObject * _PyIOBase_check_seekable(PyObject *self, PyObject *args) { - PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_seekable); + PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_seekable); if (res == NULL) return NULL; if (res != Py_True) { @@ -415,7 +415,7 @@ _io__IOBase_readable_impl(PyObject *self) PyObject * _PyIOBase_check_readable(PyObject *self, PyObject *args) { - PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_readable); + PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_readable); if (res == NULL) return NULL; if (res != Py_True) { @@ -448,7 +448,7 @@ _io__IOBase_writable_impl(PyObject *self) PyObject * _PyIOBase_check_writable(PyObject *self, PyObject *args) { - PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_writable); + PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_writable); if (res == NULL) return NULL; if (res != Py_True) { @@ -477,7 +477,7 @@ iobase_enter(PyObject *self, PyObject *args) static PyObject * iobase_exit(PyObject *self, PyObject *args) { - return _PyObject_CallMethodNoArgs(self, _PyIO_str_close); + return PyObject_CallMethodNoArgs(self, _PyIO_str_close); } /* Lower-level APIs */ @@ -556,7 +556,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) PyObject *b; if (peek != NULL) { - PyObject *readahead = _PyObject_CallOneArg(peek, _PyLong_One); + PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_One); if (readahead == NULL) { /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR occurs so we needn't do it ourselves. */ @@ -655,7 +655,7 @@ iobase_iter(PyObject *self) static PyObject * iobase_iternext(PyObject *self) { - PyObject *line = _PyObject_CallMethodNoArgs(self, _PyIO_str_readline); + PyObject *line = PyObject_CallMethodNoArgs(self, _PyIO_str_readline); if (line == NULL) return NULL; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 89b29bb8fbb72..28d54e00d8a7b 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -408,7 +408,7 @@ stringio_iternext(stringio *self) } else { /* XXX is subclassing StringIO really supported? */ - line = _PyObject_CallMethodNoArgs((PyObject *)self, + line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index c4c56cb04def2..1d45c7ae2fab9 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -527,7 +527,7 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) unsigned long long flag; if (self->decoder != Py_None) { - PyObject *state = _PyObject_CallMethodNoArgs(self->decoder, + PyObject *state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); if (state == NULL) return NULL; @@ -601,7 +601,7 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) self->seennl = 0; self->pendingcr = 0; if (self->decoder != Py_None) - return _PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); + return PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); else Py_RETURN_NONE; } @@ -963,7 +963,7 @@ _textiowrapper_fix_encoder_state(textio *self) self->encoding_start_of_stream = 1; - PyObject *cookieObj = _PyObject_CallMethodNoArgs( + PyObject *cookieObj = PyObject_CallMethodNoArgs( self->buffer, _PyIO_str_tell); if (cookieObj == NULL) { return -1; @@ -977,7 +977,7 @@ _textiowrapper_fix_encoder_state(textio *self) if (cmp == 0) { self->encoding_start_of_stream = 0; - PyObject *res = _PyObject_CallMethodOneArg( + PyObject *res = PyObject_CallMethodOneArg( self->encoder, _PyIO_str_setstate, _PyLong_Zero); if (res == NULL) { return -1; @@ -1386,7 +1386,7 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, return NULL; } - PyObject *res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) { return NULL; } @@ -1525,7 +1525,7 @@ _io_TextIOWrapper_detach_impl(textio *self) { PyObject *buffer, *res; CHECK_ATTACHED(self); - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); @@ -1597,7 +1597,7 @@ _textiowrapper_writeflush(textio *self) PyObject *ret; do { - ret = _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_write, b); + ret = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_write, b); } while (ret == NULL && _PyIO_trap_eintr()); Py_DECREF(b); if (ret == NULL) @@ -1667,7 +1667,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) self->encoding_start_of_stream = 0; } else - b = _PyObject_CallMethodOneArg(self->encoder, _PyIO_str_encode, text); + b = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_encode, text); Py_DECREF(text); if (b == NULL) @@ -1718,7 +1718,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) } if (needflush) { - ret = _PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); + ret = PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1808,7 +1808,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /* To prepare for tell(), we need to snapshot a point in the file * where the decoder's input buffer is empty. */ - PyObject *state = _PyObject_CallMethodNoArgs(self->decoder, + PyObject *state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); if (state == NULL) return -1; @@ -1849,7 +1849,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) if (chunk_size == NULL) goto fail; - input_chunk = _PyObject_CallMethodOneArg(self->buffer, + input_chunk = PyObject_CallMethodOneArg(self->buffer, (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), chunk_size); Py_DECREF(chunk_size); @@ -2393,7 +2393,7 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) utf-16, that we are expecting a BOM). */ if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = _PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); + res = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); else res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "((yi))", "", cookie->dec_flags); @@ -2408,11 +2408,11 @@ _textiowrapper_encoder_reset(textio *self, int start_of_stream) { PyObject *res; if (start_of_stream) { - res = _PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); + res = PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); self->encoding_start_of_stream = 1; } else { - res = _PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, + res = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, _PyLong_Zero); self->encoding_start_of_stream = 0; } @@ -2537,7 +2537,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) goto fail; Py_DECREF(res); @@ -2552,7 +2552,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) posobj = PyLong_FromOff_t(cookie.start_pos); if (posobj == NULL) goto fail; - res = _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_seek, posobj); + res = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_seek, posobj); Py_DECREF(posobj); if (res == NULL) goto fail; @@ -2700,14 +2700,14 @@ _io_TextIOWrapper_tell_impl(textio *self) chars_to_skip = self->decoded_chars_used; /* Decoder state will be restored at the end */ - saved_state = _PyObject_CallMethodNoArgs(self->decoder, + saved_state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); if (saved_state == NULL) goto fail; #define DECODER_GETSTATE() do { \ PyObject *dec_buffer; \ - PyObject *_state = _PyObject_CallMethodNoArgs(self->decoder, \ + PyObject *_state = PyObject_CallMethodNoArgs(self->decoder, \ _PyIO_str_getstate); \ if (_state == NULL) \ goto fail; \ @@ -2870,12 +2870,12 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) CHECK_ATTACHED(self) - res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); - return _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_truncate, pos); + return PyObject_CallMethodOneArg(self->buffer, _PyIO_str_truncate, pos); } static PyObject * @@ -3084,7 +3084,7 @@ textiowrapper_iternext(textio *self) line = _textiowrapper_readline(self, -1); } else { - line = _PyObject_CallMethodNoArgs((PyObject *)self, + line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, diff --git a/Modules/_json.c b/Modules/_json.c index a70043b605f6b..ee2070c043efc 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -777,14 +777,14 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss *next_idx_ptr = idx + 1; if (has_pairs_hook) { - val = _PyObject_CallOneArg(s->object_pairs_hook, rval); + val = PyObject_CallOneArg(s->object_pairs_hook, rval); Py_DECREF(rval); return val; } /* if object_hook is not None: rval = object_hook(rval) */ if (s->object_hook != Py_None) { - val = _PyObject_CallOneArg(s->object_hook, rval); + val = PyObject_CallOneArg(s->object_hook, rval); Py_DECREF(rval); return val; } @@ -890,7 +890,7 @@ _parse_constant(PyScannerObject *s, const char *constant, Py_ssize_t idx, Py_ssi return NULL; /* rval = parse_constant(constant) */ - rval = _PyObject_CallOneArg(s->parse_constant, cstr); + rval = PyObject_CallOneArg(s->parse_constant, cstr); idx += PyUnicode_GET_LENGTH(cstr); Py_DECREF(cstr); *next_idx_ptr = idx; @@ -989,7 +989,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ idx - start); if (numstr == NULL) return NULL; - rval = _PyObject_CallOneArg(custom_func, numstr); + rval = PyObject_CallOneArg(custom_func, numstr); } else { Py_ssize_t i, n; @@ -1399,7 +1399,7 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) if (s->fast_encode) { return s->fast_encode(NULL, obj); } - encoded = _PyObject_CallOneArg(s->encoder, obj); + encoded = PyObject_CallOneArg(s->encoder, obj); if (encoded != NULL && !PyUnicode_Check(encoded)) { PyErr_Format(PyExc_TypeError, "encoder() must return a string, not %.80s", @@ -1485,7 +1485,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, return -1; } } - newobj = _PyObject_CallOneArg(s->defaultfn, obj); + newobj = PyObject_CallOneArg(s->defaultfn, obj); if (newobj == NULL) { Py_XDECREF(ident); return -1; diff --git a/Modules/_operator.c b/Modules/_operator.c index 5aa229fa781eb..adee5fd79689d 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1682,7 +1682,7 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) newargs[0] = (PyObject *)Py_TYPE(mc); newargs[1] = mc->name; - constructor = _PyObject_FastCallDict(partial, newargs, 2, mc->kwds); + constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds); Py_DECREF(partial); return Py_BuildValue("NO", constructor, mc->args); diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 5f11fe5c88c2b..2ba7a168d0ee9 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -359,7 +359,7 @@ _Pickle_FastCall(PyObject *func, PyObject *obj) { PyObject *result; - result = _PyObject_CallOneArg(func, obj); + result = PyObject_CallOneArg(func, obj); Py_DECREF(obj); return result; } @@ -420,7 +420,7 @@ call_method(PyObject *func, PyObject *self, PyObject *obj) return PyObject_CallFunctionObjArgs(func, self, obj, NULL); } else { - return _PyObject_CallOneArg(func, obj); + return PyObject_CallOneArg(func, obj); } } @@ -2298,7 +2298,7 @@ _Pickler_write_bytes(PicklerObject *self, return -1; } } - result = _PyObject_CallOneArg(self->write, payload); + result = PyObject_CallOneArg(self->write, payload); Py_XDECREF(mem); if (result == NULL) { return -1; @@ -2506,7 +2506,7 @@ save_picklebuffer(PicklerObject *self, PyObject *obj) } int in_band = 1; if (self->buffer_callback != NULL) { - PyObject *ret = _PyObject_CallOneArg(self->buffer_callback, obj); + PyObject *ret = PyObject_CallOneArg(self->buffer_callback, obj); if (ret == NULL) { return -1; } @@ -4323,7 +4323,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) * regular reduction mechanism. */ if (self->reducer_override != NULL) { - reduce_value = _PyObject_CallOneArg(self->reducer_override, obj); + reduce_value = PyObject_CallOneArg(self->reducer_override, obj); if (reduce_value == NULL) { goto error; } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 80bb44dce9092..2aed79e14c4b5 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -80,7 +80,7 @@ _enable_gc(int need_to_reenable_gc, PyObject *gc_module) if (need_to_reenable_gc) { PyErr_Fetch(&exctype, &val, &tb); - result = _PyObject_CallMethodNoArgs( + result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->enable); if (exctype != NULL) { PyErr_Restore(exctype, val, tb); @@ -657,7 +657,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) gc_module = PyImport_ImportModule("gc"); if (gc_module == NULL) return NULL; - result = _PyObject_CallMethodNoArgs( + result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->isenabled); if (result == NULL) { Py_DECREF(gc_module); @@ -669,7 +669,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) Py_DECREF(gc_module); return NULL; } - result = _PyObject_CallMethodNoArgs( + result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->disable); if (result == NULL) { Py_DECREF(gc_module); diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 1f4bf74fc7a1e..f0fdb0382c5d3 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -287,7 +287,7 @@ random_seed(RandomObject *self, PyObject *arg) /* Calling int.__abs__() prevents calling arg.__abs__(), which might return an invalid value. See issue #31478. */ args[0] = arg; - n = _PyObject_Vectorcall(_randomstate_global->Long___abs__, args, 0, + n = PyObject_Vectorcall(_randomstate_global->Long___abs__, args, 0, NULL); } else { diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 7552d1b145394..758fc022f7810 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -183,7 +183,7 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) } } - /* We cannot replace this by _PyObject_CallOneArg() since + /* We cannot replace this by PyObject_CallOneArg() since * PyObject_CallFunction() has a special case when using a * single tuple as argument. */ data = PyObject_CallFunction(self->factory, "O", key); diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 64051669185ba..697295da9ce39 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -308,7 +308,7 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, factory = (PyObject*)&pysqlite_CursorType; } - cursor = _PyObject_CallOneArg(factory, (PyObject *)self); + cursor = PyObject_CallOneArg(factory, (PyObject *)self); if (cursor == NULL) return NULL; if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { @@ -975,7 +975,7 @@ static void _trace_callback(void* user_arg, const char* statement_string) py_statement = PyUnicode_DecodeUTF8(statement_string, strlen(statement_string), "replace"); if (py_statement) { - ret = _PyObject_CallOneArg((PyObject*)user_arg, py_statement); + ret = PyObject_CallOneArg((PyObject*)user_arg, py_statement); Py_DECREF(py_statement); } @@ -1472,7 +1472,7 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) goto finally; } - retval = _PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); + retval = PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); finally: Py_XDECREF(module); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 06275ecb26849..ab276db782607 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -266,7 +266,7 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) item = PyBytes_FromStringAndSize(val_str, nbytes); if (!item) goto error; - converted = _PyObject_CallOneArg(converter, item); + converted = PyObject_CallOneArg(converter, item); Py_DECREF(item); } } else { diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index bdcb174be4379..bb0d19f653b31 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -92,7 +92,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) Py_DECREF(key); if (adapter) { Py_INCREF(adapter); - adapted = _PyObject_CallOneArg(adapter, obj); + adapted = PyObject_CallOneArg(adapter, obj); Py_DECREF(adapter); return adapted; } @@ -105,7 +105,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) return NULL; } if (adapter) { - adapted = _PyObject_CallOneArg(adapter, obj); + adapted = PyObject_CallOneArg(adapter, obj); Py_DECREF(adapter); if (adapted == Py_None) { @@ -124,7 +124,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) return NULL; } if (adapter) { - adapted = _PyObject_CallOneArg(adapter, proto); + adapted = PyObject_CallOneArg(adapter, proto); Py_DECREF(adapter); if (adapted == Py_None) { diff --git a/Modules/_sre.c b/Modules/_sre.c index 6518e98f04e40..80c4184922941 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1081,7 +1081,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, match = pattern_new_match(self, &state, 1); if (!match) goto error; - item = _PyObject_CallOneArg(filter, match); + item = PyObject_CallOneArg(filter, match); Py_DECREF(match); if (!item) goto error; diff --git a/Modules/_struct.c b/Modules/_struct.c index cc536b46a623e..0cdfe268e645f 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -2097,7 +2097,7 @@ cache_struct_converter(PyObject *fmt, PyStructObject **ptr) return 0; } - s_object = _PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt); + s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt); if (s_object != NULL) { if (PyDict_GET_SIZE(cache) >= MAXCACHE) PyDict_Clear(cache); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index e6d30341cdfb1..eb31a0ef5c933 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4846,7 +4846,7 @@ test_pyobject_fastcalldict(PyObject *self, PyObject *args) return NULL; } - return _PyObject_FastCallDict(func, stack, nargs, kwargs); + return PyObject_VectorcallDict(func, stack, nargs, kwargs); } @@ -4880,7 +4880,7 @@ test_pyobject_vectorcall(PyObject *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); return NULL; } - return _PyObject_Vectorcall(func, stack, nargs, kwnames); + return PyObject_Vectorcall(func, stack, nargs, kwnames); } @@ -5253,7 +5253,7 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args, if (pyargs == NULL) { return NULL; } - PyObject *pykwargs = _PyObject_Vectorcall((PyObject*)&PyDict_Type, + PyObject *pykwargs = PyObject_Vectorcall((PyObject*)&PyDict_Type, args + nargs, 0, kwargs); return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs); } @@ -6133,7 +6133,7 @@ static PyTypeObject MethodDescriptorBase_Type = { .tp_call = PyVectorcall_Call, .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_METHOD_DESCRIPTOR | _Py_TPFLAGS_HAVE_VECTORCALL, + Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, .tp_descr_get = func_descr_get, }; @@ -6172,7 +6172,7 @@ static PyTypeObject MethodDescriptor2_Type = { .tp_new = MethodDescriptor2_new, .tp_call = PyVectorcall_Call, .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_HAVE_VECTORCALL, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, }; PyDoc_STRVAR(heapgctype__doc__, diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index dae1eaeabd000..74ba819b8b50b 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -104,7 +104,7 @@ static int fuzz_json_loads(const char* data, size_t size) { if (input_bytes == NULL) { return 0; } - PyObject* parsed = _PyObject_CallOneArg(json_loads_method, input_bytes); + PyObject* parsed = PyObject_CallOneArg(json_loads_method, input_bytes); if (parsed == NULL) { /* Ignore ValueError as the fuzzer will more than likely generate some invalid json and values */ @@ -263,7 +263,7 @@ static int fuzz_sre_match(const char* data, size_t size) { PyObject* pattern = compiled_patterns[idx]; PyObject* match_callable = PyObject_GetAttrString(pattern, "match"); - PyObject* matches = _PyObject_CallOneArg(match_callable, to_match); + PyObject* matches = PyObject_CallOneArg(match_callable, to_match); Py_XDECREF(matches); Py_DECREF(match_callable); diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index 7ed836598b36d..8f6f880cadf71 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -291,7 +291,7 @@ getcodec(PyObject *self, PyObject *encoding) if (codecobj == NULL) return NULL; - r = _PyObject_CallOneArg(cofunc, codecobj); + r = PyObject_CallOneArg(cofunc, codecobj); Py_DECREF(codecobj); return r; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 2dd63a9531e67..3bc07b2d8d5ae 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -92,7 +92,7 @@ call_error_callback(PyObject *errors, PyObject *exc) if (cb == NULL) return NULL; - r = _PyObject_CallOneArg(cb, exc); + r = PyObject_CallOneArg(cb, exc); Py_DECREF(cb); return r; } diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 5673f6028372f..cf164c17d7bf1 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -872,7 +872,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) _PyObject_ASSERT(op, callback != NULL); /* copy-paste of weakrefobject.c's handle_callback() */ - temp = _PyObject_CallOneArg(callback, (PyObject *)wr); + temp = PyObject_CallOneArg(callback, (PyObject *)wr); if (temp == NULL) PyErr_WriteUnraisable(callback); else diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 0dafb65c288e4..c00c2745d3f0c 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -134,7 +134,7 @@ groupby_step(groupbyobject *gbo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = _PyObject_CallOneArg(gbo->keyfunc, newvalue); + newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue); if (newkey == NULL) { Py_DECREF(newvalue); return -1; @@ -1219,7 +1219,7 @@ dropwhile_next(dropwhileobject *lz) if (lz->start == 1) return item; - good = _PyObject_CallOneArg(lz->func, item); + good = PyObject_CallOneArg(lz->func, item); if (good == NULL) { Py_DECREF(item); return NULL; @@ -1382,7 +1382,7 @@ takewhile_next(takewhileobject *lz) if (item == NULL) return NULL; - good = _PyObject_CallOneArg(lz->func, item); + good = PyObject_CallOneArg(lz->func, item); if (good == NULL) { Py_DECREF(item); return NULL; @@ -3918,7 +3918,7 @@ filterfalse_next(filterfalseobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = _PyObject_CallOneArg(lz->func, item); + good = PyObject_CallOneArg(lz->func, item); if (good == NULL) { Py_DECREF(item); return NULL; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 90167342fee50..a7f8b5086bbfa 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -119,7 +119,7 @@ set_error(xmlparseobject *self, enum XML_Error code) XML_ErrorString(code), lineno, column); if (buffer == NULL) return NULL; - err = _PyObject_CallOneArg(ErrorObject, buffer); + err = PyObject_CallOneArg(ErrorObject, buffer); Py_DECREF(buffer); if ( err != NULL && set_error_attr(err, "code", code) diff --git a/Objects/abstract.c b/Objects/abstract.c index 7ab58a8bd52c3..f0e01f7691bb3 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -179,7 +179,7 @@ PyObject_GetItem(PyObject *o, PyObject *key) return NULL; } if (meth) { - result = _PyObject_CallOneArg(meth, key); + result = PyObject_CallOneArg(meth, key); Py_DECREF(meth); return result; } @@ -780,7 +780,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) } /* And call it. */ - result = _PyObject_CallOneArg(meth, format_spec); + result = PyObject_CallOneArg(meth, format_spec); Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { @@ -2502,7 +2502,7 @@ object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls return -1; } - PyObject *res = _PyObject_CallOneArg(checker, inst); + PyObject *res = PyObject_CallOneArg(checker, inst); _Py_LeaveRecursiveCall(tstate); Py_DECREF(checker); @@ -2588,7 +2588,7 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) Py_DECREF(checker); return ok; } - PyObject *res = _PyObject_CallOneArg(checker, derived); + PyObject *res = PyObject_CallOneArg(checker, derived); _Py_LeaveRecursiveCall(tstate); Py_DECREF(checker); if (res != NULL) { diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index b2808c05b40ca..a3fc35ca4d22a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -89,7 +89,7 @@ _canresize(PyByteArrayObject *self) PyObject * PyByteArray_FromObject(PyObject *input) { - return _PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input); + return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input); } static PyObject * @@ -2015,7 +2015,7 @@ bytearray_fromhex_impl(PyTypeObject *type, PyObject *string) { PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type); if (type != &PyByteArray_Type && result != NULL) { - Py_SETREF(result, _PyObject_CallOneArg((PyObject *)type, result)); + Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result)); } return result; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index e139bed71bf6d..df3eddae6a36d 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2259,7 +2259,7 @@ bytes_fromhex_impl(PyTypeObject *type, PyObject *string) { PyObject *result = _PyBytes_FromHex(string, 0); if (type != &PyBytes_Type && result != NULL) { - Py_SETREF(result, _PyObject_CallOneArg((PyObject *)type, result)); + Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result)); } return result; } diff --git a/Objects/call.c b/Objects/call.c index d1d50b647f365..37d079d169d9d 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -95,7 +95,7 @@ _PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, { assert(callable != NULL); - /* _PyObject_FastCallDict() must not be called with an exception set, + /* PyObject_VectorcallDict() 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(tstate)); @@ -105,7 +105,7 @@ _PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, assert(nargs == 0 || args != NULL); assert(kwargs == NULL || PyDict_Check(kwargs)); - vectorcallfunc func = _PyVectorcall_Function(callable); + vectorcallfunc func = PyVectorcall_Function(callable); if (func == NULL) { /* Use tp_call instead */ return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); @@ -133,7 +133,7 @@ _PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, PyObject * -_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, +PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwargs) { PyThreadState *tstate = _PyThreadState_GET(); @@ -204,8 +204,8 @@ 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 */ + /* 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(tstate, PyExc_TypeError, @@ -259,7 +259,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - if (_PyVectorcall_Function(callable) != NULL) { + if (PyVectorcall_Function(callable) != NULL) { return PyVectorcall_Call(callable, args, kwargs); } else { @@ -796,7 +796,7 @@ object_vacall(PyThreadState *tstate, PyObject *base, PyObject * -_PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, +PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) { assert(name != NULL); diff --git a/Objects/classobject.c b/Objects/classobject.c index fb89b8aa69324..33afbcd874775 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -350,7 +350,7 @@ PyTypeObject PyMethod_Type = { PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ method_doc, /* tp_doc */ (traverseproc)method_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 49c26eb069233..aaaa4479e4b92 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -454,7 +454,7 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, if (bound == NULL) { return NULL; } - PyObject *res = _PyObject_FastCallDict(bound, _PyTuple_ITEMS(args)+1, + PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1, argc-1, kwds); Py_DECREF(bound); return res; @@ -673,7 +673,7 @@ PyTypeObject PyMethodDescr_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - _Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ @@ -1493,7 +1493,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) return NULL; } - return _PyObject_CallOneArg(gs->prop_get, obj); + return PyObject_CallOneArg(gs->prop_get, obj); } static int @@ -1514,7 +1514,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) return -1; } if (value == NULL) - res = _PyObject_CallOneArg(func, obj); + res = PyObject_CallOneArg(func, obj); else res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); if (res == NULL) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 164104ed7e151..8f6ce3996a172 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2127,7 +2127,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) _Py_IDENTIFIER(__missing__); missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__); if (missing != NULL) { - res = _PyObject_CallOneArg(missing, key); + res = PyObject_CallOneArg(missing, key); Py_DECREF(missing); return res; } diff --git a/Objects/fileobject.c b/Objects/fileobject.c index c0eff8bed5136..840d17bee66ba 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -137,7 +137,7 @@ PyFile_WriteObject(PyObject *v, PyObject *f, int flags) Py_DECREF(writer); return -1; } - result = _PyObject_CallOneArg(writer, value); + result = PyObject_CallOneArg(writer, value); Py_DECREF(value); Py_DECREF(writer); if (result == NULL) diff --git a/Objects/floatobject.c b/Objects/floatobject.c index dfc5b196f18e4..648030b659c23 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1490,7 +1490,7 @@ float_fromhex(PyTypeObject *type, PyObject *string) goto parse_error; result = PyFloat_FromDouble(negate ? -x : x); if (type != &PyFloat_Type && result != NULL) { - Py_SETREF(result, _PyObject_CallOneArg((PyObject *)type, result)); + Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result)); } return result; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index ebe68adc3362e..419db33602a36 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -654,7 +654,7 @@ PyTypeObject PyFunction_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - _Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ func_new__doc__, /* tp_doc */ (traverseproc)func_traverse, /* tp_traverse */ diff --git a/Objects/genobject.c b/Objects/genobject.c index 652c2903dd284..576d6856c7f30 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -58,7 +58,7 @@ _PyGen_Finalize(PyObject *self) /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); - res = _PyObject_CallOneArg(finalizer, self); + res = PyObject_CallOneArg(finalizer, self); if (res == NULL) { PyErr_WriteUnraisable(self); @@ -563,7 +563,7 @@ _PyGen_SetStopIterationValue(PyObject *value) return 0; } /* Construct an exception instance manually with - * _PyObject_CallOneArg and pass it to PyErr_SetObject. + * PyObject_CallOneArg and pass it to PyErr_SetObject. * * We do this to handle a situation when "value" is a tuple, in which * case PyErr_SetObject would set the value of StopIteration to @@ -571,7 +571,7 @@ _PyGen_SetStopIterationValue(PyObject *value) * * (See PyErr_SetObject/_PyErr_CreateException code for details.) */ - e = _PyObject_CallOneArg(PyExc_StopIteration, value); + e = PyObject_CallOneArg(PyExc_StopIteration, value); if (e == NULL) { return -1; } @@ -1264,7 +1264,7 @@ async_gen_init_hooks(PyAsyncGenObject *o) PyObject *res; Py_INCREF(firstiter); - res = _PyObject_CallOneArg(firstiter, (PyObject *)o); + res = PyObject_CallOneArg(firstiter, (PyObject *)o); Py_DECREF(firstiter); if (res == NULL) { return 1; diff --git a/Objects/listobject.c b/Objects/listobject.c index a406e70694a69..3c39c6444bfd6 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2226,7 +2226,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) } for (i = 0; i < saved_ob_size ; i++) { - keys[i] = _PyObject_CallOneArg(keyfunc, saved_ob_item[i]); + keys[i] = PyObject_CallOneArg(keyfunc, saved_ob_item[i]); if (keys[i] == NULL) { for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); diff --git a/Objects/longobject.c b/Objects/longobject.c index b4d0b0575bcf6..5d225cbd2fbde 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5547,7 +5547,7 @@ int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, Py_DECREF(bytes); if (long_obj != NULL && type != &PyLong_Type) { - Py_SETREF(long_obj, _PyObject_CallOneArg((PyObject *)type, long_obj)); + Py_SETREF(long_obj, PyObject_CallOneArg((PyObject *)type, long_obj)); } return long_obj; diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index d9dd11733ef1a..906d1cef69b1f 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1963,7 +1963,7 @@ struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) if (format == NULL) goto error; - structobj = _PyObject_CallOneArg(Struct, format); + structobj = PyObject_CallOneArg(Struct, format); if (structobj == NULL) goto error; @@ -2002,7 +2002,7 @@ struct_unpack_single(const char *ptr, struct unpacker *x) PyObject *v; memcpy(x->item, ptr, x->itemsize); - v = _PyObject_CallOneArg(x->unpack_from, x->mview); + v = PyObject_CallOneArg(x->unpack_from, x->mview); if (v == NULL) return NULL; diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 2a8111fea1c61..1d54c4cea6900 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -298,7 +298,7 @@ PyTypeObject PyCFunction_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ 0, /* tp_doc */ (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 0a593261c4134..30de53d902bce 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -738,7 +738,7 @@ module_getattro(PyModuleObject *m, PyObject *name) _Py_IDENTIFIER(__getattr__); getattr = _PyDict_GetItemId(m->md_dict, &PyId___getattr__); if (getattr) { - return _PyObject_CallOneArg(getattr, name); + return PyObject_CallOneArg(getattr, name); } mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); if (mod_name && PyUnicode_Check(mod_name)) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e6a84b017aa67..f32ccb137987c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1465,7 +1465,7 @@ static PyObject* call_unbound_noarg(int unbound, PyObject *func, PyObject *self) { if (unbound) { - return _PyObject_CallOneArg(func, self); + return PyObject_CallOneArg(func, self); } else { return _PyObject_CallNoArg(func); @@ -3665,7 +3665,7 @@ PyTypeObject PyType_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS | - _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ type_doc, /* tp_doc */ (traverseproc)type_traverse, /* tp_traverse */ (inquiry)type_clear, /* tp_clear */ @@ -5196,17 +5196,17 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) /* tp_hash see tp_richcompare */ { /* Always inherit tp_vectorcall_offset to support PyVectorcall_Call(). - * If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall + * If Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall * won't be used automatically. */ COPYSLOT(tp_vectorcall_offset); - /* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types + /* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types * if tp_call is not overridden */ if (!type->tp_call && - (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + (base->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) && !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; + type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL; } COPYSLOT(tp_call); } @@ -5282,14 +5282,14 @@ PyType_Ready(PyTypeObject *type) /* Consistency checks for PEP 590: * - Py_TPFLAGS_METHOD_DESCRIPTOR requires tp_descr_get - * - _Py_TPFLAGS_HAVE_VECTORCALL requires tp_call and + * - Py_TPFLAGS_HAVE_VECTORCALL requires tp_call and * tp_vectorcall_offset > 0 * To avoid mistakes, we require this before inheriting. */ if (type->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { _PyObject_ASSERT((PyObject *)type, type->tp_descr_get != NULL); } - if (type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) { + if (type->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) { _PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0); _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); } @@ -6614,7 +6614,7 @@ call_attribute(PyObject *self, PyObject *attr, PyObject *name) else attr = descr; } - res = _PyObject_CallOneArg(attr, name); + res = PyObject_CallOneArg(attr, name); Py_XDECREF(descr); return res; } @@ -7575,7 +7575,7 @@ init_subclass(PyTypeObject *type, PyObject *kwds) } - result = _PyObject_FastCallDict(func, NULL, 0, kwds); + result = PyObject_VectorcallDict(func, NULL, 0, kwds); Py_DECREF(func); if (result == NULL) { return -1; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index aa874f2a12d29..68e4f6af1314d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -4250,7 +4250,7 @@ unicode_decode_call_errorhandler_wchar( if (*exceptionObject == NULL) goto onError; - restuple = _PyObject_CallOneArg(*errorHandler, *exceptionObject); + restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject); if (restuple == NULL) goto onError; if (!PyTuple_Check(restuple)) { @@ -4354,7 +4354,7 @@ unicode_decode_call_errorhandler_writer( if (*exceptionObject == NULL) goto onError; - restuple = _PyObject_CallOneArg(*errorHandler, *exceptionObject); + restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject); if (restuple == NULL) goto onError; if (!PyTuple_Check(restuple)) { @@ -6801,7 +6801,7 @@ unicode_encode_call_errorhandler(const char *errors, if (*exceptionObject == NULL) return NULL; - restuple = _PyObject_CallOneArg(*errorHandler, *exceptionObject); + restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject); if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { @@ -8783,7 +8783,7 @@ unicode_translate_call_errorhandler(const char *errors, if (*exceptionObject == NULL) return NULL; - restuple = _PyObject_CallOneArg(*errorHandler, *exceptionObject); + restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject); if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 18c737e7e4097..7a5d9fb88af14 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -933,7 +933,7 @@ PyWeakref_GetObject(PyObject *ref) static void handle_callback(PyWeakReference *ref, PyObject *callback) { - PyObject *cbresult = _PyObject_CallOneArg(callback, (PyObject *)ref); + PyObject *cbresult = PyObject_CallOneArg(callback, (PyObject *)ref); if (cbresult == NULL) PyErr_WriteUnraisable(callback); diff --git a/Python/_warnings.c b/Python/_warnings.c index 9e8b52d353dab..acef313fc9f25 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -593,7 +593,7 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message, if (msg == NULL) goto error; - res = _PyObject_CallOneArg(show_fn, msg); + res = PyObject_CallOneArg(show_fn, msg); Py_DECREF(show_fn); Py_DECREF(msg); @@ -654,7 +654,7 @@ warn_explicit(PyObject *category, PyObject *message, } else { text = message; - message = _PyObject_CallOneArg(category, message); + message = PyObject_CallOneArg(category, message); if (message == NULL) goto cleanup; } @@ -997,7 +997,7 @@ get_source_line(PyObject *module_globals, int lineno) return NULL; } /* Call get_source() to get the source code. */ - source = _PyObject_CallOneArg(get_source, module_name); + source = PyObject_CallOneArg(get_source, module_name); Py_DECREF(get_source); Py_DECREF(module_name); if (!source) { @@ -1284,7 +1284,7 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro) int warned = 0; PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1); if (fn) { - PyObject *res = _PyObject_CallOneArg(fn, coro); + PyObject *res = PyObject_CallOneArg(fn, coro); Py_DECREF(fn); if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) { warned = 1; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 980b81041b4f9..cb048af97855f 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -56,7 +56,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) } continue; } - new_base = _PyObject_CallOneArg(meth, bases); + new_base = PyObject_CallOneArg(meth, bases); Py_DECREF(meth); if (!new_base) { goto error; @@ -203,7 +203,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, } else { PyObject *pargs[2] = {name, bases}; - ns = _PyObject_FastCallDict(prep, pargs, 2, mkw); + ns = PyObject_VectorcallDict(prep, pargs, 2, mkw); Py_DECREF(prep); } if (ns == NULL) { @@ -229,7 +229,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, } } PyObject *margs[3] = {name, bases, ns}; - cls = _PyObject_FastCallDict(meta, margs, 3, mkw); + cls = PyObject_VectorcallDict(meta, margs, 3, mkw); if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) { PyObject *cell_cls = PyCell_GET(cell); if (cell_cls != cls) { @@ -489,7 +489,7 @@ builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb } Py_INCREF(hook); - PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); + PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); Py_DECREF(hook); return retval; } @@ -575,7 +575,7 @@ filter_next(filterobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = _PyObject_CallOneArg(lz->func, item); + good = PyObject_CallOneArg(lz->func, item); if (good == NULL) { Py_DECREF(item); return NULL; @@ -1631,7 +1631,7 @@ min_max(PyObject *args, PyObject *kwds, int op) while (( item = PyIter_Next(it) )) { /* get the value from the key function */ if (keyfunc != NULL) { - val = _PyObject_CallOneArg(keyfunc, item); + val = PyObject_CallOneArg(keyfunc, item); if (val == NULL) goto Fail_it_item; } @@ -2178,7 +2178,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) if (ndigits == Py_None) result = _PyObject_CallNoArg(round); else - result = _PyObject_CallOneArg(round, ndigits); + result = PyObject_CallOneArg(round, ndigits); Py_DECREF(round); return result; } @@ -2234,7 +2234,7 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } assert(nargs >= 1); - v = _PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames); + v = PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); diff --git a/Python/ceval.c b/Python/ceval.c index deba99ed7ace2..eb0f131ae8c86 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1874,7 +1874,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_DECREF(value); goto error; } - res = _PyObject_CallOneArg(hook, value); + res = PyObject_CallOneArg(hook, value); Py_DECREF(value); if (res == NULL) goto error; @@ -3271,7 +3271,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) assert(!PyLong_Check(exc)); exit_func = PEEK(7); PyObject *stack[4] = {NULL, exc, val, tb}; - res = _PyObject_Vectorcall(exit_func, stack + 1, + res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; @@ -4846,7 +4846,7 @@ trace_call_function(PyThreadState *tstate, { PyObject *x; if (PyCFunction_Check(func)) { - C_TRACE(x, _PyObject_Vectorcall(func, args, nargs, kwnames)); + C_TRACE(x, PyObject_Vectorcall(func, args, nargs, kwnames)); return x; } else if (Py_TYPE(func) == &PyMethodDescr_Type && nargs > 0) { @@ -4862,13 +4862,13 @@ trace_call_function(PyThreadState *tstate, if (func == NULL) { return NULL; } - C_TRACE(x, _PyObject_Vectorcall(func, + C_TRACE(x, PyObject_Vectorcall(func, args+1, nargs-1, kwnames)); Py_DECREF(func); return x; } - return _PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); + return PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); } /* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault() @@ -4887,7 +4887,7 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO x = trace_call_function(tstate, func, stack, nargs, kwnames); } else { - x = _PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); + x = PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); } assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); diff --git a/Python/codecs.c b/Python/codecs.c index ee2758c5fbe91..ce86cb20ccccc 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -147,7 +147,7 @@ PyObject *_PyCodec_Lookup(const char *encoding) func = PyList_GetItem(interp->codec_search_path, i); if (func == NULL) goto onError; - result = _PyObject_CallOneArg(func, v); + result = PyObject_CallOneArg(func, v); if (result == NULL) goto onError; if (result == Py_None) { @@ -317,7 +317,7 @@ PyObject *codec_getstreamcodec(const char *encoding, if (errors != NULL) streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); else - streamcodec = _PyObject_CallOneArg(codeccls, stream); + streamcodec = PyObject_CallOneArg(codeccls, stream); Py_DECREF(codecs); return streamcodec; } diff --git a/Python/errors.c b/Python/errors.c index 652f4c9de7a84..f11b66e7958ea 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -93,7 +93,7 @@ _PyErr_CreateException(PyObject *exception, PyObject *value) return PyObject_Call(exception, value, NULL); } else { - return _PyObject_CallOneArg(exception, value); + return PyObject_CallOneArg(exception, value); } } @@ -907,7 +907,7 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, goto done; } - error = _PyObject_FastCallDict(exception, &msg, 1, kwargs); + error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); if (error != NULL) { _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); Py_DECREF(error); @@ -1422,7 +1422,7 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) goto default_hook; } - PyObject *res = _PyObject_CallOneArg(hook, hook_args); + PyObject *res = PyObject_CallOneArg(hook, hook_args); Py_DECREF(hook_args); if (res != NULL) { Py_DECREF(res); diff --git a/Python/import.c b/Python/import.c index 8bf044827c6e9..392d711299e0e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1206,7 +1206,7 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, PyObject *hook = PyList_GetItem(path_hooks, j); if (hook == NULL) return NULL; - importer = _PyObject_CallOneArg(hook, p); + importer = PyObject_CallOneArg(hook, p); if (importer != NULL) break; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 707a08e7f4996..a7f8c0b719639 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -519,7 +519,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb return NULL; } PyMem_RawFree(envar); - PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); + PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); Py_DECREF(hook); return retval; From webhook-mailer at python.org Tue Feb 11 11:50:15 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 11 Feb 2020 16:50:15 -0000 Subject: [Python-checkins] bpo-38644: Rephrase What's New entry (GH-18461) Message-ID: https://github.com/python/cpython/commit/f3fda374685dffa31ebda9e681e00ef7032b8a1d commit: f3fda374685dffa31ebda9e681e00ef7032b8a1d branch: master author: Victor Stinner committer: GitHub date: 2020-02-11T17:50:10+01:00 summary: bpo-38644: Rephrase What's New entry (GH-18461) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 4f4c7f2808d01..c0404101d7ce2 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -356,8 +356,9 @@ 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. + macros, but these macros didn't compile with the limited C API which cannot + access ``PyThreadState.recursion_depth`` field (the structure is opaque in + the limited C API). * Exclude the following functions from the limited C API: From webhook-mailer at python.org Tue Feb 11 12:32:58 2020 From: webhook-mailer at python.org (Steve Dower) Date: Tue, 11 Feb 2020 17:32:58 -0000 Subject: [Python-checkins] Fix ordering issue in Windows release upload script (GH-18465) Message-ID: https://github.com/python/cpython/commit/b138dd296a206e92ebec09b540bb88a1539563e4 commit: b138dd296a206e92ebec09b540bb88a1539563e4 branch: master author: Steve Dower committer: GitHub date: 2020-02-11T09:32:52-08:00 summary: Fix ordering issue in Windows release upload script (GH-18465) Automerge-Triggered-By: @zooba files: M .azure-pipelines/windows-release/stage-publish-pythonorg.yml diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index 8c95f1b950cd7..0474d40e4bc02 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -39,11 +39,6 @@ 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' condition: and(succeeded(), variables['BuildToPublish']) @@ -80,6 +75,11 @@ jobs: buildVersionToDownload: specific buildId: $(BuildToPublish) + - 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'])) + - template: ./gpg-sign.yml parameters: From webhook-mailer at python.org Tue Feb 11 20:20:13 2020 From: webhook-mailer at python.org (@RandyMcMillan) Date: Wed, 12 Feb 2020 01:20:13 -0000 Subject: [Python-checkins] docs: macos - change "versiona" to "versions" (GH-18467) Message-ID: https://github.com/python/cpython/commit/029e8401b7741cc0964b5f38d2c2264749dbff6b commit: 029e8401b7741cc0964b5f38d2c2264749dbff6b branch: master author: @RandyMcMillan committer: GitHub date: 2020-02-11T20:20:05-05:00 summary: docs: macos - change "versiona" to "versions" (GH-18467) files: M Mac/README.rst diff --git a/Mac/README.rst b/Mac/README.rst index 4f2e2ce6623df..ec7d873df277d 100644 --- a/Mac/README.rst +++ b/Mac/README.rst @@ -49,7 +49,7 @@ macOS specific arguments to configure system header files in their traditional locations, like ``/usr/include`` and ``/System/Library/Frameworks``; instead they are found within a MacOSX SDK. The Apple-supplied build tools handle this transparently and current - versiona of Python now handle this as well. So it is no longer necessary, + versions of Python now handle this as well. So it is no longer necessary, and since macOS 10.14, no longer possible to force the installation of system headers with ``xcode-select``. From webhook-mailer at python.org Tue Feb 11 20:39:37 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 01:39:37 -0000 Subject: [Python-checkins] docs: macos - change "versiona" to "versions" (GH-18467) (GH-18469) Message-ID: https://github.com/python/cpython/commit/0f0d2e496205c345b182b6572ee09db23f8f9daf commit: 0f0d2e496205c345b182b6572ee09db23f8f9daf branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T20:39:33-05:00 summary: docs: macos - change "versiona" to "versions" (GH-18467) (GH-18469) (cherry picked from commit 029e8401b7741cc0964b5f38d2c2264749dbff6b) Co-authored-by: @RandyMcMillan files: M Mac/README.rst diff --git a/Mac/README.rst b/Mac/README.rst index 4f2e2ce6623df..ec7d873df277d 100644 --- a/Mac/README.rst +++ b/Mac/README.rst @@ -49,7 +49,7 @@ macOS specific arguments to configure system header files in their traditional locations, like ``/usr/include`` and ``/System/Library/Frameworks``; instead they are found within a MacOSX SDK. The Apple-supplied build tools handle this transparently and current - versiona of Python now handle this as well. So it is no longer necessary, + versions of Python now handle this as well. So it is no longer necessary, and since macOS 10.14, no longer possible to force the installation of system headers with ``xcode-select``. From webhook-mailer at python.org Tue Feb 11 20:40:44 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 01:40:44 -0000 Subject: [Python-checkins] docs: macos - change "versiona" to "versions" (GH-18467) (GH-18470) Message-ID: https://github.com/python/cpython/commit/a933f74aba6eb11e7bf13d4d814dbeb4ddcb82b9 commit: a933f74aba6eb11e7bf13d4d814dbeb4ddcb82b9 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T20:40:39-05:00 summary: docs: macos - change "versiona" to "versions" (GH-18467) (GH-18470) (cherry picked from commit 029e8401b7741cc0964b5f38d2c2264749dbff6b) Co-authored-by: @RandyMcMillan files: M Mac/README.rst diff --git a/Mac/README.rst b/Mac/README.rst index 4f2e2ce6623df..ec7d873df277d 100644 --- a/Mac/README.rst +++ b/Mac/README.rst @@ -49,7 +49,7 @@ macOS specific arguments to configure system header files in their traditional locations, like ``/usr/include`` and ``/System/Library/Frameworks``; instead they are found within a MacOSX SDK. The Apple-supplied build tools handle this transparently and current - versiona of Python now handle this as well. So it is no longer necessary, + versions of Python now handle this as well. So it is no longer necessary, and since macOS 10.14, no longer possible to force the installation of system headers with ``xcode-select``. From webhook-mailer at python.org Tue Feb 11 21:28:45 2020 From: webhook-mailer at python.org (Andy Lester) Date: Wed, 12 Feb 2020 02:28:45 -0000 Subject: [Python-checkins] closes bpo-39605: Fix some casts to not cast away const. (GH-18453) Message-ID: https://github.com/python/cpython/commit/e6be9b59a911626d6597fe148c32f0342bd2bd24 commit: e6be9b59a911626d6597fe148c32f0342bd2bd24 branch: master author: Andy Lester committer: GitHub date: 2020-02-11T18:28:35-08:00 summary: closes bpo-39605: Fix some casts to not cast away const. (GH-18453) gcc -Wcast-qual turns up a number of instances of casting away constness of pointers. Some of these can be safely modified, by either: Adding the const to the type cast, as in: - return _PyUnicode_FromUCS1((unsigned char*)s, size); + return _PyUnicode_FromUCS1((const unsigned char*)s, size); or, Removing the cast entirely, because it's not necessary (but probably was at one time), as in: - PyDTrace_FUNCTION_ENTRY((char *)filename, (char *)funcname, lineno); + PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); These changes will not change code, but they will make it much easier to check for errors in consts files: M Modules/_io/textio.c M Objects/bytes_methods.c M Objects/memoryobject.c M Objects/stringlib/asciilib.h M Objects/stringlib/codecs.h M Objects/stringlib/find_max_char.h M Objects/unicodeobject.c M Python/ceval.c M Python/marshal.c M Python/pyhash.c M Python/sysmodule.c diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 1d45c7ae2fab9..3a9ce93a5eb5e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -2025,7 +2025,7 @@ find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch) { if (kind == PyUnicode_1BYTE_KIND) { assert(ch < 256); - return (char *) memchr((void *) s, (char) ch, end - s); + return (char *) memchr((const void *) s, (char) ch, end - s); } for (;;) { while (PyUnicode_READ(kind, s, 0) > ch) @@ -2043,7 +2043,7 @@ _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, int kind, const char *start, const char *end, Py_ssize_t *consumed) { - Py_ssize_t len = ((char*)end - (char*)start)/kind; + Py_ssize_t len = (end - start)/kind; if (translated) { /* Newlines are already translated, only search for \n */ diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 7d13184205922..db030be4fe756 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -12,7 +12,7 @@ PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -42,7 +42,7 @@ PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -72,7 +72,7 @@ PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -123,7 +123,7 @@ _Py_bytes_isascii(const char *cptr, Py_ssize_t len) /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & ASCII_CHAR_MASK) { Py_RETURN_FALSE; } @@ -154,7 +154,7 @@ PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -184,7 +184,7 @@ PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased; @@ -218,7 +218,7 @@ PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased; @@ -254,7 +254,7 @@ PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased, previous_is_cased; diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 906d1cef69b1f..6887c4335f1f1 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1682,8 +1682,8 @@ unpack_single(const char *ptr, const char *fmt) switch (fmt[0]) { /* signed integers and fast path for 'B' */ - case 'B': uc = *((unsigned char *)ptr); goto convert_uc; - case 'b': ld = *((signed char *)ptr); goto convert_ld; + case 'B': uc = *((const unsigned char *)ptr); goto convert_uc; + case 'b': ld = *((const signed char *)ptr); goto convert_ld; case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld; case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld; case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld; @@ -2684,8 +2684,8 @@ unpack_cmp(const char *p, const char *q, char fmt, switch (fmt) { /* signed integers and fast path for 'B' */ - case 'B': return *((unsigned char *)p) == *((unsigned char *)q); - case 'b': return *((signed char *)p) == *((signed char *)q); + case 'B': return *((const unsigned char *)p) == *((const unsigned char *)q); + case 'b': return *((const signed char *)p) == *((const signed char *)q); case 'h': CMP_SINGLE(p, q, short); return equal; case 'i': CMP_SINGLE(p, q, int); return equal; case 'l': CMP_SINGLE(p, q, long); return equal; diff --git a/Objects/stringlib/asciilib.h b/Objects/stringlib/asciilib.h index e95552624aa50..e69a2c076e3a3 100644 --- a/Objects/stringlib/asciilib.h +++ b/Objects/stringlib/asciilib.h @@ -18,7 +18,7 @@ #define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL #define STRINGLIB_STR PyUnicode_1BYTE_DATA #define STRINGLIB_LEN PyUnicode_GET_LENGTH -#define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((char*)(STR),(LEN)) +#define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((const char*)(STR),(LEN)) #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index d6f2b98f2b30a..269a5581f7005 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -46,7 +46,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* Read a whole long at a time (either 4 or 8 bytes), and do a fast unrolled copy if it only contains ASCII characters. */ - unsigned long value = *(unsigned long *) _s; + unsigned long value = *(const unsigned long *) _s; if (value & ASCII_CHAR_MASK) break; #if PY_LITTLE_ENDIAN @@ -515,7 +515,7 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, /* Fast path for runs of in-range non-surrogate chars. */ const unsigned char *_q = q; while (_q < aligned_end) { - unsigned long block = * (unsigned long *) _q; + unsigned long block = * (const unsigned long *) _q; if (native_ordering) { /* Can use buffer directly */ if (block & FAST_CHAR_MASK) diff --git a/Objects/stringlib/find_max_char.h b/Objects/stringlib/find_max_char.h index 8ccbc3094463d..f4e0a7761d311 100644 --- a/Objects/stringlib/find_max_char.h +++ b/Objects/stringlib/find_max_char.h @@ -28,7 +28,7 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) /* Help register allocation */ const unsigned char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & UCS1_ASCII_CHAR_MASK) return 255; _p += SIZEOF_LONG; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 68e4f6af1314d..fdc2ca6612cc5 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -172,8 +172,8 @@ extern "C" { #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ do { \ to_type *_to = (to_type *)(to); \ - const from_type *_iter = (from_type *)(begin); \ - const from_type *_end = (from_type *)(end); \ + const from_type *_iter = (const from_type *)(begin);\ + const from_type *_end = (const from_type *)(end);\ Py_ssize_t n = (_end) - (_iter); \ const from_type *_unrolled_end = \ _iter + _Py_SIZE_ROUND_DOWN(n, 4); \ @@ -964,21 +964,21 @@ findchar(const void *s, int kind, if ((Py_UCS1) ch != ch) return -1; if (direction > 0) - return ucs1lib_find_char((Py_UCS1 *) s, size, (Py_UCS1) ch); + return ucs1lib_find_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); else - return ucs1lib_rfind_char((Py_UCS1 *) s, size, (Py_UCS1) ch); + return ucs1lib_rfind_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); case PyUnicode_2BYTE_KIND: if ((Py_UCS2) ch != ch) return -1; if (direction > 0) - return ucs2lib_find_char((Py_UCS2 *) s, size, (Py_UCS2) ch); + return ucs2lib_find_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); else - return ucs2lib_rfind_char((Py_UCS2 *) s, size, (Py_UCS2) ch); + return ucs2lib_rfind_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); case PyUnicode_4BYTE_KIND: if (direction > 0) - return ucs4lib_find_char((Py_UCS4 *) s, size, ch); + return ucs4lib_find_char((const Py_UCS4 *) s, size, ch); else - return ucs4lib_rfind_char((Py_UCS4 *) s, size, ch); + return ucs4lib_rfind_char((const Py_UCS4 *) s, size, ch); default: Py_UNREACHABLE(); } @@ -3420,7 +3420,7 @@ PyUnicode_Decode(const char *s, /* Decode via the codec registry */ buffer = NULL; - if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0) + if (PyBuffer_FillInfo(&info, NULL, (const void *)s, size, 1, PyBUF_FULL_RO) < 0) goto onError; buffer = PyMemoryView_FromBuffer(&info); if (buffer == NULL) @@ -4921,7 +4921,7 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & ASCII_CHAR_MASK) break; _p += SIZEOF_LONG; @@ -5472,7 +5472,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, PyObject *errorHandler = NULL; PyObject *exc = NULL; - q = (unsigned char *)s; + q = (const unsigned char *)s; e = q + size; if (byteorder) @@ -5797,7 +5797,7 @@ PyUnicode_DecodeUTF16Stateful(const char *s, PyObject *exc = NULL; const char *encoding; - q = (unsigned char *)s; + q = (const unsigned char *)s; e = q + size; if (byteorder) @@ -6726,7 +6726,7 @@ PyUnicode_DecodeLatin1(const char *s, const char *errors) { /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */ - return _PyUnicode_FromUCS1((unsigned char*)s, size); + return _PyUnicode_FromUCS1((const unsigned char*)s, size); } /* create or adjust a UnicodeEncodeError */ @@ -13803,7 +13803,7 @@ _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, if (len == -1) len = strlen(ascii); - assert(ucs1lib_find_max_char((Py_UCS1*)ascii, (Py_UCS1*)ascii + len) < 128); + assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128); if (writer->buffer == NULL && !writer->overallocate) { PyObject *str; @@ -13862,7 +13862,7 @@ _PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, { Py_UCS4 maxchar; - maxchar = ucs1lib_find_max_char((Py_UCS1*)str, (Py_UCS1*)str + len); + maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len); if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1) return -1; unicode_write_cstr(writer->buffer, writer->pos, str, len); diff --git a/Python/ceval.c b/Python/ceval.c index eb0f131ae8c86..426d0bbee8901 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5440,7 +5440,7 @@ dtrace_function_entry(PyFrameObject *f) funcname = PyUnicode_AsUTF8(f->f_code->co_name); lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); - PyDTrace_FUNCTION_ENTRY((char *)filename, (char *)funcname, lineno); + PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); } static void @@ -5454,7 +5454,7 @@ dtrace_function_return(PyFrameObject *f) funcname = PyUnicode_AsUTF8(f->f_code->co_name); lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); - PyDTrace_FUNCTION_RETURN((char *)filename, (char *)funcname, lineno); + PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); } /* DTrace equivalent of maybe_call_line_trace. */ @@ -5486,7 +5486,7 @@ maybe_dtrace_line(PyFrameObject *frame, co_name = PyUnicode_AsUTF8(frame->f_code->co_name); if (!co_name) co_name = "?"; - PyDTrace_LINE((char *)co_filename, (char *)co_name, line); + PyDTrace_LINE(co_filename, co_name, line); } *instr_prev = frame->f_lasti; } diff --git a/Python/marshal.c b/Python/marshal.c index 04a8dc598988a..4a23df1dcd865 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -734,7 +734,7 @@ r_byte(RFILE *p) else { const char *ptr = r_string(1, p); if (ptr != NULL) - c = *(unsigned char *) ptr; + c = *(const unsigned char *) ptr; } return c; } diff --git a/Python/pyhash.c b/Python/pyhash.c index d381dc0230c5b..faac730d79dee 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -366,7 +366,7 @@ static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T, static uint64_t siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) { uint64_t b = (uint64_t)src_sz << 56; - const uint8_t *in = (uint8_t*)src; + const uint8_t *in = (const uint8_t*)src; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index a7f8c0b719639..cacff529758c6 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -204,7 +204,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) /* Dtrace USDT point */ if (dtrace) { - PyDTrace_AUDIT((char *)event, (void *)eventArgs); + PyDTrace_AUDIT(event, (void *)eventArgs); } /* Call interpreter hooks */ From webhook-mailer at python.org Tue Feb 11 21:47:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 02:47:28 -0000 Subject: [Python-checkins] closes bpo-39605: Fix some casts to not cast away const. (GH-18453) Message-ID: https://github.com/python/cpython/commit/190433d8150bf719fa0ba972dbacf2214942f54e commit: 190433d8150bf719fa0ba972dbacf2214942f54e branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T18:47:20-08:00 summary: closes bpo-39605: Fix some casts to not cast away const. (GH-18453) gcc -Wcast-qual turns up a number of instances of casting away constness of pointers. Some of these can be safely modified, by either: Adding the const to the type cast, as in: - return _PyUnicode_FromUCS1((unsigned char*)s, size); + return _PyUnicode_FromUCS1((const unsigned char*)s, size); or, Removing the cast entirely, because it's not necessary (but probably was at one time), as in: - PyDTrace_FUNCTION_ENTRY((char *)filename, (char *)funcname, lineno); + PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); These changes will not change code, but they will make it much easier to check for errors in consts (cherry picked from commit e6be9b59a911626d6597fe148c32f0342bd2bd24) Co-authored-by: Andy Lester files: M Modules/_io/textio.c M Objects/bytes_methods.c M Objects/memoryobject.c M Objects/stringlib/asciilib.h M Objects/stringlib/codecs.h M Objects/stringlib/find_max_char.h M Objects/unicodeobject.c M Python/marshal.c M Python/pyhash.c diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 2f4a5245681f0..a4bf7cd107670 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1985,7 +1985,7 @@ find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch) { if (kind == PyUnicode_1BYTE_KIND) { assert(ch < 256); - return (char *) memchr((void *) s, (char) ch, end - s); + return (char *) memchr((const void *) s, (char) ch, end - s); } for (;;) { while (PyUnicode_READ(kind, s, 0) > ch) @@ -2003,7 +2003,7 @@ _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, int kind, const char *start, const char *end, Py_ssize_t *consumed) { - Py_ssize_t len = ((char*)end - (char*)start)/kind; + Py_ssize_t len = (end - start)/kind; if (translated) { /* Newlines are already translated, only search for \n */ diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 7d13184205922..db030be4fe756 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -12,7 +12,7 @@ PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -42,7 +42,7 @@ PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -72,7 +72,7 @@ PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -123,7 +123,7 @@ _Py_bytes_isascii(const char *cptr, Py_ssize_t len) /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & ASCII_CHAR_MASK) { Py_RETURN_FALSE; } @@ -154,7 +154,7 @@ PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; /* Shortcut for single character strings */ @@ -184,7 +184,7 @@ PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased; @@ -218,7 +218,7 @@ PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased; @@ -254,7 +254,7 @@ PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len) { const unsigned char *p - = (unsigned char *) cptr; + = (const unsigned char *) cptr; const unsigned char *e; int cased, previous_is_cased; diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index a873ac1ec1ea5..92050791b5d16 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1681,8 +1681,8 @@ unpack_single(const char *ptr, const char *fmt) switch (fmt[0]) { /* signed integers and fast path for 'B' */ - case 'B': uc = *((unsigned char *)ptr); goto convert_uc; - case 'b': ld = *((signed char *)ptr); goto convert_ld; + case 'B': uc = *((const unsigned char *)ptr); goto convert_uc; + case 'b': ld = *((const signed char *)ptr); goto convert_ld; case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld; case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld; case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld; @@ -2683,8 +2683,8 @@ unpack_cmp(const char *p, const char *q, char fmt, switch (fmt) { /* signed integers and fast path for 'B' */ - case 'B': return *((unsigned char *)p) == *((unsigned char *)q); - case 'b': return *((signed char *)p) == *((signed char *)q); + case 'B': return *((const unsigned char *)p) == *((const unsigned char *)q); + case 'b': return *((const signed char *)p) == *((const signed char *)q); case 'h': CMP_SINGLE(p, q, short); return equal; case 'i': CMP_SINGLE(p, q, int); return equal; case 'l': CMP_SINGLE(p, q, long); return equal; diff --git a/Objects/stringlib/asciilib.h b/Objects/stringlib/asciilib.h index d0fc18d22fa5f..8f83614488e84 100644 --- a/Objects/stringlib/asciilib.h +++ b/Objects/stringlib/asciilib.h @@ -18,7 +18,7 @@ #define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL #define STRINGLIB_STR PyUnicode_1BYTE_DATA #define STRINGLIB_LEN PyUnicode_GET_LENGTH -#define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((char*)(STR),(LEN)) +#define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((const char*)(STR),(LEN)) #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index d6f2b98f2b30a..269a5581f7005 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -46,7 +46,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* Read a whole long at a time (either 4 or 8 bytes), and do a fast unrolled copy if it only contains ASCII characters. */ - unsigned long value = *(unsigned long *) _s; + unsigned long value = *(const unsigned long *) _s; if (value & ASCII_CHAR_MASK) break; #if PY_LITTLE_ENDIAN @@ -515,7 +515,7 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, /* Fast path for runs of in-range non-surrogate chars. */ const unsigned char *_q = q; while (_q < aligned_end) { - unsigned long block = * (unsigned long *) _q; + unsigned long block = * (const unsigned long *) _q; if (native_ordering) { /* Can use buffer directly */ if (block & FAST_CHAR_MASK) diff --git a/Objects/stringlib/find_max_char.h b/Objects/stringlib/find_max_char.h index 8ccbc3094463d..f4e0a7761d311 100644 --- a/Objects/stringlib/find_max_char.h +++ b/Objects/stringlib/find_max_char.h @@ -28,7 +28,7 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) /* Help register allocation */ const unsigned char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & UCS1_ASCII_CHAR_MASK) return 255; _p += SIZEOF_LONG; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0556eff8d0713..8ba379e8887e9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -171,8 +171,8 @@ extern "C" { #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ do { \ to_type *_to = (to_type *)(to); \ - const from_type *_iter = (from_type *)(begin); \ - const from_type *_end = (from_type *)(end); \ + const from_type *_iter = (const from_type *)(begin);\ + const from_type *_end = (const from_type *)(end);\ Py_ssize_t n = (_end) - (_iter); \ const from_type *_unrolled_end = \ _iter + _Py_SIZE_ROUND_DOWN(n, 4); \ @@ -919,21 +919,21 @@ findchar(const void *s, int kind, if ((Py_UCS1) ch != ch) return -1; if (direction > 0) - return ucs1lib_find_char((Py_UCS1 *) s, size, (Py_UCS1) ch); + return ucs1lib_find_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); else - return ucs1lib_rfind_char((Py_UCS1 *) s, size, (Py_UCS1) ch); + return ucs1lib_rfind_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); case PyUnicode_2BYTE_KIND: if ((Py_UCS2) ch != ch) return -1; if (direction > 0) - return ucs2lib_find_char((Py_UCS2 *) s, size, (Py_UCS2) ch); + return ucs2lib_find_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); else - return ucs2lib_rfind_char((Py_UCS2 *) s, size, (Py_UCS2) ch); + return ucs2lib_rfind_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); case PyUnicode_4BYTE_KIND: if (direction > 0) - return ucs4lib_find_char((Py_UCS4 *) s, size, ch); + return ucs4lib_find_char((const Py_UCS4 *) s, size, ch); else - return ucs4lib_rfind_char((Py_UCS4 *) s, size, ch); + return ucs4lib_rfind_char((const Py_UCS4 *) s, size, ch); default: Py_UNREACHABLE(); } @@ -3353,7 +3353,7 @@ PyUnicode_Decode(const char *s, /* Decode via the codec registry */ buffer = NULL; - if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0) + if (PyBuffer_FillInfo(&info, NULL, (const void *)s, size, 1, PyBUF_FULL_RO) < 0) goto onError; buffer = PyMemoryView_FromBuffer(&info); if (buffer == NULL) @@ -4861,7 +4861,7 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(unsigned long *) _p; + unsigned long value = *(const unsigned long *) _p; if (value & ASCII_CHAR_MASK) break; _p += SIZEOF_LONG; @@ -5406,7 +5406,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, PyObject *errorHandler = NULL; PyObject *exc = NULL; - q = (unsigned char *)s; + q = (const unsigned char *)s; e = q + size; if (byteorder) @@ -5731,7 +5731,7 @@ PyUnicode_DecodeUTF16Stateful(const char *s, PyObject *exc = NULL; const char *encoding; - q = (unsigned char *)s; + q = (const unsigned char *)s; e = q + size; if (byteorder) @@ -6660,7 +6660,7 @@ PyUnicode_DecodeLatin1(const char *s, const char *errors) { /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */ - return _PyUnicode_FromUCS1((unsigned char*)s, size); + return _PyUnicode_FromUCS1((const unsigned char*)s, size); } /* create or adjust a UnicodeEncodeError */ @@ -13708,7 +13708,7 @@ _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, if (len == -1) len = strlen(ascii); - assert(ucs1lib_find_max_char((Py_UCS1*)ascii, (Py_UCS1*)ascii + len) < 128); + assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128); if (writer->buffer == NULL && !writer->overallocate) { PyObject *str; @@ -13767,7 +13767,7 @@ _PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, { Py_UCS4 maxchar; - maxchar = ucs1lib_find_max_char((Py_UCS1*)str, (Py_UCS1*)str + len); + maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len); if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1) return -1; unicode_write_cstr(writer->buffer, writer->pos, str, len); diff --git a/Python/marshal.c b/Python/marshal.c index c6a06e8c23976..d3fee32380b58 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -734,7 +734,7 @@ r_byte(RFILE *p) else { const char *ptr = r_string(1, p); if (ptr != NULL) - c = *(unsigned char *) ptr; + c = *(const unsigned char *) ptr; } return c; } diff --git a/Python/pyhash.c b/Python/pyhash.c index 4c0b929586fc1..ba224ee373631 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -366,7 +366,7 @@ static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T, static uint64_t siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) { uint64_t b = (uint64_t)src_sz << 56; - const uint8_t *in = (uint8_t*)src; + const uint8_t *in = (const uint8_t*)src; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; From webhook-mailer at python.org Tue Feb 11 21:58:52 2020 From: webhook-mailer at python.org (Jason R. Coombs) Date: Wed, 12 Feb 2020 02:58:52 -0000 Subject: [Python-checkins] bpo-39595: Improve zipfile.Path performance (#18406) Message-ID: https://github.com/python/cpython/commit/e5bd73632e77dc5ab0cab77e48e94ca5e354be8a commit: e5bd73632e77dc5ab0cab77e48e94ca5e354be8a branch: master author: Jason R. Coombs committer: GitHub date: 2020-02-11T21:58:47-05:00 summary: bpo-39595: Improve zipfile.Path performance (#18406) * Improve zipfile.Path performance on zipfiles with a large number of entries. * ?? Added by blurb_it. * Add bpo to blurb * Sync with importlib_metadata 1.5 (6fe70ca) * Update blurb. * Remove compatibility code * Add stubs module, omitted from earlier commit Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Lib/test/test_importlib/stubs.py A Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst M Lib/importlib/metadata.py M Lib/test/test_importlib/fixtures.py M Lib/test/test_importlib/test_main.py M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index ae8ecf9b8500c..831f593277ccd 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -391,6 +391,7 @@ class FastPath: def __init__(self, root): self.root = root + self.base = os.path.basename(root).lower() def joinpath(self, child): return pathlib.Path(self.root, child) @@ -413,12 +414,11 @@ def zip_children(self): ) def is_egg(self, search): - root_n_low = os.path.split(self.root)[1].lower() - + base = self.base return ( - root_n_low == search.normalized + '.egg' - or root_n_low.startswith(search.prefix) - and root_n_low.endswith('.egg')) + base == search.versionless_egg_name + or base.startswith(search.prefix) + and base.endswith('.egg')) def search(self, name): for child in self.children(): @@ -439,6 +439,7 @@ class Prepared: prefix = '' suffixes = '.dist-info', '.egg-info' exact_matches = [''][:0] + versionless_egg_name = '' def __init__(self, name): self.name = name @@ -448,6 +449,7 @@ def __init__(self, name): self.prefix = self.normalized + '-' self.exact_matches = [ self.normalized + suffix for suffix in self.suffixes] + self.versionless_egg_name = self.normalized + '.egg' class MetadataPathFinder(DistributionFinder): diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index 0b4ce18d5a6cd..695c92a786cb0 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -47,14 +47,28 @@ def tempdir_as_cwd(): yield tmp -class SiteDir: + at contextlib.contextmanager +def install_finder(finder): + sys.meta_path.append(finder) + try: + yield + finally: + sys.meta_path.remove(finder) + + +class Fixtures: def setUp(self): self.fixtures = ExitStack() self.addCleanup(self.fixtures.close) + + +class SiteDir(Fixtures): + def setUp(self): + super(SiteDir, self).setUp() self.site_dir = self.fixtures.enter_context(tempdir()) -class OnSysPath: +class OnSysPath(Fixtures): @staticmethod @contextlib.contextmanager def add_sys_path(dir): @@ -198,3 +212,8 @@ def build_files(file_defs, prefix=pathlib.Path()): def DALS(str): "Dedent and left-strip" return textwrap.dedent(str).lstrip() + + +class NullFinder: + def find_module(self, name): + pass diff --git a/Lib/test/test_importlib/stubs.py b/Lib/test/test_importlib/stubs.py new file mode 100644 index 0000000000000..e5b011c399fa9 --- /dev/null +++ b/Lib/test/test_importlib/stubs.py @@ -0,0 +1,10 @@ +import unittest + + +class fake_filesystem_unittest: + """ + Stubbed version of the pyfakefs module + """ + class TestCase(unittest.TestCase): + def setUpPyfakefs(self): + self.skipTest("pyfakefs not available") diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index c5f1dbbae325e..42a79992ecc8c 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -7,6 +7,11 @@ import unittest import importlib.metadata +try: + import pyfakefs.fake_filesystem_unittest as ffs +except ImportError: + from .stubs import fake_filesystem_unittest as ffs + from . import fixtures from importlib.metadata import ( Distribution, EntryPoint, @@ -185,6 +190,33 @@ def test_egg(self): version('foo') +class MissingSysPath(fixtures.OnSysPath, unittest.TestCase): + site_dir = '/does-not-exist' + + def test_discovery(self): + """ + Discovering distributions should succeed even if + there is an invalid path on sys.path. + """ + importlib.metadata.distributions() + + +class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase): + site_dir = '/access-denied' + + def setUp(self): + super(InaccessibleSysPath, self).setUp() + self.setUpPyfakefs() + self.fs.create_dir(self.site_dir, perm_bits=000) + + def test_discovery(self): + """ + Discovering distributions should succeed even if + there is an invalid path on sys.path. + """ + list(importlib.metadata.distributions()) + + class TestEntryPoints(unittest.TestCase): def __init__(self, *args): super(TestEntryPoints, self).__init__(*args) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index c334715f3d81b..09fc850600610 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2724,16 +2724,71 @@ def test_extract_command(self): self.assertEqual(f.read(), zf.read(zi)) +class TestExecutablePrependedZip(unittest.TestCase): + """Test our ability to open zip files with an executable prepended.""" + + def setUp(self): + self.exe_zip = findfile('exe_with_zip', subdir='ziptestdata') + self.exe_zip64 = findfile('exe_with_z64', subdir='ziptestdata') + + def _test_zip_works(self, name): + # bpo28494 sanity check: ensure is_zipfile works on these. + self.assertTrue(zipfile.is_zipfile(name), + f'is_zipfile failed on {name}') + # Ensure we can operate on these via ZipFile. + with zipfile.ZipFile(name) as zipfp: + for n in zipfp.namelist(): + data = zipfp.read(n) + self.assertIn(b'FAVORITE_NUMBER', data) + + def test_read_zip_with_exe_prepended(self): + self._test_zip_works(self.exe_zip) + + def test_read_zip64_with_exe_prepended(self): + self._test_zip_works(self.exe_zip64) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip2(self): + output = subprocess.check_output([self.exe_zip, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip64(self): + output = subprocess.check_output([self.exe_zip64, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + # Poor man's technique to consume a (smallish) iterable. consume = tuple +# from jaraco.itertools 5.0 +class jaraco: + class itertools: + class Counter: + def __init__(self, i): + self.count = 0 + self._orig_iter = iter(i) + + def __iter__(self): + return self + + def __next__(self): + result = next(self._orig_iter) + self.count += 1 + return result + + def add_dirs(zf): """ Given a writable zip file zf, inject directory entries for any directories implied by the presence of children. """ - for name in zipfile.Path._implied_dirs(zf.namelist()): + for name in zipfile.CompleteDirs._implied_dirs(zf.namelist()): zf.writestr(name, b"") return zf @@ -2774,44 +2829,6 @@ def build_alpharep_fixture(): return zf -class TestExecutablePrependedZip(unittest.TestCase): - """Test our ability to open zip files with an executable prepended.""" - - def setUp(self): - self.exe_zip = findfile('exe_with_zip', subdir='ziptestdata') - self.exe_zip64 = findfile('exe_with_z64', subdir='ziptestdata') - - def _test_zip_works(self, name): - # bpo-28494 sanity check: ensure is_zipfile works on these. - self.assertTrue(zipfile.is_zipfile(name), - f'is_zipfile failed on {name}') - # Ensure we can operate on these via ZipFile. - with zipfile.ZipFile(name) as zipfp: - for n in zipfp.namelist(): - data = zipfp.read(n) - self.assertIn(b'FAVORITE_NUMBER', data) - - def test_read_zip_with_exe_prepended(self): - self._test_zip_works(self.exe_zip) - - def test_read_zip64_with_exe_prepended(self): - self._test_zip_works(self.exe_zip64) - - @unittest.skipUnless(sys.executable, 'sys.executable required.') - @unittest.skipUnless(os.access('/bin/bash', os.X_OK), - 'Test relies on #!/bin/bash working.') - def test_execute_zip2(self): - output = subprocess.check_output([self.exe_zip, sys.executable]) - self.assertIn(b'number in executable: 5', output) - - @unittest.skipUnless(sys.executable, 'sys.executable required.') - @unittest.skipUnless(os.access('/bin/bash', os.X_OK), - 'Test relies on #!/bin/bash working.') - def test_execute_zip64(self): - output = subprocess.check_output([self.exe_zip64, sys.executable]) - self.assertIn(b'number in executable: 5', output) - - class TestPath(unittest.TestCase): def setUp(self): self.fixtures = contextlib.ExitStack() @@ -2849,6 +2866,14 @@ def test_iterdir_and_types(self): i, = h.iterdir() assert i.is_file() + def test_subdir_is_dir(self): + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + assert (root / 'b').is_dir() + assert (root / 'b/').is_dir() + assert (root / 'g').is_dir() + assert (root / 'g/').is_dir() + def test_open(self): for alpharep in self.zipfile_alpharep(): root = zipfile.Path(alpharep) @@ -2910,6 +2935,45 @@ def test_missing_dir_parent(self): root = zipfile.Path(alpharep) assert (root / 'missing dir/').parent.at == '' + def test_mutability(self): + """ + If the underlying zipfile is changed, the Path object should + reflect that change. + """ + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() + alpharep.writestr('foo.txt', 'foo') + alpharep.writestr('bar/baz.txt', 'baz') + assert any( + child.name == 'foo.txt' + for child in root.iterdir()) + assert (root / 'foo.txt').read_text() == 'foo' + baz, = (root / 'bar').iterdir() + assert baz.read_text() == 'baz' + + HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13 + + def huge_zipfile(self): + """Create a read-only zipfile with a huge number of entries entries.""" + strm = io.BytesIO() + zf = zipfile.ZipFile(strm, "w") + for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)): + zf.writestr(entry, entry) + zf.mode = 'r' + return zf + + def test_joinpath_constant_time(self): + """ + Ensure joinpath on items in zipfile is linear time. + """ + root = zipfile.Path(self.huge_zipfile()) + entries = jaraco.itertools.Counter(root.iterdir()) + for entry in entries: + entry.joinpath('suffix') + # Check the file iterated all items + assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 2da87ef505e6e..4510fac250b97 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -16,6 +16,8 @@ import sys import threading import time +import contextlib +from collections import OrderedDict try: import zlib # We may need its compression method @@ -2159,6 +2161,79 @@ def _ancestry(path): path, tail = posixpath.split(path) +class CompleteDirs(ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + # Deduplicate entries in original order + implied_dirs = OrderedDict.fromkeys( + p + posixpath.sep for p in parents + # Cast names to a set for O(1) lookups + if p + posixpath.sep not in set(names) + ) + return implied_dirs + + def namelist(self): + names = super(CompleteDirs, self).namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, ZipFile): + return cls(source) + + # Only allow for FastPath when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + res = cls.__new__(cls) + vars(res).update(vars(source)) + return res + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super(FastLookup, self).namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super(FastLookup, self)._name_set() + return self.__lookup + + class Path: """ A pathlib-compatible interface for zip files. @@ -2227,7 +2302,7 @@ class Path: __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" def __init__(self, root, at=""): - self.root = root if isinstance(root, ZipFile) else ZipFile(root) + self.root = FastLookup.make(root) self.at = at @property @@ -2259,12 +2334,12 @@ def is_file(self): return not self.is_dir() def exists(self): - return self.at in self._names() + return self.at in self.root._name_set() def iterdir(self): if not self.is_dir(): raise ValueError("Can't listdir a file") - subs = map(self._next, self._names()) + subs = map(self._next, self.root.namelist()) return filter(self._is_child, subs) def __str__(self): @@ -2275,25 +2350,10 @@ def __repr__(self): def joinpath(self, add): next = posixpath.join(self.at, add) - next_dir = posixpath.join(self.at, add, "") - names = self._names() - return self._next(next_dir if next not in names and next_dir in names else next) + return self._next(self.root.resolve_dir(next)) __truediv__ = joinpath - @staticmethod - def _implied_dirs(names): - return _unique_everseen( - parent + "/" - for name in names - for parent in _parents(name) - if parent + "/" not in names - ) - - @classmethod - def _add_implied_dirs(cls, names): - return names + list(cls._implied_dirs(names)) - @property def parent(self): parent_at = posixpath.dirname(self.at.rstrip('/')) @@ -2301,9 +2361,6 @@ def parent(self): parent_at += '/' return self._next(parent_at) - def _names(self): - return self._add_implied_dirs(self.root.namelist()) - def main(args=None): import argparse @@ -2365,5 +2422,6 @@ def addToZip(zf, path, zippath): zippath = '' addToZip(zf, path, zippath) + if __name__ == "__main__": main() diff --git a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst new file mode 100644 index 0000000000000..3a461389af7d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst @@ -0,0 +1 @@ +Improved performance of zipfile.Path for files with a large number of entries. Also improved performance and fixed minor issue as published with `importlib_metadata 1.5 `_. From webhook-mailer at python.org Tue Feb 11 22:21:36 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 03:21:36 -0000 Subject: [Python-checkins] bpo-39595: Improve zipfile.Path performance (GH-18406) (GH-18472) Message-ID: https://github.com/python/cpython/commit/ed4d263e8767b0e4c47df99141b500d36ce0275d commit: ed4d263e8767b0e4c47df99141b500d36ce0275d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T22:21:32-05:00 summary: bpo-39595: Improve zipfile.Path performance (GH-18406) (GH-18472) * Improve zipfile.Path performance on zipfiles with a large number of entries. * ?? Added by blurb_it. * Add bpo to blurb * Sync with importlib_metadata 1.5 (6fe70ca) * Update blurb. * Remove compatibility code * Add stubs module, omitted from earlier commit Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> (cherry picked from commit e5bd73632e77dc5ab0cab77e48e94ca5e354be8a) Co-authored-by: Jason R. Coombs Co-authored-by: Jason R. Coombs files: A Lib/test/test_importlib/stubs.py A Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst M Lib/importlib/metadata.py M Lib/test/test_importlib/fixtures.py M Lib/test/test_importlib/test_main.py M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index ae8ecf9b8500c..831f593277ccd 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -391,6 +391,7 @@ class FastPath: def __init__(self, root): self.root = root + self.base = os.path.basename(root).lower() def joinpath(self, child): return pathlib.Path(self.root, child) @@ -413,12 +414,11 @@ def zip_children(self): ) def is_egg(self, search): - root_n_low = os.path.split(self.root)[1].lower() - + base = self.base return ( - root_n_low == search.normalized + '.egg' - or root_n_low.startswith(search.prefix) - and root_n_low.endswith('.egg')) + base == search.versionless_egg_name + or base.startswith(search.prefix) + and base.endswith('.egg')) def search(self, name): for child in self.children(): @@ -439,6 +439,7 @@ class Prepared: prefix = '' suffixes = '.dist-info', '.egg-info' exact_matches = [''][:0] + versionless_egg_name = '' def __init__(self, name): self.name = name @@ -448,6 +449,7 @@ def __init__(self, name): self.prefix = self.normalized + '-' self.exact_matches = [ self.normalized + suffix for suffix in self.suffixes] + self.versionless_egg_name = self.normalized + '.egg' class MetadataPathFinder(DistributionFinder): diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index 0b4ce18d5a6cd..695c92a786cb0 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -47,14 +47,28 @@ def tempdir_as_cwd(): yield tmp -class SiteDir: + at contextlib.contextmanager +def install_finder(finder): + sys.meta_path.append(finder) + try: + yield + finally: + sys.meta_path.remove(finder) + + +class Fixtures: def setUp(self): self.fixtures = ExitStack() self.addCleanup(self.fixtures.close) + + +class SiteDir(Fixtures): + def setUp(self): + super(SiteDir, self).setUp() self.site_dir = self.fixtures.enter_context(tempdir()) -class OnSysPath: +class OnSysPath(Fixtures): @staticmethod @contextlib.contextmanager def add_sys_path(dir): @@ -198,3 +212,8 @@ def build_files(file_defs, prefix=pathlib.Path()): def DALS(str): "Dedent and left-strip" return textwrap.dedent(str).lstrip() + + +class NullFinder: + def find_module(self, name): + pass diff --git a/Lib/test/test_importlib/stubs.py b/Lib/test/test_importlib/stubs.py new file mode 100644 index 0000000000000..e5b011c399fa9 --- /dev/null +++ b/Lib/test/test_importlib/stubs.py @@ -0,0 +1,10 @@ +import unittest + + +class fake_filesystem_unittest: + """ + Stubbed version of the pyfakefs module + """ + class TestCase(unittest.TestCase): + def setUpPyfakefs(self): + self.skipTest("pyfakefs not available") diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index c5f1dbbae325e..42a79992ecc8c 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -7,6 +7,11 @@ import unittest import importlib.metadata +try: + import pyfakefs.fake_filesystem_unittest as ffs +except ImportError: + from .stubs import fake_filesystem_unittest as ffs + from . import fixtures from importlib.metadata import ( Distribution, EntryPoint, @@ -185,6 +190,33 @@ def test_egg(self): version('foo') +class MissingSysPath(fixtures.OnSysPath, unittest.TestCase): + site_dir = '/does-not-exist' + + def test_discovery(self): + """ + Discovering distributions should succeed even if + there is an invalid path on sys.path. + """ + importlib.metadata.distributions() + + +class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase): + site_dir = '/access-denied' + + def setUp(self): + super(InaccessibleSysPath, self).setUp() + self.setUpPyfakefs() + self.fs.create_dir(self.site_dir, perm_bits=000) + + def test_discovery(self): + """ + Discovering distributions should succeed even if + there is an invalid path on sys.path. + """ + list(importlib.metadata.distributions()) + + class TestEntryPoints(unittest.TestCase): def __init__(self, *args): super(TestEntryPoints, self).__init__(*args) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index c65de9202c0c4..61bca8651c02a 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2683,16 +2683,71 @@ def test_extract_command(self): self.assertEqual(f.read(), zf.read(zi)) +class TestExecutablePrependedZip(unittest.TestCase): + """Test our ability to open zip files with an executable prepended.""" + + def setUp(self): + self.exe_zip = findfile('exe_with_zip', subdir='ziptestdata') + self.exe_zip64 = findfile('exe_with_z64', subdir='ziptestdata') + + def _test_zip_works(self, name): + # bpo28494 sanity check: ensure is_zipfile works on these. + self.assertTrue(zipfile.is_zipfile(name), + f'is_zipfile failed on {name}') + # Ensure we can operate on these via ZipFile. + with zipfile.ZipFile(name) as zipfp: + for n in zipfp.namelist(): + data = zipfp.read(n) + self.assertIn(b'FAVORITE_NUMBER', data) + + def test_read_zip_with_exe_prepended(self): + self._test_zip_works(self.exe_zip) + + def test_read_zip64_with_exe_prepended(self): + self._test_zip_works(self.exe_zip64) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip2(self): + output = subprocess.check_output([self.exe_zip, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + @unittest.skipUnless(sys.executable, 'sys.executable required.') + @unittest.skipUnless(os.access('/bin/bash', os.X_OK), + 'Test relies on #!/bin/bash working.') + def test_execute_zip64(self): + output = subprocess.check_output([self.exe_zip64, sys.executable]) + self.assertIn(b'number in executable: 5', output) + + # Poor man's technique to consume a (smallish) iterable. consume = tuple +# from jaraco.itertools 5.0 +class jaraco: + class itertools: + class Counter: + def __init__(self, i): + self.count = 0 + self._orig_iter = iter(i) + + def __iter__(self): + return self + + def __next__(self): + result = next(self._orig_iter) + self.count += 1 + return result + + def add_dirs(zf): """ Given a writable zip file zf, inject directory entries for any directories implied by the presence of children. """ - for name in zipfile.Path._implied_dirs(zf.namelist()): + for name in zipfile.CompleteDirs._implied_dirs(zf.namelist()): zf.writestr(name, b"") return zf @@ -2733,44 +2788,6 @@ def build_alpharep_fixture(): return zf -class TestExecutablePrependedZip(unittest.TestCase): - """Test our ability to open zip files with an executable prepended.""" - - def setUp(self): - self.exe_zip = findfile('exe_with_zip', subdir='ziptestdata') - self.exe_zip64 = findfile('exe_with_z64', subdir='ziptestdata') - - def _test_zip_works(self, name): - # bpo-28494 sanity check: ensure is_zipfile works on these. - self.assertTrue(zipfile.is_zipfile(name), - f'is_zipfile failed on {name}') - # Ensure we can operate on these via ZipFile. - with zipfile.ZipFile(name) as zipfp: - for n in zipfp.namelist(): - data = zipfp.read(n) - self.assertIn(b'FAVORITE_NUMBER', data) - - def test_read_zip_with_exe_prepended(self): - self._test_zip_works(self.exe_zip) - - def test_read_zip64_with_exe_prepended(self): - self._test_zip_works(self.exe_zip64) - - @unittest.skipUnless(sys.executable, 'sys.executable required.') - @unittest.skipUnless(os.access('/bin/bash', os.X_OK), - 'Test relies on #!/bin/bash working.') - def test_execute_zip2(self): - output = subprocess.check_output([self.exe_zip, sys.executable]) - self.assertIn(b'number in executable: 5', output) - - @unittest.skipUnless(sys.executable, 'sys.executable required.') - @unittest.skipUnless(os.access('/bin/bash', os.X_OK), - 'Test relies on #!/bin/bash working.') - def test_execute_zip64(self): - output = subprocess.check_output([self.exe_zip64, sys.executable]) - self.assertIn(b'number in executable: 5', output) - - class TestPath(unittest.TestCase): def setUp(self): self.fixtures = contextlib.ExitStack() @@ -2808,6 +2825,14 @@ def test_iterdir_and_types(self): i, = h.iterdir() assert i.is_file() + def test_subdir_is_dir(self): + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + assert (root / 'b').is_dir() + assert (root / 'b/').is_dir() + assert (root / 'g').is_dir() + assert (root / 'g/').is_dir() + def test_open(self): for alpharep in self.zipfile_alpharep(): root = zipfile.Path(alpharep) @@ -2869,6 +2894,45 @@ def test_missing_dir_parent(self): root = zipfile.Path(alpharep) assert (root / 'missing dir/').parent.at == '' + def test_mutability(self): + """ + If the underlying zipfile is changed, the Path object should + reflect that change. + """ + for alpharep in self.zipfile_alpharep(): + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() + alpharep.writestr('foo.txt', 'foo') + alpharep.writestr('bar/baz.txt', 'baz') + assert any( + child.name == 'foo.txt' + for child in root.iterdir()) + assert (root / 'foo.txt').read_text() == 'foo' + baz, = (root / 'bar').iterdir() + assert baz.read_text() == 'baz' + + HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13 + + def huge_zipfile(self): + """Create a read-only zipfile with a huge number of entries entries.""" + strm = io.BytesIO() + zf = zipfile.ZipFile(strm, "w") + for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)): + zf.writestr(entry, entry) + zf.mode = 'r' + return zf + + def test_joinpath_constant_time(self): + """ + Ensure joinpath on items in zipfile is linear time. + """ + root = zipfile.Path(self.huge_zipfile()) + entries = jaraco.itertools.Counter(root.iterdir()) + for entry in entries: + entry.joinpath('suffix') + # Check the file iterated all items + assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 8b99c1189baa8..5dc6516cc47b7 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -16,6 +16,8 @@ import sys import threading import time +import contextlib +from collections import OrderedDict try: import zlib # We may need its compression method @@ -2182,6 +2184,79 @@ def _ancestry(path): path, tail = posixpath.split(path) +class CompleteDirs(ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + # Deduplicate entries in original order + implied_dirs = OrderedDict.fromkeys( + p + posixpath.sep for p in parents + # Cast names to a set for O(1) lookups + if p + posixpath.sep not in set(names) + ) + return implied_dirs + + def namelist(self): + names = super(CompleteDirs, self).namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, ZipFile): + return cls(source) + + # Only allow for FastPath when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + res = cls.__new__(cls) + vars(res).update(vars(source)) + return res + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super(FastLookup, self).namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super(FastLookup, self)._name_set() + return self.__lookup + + class Path: """ A pathlib-compatible interface for zip files. @@ -2250,7 +2325,7 @@ class Path: __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" def __init__(self, root, at=""): - self.root = root if isinstance(root, ZipFile) else ZipFile(root) + self.root = FastLookup.make(root) self.at = at @property @@ -2282,12 +2357,12 @@ def is_file(self): return not self.is_dir() def exists(self): - return self.at in self._names() + return self.at in self.root._name_set() def iterdir(self): if not self.is_dir(): raise ValueError("Can't listdir a file") - subs = map(self._next, self._names()) + subs = map(self._next, self.root.namelist()) return filter(self._is_child, subs) def __str__(self): @@ -2298,25 +2373,10 @@ def __repr__(self): def joinpath(self, add): next = posixpath.join(self.at, add) - next_dir = posixpath.join(self.at, add, "") - names = self._names() - return self._next(next_dir if next not in names and next_dir in names else next) + return self._next(self.root.resolve_dir(next)) __truediv__ = joinpath - @staticmethod - def _implied_dirs(names): - return _unique_everseen( - parent + "/" - for name in names - for parent in _parents(name) - if parent + "/" not in names - ) - - @classmethod - def _add_implied_dirs(cls, names): - return names + list(cls._implied_dirs(names)) - @property def parent(self): parent_at = posixpath.dirname(self.at.rstrip('/')) @@ -2324,9 +2384,6 @@ def parent(self): parent_at += '/' return self._next(parent_at) - def _names(self): - return self._add_implied_dirs(self.root.namelist()) - def main(args=None): import argparse @@ -2388,5 +2445,6 @@ def addToZip(zf, path, zippath): zippath = '' addToZip(zf, path, zippath) + if __name__ == "__main__": main() diff --git a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst new file mode 100644 index 0000000000000..3a461389af7d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst @@ -0,0 +1 @@ +Improved performance of zipfile.Path for files with a large number of entries. Also improved performance and fixed minor issue as published with `importlib_metadata 1.5 `_. From webhook-mailer at python.org Tue Feb 11 22:36:22 2020 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 12 Feb 2020 03:36:22 -0000 Subject: [Python-checkins] bpo-39605: Remove a cast that causes a warning. (GH-18473) Message-ID: https://github.com/python/cpython/commit/95905ce0f41fd42eb1ef60ddb83f057401c3d52f commit: 95905ce0f41fd42eb1ef60ddb83f057401c3d52f branch: master author: Benjamin Peterson committer: GitHub date: 2020-02-11T19:36:14-08:00 summary: bpo-39605: Remove a cast that causes a warning. (GH-18473) files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fdc2ca6612cc5..8470e41624bd4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3420,7 +3420,7 @@ PyUnicode_Decode(const char *s, /* Decode via the codec registry */ buffer = NULL; - if (PyBuffer_FillInfo(&info, NULL, (const void *)s, size, 1, PyBUF_FULL_RO) < 0) + if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0) goto onError; buffer = PyMemoryView_FromBuffer(&info); if (buffer == NULL) From webhook-mailer at python.org Tue Feb 11 22:52:54 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 03:52:54 -0000 Subject: [Python-checkins] bpo-39605: Remove a cast that causes a warning. (GH-18473) Message-ID: https://github.com/python/cpython/commit/0b8f738eb3ee0110461e7da28c0b6b452f91999d commit: 0b8f738eb3ee0110461e7da28c0b6b452f91999d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-11T19:52:46-08:00 summary: bpo-39605: Remove a cast that causes a warning. (GH-18473) (cherry picked from commit 95905ce0f41fd42eb1ef60ddb83f057401c3d52f) Co-authored-by: Benjamin Peterson files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8ba379e8887e9..4c2b42f959b83 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3353,7 +3353,7 @@ PyUnicode_Decode(const char *s, /* Decode via the codec registry */ buffer = NULL; - if (PyBuffer_FillInfo(&info, NULL, (const void *)s, size, 1, PyBUF_FULL_RO) < 0) + if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0) goto onError; buffer = PyMemoryView_FromBuffer(&info); if (buffer == NULL) From webhook-mailer at python.org Wed Feb 12 05:11:42 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 12 Feb 2020 10:11:42 -0000 Subject: [Python-checkins] bpo-39567: Add audit for os.walk(), os.fwalk(), Path.glob() and Path.rglob(). (GH-18372) Message-ID: https://github.com/python/cpython/commit/f4f445b69306c68a2ba8ce8eb8c6cb3064db5fe7 commit: f4f445b69306c68a2ba8ce8eb8c6cb3064db5fe7 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-12T12:11:34+02:00 summary: bpo-39567: Add audit for os.walk(), os.fwalk(), Path.glob() and Path.rglob(). (GH-18372) files: A Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst M Lib/os.py M Lib/pathlib.py diff --git a/Lib/os.py b/Lib/os.py index 7ae102617e8b1..ab75b94d4fe45 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -336,7 +336,10 @@ def walk(top, topdown=True, onerror=None, followlinks=False): dirs.remove('CVS') # don't visit CVS directories """ - top = fspath(top) + sys.audit("os.walk", top, topdown, onerror, followlinks) + return _walk(fspath(top), topdown, onerror, followlinks) + +def _walk(top, topdown, onerror, followlinks): dirs = [] nondirs = [] walk_dirs = [] @@ -410,11 +413,11 @@ def walk(top, topdown=True, onerror=None, followlinks=False): # the caller can replace the directory entry during the "yield" # above. if followlinks or not islink(new_path): - yield from walk(new_path, topdown, onerror, followlinks) + yield from _walk(new_path, topdown, onerror, followlinks) else: # Recurse into sub-directories for new_path in walk_dirs: - yield from walk(new_path, topdown, onerror, followlinks) + yield from _walk(new_path, topdown, onerror, followlinks) # Yield after recursion if going bottom up yield top, dirs, nondirs @@ -455,6 +458,7 @@ def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd= if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories """ + sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd) if not isinstance(top, int) or not hasattr(top, '__index__'): top = fspath(top) # Note: To guard against symlink races, we use the standard diff --git a/Lib/pathlib.py b/Lib/pathlib.py index a5f3313902e1b..cfa574af6e8ba 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1134,6 +1134,7 @@ def glob(self, pattern): """Iterate over this subtree and yield all existing files (of any kind, including directories) matching the given relative pattern. """ + sys.audit("pathlib.Path.glob", self, pattern) if not pattern: raise ValueError("Unacceptable pattern: {!r}".format(pattern)) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) @@ -1148,6 +1149,7 @@ def rglob(self, pattern): directories) matching the given relative pattern, anywhere in this subtree. """ + sys.audit("pathlib.Path.rglob", self, pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) if drv or root: raise NotImplementedError("Non-relative patterns are unsupported") diff --git a/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst b/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst new file mode 100644 index 0000000000000..3c4700f455b5e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst @@ -0,0 +1,2 @@ +Added audit for :func:`os.walk`, :func:`os.fwalk`, :meth:`pathlib.Path.glob` +and :meth:`pathlib.Path.rglob`. From webhook-mailer at python.org Wed Feb 12 05:17:08 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 12 Feb 2020 10:17:08 -0000 Subject: [Python-checkins] bpo-39219: Fix SyntaxError attributes in the tokenizer. (GH-17828) Message-ID: https://github.com/python/cpython/commit/0cc6b5e559b8303b18fdd56c2befd900fe7b5e35 commit: 0cc6b5e559b8303b18fdd56c2befd900fe7b5e35 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-12T12:17:00+02:00 summary: bpo-39219: Fix SyntaxError attributes in the tokenizer. (GH-17828) * Always set the text attribute. * Correct the offset attribute for non-ascii sources. files: A Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst M Lib/test/test_exceptions.py M Parser/tokenizer.c diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 4d1aa4bca623f..22a22363a7d43 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -179,17 +179,25 @@ def ckmsg(src, msg, exception=SyntaxError): ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) def testSyntaxErrorOffset(self): - def check(src, lineno, offset): + def check(src, lineno, offset, encoding='utf-8'): with self.assertRaises(SyntaxError) as cm: compile(src, '', 'exec') self.assertEqual(cm.exception.lineno, lineno) self.assertEqual(cm.exception.offset, offset) + if cm.exception.text is not None: + if not isinstance(src, str): + src = src.decode(encoding, 'replace') + line = src.split('\n')[lineno-1] + self.assertEqual(cm.exception.text.rstrip('\n'), line) check('def fact(x):\n\treturn x!\n', 2, 10) check('1 +\n', 1, 4) check('def spam():\n print(1)\n print(2)', 3, 10) check('Python = "Python" +', 1, 20) check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) + check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +', + 2, 19, encoding='cp1251') + check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18) check('x = "a', 1, 7) check('lambda x: x = 2', 1, 1) @@ -205,6 +213,10 @@ def check(src, lineno, offset): check('0010 + 2', 1, 4) check('x = 32e-+4', 1, 8) check('x = 0o9', 1, 6) + check('\u03b1 = 0xI', 1, 6) + check(b'\xce\xb1 = 0xI', 1, 6) + check(b'# -*- coding: iso8859-7 -*-\n\xe1 = 0xI', 2, 6, + encoding='iso8859-7') # Errors thrown by symtable.c check('x = [(yield i) for i in range(3)]', 1, 5) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst new file mode 100644 index 0000000000000..dac8360df712c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst @@ -0,0 +1,2 @@ +Syntax errors raised in the tokenizer now always set correct "text" and +"offset" attributes. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index c37cd927df5a4..630b0aaab03f9 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1,6 +1,7 @@ /* Tokenizer implementation */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include @@ -1034,17 +1035,44 @@ tok_backup(struct tok_state *tok, int c) static int syntaxerror(struct tok_state *tok, const char *format, ...) { + PyObject *errmsg, *errtext, *args; va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - PyErr_FormatV(PyExc_SyntaxError, format, vargs); + errmsg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); - PyErr_SyntaxLocationObject(tok->filename, - tok->lineno, - (int)(tok->cur - tok->line_start)); + if (!errmsg) { + goto error; + } + + errtext = PyUnicode_DecodeUTF8(tok->line_start, tok->cur - tok->line_start, + "replace"); + if (!errtext) { + goto error; + } + int offset = (int)PyUnicode_GET_LENGTH(errtext); + Py_ssize_t line_len = strcspn(tok->line_start, "\n"); + if (line_len != tok->cur - tok->line_start) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(tok->line_start, line_len, + "replace"); + } + if (!errtext) { + goto error; + } + + args = Py_BuildValue("(O(OiiN))", errmsg, + tok->filename, tok->lineno, offset, errtext); + if (args) { + PyErr_SetObject(PyExc_SyntaxError, args); + Py_DECREF(args); + } + +error: + Py_XDECREF(errmsg); tok->done = E_ERROR; return ERRORTOKEN; } From webhook-mailer at python.org Wed Feb 12 05:19:08 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 12 Feb 2020 10:19:08 -0000 Subject: [Python-checkins] bpo-32856: Optimize the assignment idiom in comprehensions. (GH-16814) Message-ID: https://github.com/python/cpython/commit/8c579b1cc86053473eb052b76327279476740c9b commit: 8c579b1cc86053473eb052b76327279476740c9b branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-12T12:18:59+02:00 summary: bpo-32856: Optimize the assignment idiom in comprehensions. (GH-16814) Now `for y in [expr]` in comprehensions is as fast as a simple assignment `y = expr`. files: A Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD.rst M Doc/whatsnew/3.9.rst M Lib/test/test_dictcomps.py M Lib/test/test_genexps.py M Lib/test/test_listcomps.py M Lib/test/test_peepholer.py M Lib/test/test_setcomps.py M Python/compile.c diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index c0404101d7ce2..ec179845aee7c 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -315,6 +315,17 @@ case), and one used ``__VENV_NAME__`` instead. Optimizations ============= +* Optimized the idiom for assignment a temporary variable in comprehensions. + Now ``for y in [expr]`` in comprehensions is as fast as a simple assignment + ``y = expr``. For example: + + sums = [s for s in [0] for x in data for s in [s + x]] + + Unlike to the ``:=`` operator this idiom does not leak a variable to the + outer scope. + + (Contributed by Serhiy Storchaka in :issue:`32856`.) + Build and C API Changes ======================= diff --git a/Lib/test/test_dictcomps.py b/Lib/test/test_dictcomps.py index 927e3103e664b..16aa651b93c46 100644 --- a/Lib/test/test_dictcomps.py +++ b/Lib/test/test_dictcomps.py @@ -111,5 +111,22 @@ def add_call(pos, value): self.assertEqual(actual, expected) self.assertEqual(actual_calls, expected_calls) + def test_assignment_idiom_in_comprehensions(self): + expected = {1: 1, 2: 4, 3: 9, 4: 16} + actual = {j: j*j for i in range(4) for j in [i+1]} + self.assertEqual(actual, expected) + expected = {3: 2, 5: 6, 7: 12, 9: 20} + actual = {j+k: j*k for i in range(4) for j in [i+1] for k in [j+1]} + self.assertEqual(actual, expected) + expected = {3: 2, 5: 6, 7: 12, 9: 20} + actual = {j+k: j*k for i in range(4) for j, k in [(i+1, i+2)]} + self.assertEqual(actual, expected) + + def test_star_expression(self): + expected = {0: 0, 1: 1, 2: 4, 3: 9} + self.assertEqual({i: i*i for i in [*range(4)]}, expected) + self.assertEqual({i: i*i for i in (*range(4),)}, expected) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index fd712bb172d5d..86e4e195f55ec 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -15,6 +15,22 @@ >>> list((i,j) for i in range(4) for j in range(i) ) [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)] +Test the idiom for temporary variable assignment in comprehensions. + + >>> list((j*j for i in range(4) for j in [i+1])) + [1, 4, 9, 16] + >>> list((j*k for i in range(4) for j in [i+1] for k in [j+1])) + [2, 6, 12, 20] + >>> list((j*k for i in range(4) for j, k in [(i+1, i+2)])) + [2, 6, 12, 20] + +Not assignment + + >>> list((i*i for i in [*range(4)])) + [0, 1, 4, 9] + >>> list((i*i for i in (*range(4),))) + [0, 1, 4, 9] + Make sure the induction variable is not exposed >>> i = 20 diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index ddb169fe58957..62b3319ad936d 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -16,6 +16,22 @@ >>> [(i,j) for i in range(4) for j in range(i)] [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)] +Test the idiom for temporary variable assignment in comprehensions. + + >>> [j*j for i in range(4) for j in [i+1]] + [1, 4, 9, 16] + >>> [j*k for i in range(4) for j in [i+1] for k in [j+1]] + [2, 6, 12, 20] + >>> [j*k for i in range(4) for j, k in [(i+1, i+2)]] + [2, 6, 12, 20] + +Not assignment + + >>> [i*i for i in [*range(4)]] + [0, 1, 4, 9] + >>> [i*i for i in (*range(4),)] + [0, 1, 4, 9] + Make sure the induction variable is not exposed >>> i = 20 diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 567e6a14361d1..7913e91e453ca 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -495,6 +495,20 @@ def f(x): return 6 self.check_lnotab(f) + def test_assignment_idiom_in_comprehensions(self): + def listcomp(): + return [y for x in a for y in [f(x)]] + self.assertEqual(count_instr_recursively(listcomp, 'FOR_ITER'), 1) + def setcomp(): + return {y for x in a for y in [f(x)]} + self.assertEqual(count_instr_recursively(setcomp, 'FOR_ITER'), 1) + def dictcomp(): + return {y: y for x in a for y in [f(x)]} + self.assertEqual(count_instr_recursively(dictcomp, 'FOR_ITER'), 1) + def genexpr(): + return (y for x in a for y in [f(x)]) + self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1) + class TestBuglets(unittest.TestCase): diff --git a/Lib/test/test_setcomps.py b/Lib/test/test_setcomps.py index fb7cde03d7823..ecc4fffec0d84 100644 --- a/Lib/test/test_setcomps.py +++ b/Lib/test/test_setcomps.py @@ -21,6 +21,22 @@ >>> list(sorted({(i,j) for i in range(4) for j in range(i)})) [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)] +Test the idiom for temporary variable assignment in comprehensions. + + >>> sorted({j*j for i in range(4) for j in [i+1]}) + [1, 4, 9, 16] + >>> sorted({j*k for i in range(4) for j in [i+1] for k in [j+1]}) + [2, 6, 12, 20] + >>> sorted({j*k for i in range(4) for j, k in [(i+1, i+2)]}) + [2, 6, 12, 20] + +Not assignment + + >>> sorted({i*i for i in [*range(4)]}) + [0, 1, 4, 9] + >>> sorted({i*i for i in (*range(4),)}) + [0, 1, 4, 9] + Make sure the induction variable is not exposed >>> i = 20 diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD.rst new file mode 100644 index 0000000000000..c1cd68f672712 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD.rst @@ -0,0 +1,3 @@ +Optimized the idiom for assignment a temporary variable in comprehensions. +Now ``for y in [expr]`` in comprehensions is as fast as a simple assignment +``y = expr``. diff --git a/Python/compile.c b/Python/compile.c index 04b8fe46e194d..bf8c8109d0758 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -212,11 +212,13 @@ static int compiler_set_qualname(struct compiler *); static int compiler_sync_comprehension_generator( struct compiler *c, asdl_seq *generators, int gen_index, + int depth, expr_ty elt, expr_ty val, int type); static int compiler_async_comprehension_generator( struct compiler *c, asdl_seq *generators, int gen_index, + int depth, expr_ty elt, expr_ty val, int type); static PyCodeObject *assemble(struct compiler *, int addNone); @@ -4343,22 +4345,24 @@ compiler_call_helper(struct compiler *c, static int compiler_comprehension_generator(struct compiler *c, asdl_seq *generators, int gen_index, + int depth, expr_ty elt, expr_ty val, int type) { comprehension_ty gen; gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); if (gen->is_async) { return compiler_async_comprehension_generator( - c, generators, gen_index, elt, val, type); + c, generators, gen_index, depth, elt, val, type); } else { return compiler_sync_comprehension_generator( - c, generators, gen_index, elt, val, type); + c, generators, gen_index, depth, elt, val, type); } } static int compiler_sync_comprehension_generator(struct compiler *c, asdl_seq *generators, int gen_index, + int depth, expr_ty elt, expr_ty val, int type) { /* generate code for the iterator, then each of the ifs, @@ -4386,12 +4390,38 @@ compiler_sync_comprehension_generator(struct compiler *c, } else { /* Sub-iter - calculate on the fly */ - VISIT(c, expr, gen->iter); - ADDOP(c, GET_ITER); + /* Fast path for the temporary variable assignment idiom: + for y in [f(x)] + */ + asdl_seq *elts; + switch (gen->iter->kind) { + case List_kind: + elts = gen->iter->v.List.elts; + break; + case Tuple_kind: + elts = gen->iter->v.Tuple.elts; + break; + default: + elts = NULL; + } + if (asdl_seq_LEN(elts) == 1) { + expr_ty elt = asdl_seq_GET(elts, 0); + if (elt->kind != Starred_kind) { + VISIT(c, expr, elt); + start = NULL; + } + } + if (start) { + VISIT(c, expr, gen->iter); + ADDOP(c, GET_ITER); + } + } + if (start) { + depth++; + compiler_use_next_block(c, start); + ADDOP_JREL(c, FOR_ITER, anchor); + NEXT_BLOCK(c); } - compiler_use_next_block(c, start); - ADDOP_JREL(c, FOR_ITER, anchor); - NEXT_BLOCK(c); VISIT(c, expr, gen->target); /* XXX this needs to be cleaned up...a lot! */ @@ -4405,7 +4435,7 @@ compiler_sync_comprehension_generator(struct compiler *c, if (++gen_index < asdl_seq_LEN(generators)) if (!compiler_comprehension_generator(c, - generators, gen_index, + generators, gen_index, depth, elt, val, type)) return 0; @@ -4420,18 +4450,18 @@ compiler_sync_comprehension_generator(struct compiler *c, break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, gen_index + 1); + ADDOP_I(c, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, gen_index + 1); + ADDOP_I(c, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, gen_index + 1); + ADDOP_I(c, MAP_ADD, depth + 1); break; default: return 0; @@ -4440,8 +4470,10 @@ compiler_sync_comprehension_generator(struct compiler *c, compiler_use_next_block(c, skip); } compiler_use_next_block(c, if_cleanup); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, anchor); + if (start) { + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + compiler_use_next_block(c, anchor); + } return 1; } @@ -4449,6 +4481,7 @@ compiler_sync_comprehension_generator(struct compiler *c, static int compiler_async_comprehension_generator(struct compiler *c, asdl_seq *generators, int gen_index, + int depth, expr_ty elt, expr_ty val, int type) { comprehension_ty gen; @@ -4492,9 +4525,10 @@ compiler_async_comprehension_generator(struct compiler *c, NEXT_BLOCK(c); } + depth++; if (++gen_index < asdl_seq_LEN(generators)) if (!compiler_comprehension_generator(c, - generators, gen_index, + generators, gen_index, depth, elt, val, type)) return 0; @@ -4509,18 +4543,18 @@ compiler_async_comprehension_generator(struct compiler *c, break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, gen_index + 1); + ADDOP_I(c, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, gen_index + 1); + ADDOP_I(c, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, gen_index + 1); + ADDOP_I(c, MAP_ADD, depth + 1); break; default: return 0; @@ -4583,7 +4617,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, ADDOP_I(c, op, 0); } - if (!compiler_comprehension_generator(c, generators, 0, elt, + if (!compiler_comprehension_generator(c, generators, 0, 0, elt, val, type)) goto error_in_scope; From webhook-mailer at python.org Wed Feb 12 05:35:15 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 10:35:15 -0000 Subject: [Python-checkins] bpo-39219: Fix SyntaxError attributes in the tokenizer. (GH-17828) Message-ID: https://github.com/python/cpython/commit/efd878cdb46d9c7038d93fb36eb1ff7dc5baf9ec commit: efd878cdb46d9c7038d93fb36eb1ff7dc5baf9ec branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-12T02:35:10-08:00 summary: bpo-39219: Fix SyntaxError attributes in the tokenizer. (GH-17828) * Always set the text attribute. * Correct the offset attribute for non-ascii sources. (cherry picked from commit 0cc6b5e559b8303b18fdd56c2befd900fe7b5e35) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst M Lib/test/test_exceptions.py M Parser/tokenizer.c diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 10c1e076464e2..3a32253157369 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -179,17 +179,25 @@ def ckmsg(src, msg, exception=SyntaxError): ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) def testSyntaxErrorOffset(self): - def check(src, lineno, offset): + def check(src, lineno, offset, encoding='utf-8'): with self.assertRaises(SyntaxError) as cm: compile(src, '', 'exec') self.assertEqual(cm.exception.lineno, lineno) self.assertEqual(cm.exception.offset, offset) + if cm.exception.text is not None: + if not isinstance(src, str): + src = src.decode(encoding, 'replace') + line = src.split('\n')[lineno-1] + self.assertEqual(cm.exception.text.rstrip('\n'), line) check('def fact(x):\n\treturn x!\n', 2, 10) check('1 +\n', 1, 4) check('def spam():\n print(1)\n print(2)', 3, 10) check('Python = "Python" +', 1, 20) check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) + check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +', + 2, 19, encoding='cp1251') + check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18) check('x = "a', 1, 7) check('lambda x: x = 2', 1, 1) @@ -205,6 +213,10 @@ def check(src, lineno, offset): check('0010 + 2', 1, 4) check('x = 32e-+4', 1, 8) check('x = 0o9', 1, 6) + check('\u03b1 = 0xI', 1, 6) + check(b'\xce\xb1 = 0xI', 1, 6) + check(b'# -*- coding: iso8859-7 -*-\n\xe1 = 0xI', 2, 6, + encoding='iso8859-7') # Errors thrown by symtable.c check('x = [(yield i) for i in range(3)]', 1, 5) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst new file mode 100644 index 0000000000000..dac8360df712c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst @@ -0,0 +1,2 @@ +Syntax errors raised in the tokenizer now always set correct "text" and +"offset" attributes. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index f73c32684c7b7..aecbcebb917e8 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1,6 +1,7 @@ /* Tokenizer implementation */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include @@ -1034,17 +1035,44 @@ tok_backup(struct tok_state *tok, int c) static int syntaxerror(struct tok_state *tok, const char *format, ...) { + PyObject *errmsg, *errtext, *args; va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - PyErr_FormatV(PyExc_SyntaxError, format, vargs); + errmsg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); - PyErr_SyntaxLocationObject(tok->filename, - tok->lineno, - (int)(tok->cur - tok->line_start)); + if (!errmsg) { + goto error; + } + + errtext = PyUnicode_DecodeUTF8(tok->line_start, tok->cur - tok->line_start, + "replace"); + if (!errtext) { + goto error; + } + int offset = (int)PyUnicode_GET_LENGTH(errtext); + Py_ssize_t line_len = strcspn(tok->line_start, "\n"); + if (line_len != tok->cur - tok->line_start) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(tok->line_start, line_len, + "replace"); + } + if (!errtext) { + goto error; + } + + args = Py_BuildValue("(O(OiiN))", errmsg, + tok->filename, tok->lineno, offset, errtext); + if (args) { + PyErr_SetObject(PyExc_SyntaxError, args); + Py_DECREF(args); + } + +error: + Py_XDECREF(errmsg); tok->done = E_ERROR; return ERRORTOKEN; } From webhook-mailer at python.org Wed Feb 12 07:02:42 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 12 Feb 2020 12:02:42 -0000 Subject: [Python-checkins] bpo-21016: pydoc and trace use sysconfig (GH-18476) Message-ID: https://github.com/python/cpython/commit/4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd commit: 4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd branch: master author: Victor Stinner committer: GitHub date: 2020-02-12T13:02:29+01:00 summary: bpo-21016: pydoc and trace use sysconfig (GH-18476) bpo-21016, bpo-1294959: The pydoc and trace modules now use the sysconfig module to get the path to the Python standard library, to support uncommon installation path like /usr/lib64/python3.9/ on Fedora. Co-Authored-By: Jan Mat?jek files: A Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst M Lib/pydoc.py M Lib/trace.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index e32fdf76978e2..f172700a15f9d 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -66,6 +66,7 @@ class or function within a module or module in a package. If the import platform import re import sys +import sysconfig import time import tokenize import urllib.parse @@ -392,9 +393,7 @@ def fail(self, object, name=None, *args): docmodule = docclass = docroutine = docother = docproperty = docdata = fail - def getdocloc(self, object, - basedir=os.path.join(sys.base_exec_prefix, "lib", - "python%d.%d" % sys.version_info[:2])): + def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')): """Return the location of module docs or None""" try: diff --git a/Lib/trace.py b/Lib/trace.py index 681c3f9d05f81..52047c3fbf473 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -52,6 +52,7 @@ import linecache import os import sys +import sysconfig import token import tokenize import inspect @@ -660,9 +661,8 @@ def main(): opts = parser.parse_args() if opts.ignore_dir: - rel_path = 'lib', 'python{0.major}.{0.minor}'.format(sys.version_info) - _prefix = os.path.join(sys.base_prefix, *rel_path) - _exec_prefix = os.path.join(sys.base_exec_prefix, *rel_path) + _prefix = sysconfig.get_path("stdlib") + _exec_prefix = sysconfig.get_path("platstdlib") def parse_ignore_dir(s): s = os.path.expanduser(os.path.expandvars(s)) diff --git a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst new file mode 100644 index 0000000000000..fb91bb3825555 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst @@ -0,0 +1,4 @@ +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. +Patch by Jan Mat?jek. From webhook-mailer at python.org Wed Feb 12 07:32:54 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 12:32:54 -0000 Subject: [Python-checkins] bpo-21016: pydoc and trace use sysconfig (GH-18476) Message-ID: https://github.com/python/cpython/commit/ca133e53fafdec1aa77613fcb7558deed959383f commit: ca133e53fafdec1aa77613fcb7558deed959383f branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-12T04:32:46-08:00 summary: bpo-21016: pydoc and trace use sysconfig (GH-18476) bpo-21016, bpo-1294959: The pydoc and trace modules now use the sysconfig module to get the path to the Python standard library, to support uncommon installation path like /usr/lib64/python3.9/ on Fedora. Co-Authored-By: Jan Mat?jek (cherry picked from commit 4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst M Lib/pydoc.py M Lib/trace.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 44df8c854ae9e..978e4cd0baa5b 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -66,6 +66,7 @@ class or function within a module or module in a package. If the import platform import re import sys +import sysconfig import time import tokenize import urllib.parse @@ -398,9 +399,7 @@ def fail(self, object, name=None, *args): docmodule = docclass = docroutine = docother = docproperty = docdata = fail - def getdocloc(self, object, - basedir=os.path.join(sys.base_exec_prefix, "lib", - "python%d.%d" % sys.version_info[:2])): + def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')): """Return the location of module docs or None""" try: diff --git a/Lib/trace.py b/Lib/trace.py index 206bd2b689f11..c804a0d75669a 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -53,6 +53,7 @@ import os import re import sys +import sysconfig import token import tokenize import inspect @@ -671,9 +672,8 @@ def main(): opts = parser.parse_args() if opts.ignore_dir: - rel_path = 'lib', 'python{0.major}.{0.minor}'.format(sys.version_info) - _prefix = os.path.join(sys.base_prefix, *rel_path) - _exec_prefix = os.path.join(sys.base_exec_prefix, *rel_path) + _prefix = sysconfig.get_path("stdlib") + _exec_prefix = sysconfig.get_path("platstdlib") def parse_ignore_dir(s): s = os.path.expanduser(os.path.expandvars(s)) diff --git a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst new file mode 100644 index 0000000000000..fb91bb3825555 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst @@ -0,0 +1,4 @@ +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. +Patch by Jan Mat?jek. From webhook-mailer at python.org Wed Feb 12 07:32:59 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 12:32:59 -0000 Subject: [Python-checkins] bpo-21016: pydoc and trace use sysconfig (GH-18476) Message-ID: https://github.com/python/cpython/commit/ac6f4d2db703c0ff88e496bcb7b7fe55cf2ac458 commit: ac6f4d2db703c0ff88e496bcb7b7fe55cf2ac458 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-12T04:32:52-08:00 summary: bpo-21016: pydoc and trace use sysconfig (GH-18476) bpo-21016, bpo-1294959: The pydoc and trace modules now use the sysconfig module to get the path to the Python standard library, to support uncommon installation path like /usr/lib64/python3.9/ on Fedora. Co-Authored-By: Jan Mat?jek (cherry picked from commit 4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst M Lib/pydoc.py M Lib/trace.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 9a22e56686f61..dc3377d68f8ca 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -66,6 +66,7 @@ class or function within a module or module in a package. If the import platform import re import sys +import sysconfig import time import tokenize import urllib.parse @@ -392,9 +393,7 @@ def fail(self, object, name=None, *args): docmodule = docclass = docroutine = docother = docproperty = docdata = fail - def getdocloc(self, object, - basedir=os.path.join(sys.base_exec_prefix, "lib", - "python%d.%d" % sys.version_info[:2])): + def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')): """Return the location of module docs or None""" try: diff --git a/Lib/trace.py b/Lib/trace.py index 62325d3f238ad..a44735761df42 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -52,6 +52,7 @@ import linecache import os import sys +import sysconfig import token import tokenize import inspect @@ -676,9 +677,8 @@ def main(): opts = parser.parse_args() if opts.ignore_dir: - rel_path = 'lib', 'python{0.major}.{0.minor}'.format(sys.version_info) - _prefix = os.path.join(sys.base_prefix, *rel_path) - _exec_prefix = os.path.join(sys.base_exec_prefix, *rel_path) + _prefix = sysconfig.get_path("stdlib") + _exec_prefix = sysconfig.get_path("platstdlib") def parse_ignore_dir(s): s = os.path.expanduser(os.path.expandvars(s)) diff --git a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst new file mode 100644 index 0000000000000..fb91bb3825555 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst @@ -0,0 +1,4 @@ +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. +Patch by Jan Mat?jek. From webhook-mailer at python.org Wed Feb 12 14:56:10 2020 From: webhook-mailer at python.org (William Chargin) Date: Wed, 12 Feb 2020 19:56:10 -0000 Subject: [Python-checkins] bpo-18819: tarfile: only set device fields for device files (GH-18080) Message-ID: https://github.com/python/cpython/commit/674935b8caf33e47c78f1b8e197b1b77a04992d2 commit: 674935b8caf33e47c78f1b8e197b1b77a04992d2 branch: master author: William Chargin committer: GitHub date: 2020-02-12T11:56:02-08:00 summary: bpo-18819: tarfile: only set device fields for device files (GH-18080) The GNU docs describe the `devmajor` and `devminor` fields of the tar header struct only in the context of character and block special files, suggesting that in other cases they are not populated. Typical utilities behave accordingly; this patch teaches `tarfile` to do the same. files: A Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst M Lib/tarfile.py M Lib/test/test_tarfile.py M Misc/ACKS diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 90a2c95b315b3..e2b60532f693d 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -930,6 +930,14 @@ def _create_header(info, format, encoding, errors): """Return a header block. info is a dictionary with file information, format must be one of the *_FORMAT constants. """ + has_device_fields = info.get("type") in (CHRTYPE, BLKTYPE) + if has_device_fields: + devmajor = itn(info.get("devmajor", 0), 8, format) + devminor = itn(info.get("devminor", 0), 8, format) + else: + devmajor = stn("", 8, encoding, errors) + devminor = stn("", 8, encoding, errors) + parts = [ stn(info.get("name", ""), 100, encoding, errors), itn(info.get("mode", 0) & 0o7777, 8, format), @@ -943,8 +951,8 @@ def _create_header(info, format, encoding, errors): info.get("magic", POSIX_MAGIC), stn(info.get("uname", ""), 32, encoding, errors), stn(info.get("gname", ""), 32, encoding, errors), - itn(info.get("devmajor", 0), 8, format), - itn(info.get("devminor", 0), 8, format), + devmajor, + devminor, stn(info.get("prefix", ""), 155, encoding, errors) ] diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 6a901089611cd..cae96802ded67 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1549,6 +1549,52 @@ def test_longnamelink_1025(self): ("longlnk/" * 127) + "longlink_") +class DeviceHeaderTest(WriteTestBase, unittest.TestCase): + + prefix = "w:" + + def test_headers_written_only_for_device_files(self): + # Regression test for bpo-18819. + tempdir = os.path.join(TEMPDIR, "device_header_test") + os.mkdir(tempdir) + try: + tar = tarfile.open(tmpname, self.mode) + try: + input_blk = tarfile.TarInfo(name="my_block_device") + input_reg = tarfile.TarInfo(name="my_regular_file") + input_blk.type = tarfile.BLKTYPE + input_reg.type = tarfile.REGTYPE + tar.addfile(input_blk) + tar.addfile(input_reg) + finally: + tar.close() + + # devmajor and devminor should be *interpreted* as 0 in both... + tar = tarfile.open(tmpname, "r") + try: + output_blk = tar.getmember("my_block_device") + output_reg = tar.getmember("my_regular_file") + finally: + tar.close() + self.assertEqual(output_blk.devmajor, 0) + self.assertEqual(output_blk.devminor, 0) + self.assertEqual(output_reg.devmajor, 0) + self.assertEqual(output_reg.devminor, 0) + + # ...but the fields should not actually be set on regular files: + with open(tmpname, "rb") as infile: + buf = infile.read() + buf_blk = buf[output_blk.offset:output_blk.offset_data] + buf_reg = buf[output_reg.offset:output_reg.offset_data] + # See `struct posixheader` in GNU docs for byte offsets: + # + device_headers = slice(329, 329 + 16) + self.assertEqual(buf_blk[device_headers], b"0000000\0" * 2) + self.assertEqual(buf_reg[device_headers], b"\0" * 16) + finally: + support.rmtree(tempdir) + + class CreateTest(WriteTestBase, unittest.TestCase): prefix = "x:" diff --git a/Misc/ACKS b/Misc/ACKS index 5a779833e68be..933402069b4fd 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -286,6 +286,7 @@ Brad Chapman Greg Chapman Mitch Chapman Matt Chaput +William Chargin Yogesh Chaudhari David Chaum Nicolas Chauvat diff --git a/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst b/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst new file mode 100644 index 0000000000000..e9f111ad62e28 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst @@ -0,0 +1,3 @@ +Omit ``devmajor`` and ``devminor`` fields for non-device files in +:mod:`tarfile` archives, enabling bit-for-bit compatibility with GNU +``tar(1)``. From webhook-mailer at python.org Wed Feb 12 15:37:54 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 12 Feb 2020 20:37:54 -0000 Subject: [Python-checkins] bpo-39474: Fix AST pos for expressions like (a)(b), (a)[b] and (a).b. (GH-18477) Message-ID: https://github.com/python/cpython/commit/6e619c48b8e804ece9521453fc8da0640a04d5b1 commit: 6e619c48b8e804ece9521453fc8da0640a04d5b1 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-12T22:37:49+02:00 summary: bpo-39474: Fix AST pos for expressions like (a)(b), (a)[b] and (a).b. (GH-18477) files: A Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 6d1e419932261..2ed4657822e54 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1707,6 +1707,33 @@ def test_attribute_spaces(self): self._check_content(s, call, s) self._check_content(s, call.args[0], 'x. y .z') + def test_redundant_parenthesis(self): + s = '( ( ( a + b ) ) )' + v = ast.parse(s).body[0].value + self.assertEqual(type(v).__name__, 'BinOp') + self._check_content(s, v, 'a + b') + s2 = 'await ' + s + v = ast.parse(s2).body[0].value.value + self.assertEqual(type(v).__name__, 'BinOp') + self._check_content(s2, v, 'a + b') + + def test_trailers_with_redundant_parenthesis(self): + tests = ( + ('( ( ( a ) ) ) ( )', 'Call'), + ('( ( ( a ) ) ) ( b )', 'Call'), + ('( ( ( a ) ) ) [ b ]', 'Subscript'), + ('( ( ( a ) ) ) . b', 'Attribute'), + ) + for s, t in tests: + with self.subTest(s): + v = ast.parse(s).body[0].value + self.assertEqual(type(v).__name__, t) + self._check_content(s, v, s) + s2 = 'await ' + s + v = ast.parse(s2).body[0].value.value + self.assertEqual(type(v).__name__, t) + self._check_content(s2, v, s) + def test_displays(self): s1 = '[{}, {1, }, {1, 2,} ]' s2 = '{a: b, f (): g () ,}' diff --git a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst new file mode 100644 index 0000000000000..e990f84a9dbf2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst @@ -0,0 +1,2 @@ +Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` +and ``(a).b``. diff --git a/Python/ast.c b/Python/ast.c index bab672b29589f..ad25565b7c7f8 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -583,7 +583,7 @@ static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool); /* Note different signature for ast_for_call */ static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, - const node *, const node *); + const node *, const node *, const node *); static PyObject *parsenumber(struct compiling *, const char *); static expr_ty parsestrplus(struct compiling *, const node *n); @@ -1757,7 +1757,8 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else { - d = ast_for_call(c, CHILD(n, 3), name_expr, CHILD(n, 2), CHILD(n, 4)); + d = ast_for_call(c, CHILD(n, 3), name_expr, + CHILD(n, 1), CHILD(n, 2), CHILD(n, 4)); if (!d) return NULL; name_expr = NULL; @@ -2658,7 +2659,7 @@ ast_for_binop(struct compiling *c, const node *n) } static expr_ty -ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) +ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const node *start) { /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] @@ -2668,17 +2669,18 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) REQ(n, trailer); if (TYPE(CHILD(n, 0)) == LPAR) { if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, LINENO(n), n->n_col_offset, + return Call(left_expr, NULL, NULL, LINENO(start), start->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); else - return ast_for_call(c, CHILD(n, 1), left_expr, CHILD(n, 0), CHILD(n, 2)); + return ast_for_call(c, CHILD(n, 1), left_expr, + start, CHILD(n, 0), CHILD(n, 2)); } else if (TYPE(CHILD(n, 0)) == DOT) { PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); if (!attr_id) return NULL; return Attribute(left_expr, attr_id, Load, - LINENO(n), n->n_col_offset, + LINENO(start), start->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { @@ -2689,7 +2691,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) slice_ty slc = ast_for_slice(c, CHILD(n, 0)); if (!slc) return NULL; - return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset, + return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } @@ -2716,7 +2718,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) } if (!simple) { return Subscript(left_expr, ExtSlice(slices, c->c_arena), - Load, LINENO(n), n->n_col_offset, + Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } /* extract Index values and put them in a Tuple */ @@ -2733,7 +2735,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) if (!e) return NULL; return Subscript(left_expr, Index(e, c->c_arena), - Load, LINENO(n), n->n_col_offset, + Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } } @@ -2771,7 +2773,7 @@ static expr_ty ast_for_atom_expr(struct compiling *c, const node *n) { int i, nch, start = 0; - expr_ty e, tmp; + expr_ty e; REQ(n, atom_expr); nch = NCH(n); @@ -2800,12 +2802,9 @@ ast_for_atom_expr(struct compiling *c, const node *n) node *ch = CHILD(n, i); if (TYPE(ch) != trailer) break; - tmp = ast_for_trailer(c, ch, e); - if (!tmp) + e = ast_for_trailer(c, ch, e, CHILD(n, start)); + if (!e) return NULL; - tmp->lineno = e->lineno; - tmp->col_offset = e->col_offset; - e = tmp; } if (start) { @@ -3035,7 +3034,7 @@ ast_for_expr(struct compiling *c, const node *n) static expr_ty ast_for_call(struct compiling *c, const node *n, expr_ty func, - const node *maybegenbeg, const node *closepar) + const node *start, const node *maybegenbeg, const node *closepar) { /* arglist: argument (',' argument)* [','] @@ -3239,7 +3238,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, } } - return Call(func, args, keywords, func->lineno, func->col_offset, + return Call(func, args, keywords, LINENO(start), start->n_col_offset, closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena); } @@ -4486,7 +4485,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset, c->c_arena); - call = ast_for_call(c, CHILD(n, 3), dummy, NULL, CHILD(n, 4)); + call = ast_for_call(c, CHILD(n, 3), dummy, + CHILD(n, 1), NULL, CHILD(n, 4)); if (!call) return NULL; } From webhook-mailer at python.org Wed Feb 12 15:56:51 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 12 Feb 2020 20:56:51 -0000 Subject: [Python-checkins] bpo-39474: Fix AST pos for expressions like (a)(b), (a)[b] and (a).b. (GH-18477) Message-ID: https://github.com/python/cpython/commit/2076d4f97ef514bb4dc4ca768fbaa3f538ce7f1f commit: 2076d4f97ef514bb4dc4ca768fbaa3f538ce7f1f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-12T12:56:44-08:00 summary: bpo-39474: Fix AST pos for expressions like (a)(b), (a)[b] and (a).b. (GH-18477) (cherry picked from commit 6e619c48b8e804ece9521453fc8da0640a04d5b1) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e843d53781d25..3e8a39dc41047 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1642,6 +1642,33 @@ def test_attribute_spaces(self): self._check_content(s, call, s) self._check_content(s, call.args[0], 'x. y .z') + def test_redundant_parenthesis(self): + s = '( ( ( a + b ) ) )' + v = ast.parse(s).body[0].value + self.assertEqual(type(v).__name__, 'BinOp') + self._check_content(s, v, 'a + b') + s2 = 'await ' + s + v = ast.parse(s2).body[0].value.value + self.assertEqual(type(v).__name__, 'BinOp') + self._check_content(s2, v, 'a + b') + + def test_trailers_with_redundant_parenthesis(self): + tests = ( + ('( ( ( a ) ) ) ( )', 'Call'), + ('( ( ( a ) ) ) ( b )', 'Call'), + ('( ( ( a ) ) ) [ b ]', 'Subscript'), + ('( ( ( a ) ) ) . b', 'Attribute'), + ) + for s, t in tests: + with self.subTest(s): + v = ast.parse(s).body[0].value + self.assertEqual(type(v).__name__, t) + self._check_content(s, v, s) + s2 = 'await ' + s + v = ast.parse(s2).body[0].value.value + self.assertEqual(type(v).__name__, t) + self._check_content(s2, v, s) + def test_displays(self): s1 = '[{}, {1, }, {1, 2,} ]' s2 = '{a: b, f (): g () ,}' diff --git a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst new file mode 100644 index 0000000000000..e990f84a9dbf2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst @@ -0,0 +1,2 @@ +Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` +and ``(a).b``. diff --git a/Python/ast.c b/Python/ast.c index 12f24f2c22ab9..f70d48ba3a15d 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -583,7 +583,7 @@ static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool); /* Note different signature for ast_for_call */ static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, - const node *, const node *); + const node *, const node *, const node *); static PyObject *parsenumber(struct compiling *, const char *); static expr_ty parsestrplus(struct compiling *, const node *n); @@ -1757,7 +1757,8 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else { - d = ast_for_call(c, CHILD(n, 3), name_expr, CHILD(n, 2), CHILD(n, 4)); + d = ast_for_call(c, CHILD(n, 3), name_expr, + CHILD(n, 1), CHILD(n, 2), CHILD(n, 4)); if (!d) return NULL; name_expr = NULL; @@ -2658,7 +2659,7 @@ ast_for_binop(struct compiling *c, const node *n) } static expr_ty -ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) +ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const node *start) { /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] @@ -2668,17 +2669,18 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) REQ(n, trailer); if (TYPE(CHILD(n, 0)) == LPAR) { if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, LINENO(n), n->n_col_offset, + return Call(left_expr, NULL, NULL, LINENO(start), start->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); else - return ast_for_call(c, CHILD(n, 1), left_expr, CHILD(n, 0), CHILD(n, 2)); + return ast_for_call(c, CHILD(n, 1), left_expr, + start, CHILD(n, 0), CHILD(n, 2)); } else if (TYPE(CHILD(n, 0)) == DOT) { PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); if (!attr_id) return NULL; return Attribute(left_expr, attr_id, Load, - LINENO(n), n->n_col_offset, + LINENO(start), start->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { @@ -2689,7 +2691,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) slice_ty slc = ast_for_slice(c, CHILD(n, 0)); if (!slc) return NULL; - return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset, + return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } @@ -2716,7 +2718,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) } if (!simple) { return Subscript(left_expr, ExtSlice(slices, c->c_arena), - Load, LINENO(n), n->n_col_offset, + Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } /* extract Index values and put them in a Tuple */ @@ -2733,7 +2735,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) if (!e) return NULL; return Subscript(left_expr, Index(e, c->c_arena), - Load, LINENO(n), n->n_col_offset, + Load, LINENO(start), start->n_col_offset, n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } } @@ -2771,7 +2773,7 @@ static expr_ty ast_for_atom_expr(struct compiling *c, const node *n) { int i, nch, start = 0; - expr_ty e, tmp; + expr_ty e; REQ(n, atom_expr); nch = NCH(n); @@ -2800,12 +2802,9 @@ ast_for_atom_expr(struct compiling *c, const node *n) node *ch = CHILD(n, i); if (TYPE(ch) != trailer) break; - tmp = ast_for_trailer(c, ch, e); - if (!tmp) + e = ast_for_trailer(c, ch, e, CHILD(n, start)); + if (!e) return NULL; - tmp->lineno = e->lineno; - tmp->col_offset = e->col_offset; - e = tmp; } if (start) { @@ -3035,7 +3034,7 @@ ast_for_expr(struct compiling *c, const node *n) static expr_ty ast_for_call(struct compiling *c, const node *n, expr_ty func, - const node *maybegenbeg, const node *closepar) + const node *start, const node *maybegenbeg, const node *closepar) { /* arglist: argument (',' argument)* [','] @@ -3239,7 +3238,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, } } - return Call(func, args, keywords, func->lineno, func->col_offset, + return Call(func, args, keywords, LINENO(start), start->n_col_offset, closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena); } @@ -4489,7 +4488,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset, c->c_arena); - call = ast_for_call(c, CHILD(n, 3), dummy, NULL, CHILD(n, 4)); + call = ast_for_call(c, CHILD(n, 3), dummy, + CHILD(n, 1), NULL, CHILD(n, 4)); if (!call) return NULL; } From webhook-mailer at python.org Wed Feb 12 16:32:38 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 12 Feb 2020 21:32:38 -0000 Subject: [Python-checkins] bpo-35081: Move bytes_methods.h to the internal C API (GH-18492) Message-ID: https://github.com/python/cpython/commit/45876a90e2663f12b90c2090ec3e48bd97841aae commit: 45876a90e2663f12b90c2090ec3e48bd97841aae branch: master author: Victor Stinner committer: GitHub date: 2020-02-12T22:32:34+01:00 summary: bpo-35081: Move bytes_methods.h to the internal C API (GH-18492) Move the bytes_methods.h header file to the internal C API as pycore_bytes_methods.h: it only contains private symbols (prefixed by "_Py"), except of the PyDoc_STRVAR_shared() macro. files: A Include/internal/pycore_bytes_methods.h A Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst D Include/bytes_methods.h M Makefile.pre.in M Objects/bytearrayobject.c M Objects/bytes_methods.c M Objects/bytesobject.c M Objects/stringlib/ctype.h M Objects/unicodeobject.c M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters diff --git a/Include/bytes_methods.h b/Include/internal/pycore_bytes_methods.h similarity index 97% rename from Include/bytes_methods.h rename to Include/internal/pycore_bytes_methods.h index 8434a50a4bba7..11e8ab20e9136 100644 --- a/Include/bytes_methods.h +++ b/Include/internal/pycore_bytes_methods.h @@ -2,6 +2,10 @@ #ifndef Py_BYTES_CTYPE_H #define Py_BYTES_CTYPE_H +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + /* * The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray) * methods of the given names, they operate on ASCII byte strings. diff --git a/Makefile.pre.in b/Makefile.pre.in index 3da104bac87d0..aae93ff82c145 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -970,7 +970,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/bltinmodule.h \ $(srcdir)/Include/boolobject.h \ $(srcdir)/Include/bytearrayobject.h \ - $(srcdir)/Include/bytes_methods.h \ $(srcdir)/Include/bytesobject.h \ $(srcdir)/Include/cellobject.h \ $(srcdir)/Include/ceval.h \ @@ -1077,6 +1076,7 @@ PYTHON_HEADERS= \ \ $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_atomic.h \ + $(srcdir)/Include/internal/pycore_bytes_methods.h \ $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_code.h \ diff --git a/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst b/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst new file mode 100644 index 0000000000000..6be33200d9e2b --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst @@ -0,0 +1,3 @@ +Move the ``bytes_methods.h`` header file to the internal C API as +``pycore_bytes_methods.h``: it only contains private symbols (prefixed by +``_Py``), except of the ``PyDoc_STRVAR_shared()`` macro. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index a3fc35ca4d22a..d3964358bc59d 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2,11 +2,11 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_bytes_methods.h" #include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" -#include "bytes_methods.h" #include "bytesobject.h" #include "pystrhex.h" diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index db030be4fe756..a4b3868e72522 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "bytes_methods.h" +#include "pycore_bytes_methods.h" PyDoc_STRVAR_shared(_Py_isspace__doc__, "B.isspace() -> bool\n\ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index df3eddae6a36d..bd8af72ade5d3 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3,11 +3,11 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_bytes_methods.h" #include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" -#include "bytes_methods.h" #include "pystrhex.h" #include diff --git a/Objects/stringlib/ctype.h b/Objects/stringlib/ctype.h index 843cfa22a8454..9b319b07d11bc 100644 --- a/Objects/stringlib/ctype.h +++ b/Objects/stringlib/ctype.h @@ -2,7 +2,7 @@ # error "ctype.h only compatible with byte-wise strings" #endif -#include "bytes_methods.h" +#include "pycore_bytes_methods.h" static PyObject* stringlib_isspace(PyObject *self, PyObject *Py_UNUSED(ignored)) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8470e41624bd4..11fa1fb5ff798 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -40,6 +40,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_bytes_methods.h" #include "pycore_fileutils.h" #include "pycore_initconfig.h" #include "pycore_object.h" @@ -47,7 +48,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "ucnhash.h" -#include "bytes_methods.h" #include "stringlib/eq.h" #ifdef MS_WINDOWS diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 36a27f467405d..a3719d8558de7 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -115,7 +115,6 @@ - @@ -161,6 +160,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 0301557b3e50d..67e223dab4396 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -48,9 +48,6 @@ Include - - Include - Include @@ -186,6 +183,9 @@ Include + + Include + Include From webhook-mailer at python.org Wed Feb 12 16:54:53 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 12 Feb 2020 21:54:53 -0000 Subject: [Python-checkins] bpo-35081: Move dtoa.h header to the internal C API (GH-18489) Message-ID: https://github.com/python/cpython/commit/e9e7d284c434768333fdfb53a3663eae74cb995a commit: e9e7d284c434768333fdfb53a3663eae74cb995a branch: master author: Victor Stinner committer: GitHub date: 2020-02-12T22:54:42+01:00 summary: bpo-35081: Move dtoa.h header to the internal C API (GH-18489) Move the dtoa.h header file to the internal C API as pycore_dtoa.h: it only contains private functions (prefixed by "_Py"). The math and cmath modules must now be compiled with the Py_BUILD_CORE macro defined. files: A Include/internal/pycore_dtoa.h A Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst D Include/dtoa.h M Include/Python.h M Makefile.pre.in M Modules/Setup M Modules/cmathmodule.c M Modules/mathmodule.c M Objects/floatobject.c M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/dtoa.c M Python/pystrtod.c M setup.py diff --git a/Include/Python.h b/Include/Python.h index d6e5b139ac679..969d8e6bea741 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -152,7 +152,6 @@ #include "pyctype.h" #include "pystrtod.h" #include "pystrcmp.h" -#include "dtoa.h" #include "fileutils.h" #include "pyfpe.h" #include "tracemalloc.h" diff --git a/Include/dtoa.h b/Include/internal/pycore_dtoa.h similarity index 66% rename from Include/dtoa.h rename to Include/internal/pycore_dtoa.h index 9bfb6251db831..3faf8cf6b2eef 100644 --- a/Include/dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -1,9 +1,15 @@ -#ifndef Py_LIMITED_API #ifndef PY_NO_SHORT_FLOAT_REPR #ifdef __cplusplus extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* These functions are used by modules compiled as C extension like math: + they must be exported. */ + PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); @@ -11,9 +17,7 @@ PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); PyAPI_FUNC(double) _Py_dg_stdnan(int sign); PyAPI_FUNC(double) _Py_dg_infinity(int sign); - #ifdef __cplusplus } #endif -#endif -#endif +#endif /* !PY_NO_SHORT_FLOAT_REPR */ diff --git a/Makefile.pre.in b/Makefile.pre.in index aae93ff82c145..f5540a2f0a6b4 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -981,7 +981,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/context.h \ $(srcdir)/Include/descrobject.h \ $(srcdir)/Include/dictobject.h \ - $(srcdir)/Include/dtoa.h \ $(srcdir)/Include/dynamic_annotations.h \ $(srcdir)/Include/enumobject.h \ $(srcdir)/Include/errcode.h \ @@ -1082,6 +1081,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ + $(srcdir)/Include/internal/pycore_dtoa.h \ $(srcdir)/Include/internal/pycore_fileutils.h \ $(srcdir)/Include/internal/pycore_getopt.h \ $(srcdir)/Include/internal/pycore_gil.h \ diff --git a/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst b/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst new file mode 100644 index 0000000000000..94e6ae7e42cc8 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst @@ -0,0 +1,5 @@ +Move the ``dtoa.h`` header file to the internal C API as ``pycore_dtoa.h``: +it only contains private functions (prefixed by ``_Py``). The :mod:`math` and +:mod:`cmath` modules must now be compiled with the ``Py_BUILD_CORE`` macro +defined. + diff --git a/Modules/Setup b/Modules/Setup index 983fa014ecb24..40266a192bc5e 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -167,8 +167,8 @@ _symtable symtablemodule.c # Modules that should always be present (non UNIX dependent): #array arraymodule.c # array objects -#cmath cmathmodule.c _math.c # -lm # complex math library functions -#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() +#cmath cmathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # complex math library functions +#math mathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # math library functions, e.g. sin() #_contextvars _contextvarsmodule.c # Context Variables #_struct _struct.c # binary structure packing/unpacking #_weakref _weakref.c # basic weak reference support diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 8b21decfa53fc..5eac4b4940bea 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -3,6 +3,7 @@ /* much code borrowed from mathmodule.c */ #include "Python.h" +#include "pycore_dtoa.h" #include "_math.h" /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index f012b51d86698..309f229159540 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -53,6 +53,7 @@ raised for division by zero and mod by zero. */ #include "Python.h" +#include "pycore_dtoa.h" #include "_math.h" #include "clinic/mathmodule.c.h" diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 648030b659c23..04f968e56b142 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -4,6 +4,7 @@ for any kind of float exception without losing portability. */ #include "Python.h" +#include "pycore_dtoa.h" #include #include diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index a3719d8558de7..7d597bcdac666 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -166,6 +166,7 @@ + @@ -223,7 +224,6 @@ - diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 67e223dab4396..9563bdc25ebdb 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -201,6 +201,9 @@ Include + + Include + Include @@ -360,9 +363,6 @@ Include - - Include - Include diff --git a/Python/dtoa.c b/Python/dtoa.c index b7bb7acfb6c21..822adc612962a 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -115,6 +115,7 @@ /* Linking of Python's #defines to Gay's #defines starts here. */ #include "Python.h" +#include "pycore_dtoa.h" /* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile the following code */ diff --git a/Python/pystrtod.c b/Python/pystrtod.c index 94dc4818c2f47..1c8202c776188 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -1,6 +1,7 @@ /* -*- Mode: C; c-file-style: "python" -*- */ #include +#include "pycore_dtoa.h" #include /* Case-insensitive string match used for nan and inf detection; t should be diff --git a/setup.py b/setup.py index 02f523c42d355..51e67fe4a558b 100644 --- a/setup.py +++ b/setup.py @@ -734,12 +734,14 @@ def detect_simple_extensions(self): # math library functions, e.g. sin() self.add(Extension('math', ['mathmodule.c'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'], extra_objects=[shared_math], depends=['_math.h', shared_math], libraries=['m'])) # complex math library functions self.add(Extension('cmath', ['cmathmodule.c'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'], extra_objects=[shared_math], depends=['_math.h', shared_math], libraries=['m'])) From webhook-mailer at python.org Wed Feb 12 17:54:35 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 12 Feb 2020 22:54:35 -0000 Subject: [Python-checkins] bpo-35134: Add Include/cpython/bytesobject.h file (GH-18494) Message-ID: https://github.com/python/cpython/commit/98921aeaf5879b51e2dd1870c9285cfa8d1a52c7 commit: 98921aeaf5879b51e2dd1870c9285cfa8d1a52c7 branch: master author: Victor Stinner committer: GitHub date: 2020-02-12T23:54:31+01:00 summary: bpo-35134: Add Include/cpython/bytesobject.h file (GH-18494) Add Include/cpython/bytearrayobject.h and Include/cpython/bytesobject.h header files. Move CPython C API from Include/bytesobject.h into a new Include/cpython/bytesobject.h header file which is included by Include/bytesobject.h. Do a similar change for Include/bytearrayobject.h. files: A Include/cpython/bytearrayobject.h A Include/cpython/bytesobject.h M Include/bytearrayobject.h M Include/bytesobject.h M Makefile.pre.in M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h index 647a17a819d23..341ab38a15d5a 100644 --- a/Include/bytearrayobject.h +++ b/Include/bytearrayobject.h @@ -18,17 +18,6 @@ extern "C" { * to contain a char pointer, not an unsigned char pointer. */ -/* Object layout */ -#ifndef Py_LIMITED_API -typedef struct { - PyObject_VAR_HEAD - Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ - char *ob_bytes; /* Physical backing buffer */ - char *ob_start; /* Logical start inside ob_bytes */ - Py_ssize_t ob_exports; /* How many buffer exports */ -} PyByteArrayObject; -#endif - /* Type object */ PyAPI_DATA(PyTypeObject) PyByteArray_Type; PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; @@ -45,14 +34,10 @@ PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); -/* Macros, trading safety for speed */ #ifndef Py_LIMITED_API -#define PyByteArray_AS_STRING(self) \ - (assert(PyByteArray_Check(self)), \ - Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string) -#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self)) - -PyAPI_DATA(char) _PyByteArray_empty_string[]; +# define Py_CPYTHON_BYTEARRAYOBJECT_H +# include "cpython/bytearrayobject.h" +# undef Py_CPYTHON_BYTEARRAYOBJECT_H #endif #ifdef __cplusplus diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 4aaa71a832bd7..27c31ee342c88 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -27,20 +27,6 @@ functions should be applied to nil objects. /* Caching the hash (ob_shash) saves recalculation of a string's hash value. This significantly speeds up dict lookups. */ -#ifndef Py_LIMITED_API -typedef struct { - PyObject_VAR_HEAD - Py_hash_t ob_shash; - char ob_sval[1]; - - /* Invariants: - * ob_sval contains space for 'ob_size+1' elements. - * ob_sval[ob_size] == 0. - * ob_shash is the hash of the string or -1 if not computed yet. - */ -} PyBytesObject; -#endif - PyAPI_DATA(PyTypeObject) PyBytes_Type; PyAPI_DATA(PyTypeObject) PyBytesIter_Type; @@ -60,38 +46,9 @@ PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( - const char *format, - Py_ssize_t format_len, - PyObject *args, - int use_bytearray); -PyAPI_FUNC(PyObject*) _PyBytes_FromHex( - PyObject *string, - int use_bytearray); -#endif PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *); -#ifndef Py_LIMITED_API -/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ -PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, - const char *, const char **); -#endif - -/* Macro, trading safety for speed */ -#ifndef Py_LIMITED_API -#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ - (((PyBytesObject *)(op))->ob_sval)) -#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) -#endif - -/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, - x must be an iterable object. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); -#endif /* Provides access to the internal data buffer and size of a string object or the default encoded version of a Unicode object. Passing @@ -114,85 +71,10 @@ PyAPI_FUNC(int) PyBytes_AsStringAndSize( #define F_ZERO (1<<4) #ifndef Py_LIMITED_API -/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". - A _PyBytesWriter variable must be declared at the end of variables in a - function to optimize the memory allocation on the stack. */ -typedef struct { - /* bytes, bytearray or NULL (when the small buffer is used) */ - PyObject *buffer; - - /* Number of allocated size. */ - Py_ssize_t allocated; - - /* Minimum number of allocated bytes, - incremented by _PyBytesWriter_Prepare() */ - Py_ssize_t min_size; - - /* If non-zero, use a bytearray instead of a bytes object for buffer. */ - int use_bytearray; - - /* If non-zero, overallocate the buffer (default: 0). - This flag must be zero if use_bytearray is non-zero. */ - int overallocate; - - /* Stack buffer */ - int use_small_buffer; - char small_buffer[512]; -} _PyBytesWriter; - -/* Initialize a bytes writer - - By default, the overallocation is disabled. Set the overallocate attribute - to control the allocation of the buffer. */ -PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); - -/* Get the buffer content and reset the writer. - Return a bytes object, or a bytearray object if use_bytearray is non-zero. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, - void *str); - -/* Deallocate memory of a writer (clear its internal buffer). */ -PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); - -/* Allocate the buffer to write size bytes. - Return the pointer to the beginning of buffer data. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, - Py_ssize_t size); - -/* Ensure that the buffer is large enough to write *size* bytes. - Add size to the writer minimum size (min_size attribute). - - str is the current pointer inside the buffer. - Return the updated current pointer inside the buffer. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, - void *str, - Py_ssize_t size); - -/* Resize the buffer to make it larger. - The new buffer may be larger than size bytes because of overallocation. - Return the updated current pointer inside the buffer. - Raise an exception and return NULL on error. - - Note: size must be greater than the number of allocated bytes in the writer. - - This function doesn't use the writer minimum size (min_size attribute). - - See also _PyBytesWriter_Prepare(). - */ -PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, - void *str, - Py_ssize_t size); - -/* Write bytes. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, - void *str, - const void *bytes, - Py_ssize_t size); -#endif /* Py_LIMITED_API */ +# define Py_CPYTHON_BYTESOBJECT_H +# include "cpython/bytesobject.h" +# undef Py_CPYTHON_BYTESOBJECT_H +#endif #ifdef __cplusplus } diff --git a/Include/cpython/bytearrayobject.h b/Include/cpython/bytearrayobject.h new file mode 100644 index 0000000000000..569b0cd036986 --- /dev/null +++ b/Include/cpython/bytearrayobject.h @@ -0,0 +1,20 @@ +#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H +# error "this header file must not be included directly" +#endif + +/* Object layout */ +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ + char *ob_bytes; /* Physical backing buffer */ + char *ob_start; /* Logical start inside ob_bytes */ + Py_ssize_t ob_exports; /* How many buffer exports */ +} PyByteArrayObject; + +/* Macros, trading safety for speed */ +#define PyByteArray_AS_STRING(self) \ + (assert(PyByteArray_Check(self)), \ + Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string) +#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self)) + +PyAPI_DATA(char) _PyByteArray_empty_string[]; diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h new file mode 100644 index 0000000000000..f284c5835df09 --- /dev/null +++ b/Include/cpython/bytesobject.h @@ -0,0 +1,118 @@ +#ifndef Py_CPYTHON_BYTESOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + PyObject_VAR_HEAD + Py_hash_t ob_shash; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the string or -1 if not computed yet. + */ +} PyBytesObject; + +PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( + const char *format, + Py_ssize_t format_len, + PyObject *args, + int use_bytearray); +PyAPI_FUNC(PyObject*) _PyBytes_FromHex( + PyObject *string, + int use_bytearray); + +/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ +PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, const char **); + +/* Macro, trading safety for speed */ +#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ + (((PyBytesObject *)(op))->ob_sval)) +#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) + +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, + x must be an iterable object. */ +PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); + + +/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". + A _PyBytesWriter variable must be declared at the end of variables in a + function to optimize the memory allocation on the stack. */ +typedef struct { + /* bytes, bytearray or NULL (when the small buffer is used) */ + PyObject *buffer; + + /* Number of allocated size. */ + Py_ssize_t allocated; + + /* Minimum number of allocated bytes, + incremented by _PyBytesWriter_Prepare() */ + Py_ssize_t min_size; + + /* If non-zero, use a bytearray instead of a bytes object for buffer. */ + int use_bytearray; + + /* If non-zero, overallocate the buffer (default: 0). + This flag must be zero if use_bytearray is non-zero. */ + int overallocate; + + /* Stack buffer */ + int use_small_buffer; + char small_buffer[512]; +} _PyBytesWriter; + +/* Initialize a bytes writer + + By default, the overallocation is disabled. Set the overallocate attribute + to control the allocation of the buffer. */ +PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); + +/* Get the buffer content and reset the writer. + Return a bytes object, or a bytearray object if use_bytearray is non-zero. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, + void *str); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); + +/* Allocate the buffer to write size bytes. + Return the pointer to the beginning of buffer data. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, + Py_ssize_t size); + +/* Ensure that the buffer is large enough to write *size* bytes. + Add size to the writer minimum size (min_size attribute). + + str is the current pointer inside the buffer. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Resize the buffer to make it larger. + The new buffer may be larger than size bytes because of overallocation. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. + + Note: size must be greater than the number of allocated bytes in the writer. + + This function doesn't use the writer minimum size (min_size attribute). + + See also _PyBytesWriter_Prepare(). + */ +PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Write bytes. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, + void *str, + const void *bytes, + Py_ssize_t size); diff --git a/Makefile.pre.in b/Makefile.pre.in index f5540a2f0a6b4..2f3fab7b33ccb 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1055,6 +1055,8 @@ PYTHON_HEADERS= \ $(srcdir)/Include/Python-ast.h \ \ $(srcdir)/Include/cpython/abstract.h \ + $(srcdir)/Include/cpython/bytearrayobject.h \ + $(srcdir)/Include/cpython/bytesobject.h \ $(srcdir)/Include/cpython/ceval.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 7d597bcdac666..9e6323fdcbb0d 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -126,6 +126,8 @@ + + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 9563bdc25ebdb..b1412d550c05a 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -81,6 +81,12 @@ Include + + Include + + + Include + Include From webhook-mailer at python.org Wed Feb 12 17:55:14 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 12 Feb 2020 22:55:14 -0000 Subject: [Python-checkins] bpo-35134: Add Include/cpython/fileutils.h header file (GH-18493) Message-ID: https://github.com/python/cpython/commit/8c3aee65ed3aff3668da330ccd6f9ba7b2aa4567 commit: 8c3aee65ed3aff3668da330ccd6f9ba7b2aa4567 branch: master author: Victor Stinner committer: GitHub date: 2020-02-12T23:55:09+01:00 summary: bpo-35134: Add Include/cpython/fileutils.h header file (GH-18493) Move CPython C API from Include/fileutils.h into a new Include/cpython/fileutils.h header file which is included by Include/fileutils.h. Exclude the following private symbols from the limited C API: * _Py_error_handler * _Py_GetErrorHandler() * _Py_DecodeLocaleEx() * _Py_EncodeLocaleEx() files: A Include/cpython/fileutils.h M Include/fileutils.h M Makefile.pre.in M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters diff --git a/Include/cpython/fileutils.h b/Include/cpython/fileutils.h new file mode 100644 index 0000000000000..e79d03e24f577 --- /dev/null +++ b/Include/cpython/fileutils.h @@ -0,0 +1,165 @@ +#ifndef Py_CPYTHON_FILEUTILS_H +# error "this header file must not be included directly" +#endif + +typedef enum { + _Py_ERROR_UNKNOWN=0, + _Py_ERROR_STRICT, + _Py_ERROR_SURROGATEESCAPE, + _Py_ERROR_REPLACE, + _Py_ERROR_IGNORE, + _Py_ERROR_BACKSLASHREPLACE, + _Py_ERROR_SURROGATEPASS, + _Py_ERROR_XMLCHARREFREPLACE, + _Py_ERROR_OTHER +} _Py_error_handler; + +PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); + +PyAPI_FUNC(int) _Py_DecodeLocaleEx( + const char *arg, + wchar_t **wstr, + size_t *wlen, + const char **reason, + int current_locale, + _Py_error_handler errors); + +PyAPI_FUNC(int) _Py_EncodeLocaleEx( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int current_locale, + _Py_error_handler errors); + + +PyAPI_FUNC(PyObject *) _Py_device_encoding(int); + +#if defined(MS_WINDOWS) || defined(__APPLE__) + /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). + On macOS 10.13, read() and write() with more than INT_MAX bytes + fail with EINVAL (bpo-24658). */ +# define _PY_READ_MAX INT_MAX +# define _PY_WRITE_MAX INT_MAX +#else + /* write() should truncate the input to PY_SSIZE_T_MAX bytes, + but it's safer to do it ourself to have a portable behaviour */ +# define _PY_READ_MAX PY_SSIZE_T_MAX +# define _PY_WRITE_MAX PY_SSIZE_T_MAX +#endif + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + uint64_t st_ino; + unsigned short st_mode; + int st_nlink; + int st_uid; + int st_gid; + unsigned long st_rdev; + __int64 st_size; + time_t st_atime; + int st_atime_nsec; + time_t st_mtime; + int st_mtime_nsec; + time_t st_ctime; + int st_ctime_nsec; + unsigned long st_file_attributes; + unsigned long st_reparse_tag; +}; +#else +# define _Py_stat_struct stat +#endif + +PyAPI_FUNC(int) _Py_fstat( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_fstat_noraise( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_stat( + PyObject *path, + struct stat *status); + +PyAPI_FUNC(int) _Py_open( + const char *pathname, + int flags); + +PyAPI_FUNC(int) _Py_open_noraise( + const char *pathname, + int flags); + +PyAPI_FUNC(FILE *) _Py_wfopen( + const wchar_t *path, + const wchar_t *mode); + +PyAPI_FUNC(FILE*) _Py_fopen( + const char *pathname, + const char *mode); + +PyAPI_FUNC(FILE*) _Py_fopen_obj( + PyObject *path, + const char *mode); + +PyAPI_FUNC(Py_ssize_t) _Py_read( + int fd, + void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write( + int fd, + const void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( + int fd, + const void *buf, + size_t count); + +#ifdef HAVE_READLINK +PyAPI_FUNC(int) _Py_wreadlink( + const wchar_t *path, + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); +#endif + +#ifdef HAVE_REALPATH +PyAPI_FUNC(wchar_t*) _Py_wrealpath( + const wchar_t *path, + wchar_t *resolved_path, + /* Number of characters of 'resolved_path' buffer + including the trailing NUL character */ + size_t resolved_path_len); +#endif + +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_isabs(const wchar_t *path); +#endif + +PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p); + +PyAPI_FUNC(wchar_t*) _Py_wgetcwd( + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); + +PyAPI_FUNC(int) _Py_get_inheritable(int fd); + +PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_dup(int fd); + +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_get_blocking(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +#endif /* !MS_WINDOWS */ diff --git a/Include/fileutils.h b/Include/fileutils.h index a9655bbf9a5f0..12bd071c49c04 100644 --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -18,173 +18,12 @@ PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( size_t *error_pos); #endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000 -typedef enum { - _Py_ERROR_UNKNOWN=0, - _Py_ERROR_STRICT, - _Py_ERROR_SURROGATEESCAPE, - _Py_ERROR_REPLACE, - _Py_ERROR_IGNORE, - _Py_ERROR_BACKSLASHREPLACE, - _Py_ERROR_SURROGATEPASS, - _Py_ERROR_XMLCHARREFREPLACE, - _Py_ERROR_OTHER -} _Py_error_handler; - -PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); - -PyAPI_FUNC(int) _Py_DecodeLocaleEx( - const char *arg, - wchar_t **wstr, - size_t *wlen, - const char **reason, - int current_locale, - _Py_error_handler errors); - -PyAPI_FUNC(int) _Py_EncodeLocaleEx( - const wchar_t *text, - char **str, - size_t *error_pos, - const char **reason, - int current_locale, - _Py_error_handler errors); -#endif - #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _Py_device_encoding(int); - -#if defined(MS_WINDOWS) || defined(__APPLE__) - /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). - On macOS 10.13, read() and write() with more than INT_MAX bytes - fail with EINVAL (bpo-24658). */ -# define _PY_READ_MAX INT_MAX -# define _PY_WRITE_MAX INT_MAX -#else - /* write() should truncate the input to PY_SSIZE_T_MAX bytes, - but it's safer to do it ourself to have a portable behaviour */ -# define _PY_READ_MAX PY_SSIZE_T_MAX -# define _PY_WRITE_MAX PY_SSIZE_T_MAX +# define Py_CPYTHON_FILEUTILS_H +# include "cpython/fileutils.h" +# undef Py_CPYTHON_FILEUTILS_H #endif -#ifdef MS_WINDOWS -struct _Py_stat_struct { - unsigned long st_dev; - uint64_t st_ino; - unsigned short st_mode; - int st_nlink; - int st_uid; - int st_gid; - unsigned long st_rdev; - __int64 st_size; - time_t st_atime; - int st_atime_nsec; - time_t st_mtime; - int st_mtime_nsec; - time_t st_ctime; - int st_ctime_nsec; - unsigned long st_file_attributes; - unsigned long st_reparse_tag; -}; -#else -# define _Py_stat_struct stat -#endif - -PyAPI_FUNC(int) _Py_fstat( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_fstat_noraise( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_stat( - PyObject *path, - struct stat *status); - -PyAPI_FUNC(int) _Py_open( - const char *pathname, - int flags); - -PyAPI_FUNC(int) _Py_open_noraise( - const char *pathname, - int flags); - -PyAPI_FUNC(FILE *) _Py_wfopen( - const wchar_t *path, - const wchar_t *mode); - -PyAPI_FUNC(FILE*) _Py_fopen( - const char *pathname, - const char *mode); - -PyAPI_FUNC(FILE*) _Py_fopen_obj( - PyObject *path, - const char *mode); - -PyAPI_FUNC(Py_ssize_t) _Py_read( - int fd, - void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write( - int fd, - const void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( - int fd, - const void *buf, - size_t count); - -#ifdef HAVE_READLINK -PyAPI_FUNC(int) _Py_wreadlink( - const wchar_t *path, - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); -#endif - -#ifdef HAVE_REALPATH -PyAPI_FUNC(wchar_t*) _Py_wrealpath( - const wchar_t *path, - wchar_t *resolved_path, - /* Number of characters of 'resolved_path' buffer - including the trailing NUL character */ - size_t resolved_path_len); -#endif - -#ifndef MS_WINDOWS -PyAPI_FUNC(int) _Py_isabs(const wchar_t *path); -#endif - -PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p); - -PyAPI_FUNC(wchar_t*) _Py_wgetcwd( - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); - -PyAPI_FUNC(int) _Py_get_inheritable(int fd); - -PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_dup(int fd); - -#ifndef MS_WINDOWS -PyAPI_FUNC(int) _Py_get_blocking(int fd); - -PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); -#endif /* !MS_WINDOWS */ - -#endif /* Py_LIMITED_API */ - #ifdef __cplusplus } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in index 2f3fab7b33ccb..3199a1aa02d65 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1060,6 +1060,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/ceval.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ + $(srcdir)/Include/cpython/fileutils.h \ $(srcdir)/Include/cpython/import.h \ $(srcdir)/Include/cpython/initconfig.h \ $(srcdir)/Include/cpython/interpreteridobject.h \ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 9e6323fdcbb0d..0acf7f4a8de80 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -131,6 +131,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index b1412d550c05a..a846a37630a1c 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -96,6 +96,9 @@ Include + + Include + Include From webhook-mailer at python.org Wed Feb 12 23:53:09 2020 From: webhook-mailer at python.org (Andy Lester) Date: Thu, 13 Feb 2020 04:53:09 -0000 Subject: [Python-checkins] closes bpo-39621: Make buf arg to md5_compress be const. (GH-18497) Message-ID: https://github.com/python/cpython/commit/597ebed748d0b0c061f8c108bd98270d103286c1 commit: 597ebed748d0b0c061f8c108bd98270d103286c1 branch: master author: Andy Lester committer: GitHub date: 2020-02-12T20:53:01-08:00 summary: closes bpo-39621: Make buf arg to md5_compress be const. (GH-18497) files: M Modules/md5module.c diff --git a/Modules/md5module.c b/Modules/md5module.c index d783ae5a765fa..ea2bafb9b65e8 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -119,7 +119,7 @@ typedef struct { a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; -static void md5_compress(struct md5_state *md5, unsigned char *buf) +static void md5_compress(struct md5_state *md5, const unsigned char *buf) { MD5_INT32 i, W[16], a, b, c, d; @@ -242,7 +242,7 @@ md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) while (inlen > 0) { if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { - md5_compress(md5, (unsigned char *)in); + md5_compress(md5, in); md5->length += MD5_BLOCKSIZE * 8; in += MD5_BLOCKSIZE; inlen -= MD5_BLOCKSIZE; From webhook-mailer at python.org Thu Feb 13 00:12:57 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 13 Feb 2020 05:12:57 -0000 Subject: [Python-checkins] closes bpo-39621: Make buf arg to md5_compress be const. (GH-18497) Message-ID: https://github.com/python/cpython/commit/669981b3b14dd16dec42089d6ac8d6449fde8abd commit: 669981b3b14dd16dec42089d6ac8d6449fde8abd branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-12T21:12:53-08:00 summary: closes bpo-39621: Make buf arg to md5_compress be const. (GH-18497) (cherry picked from commit 597ebed748d0b0c061f8c108bd98270d103286c1) Co-authored-by: Andy Lester files: M Modules/md5module.c diff --git a/Modules/md5module.c b/Modules/md5module.c index b9a351a8c1cdd..c2ebaaf61f91c 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -119,7 +119,7 @@ typedef struct { a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; -static void md5_compress(struct md5_state *md5, unsigned char *buf) +static void md5_compress(struct md5_state *md5, const unsigned char *buf) { MD5_INT32 i, W[16], a, b, c, d; @@ -242,7 +242,7 @@ md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) while (inlen > 0) { if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { - md5_compress(md5, (unsigned char *)in); + md5_compress(md5, in); md5->length += MD5_BLOCKSIZE * 8; in += MD5_BLOCKSIZE; inlen -= MD5_BLOCKSIZE; From webhook-mailer at python.org Thu Feb 13 02:47:50 2020 From: webhook-mailer at python.org (Saiyang Gou) Date: Thu, 13 Feb 2020 07:47:50 -0000 Subject: [Python-checkins] bpo-39184: Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal`, `syslog` (GH-18407) Message-ID: https://github.com/python/cpython/commit/7514f4f6254f4a2d13ea8e5632a8e5f22b637e0b commit: 7514f4f6254f4a2d13ea8e5632a8e5f22b637e0b branch: master author: Saiyang Gou committer: GitHub date: 2020-02-13T07:47:42Z summary: bpo-39184: Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal`, `syslog` (GH-18407) files: A Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst M Doc/library/fcntl.rst M Doc/library/msvcrt.rst M Doc/library/os.rst M Doc/library/resource.rst M Doc/library/shutil.rst M Doc/library/signal.rst M Doc/library/syslog.rst M Lib/shutil.py M Modules/fcntlmodule.c M Modules/posixmodule.c M Modules/resource.c M Modules/signalmodule.c M Modules/syslogmodule.c M PC/msvcrtmodule.c diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 5c172b836acca..07a15d27216e9 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -63,6 +63,8 @@ The module defines the following functions: If the :c:func:`fcntl` fails, an :exc:`OSError` is raised. + .. audit-event:: fcntl.fcntl fd,cmd,arg fcntl.fcntl + .. function:: ioctl(fd, request, arg=0, mutate_flag=True) @@ -112,6 +114,8 @@ The module defines the following functions: >>> buf array('h', [13341]) + .. audit-event:: fcntl.ioctl fd,request,arg fcntl.ioctl + .. function:: flock(fd, operation) @@ -122,6 +126,8 @@ The module defines the following functions: If the :c:func:`flock` fails, an :exc:`OSError` exception is raised. + .. audit-event:: fcntl.flock fd,operation fcntl.flock + .. function:: lockf(fd, cmd, len=0, start=0, whence=0) @@ -155,6 +161,8 @@ The module defines the following functions: The default for *len* is 0 which means to lock to the end of the file. The default for *whence* is also 0. + .. audit-event:: fcntl.lockf fd,cmd,len,start,whence fcntl.lockf + Examples (all on a SVR4 compliant system):: import struct, fcntl, os diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 14ad2cd4373af..42fffee6a0f44 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -42,6 +42,8 @@ File Operations regions in a file may be locked at the same time, but may not overlap. Adjacent regions are not merged; they must be unlocked individually. + .. audit-event:: msvcrt.locking fd,mode,nbytes msvcrt.locking + .. data:: LK_LOCK LK_RLCK @@ -77,12 +79,16 @@ File Operations and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter to :func:`os.fdopen` to create a file object. + .. audit-event:: msvcrt.open_osfhandle handle,flags msvcrt.open_osfhandle + .. function:: get_osfhandle(fd) Return the file handle for the file descriptor *fd*. Raises :exc:`OSError` if *fd* is not recognized. + .. audit-event:: msvcrt.get_osfhandle fd msvcrt.get_osfhandle + .. _msvcrt-console: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index b06a318c3d79d..af02a373f33dc 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -445,6 +445,8 @@ process and user. On some platforms, including FreeBSD and Mac OS X, setting ``environ`` may cause memory leaks. Refer to the system documentation for :c:func:`putenv`. + .. audit-event:: os.putenv key,value os.putenv + .. versionchanged:: 3.9 The function is now always available. @@ -640,6 +642,8 @@ process and user. don't update ``os.environ``, so it is actually preferable to delete items of ``os.environ``. + .. audit-event:: os.unsetenv key os.unsetenv + .. versionchanged:: 3.9 The function is now always available and is also available on Windows. @@ -766,6 +770,8 @@ as internal buffering of data. docs for :func:`chmod` for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(fd, mode)``. + .. audit-event:: os.chmod path,mode,dir_fd os.fchmod + .. availability:: Unix. @@ -776,6 +782,8 @@ as internal buffering of data. :func:`chown`. As of Python 3.3, this is equivalent to ``os.chown(fd, uid, gid)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.fchown + .. availability:: Unix. @@ -883,6 +891,8 @@ as internal buffering of data. :data:`F_ULOCK` or :data:`F_TEST`. *len* specifies the section of the file to lock. + .. audit-event:: os.lockf fd,cmd,len os.lockf + .. availability:: Unix. .. versionadded:: 3.3 @@ -1603,6 +1613,8 @@ features: This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. audit-event:: os.chdir path os.chdir + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. @@ -1631,6 +1643,8 @@ features: This function can support :ref:`not following symlinks `. + .. audit-event:: os.chflags path,flags os.chflags + .. availability:: Unix. .. versionadded:: 3.3 @@ -1676,6 +1690,8 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1696,6 +1712,8 @@ features: See :func:`shutil.chown` for a higher-level function that accepts names in addition to numeric ids. + .. audit-event:: os.chown path,uid,gid,dir_fd os.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -1722,6 +1740,8 @@ features: descriptor *fd*. The descriptor must refer to an opened directory, not an open file. As of Python 3.3, this is equivalent to ``os.chdir(fd)``. + .. audit-event:: os.chdir path os.fchdir + .. availability:: Unix. @@ -1746,6 +1766,8 @@ features: not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chflags(path, flags, follow_symlinks=False)``. + .. audit-event:: os.chflags path,flags os.lchflags + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1759,6 +1781,8 @@ features: for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(path, mode, follow_symlinks=False)``. + .. audit-event:: os.chmod path,mode,dir_fd os.lchmod + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1770,6 +1794,8 @@ features: function will not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chown(path, uid, gid, follow_symlinks=False)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.lchown + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1784,6 +1810,8 @@ features: supply :ref:`paths relative to directory descriptors `, and :ref:`not following symlinks `. + .. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -1886,6 +1914,8 @@ features: It is also possible to create temporary directories; see the :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. + .. audit-event:: os.mkdir path,mode,dir_fd os.mkdir + .. versionadded:: 3.3 The *dir_fd* argument. @@ -1918,6 +1948,8 @@ features: This function handles UNC paths correctly. + .. audit-event:: os.mkdir path,mode,dir_fd os.makedirs + .. versionadded:: 3.2 The *exist_ok* parameter. @@ -2083,6 +2115,8 @@ features: This function is semantically identical to :func:`unlink`. + .. audit-event:: os.remove path,dir_fd os.remove + .. versionadded:: 3.3 The *dir_fd* argument. @@ -2103,6 +2137,8 @@ features: they are empty. Raises :exc:`OSError` if the leaf directory could not be successfully removed. + .. audit-event:: os.remove path,dir_fd os.removedirs + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2128,6 +2164,8 @@ features: If you want cross-platform overwriting of the destination, use :func:`replace`. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.rename + .. versionadded:: 3.3 The *src_dir_fd* and *dst_dir_fd* arguments. @@ -2147,6 +2185,8 @@ features: This function can fail with the new directory structure made if you lack permissions needed to remove the leaf directory or file. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.renames + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *old* and *new*. @@ -2162,6 +2202,8 @@ features: This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to supply :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.replace + .. versionadded:: 3.3 .. versionchanged:: 3.6 @@ -2178,6 +2220,8 @@ features: This function can support :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rmdir path,dir_fd os.rmdir + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2821,6 +2865,8 @@ features: :exc:`OSError` is raised when the function is called by an unprivileged user. + .. audit-event:: os.symlink src,dst,dir_fd os.symlink + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -2873,6 +2919,8 @@ features: traditional Unix name. Please see the documentation for :func:`remove` for further information. + .. audit-event:: os.remove path,dir_fd os.unlink + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2910,6 +2958,8 @@ features: :ref:`paths relative to directory descriptors ` and :ref:`not following symlinks `. + .. audit-event:: os.utime path,times,ns,dir_fd os.utime + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd*, *follow_symlinks*, and *ns* parameters. @@ -3135,6 +3185,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.getxattr path,attribute os.getxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3149,6 +3201,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.listxattr path os.listxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -3163,6 +3217,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.removexattr path,attribute os.removexattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3186,6 +3242,8 @@ These functions are all available on Linux only. A bug in Linux kernel versions less than 2.6.39 caused the flags argument to be ignored on some filesystems. + .. audit-event:: os.setxattr path,attribute,value,flags os.setxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3248,6 +3306,8 @@ to be ignored. `_ for more information about how DLLs are loaded. + .. audit-event:: os.add_dll_directory path os.add_dll_directory + .. availability:: Windows. .. versionadded:: 3.8 @@ -3480,6 +3540,8 @@ written in Python, such as a mail server's external command delivery program. Note that some platforms including FreeBSD <= 6.3 and Cygwin have known issues when using ``fork()`` from a thread. + .. audit-event:: os.fork "" os.fork + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3499,6 +3561,8 @@ 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. + .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3525,6 +3589,8 @@ written in Python, such as a mail server's external command delivery program. See also :func:`signal.pthread_kill`. + .. audit-event:: os.kill pid,sig os.kill + .. versionadded:: 3.2 Windows support. @@ -3537,6 +3603,8 @@ written in Python, such as a mail server's external command delivery program. Send the signal *sig* to the process group *pgid*. + .. audit-event:: os.killpg pgid,sig os.killpg + .. availability:: Unix. diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 3573da7ea2d71..e4eac43642d14 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -78,6 +78,9 @@ this module for those platforms. VxWorks only supports setting :data:`RLIMIT_NOFILE`. + .. audit-event:: resource.setrlimit resource,limits resource.setrlimit + + .. function:: prlimit(pid, resource[, limits]) Combines :func:`setrlimit` and :func:`getrlimit` in one function and @@ -94,6 +97,8 @@ this module for those platforms. :exc:`PermissionError` when the user doesn't have ``CAP_SYS_RESOURCE`` for the process. + .. audit-event:: resource.prlimit pid,resource,limits resource.prlimit + .. availability:: Linux 2.6.36 or later with glibc 2.13 or later. .. versionadded:: 3.4 diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 59390d0e907eb..c7c63e6f80844 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -67,6 +67,8 @@ Directory and files operations a new symbolic link will be created instead of copying the file *src* points to. + .. audit-event:: shutil.copyfile src,dst shutil.copyfile + .. versionchanged:: 3.3 :exc:`IOError` used to be raised instead of :exc:`OSError`. Added *follow_symlinks* argument. @@ -101,6 +103,8 @@ Directory and files operations :func:`copymode` cannot modify symbolic links on the local platform, and it is asked to do so, it will do nothing and return. + .. audit-event:: shutil.copymode src,dst shutil.copymode + .. versionchanged:: 3.3 Added *follow_symlinks* argument. @@ -146,6 +150,8 @@ Directory and files operations Please see :data:`os.supports_follow_symlinks` for more information. + .. audit-event:: shutil.copystat src,dst shutil.copystat + .. versionchanged:: 3.3 Added *follow_symlinks* argument and support for Linux extended attributes. @@ -167,6 +173,10 @@ Directory and files operations To preserve all file metadata from the original, use :func:`~shutil.copy2` instead. + .. audit-event:: shutil.copyfile src,dst shutil.copy + + .. audit-event:: shutil.copymode src,dst shutil.copy + .. versionchanged:: 3.3 Added *follow_symlinks* argument. Now returns path to the newly created file. @@ -194,6 +204,10 @@ Directory and files operations Please see :func:`copystat` for more information about platform support for modifying symbolic link metadata. + .. audit-event:: shutil.copyfile src,dst shutil.copy2 + + .. audit-event:: shutil.copystat src,dst shutil.copy2 + .. versionchanged:: 3.3 Added *follow_symlinks* argument, try to copy extended file system attributes too (currently Linux only). @@ -342,6 +356,8 @@ Directory and files operations *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. + .. audit-event:: shutil.move src,dst shutil.move + .. versionchanged:: 3.3 Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's :program:`mv`. @@ -381,6 +397,8 @@ Directory and files operations See also :func:`os.chown`, the underlying function. + .. audit-event:: shutil.chown path,user,group shutil.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -632,6 +650,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. registered for that extension. In case none is found, a :exc:`ValueError` is raised. + .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive + .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index a79fc501352d4..8b3ab412bd368 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -277,6 +277,8 @@ The :mod:`signal` module defines the following functions: If *signalnum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if the target thread is still running. + .. audit-event:: signal.pthread_kill thread_id,signalnum signal.pthread_kill + .. availability:: Unix. See the man page :manpage:`pthread_kill(3)` for further information. diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 7151527ce57a5..d264a3340c98b 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -31,6 +31,8 @@ The module defines the following functions: If :func:`openlog` has not been called prior to the call to :func:`syslog`, ``openlog()`` will be called with no arguments. + .. audit-event:: syslog.syslog priority,message syslog.syslog + .. function:: openlog([ident[, logoption[, facility]]]) @@ -45,6 +47,8 @@ The module defines the following functions: keyword argument (default is :const:`LOG_USER`) sets the default facility for messages which do not have a facility explicitly encoded. + .. audit-event:: syslog.openlog ident,logoption,facility syslog.openlog + .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was required. The default for *ident* was dependent on the system libraries, @@ -60,6 +64,8 @@ The module defines the following functions: :func:`openlog` hasn't already been called), and *ident* and other :func:`openlog` parameters are reset to defaults. + .. audit-event:: syslog.closelog "" syslog.closelog + .. function:: setlogmask(maskpri) @@ -70,6 +76,8 @@ The module defines the following functions: ``LOG_UPTO(pri)`` calculates the mask for all priorities up to and including *pri*. + .. audit-event:: syslog.setlogmask maskpri syslog.setlogmask + The module defines the following constants: Priority levels (high to low): diff --git a/Lib/shutil.py b/Lib/shutil.py index 9a83a3242ed91..a4ce2c0290bc9 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -235,6 +235,8 @@ def copyfile(src, dst, *, follow_symlinks=True): symlink will be created instead of copying the file it points to. """ + sys.audit("shutil.copyfile", src, dst) + if _samefile(src, dst): raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) @@ -289,6 +291,8 @@ def copymode(src, dst, *, follow_symlinks=True): (e.g. Linux) this method does nothing. """ + sys.audit("shutil.copymode", src, dst) + if not follow_symlinks and _islink(src) and os.path.islink(dst): if hasattr(os, 'lchmod'): stat_func, chmod_func = os.lstat, os.lchmod @@ -340,6 +344,8 @@ def copystat(src, dst, *, follow_symlinks=True): If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. """ + sys.audit("shutil.copystat", src, dst) + def _nop(*args, ns=None, follow_symlinks=None): pass @@ -778,6 +784,7 @@ def move(src, dst, copy_function=copy2): the issues this implementation glosses over. """ + sys.audit("shutil.move", src, dst) real_dst = dst if os.path.isdir(dst): if _samefile(src, dst): @@ -1208,6 +1215,8 @@ def unpack_archive(filename, extract_dir=None, format=None): In case none is found, a ValueError is raised. """ + sys.audit("shutil.unpack_archive", filename, extract_dir, format) + if extract_dir is None: extract_dir = os.getcwd() @@ -1275,6 +1284,7 @@ def chown(path, user=None, group=None): user and group can be the uid/gid or the user/group names, and in that case, they are converted to their respective uid/gid. """ + sys.audit('shutil.chown', path, user, group) if user is None and group is None: raise ValueError("user and/or group must be set") diff --git a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst new file mode 100644 index 0000000000000..cf25c24d58788 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst @@ -0,0 +1 @@ +Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal` and `syslog`. \ No newline at end of file diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 11906aa582929..43f9b22f67207 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -66,6 +66,10 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) char buf[1024]; int async_err = 0; + if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) { + return NULL; + } + if (arg != NULL) { int parse_result; @@ -171,6 +175,11 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, Py_ssize_t len; char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ + if (PySys_Audit("fcntl.ioctl", "iIO", fd, code, + ob_arg ? ob_arg : Py_None) < 0) { + return NULL; + } + if (ob_arg != NULL) { if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { char *arg; @@ -288,6 +297,10 @@ fcntl_flock_impl(PyObject *module, int fd, int code) int ret; int async_err = 0; + if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) { + return NULL; + } + #ifdef HAVE_FLOCK do { Py_BEGIN_ALLOW_THREADS @@ -372,6 +385,11 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, int ret; int async_err = 0; + if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None, + startobj ? startobj : Py_None, whence) < 0) { + return NULL; + } + #ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ec3da4fb2fc6e..4d6d255b3469b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2911,6 +2911,10 @@ os_chdir_impl(PyObject *module, path_t *path) { int result; + if (PySys_Audit("os.chdir", "(O)", path->object) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS /* on unix, success = 0, on windows, success = !0 */ @@ -2950,6 +2954,9 @@ static PyObject * os_fchdir_impl(PyObject *module, int fd) /*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/ { + if (PySys_Audit("os.chdir", "(i)", fd) < 0) { + return NULL; + } return posix_fildes_fd(fd, fchdir); } #endif /* HAVE_FCHDIR */ @@ -3007,6 +3014,11 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, return NULL; #endif + if (PySys_Audit("os.chmod", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesW(path->wide); @@ -3103,6 +3115,10 @@ os_fchmod_impl(PyObject *module, int fd, int mode) int res; int async_err = 0; + if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS res = fchmod(fd, mode); @@ -3134,6 +3150,9 @@ os_lchmod_impl(PyObject *module, path_t *path, int mode) /*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/ { int res; + if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchmod(path->narrow, mode); Py_END_ALLOW_THREADS @@ -3176,6 +3195,10 @@ os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, return NULL; #endif + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LCHFLAGS if (!follow_symlinks) @@ -3211,6 +3234,9 @@ os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags) /*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/ { int res; + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchflags(path->narrow, flags); Py_END_ALLOW_THREADS @@ -3373,6 +3399,11 @@ os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, } #endif + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN if (path->fd != -1) @@ -3422,6 +3453,10 @@ os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid) int res; int async_err = 0; + if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS res = fchown(fd, uid, gid); @@ -3454,6 +3489,9 @@ os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) /*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/ { int res; + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchown(path->narrow, uid, gid); Py_END_ALLOW_THREADS @@ -3647,6 +3685,12 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, } #endif + if (PySys_Audit("os.link", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = CreateHardLinkW(dst->wide, src->wide, NULL); @@ -4114,6 +4158,11 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) { int result; + if (PySys_Audit("os.mkdir", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = CreateDirectoryW(path->wide, NULL); @@ -4259,6 +4308,12 @@ internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is } #endif + if (PySys_Audit("os.rename", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = MoveFileExW(src->wide, dst->wide, flags); @@ -4359,6 +4414,11 @@ os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) { int result; + if (PySys_Audit("os.rmdir", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS /* Windows, success=1, UNIX, success=0 */ @@ -4517,6 +4577,11 @@ os_unlink_impl(PyObject *module, path_t *path, int dir_fd) { int result; + if (PySys_Audit("os.remove", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS @@ -4933,6 +4998,11 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, } #endif + if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, @@ -5234,8 +5304,7 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) return NULL; } - if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, - argv, Py_None) < 0) { + if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) { free_string_array(argvlist, argc); return NULL; } @@ -5311,8 +5380,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (envlist == NULL) goto fail_0; - if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, - argv, env) < 0) { + if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) { goto fail_1; } @@ -5665,8 +5733,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a } attrp = &attr; - if (PySys_Audit("os.posix_spawn", "OOO", - path->object ? path->object : Py_None, argv, env) < 0) { + if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) { goto exit; } @@ -5910,8 +5977,7 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) mode = _P_OVERLAY; #endif - if (PySys_Audit("os.spawn", "iOOO", mode, - path->object ? path->object : Py_None, argv, + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, Py_None) < 0) { free_string_array(argvlist, argc); return NULL; @@ -6026,8 +6092,7 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, mode = _P_OVERLAY; #endif - if (PySys_Audit("os.spawn", "iOOO", mode, - path->object ? path->object : Py_None, argv, env) < 0) { + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) { goto fail_2; } @@ -6182,6 +6247,9 @@ os_fork_impl(PyObject *module) PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } + if (PySys_Audit("os.fork", NULL) < 0) { + return NULL; + } PyOS_BeforeFork(); pid = fork(); if (pid == 0) { @@ -6788,6 +6856,9 @@ os_forkpty_impl(PyObject *module) PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } + if (PySys_Audit("os.forkpty", NULL) < 0) { + return NULL; + } PyOS_BeforeFork(); pid = forkpty(&master_fd, NULL, NULL, NULL); if (pid == 0) { @@ -7309,14 +7380,15 @@ Kill a process with a signal. static PyObject * os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) /*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/ -#ifndef MS_WINDOWS { + if (PySys_Audit("os.kill", "in", pid, signal) < 0) { + return NULL; + } +#ifndef MS_WINDOWS if (kill(pid, (int)signal) == -1) return posix_error(); Py_RETURN_NONE; -} #else /* !MS_WINDOWS */ -{ PyObject *result; DWORD sig = (DWORD)signal; DWORD err; @@ -7351,8 +7423,8 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) CloseHandle(handle); return result; -} #endif /* !MS_WINDOWS */ +} #endif /* HAVE_KILL */ @@ -7371,6 +7443,9 @@ static PyObject * os_killpg_impl(PyObject *module, pid_t pgid, int signal) /*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/ { + if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) { + return NULL; + } /* XXX some man pages make the `pgid` parameter an int, others a pid_t. Since getpgrp() returns a pid_t, we assume killpg should take the same type. Moreover, pid_t is always at least as wide as @@ -8143,6 +8218,11 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, int result; #endif + if (PySys_Audit("os.symlink", "OOi", src->object, dst->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS if (windows_has_symlink_unprivileged_flag) { @@ -8745,6 +8825,10 @@ os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) { int res; + if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS res = lockf(fd, command, length); Py_END_ALLOW_THREADS @@ -10147,6 +10231,9 @@ static PyObject * os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ { + if (PySys_Audit("os.putenv", "OO", name, value) < 0) { + return NULL; + } return win32_putenv(name, value); } #else @@ -10172,6 +10259,10 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) return NULL; } + if (PySys_Audit("os.putenv", "OO", name, value) < 0) { + return NULL; + } + if (setenv(name_string, value_string, 1)) { return posix_error(); } @@ -10193,6 +10284,9 @@ static PyObject * os_unsetenv_impl(PyObject *module, PyObject *name) /*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/ { + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; + } return win32_putenv(name, NULL); } #else @@ -10208,6 +10302,9 @@ static PyObject * os_unsetenv_impl(PyObject *module, PyObject *name) /*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/ { + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; + } #ifdef HAVE_BROKEN_UNSETENV unsetenv(PyBytes_AS_STRING(name)); #else @@ -11730,9 +11827,7 @@ os_startfile_impl(PyObject *module, path_t *filepath, "startfile not available on this platform"); } - if (PySys_Audit("os.startfile", "Ou", - filepath->object ? filepath->object : Py_None, - operation) < 0) { + if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) { return NULL; } @@ -11910,6 +12005,10 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) { + return NULL; + } + for (i = 0; ; i++) { void *ptr; ssize_t result; @@ -11981,6 +12080,11 @@ os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object, + value->buf, value->len, flags) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS; if (path->fd > -1) result = fsetxattr(path->fd, attribute->narrow, @@ -12029,6 +12133,10 @@ os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS; if (path->fd > -1) result = fremovexattr(path->fd, attribute->narrow); @@ -12074,6 +12182,11 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) goto exit; + if (PySys_Audit("os.listxattr", "(O)", + path->object ? path->object : Py_None) < 0) { + return NULL; + } + name = path->narrow ? path->narrow : "."; for (i = 0; ; i++) { @@ -13550,6 +13663,10 @@ os__add_dll_directory_impl(PyObject *module, path_t *path) DLL_DIRECTORY_COOKIE cookie = 0; DWORD err = 0; + if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) { + return NULL; + } + /* For Windows 7, we have to load this. As this will be a fairly infrequent operation, just do it each time. Kernel32 is always loaded. */ diff --git a/Modules/resource.c b/Modules/resource.c index 87c72e7409895..afde03c6c7e55 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -224,6 +224,11 @@ resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits) return NULL; } + if (PySys_Audit("resource.setrlimit", "iO", resource, + limits ? limits : Py_None) < 0) { + return NULL; + } + if (py2rlimit(limits, &rl) < 0) { return NULL; } @@ -269,6 +274,11 @@ resource_prlimit_impl(PyObject *module, pid_t pid, int resource, return NULL; } + if (PySys_Audit("resource.prlimit", "iiO", pid, resource, + limits ? limits : Py_None) < 0) { + return NULL; + } + if (group_right_1) { if (py2rlimit(limits, &new_limit) < 0) { return NULL; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 693b90b6c631e..a197673746240 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1236,6 +1236,10 @@ signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, { int err; + if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) { + return NULL; + } + err = pthread_kill((pthread_t)thread_id, signalnum); if (err != 0) { errno = err; diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 539224f2c5b67..24517925c32eb 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -144,6 +144,10 @@ syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) return NULL; } + if (PySys_Audit("syslog.openlog", "sll", ident, logopt, facility) < 0) { + return NULL; + } + openlog(ident, logopt, facility); S_log_open = 1; @@ -170,6 +174,10 @@ syslog_syslog(PyObject * self, PyObject * args) if (message == NULL) return NULL; + if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) { + return NULL; + } + /* if log is not opened, open it now */ if (!S_log_open) { PyObject *openargs; @@ -194,6 +202,9 @@ syslog_syslog(PyObject * self, PyObject * args) static PyObject * syslog_closelog(PyObject *self, PyObject *unused) { + if (PySys_Audit("syslog.closelog", NULL) < 0) { + return NULL; + } if (S_log_open) { closelog(); Py_CLEAR(S_ident_o); @@ -209,6 +220,9 @@ syslog_setlogmask(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) return NULL; + if (PySys_Audit("syslog.setlogmask", "(O)", args ? args : Py_None) < 0) { + return NULL; + } omaskpri = setlogmask(maskpri); return PyLong_FromLong(omaskpri); } diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index c4113e54c2b8f..5c06ec2621ea6 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -116,6 +116,10 @@ msvcrt_locking_impl(PyObject *module, int fd, int mode, long nbytes) { int err; + if (PySys_Audit("msvcrt.locking", "iil", fd, mode, nbytes) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH err = _locking(fd, mode, nbytes); @@ -175,6 +179,10 @@ msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags) { int fd; + if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) { + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH fd = _open_osfhandle((intptr_t)handle, flags); _Py_END_SUPPRESS_IPH @@ -201,6 +209,10 @@ msvcrt_get_osfhandle_impl(PyObject *module, int fd) { intptr_t handle = -1; + if (PySys_Audit("msvcrt.get_osfhandle", "(i)", fd) < 0) { + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH handle = _get_osfhandle(fd); _Py_END_SUPPRESS_IPH From webhook-mailer at python.org Thu Feb 13 03:15:46 2020 From: webhook-mailer at python.org (Nathaniel J. Smith) Date: Thu, 13 Feb 2020 08:15:46 -0000 Subject: [Python-checkins] bpo-39606: allow closing async generators that are already closed (GH-18475) Message-ID: https://github.com/python/cpython/commit/925dc7fb1d0db85dc137afa4cd14211bf0d67414 commit: 925dc7fb1d0db85dc137afa4cd14211bf0d67414 branch: master author: Nathaniel J. Smith committer: GitHub date: 2020-02-13T00:15:38-08:00 summary: bpo-39606: allow closing async generators that are already closed (GH-18475) The fix for [bpo-39386](https://bugs.python.org/issue39386) attempted to make it so you couldn't reuse a agen.aclose() coroutine object. It accidentally also prevented you from calling aclose() at all on an async generator that was already closed or exhausted. This commit fixes it so we're only blocking the actually illegal cases, while allowing the legal cases. The new tests failed before this patch. Also confirmed that this fixes the test failures we were seeing in Trio with Python dev builds: https://github.com/python-trio/trio/pull/1396 https://bugs.python.org/issue39606 files: A Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.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 24b20bec2b2d1..fb6321d2264f3 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1128,7 +1128,7 @@ def exception_handler(loop, context): self.assertEqual([], messages) - def test_async_gen_await_anext_twice(self): + def test_async_gen_await_same_anext_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1147,7 +1147,7 @@ def test_async_gen_await_anext_twice(self): self.loop.run_until_complete(run()) - def test_async_gen_await_aclose_twice(self): + def test_async_gen_await_same_aclose_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1164,6 +1164,32 @@ def test_async_gen_await_aclose_twice(self): self.loop.run_until_complete(run()) + def test_async_gen_aclose_twice_with_different_coros(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + await it.aclose() + await it.aclose() + + self.loop.run_until_complete(run()) + + def test_async_gen_aclose_after_exhaustion(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + async for _ in it: + pass + await it.aclose() + + self.loop.run_until_complete(run()) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst new file mode 100644 index 0000000000000..b7cbe4e91f59c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst @@ -0,0 +1,2 @@ +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. diff --git a/Objects/genobject.c b/Objects/genobject.c index 576d6856c7f30..0efd57de7a5a3 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1797,16 +1797,22 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) PyFrameObject *f = gen->gi_frame; PyObject *retval; - if (f == NULL || f->f_stacktop == NULL || - o->agt_state == AWAITABLE_STATE_CLOSED) { + if (o->agt_state == AWAITABLE_STATE_CLOSED) { PyErr_SetString( PyExc_RuntimeError, "cannot reuse already awaited aclose()/athrow()"); return NULL; } + if (f == NULL || f->f_stacktop == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + if (o->agt_state == AWAITABLE_STATE_INIT) { if (o->agt_gen->ag_running_async) { + o->agt_state = AWAITABLE_STATE_CLOSED; if (o->agt_args == NULL) { PyErr_SetString( PyExc_RuntimeError, @@ -1878,7 +1884,6 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) /* aclose() mode */ if (retval) { if (_PyAsyncGenWrappedValue_CheckExact(retval)) { - o->agt_gen->ag_running_async = 0; Py_DECREF(retval); goto yield_close; } @@ -1893,16 +1898,17 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) yield_close: o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetString( PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; check_error: o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { - o->agt_state = AWAITABLE_STATE_CLOSED; if (o->agt_args == NULL) { /* when aclose() is called we don't want to propagate StopAsyncIteration or GeneratorExit; just raise @@ -1936,6 +1942,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) /* aclose() mode */ if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; From webhook-mailer at python.org Thu Feb 13 03:30:35 2020 From: webhook-mailer at python.org (Steve Dower) Date: Thu, 13 Feb 2020 08:30:35 -0000 Subject: [Python-checkins] bpo-39184: Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal`, `syslog` (GH-18407) Message-ID: https://github.com/python/cpython/commit/a00b5be5f71b702ab80b0a7c046485046aaae160 commit: a00b5be5f71b702ab80b0a7c046485046aaae160 branch: 3.8 author: Steve Dower committer: GitHub date: 2020-02-13T08:30:27Z summary: bpo-39184: Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal`, `syslog` (GH-18407) Co-authored-by: Saiyang Gou files: A Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst M Doc/library/fcntl.rst M Doc/library/msvcrt.rst M Doc/library/os.rst M Doc/library/resource.rst M Doc/library/shutil.rst M Doc/library/signal.rst M Doc/library/syslog.rst M Lib/shutil.py M Modules/fcntlmodule.c M Modules/posixmodule.c M Modules/resource.c M Modules/signalmodule.c M Modules/syslogmodule.c M PC/msvcrtmodule.c diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index a7390150f7910..69484b647363d 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -57,6 +57,8 @@ The module defines the following functions: If the :c:func:`fcntl` fails, an :exc:`OSError` is raised. + .. audit-event:: fcntl.fcntl fd,cmd,arg fcntl.fcntl + .. function:: ioctl(fd, request, arg=0, mutate_flag=True) @@ -106,6 +108,8 @@ The module defines the following functions: >>> buf array('h', [13341]) + .. audit-event:: fcntl.ioctl fd,request,arg fcntl.ioctl + .. function:: flock(fd, operation) @@ -116,6 +120,8 @@ The module defines the following functions: If the :c:func:`flock` fails, an :exc:`OSError` exception is raised. + .. audit-event:: fcntl.flock fd,operation fcntl.flock + .. function:: lockf(fd, cmd, len=0, start=0, whence=0) @@ -149,6 +155,8 @@ The module defines the following functions: The default for *len* is 0 which means to lock to the end of the file. The default for *whence* is also 0. + .. audit-event:: fcntl.lockf fd,cmd,len,start,whence fcntl.lockf + Examples (all on a SVR4 compliant system):: import struct, fcntl, os diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 14ad2cd4373af..42fffee6a0f44 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -42,6 +42,8 @@ File Operations regions in a file may be locked at the same time, but may not overlap. Adjacent regions are not merged; they must be unlocked individually. + .. audit-event:: msvcrt.locking fd,mode,nbytes msvcrt.locking + .. data:: LK_LOCK LK_RLCK @@ -77,12 +79,16 @@ File Operations and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter to :func:`os.fdopen` to create a file object. + .. audit-event:: msvcrt.open_osfhandle handle,flags msvcrt.open_osfhandle + .. function:: get_osfhandle(fd) Return the file handle for the file descriptor *fd*. Raises :exc:`OSError` if *fd* is not recognized. + .. audit-event:: msvcrt.get_osfhandle fd msvcrt.get_osfhandle + .. _msvcrt-console: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 0d8df34c345c4..3157b887b535c 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -451,6 +451,8 @@ process and user. calls to :func:`putenv` don't update ``os.environ``, so it is actually preferable to assign to items of ``os.environ``. + .. audit-event:: os.putenv key,value os.putenv + .. function:: setegid(egid) @@ -643,6 +645,8 @@ process and user. calls to :func:`unsetenv` don't update ``os.environ``, so it is actually preferable to delete items of ``os.environ``. + .. audit-event:: os.unsetenv key os.unsetenv + .. availability:: most flavors of Unix. @@ -768,6 +772,8 @@ as internal buffering of data. docs for :func:`chmod` for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(fd, mode)``. + .. audit-event:: os.chmod path,mode,dir_fd os.fchmod + .. availability:: Unix. @@ -778,6 +784,8 @@ as internal buffering of data. :func:`chown`. As of Python 3.3, this is equivalent to ``os.chown(fd, uid, gid)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.fchown + .. availability:: Unix. @@ -885,6 +893,8 @@ as internal buffering of data. :data:`F_ULOCK` or :data:`F_TEST`. *len* specifies the section of the file to lock. + .. audit-event:: os.lockf fd,cmd,len os.lockf + .. availability:: Unix. .. versionadded:: 3.3 @@ -1602,6 +1612,8 @@ features: This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. audit-event:: os.chdir path os.chdir + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. @@ -1630,6 +1642,8 @@ features: This function can support :ref:`not following symlinks `. + .. audit-event:: os.chflags path,flags os.chflags + .. availability:: Unix. .. versionadded:: 3.3 @@ -1675,6 +1689,8 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1695,6 +1711,8 @@ features: See :func:`shutil.chown` for a higher-level function that accepts names in addition to numeric ids. + .. audit-event:: os.chown path,uid,gid,dir_fd os.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -1721,6 +1739,8 @@ features: descriptor *fd*. The descriptor must refer to an opened directory, not an open file. As of Python 3.3, this is equivalent to ``os.chdir(fd)``. + .. audit-event:: os.chdir path os.fchdir + .. availability:: Unix. @@ -1745,6 +1765,8 @@ features: not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chflags(path, flags, follow_symlinks=False)``. + .. audit-event:: os.chflags path,flags os.lchflags + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1758,6 +1780,8 @@ features: for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(path, mode, follow_symlinks=False)``. + .. audit-event:: os.chmod path,mode,dir_fd os.lchmod + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1769,6 +1793,8 @@ features: function will not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chown(path, uid, gid, follow_symlinks=False)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.lchown + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1783,6 +1809,8 @@ features: supply :ref:`paths relative to directory descriptors `, and :ref:`not following symlinks `. + .. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -1885,6 +1913,8 @@ features: It is also possible to create temporary directories; see the :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. + .. audit-event:: os.mkdir path,mode,dir_fd os.mkdir + .. versionadded:: 3.3 The *dir_fd* argument. @@ -1917,6 +1947,8 @@ features: This function handles UNC paths correctly. + .. audit-event:: os.mkdir path,mode,dir_fd os.makedirs + .. versionadded:: 3.2 The *exist_ok* parameter. @@ -2082,6 +2114,8 @@ features: This function is semantically identical to :func:`unlink`. + .. audit-event:: os.remove path,dir_fd os.remove + .. versionadded:: 3.3 The *dir_fd* argument. @@ -2102,6 +2136,8 @@ features: they are empty. Raises :exc:`OSError` if the leaf directory could not be successfully removed. + .. audit-event:: os.remove path,dir_fd os.removedirs + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2127,6 +2163,8 @@ features: If you want cross-platform overwriting of the destination, use :func:`replace`. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.rename + .. versionadded:: 3.3 The *src_dir_fd* and *dst_dir_fd* arguments. @@ -2146,6 +2184,8 @@ features: This function can fail with the new directory structure made if you lack permissions needed to remove the leaf directory or file. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.renames + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *old* and *new*. @@ -2161,6 +2201,8 @@ features: This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to supply :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.replace + .. versionadded:: 3.3 .. versionchanged:: 3.6 @@ -2177,6 +2219,8 @@ features: This function can support :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rmdir path,dir_fd os.rmdir + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2820,6 +2864,8 @@ features: :exc:`OSError` is raised when the function is called by an unprivileged user. + .. audit-event:: os.symlink src,dst,dir_fd os.symlink + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -2872,6 +2918,8 @@ features: traditional Unix name. Please see the documentation for :func:`remove` for further information. + .. audit-event:: os.remove path,dir_fd os.unlink + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2909,6 +2957,8 @@ features: :ref:`paths relative to directory descriptors ` and :ref:`not following symlinks `. + .. audit-event:: os.utime path,times,ns,dir_fd os.utime + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd*, *follow_symlinks*, and *ns* parameters. @@ -3134,6 +3184,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.getxattr path,attribute os.getxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3148,6 +3200,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.listxattr path os.listxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -3162,6 +3216,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.removexattr path,attribute os.removexattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3185,6 +3241,8 @@ These functions are all available on Linux only. A bug in Linux kernel versions less than 2.6.39 caused the flags argument to be ignored on some filesystems. + .. audit-event:: os.setxattr path,attribute,value,flags os.setxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3247,6 +3305,8 @@ to be ignored. `_ for more information about how DLLs are loaded. + .. audit-event:: os.add_dll_directory path os.add_dll_directory + .. availability:: Windows. .. versionadded:: 3.8 @@ -3479,6 +3539,8 @@ written in Python, such as a mail server's external command delivery program. Note that some platforms including FreeBSD <= 6.3 and Cygwin have known issues when using ``fork()`` from a thread. + .. audit-event:: os.fork "" os.fork + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3498,6 +3560,8 @@ 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. + .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3524,6 +3588,8 @@ written in Python, such as a mail server's external command delivery program. See also :func:`signal.pthread_kill`. + .. audit-event:: os.kill pid,sig os.kill + .. versionadded:: 3.2 Windows support. @@ -3536,6 +3602,8 @@ written in Python, such as a mail server's external command delivery program. Send the signal *sig* to the process group *pgid*. + .. audit-event:: os.killpg pgid,sig os.killpg + .. availability:: Unix. diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 3573da7ea2d71..e4eac43642d14 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -78,6 +78,9 @@ this module for those platforms. VxWorks only supports setting :data:`RLIMIT_NOFILE`. + .. audit-event:: resource.setrlimit resource,limits resource.setrlimit + + .. function:: prlimit(pid, resource[, limits]) Combines :func:`setrlimit` and :func:`getrlimit` in one function and @@ -94,6 +97,8 @@ this module for those platforms. :exc:`PermissionError` when the user doesn't have ``CAP_SYS_RESOURCE`` for the process. + .. audit-event:: resource.prlimit pid,resource,limits resource.prlimit + .. availability:: Linux 2.6.36 or later with glibc 2.13 or later. .. versionadded:: 3.4 diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 174b7e875a38a..bd24de7202321 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -67,6 +67,8 @@ Directory and files operations a new symbolic link will be created instead of copying the file *src* points to. + .. audit-event:: shutil.copyfile src,dst shutil.copyfile + .. versionchanged:: 3.3 :exc:`IOError` used to be raised instead of :exc:`OSError`. Added *follow_symlinks* argument. @@ -101,6 +103,8 @@ Directory and files operations :func:`copymode` cannot modify symbolic links on the local platform, and it is asked to do so, it will do nothing and return. + .. audit-event:: shutil.copymode src,dst shutil.copymode + .. versionchanged:: 3.3 Added *follow_symlinks* argument. @@ -146,6 +150,8 @@ Directory and files operations Please see :data:`os.supports_follow_symlinks` for more information. + .. audit-event:: shutil.copystat src,dst shutil.copystat + .. versionchanged:: 3.3 Added *follow_symlinks* argument and support for Linux extended attributes. @@ -167,6 +173,10 @@ Directory and files operations To preserve all file metadata from the original, use :func:`~shutil.copy2` instead. + .. audit-event:: shutil.copyfile src,dst shutil.copy + + .. audit-event:: shutil.copymode src,dst shutil.copy + .. versionchanged:: 3.3 Added *follow_symlinks* argument. Now returns path to the newly created file. @@ -194,6 +204,10 @@ Directory and files operations Please see :func:`copystat` for more information about platform support for modifying symbolic link metadata. + .. audit-event:: shutil.copyfile src,dst shutil.copy2 + + .. audit-event:: shutil.copystat src,dst shutil.copy2 + .. versionchanged:: 3.3 Added *follow_symlinks* argument, try to copy extended file system attributes too (currently Linux only). @@ -342,6 +356,8 @@ Directory and files operations *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. + .. audit-event:: shutil.move src,dst shutil.move + .. versionchanged:: 3.3 Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's :program:`mv`. @@ -378,6 +394,8 @@ Directory and files operations See also :func:`os.chown`, the underlying function. + .. audit-event:: shutil.chown path,user,group shutil.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -629,6 +647,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. registered for that extension. In case none is found, a :exc:`ValueError` is raised. + .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive + .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 8fecc2b7eed0e..932201b0e9d7d 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -264,6 +264,8 @@ The :mod:`signal` module defines the following functions: If *signalnum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if the target thread is still running. + .. audit-event:: signal.pthread_kill thread_id,signalnum signal.pthread_kill + .. availability:: Unix. See the man page :manpage:`pthread_kill(3)` for further information. diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 7151527ce57a5..d264a3340c98b 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -31,6 +31,8 @@ The module defines the following functions: If :func:`openlog` has not been called prior to the call to :func:`syslog`, ``openlog()`` will be called with no arguments. + .. audit-event:: syslog.syslog priority,message syslog.syslog + .. function:: openlog([ident[, logoption[, facility]]]) @@ -45,6 +47,8 @@ The module defines the following functions: keyword argument (default is :const:`LOG_USER`) sets the default facility for messages which do not have a facility explicitly encoded. + .. audit-event:: syslog.openlog ident,logoption,facility syslog.openlog + .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was required. The default for *ident* was dependent on the system libraries, @@ -60,6 +64,8 @@ The module defines the following functions: :func:`openlog` hasn't already been called), and *ident* and other :func:`openlog` parameters are reset to defaults. + .. audit-event:: syslog.closelog "" syslog.closelog + .. function:: setlogmask(maskpri) @@ -70,6 +76,8 @@ The module defines the following functions: ``LOG_UPTO(pri)`` calculates the mask for all priorities up to and including *pri*. + .. audit-event:: syslog.setlogmask maskpri syslog.setlogmask + The module defines the following constants: Priority levels (high to low): diff --git a/Lib/shutil.py b/Lib/shutil.py index cde7b860050a2..1f05d80f32a8f 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -235,6 +235,8 @@ def copyfile(src, dst, *, follow_symlinks=True): symlink will be created instead of copying the file it points to. """ + sys.audit("shutil.copyfile", src, dst) + if _samefile(src, dst): raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) @@ -289,6 +291,8 @@ def copymode(src, dst, *, follow_symlinks=True): (e.g. Linux) this method does nothing. """ + sys.audit("shutil.copymode", src, dst) + if not follow_symlinks and _islink(src) and os.path.islink(dst): if hasattr(os, 'lchmod'): stat_func, chmod_func = os.lstat, os.lchmod @@ -340,6 +344,8 @@ def copystat(src, dst, *, follow_symlinks=True): If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. """ + sys.audit("shutil.copystat", src, dst) + def _nop(*args, ns=None, follow_symlinks=None): pass @@ -766,6 +772,7 @@ def move(src, dst, copy_function=copy2): the issues this implementation glosses over. """ + sys.audit("shutil.move", src, dst) real_dst = dst if os.path.isdir(dst): if _samefile(src, dst): @@ -1193,6 +1200,8 @@ def unpack_archive(filename, extract_dir=None, format=None): In case none is found, a ValueError is raised. """ + sys.audit("shutil.unpack_archive", filename, extract_dir, format) + if extract_dir is None: extract_dir = os.getcwd() @@ -1260,6 +1269,7 @@ def chown(path, user=None, group=None): user and group can be the uid/gid or the user/group names, and in that case, they are converted to their respective uid/gid. """ + sys.audit('shutil.chown', path, user, group) if user is None and group is None: raise ValueError("user and/or group must be set") diff --git a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst new file mode 100644 index 0000000000000..cf25c24d58788 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst @@ -0,0 +1 @@ +Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shutil`, `signal` and `syslog`. \ No newline at end of file diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 0fbf7876c3e20..a7d2193022e98 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -66,6 +66,10 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) char buf[1024]; int async_err = 0; + if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) { + return NULL; + } + if (arg != NULL) { int parse_result; @@ -171,6 +175,11 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, Py_ssize_t len; char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ + if (PySys_Audit("fcntl.ioctl", "iIO", fd, code, + ob_arg ? ob_arg : Py_None) < 0) { + return NULL; + } + if (ob_arg != NULL) { if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { char *arg; @@ -288,6 +297,10 @@ fcntl_flock_impl(PyObject *module, int fd, int code) int ret; int async_err = 0; + if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) { + return NULL; + } + #ifdef HAVE_FLOCK do { Py_BEGIN_ALLOW_THREADS @@ -372,6 +385,11 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, int ret; int async_err = 0; + if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None, + startobj ? startobj : Py_None, whence) < 0) { + return NULL; + } + #ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 88b47164bca09..2f791d1df953a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2827,6 +2827,10 @@ os_chdir_impl(PyObject *module, path_t *path) { int result; + if (PySys_Audit("os.chdir", "(O)", path->object) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS /* on unix, success = 0, on windows, success = !0 */ @@ -2866,6 +2870,9 @@ static PyObject * os_fchdir_impl(PyObject *module, int fd) /*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/ { + if (PySys_Audit("os.chdir", "(i)", fd) < 0) { + return NULL; + } return posix_fildes_fd(fd, fchdir); } #endif /* HAVE_FCHDIR */ @@ -2923,6 +2930,11 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, return NULL; #endif + if (PySys_Audit("os.chmod", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesW(path->wide); @@ -3019,6 +3031,10 @@ os_fchmod_impl(PyObject *module, int fd, int mode) int res; int async_err = 0; + if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS res = fchmod(fd, mode); @@ -3050,6 +3066,9 @@ os_lchmod_impl(PyObject *module, path_t *path, int mode) /*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/ { int res; + if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchmod(path->narrow, mode); Py_END_ALLOW_THREADS @@ -3092,6 +3111,10 @@ os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, return NULL; #endif + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LCHFLAGS if (!follow_symlinks) @@ -3127,6 +3150,9 @@ os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags) /*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/ { int res; + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchflags(path->narrow, flags); Py_END_ALLOW_THREADS @@ -3289,6 +3315,11 @@ os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, } #endif + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN if (path->fd != -1) @@ -3338,6 +3369,10 @@ os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid) int res; int async_err = 0; + if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS res = fchown(fd, uid, gid); @@ -3370,6 +3405,9 @@ os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) /*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/ { int res; + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) { + return NULL; + } Py_BEGIN_ALLOW_THREADS res = lchown(path->narrow, uid, gid); Py_END_ALLOW_THREADS @@ -3563,6 +3601,12 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, } #endif + if (PySys_Audit("os.link", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = CreateHardLinkW(dst->wide, src->wide, NULL); @@ -4034,6 +4078,11 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) { int result; + if (PySys_Audit("os.mkdir", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = CreateDirectoryW(path->wide, NULL); @@ -4179,6 +4228,12 @@ internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is } #endif + if (PySys_Audit("os.rename", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS result = MoveFileExW(src->wide, dst->wide, flags); @@ -4279,6 +4334,11 @@ os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) { int result; + if (PySys_Audit("os.rmdir", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS /* Windows, success=1, UNIX, success=0 */ @@ -4437,6 +4497,11 @@ os_unlink_impl(PyObject *module, path_t *path, int dir_fd) { int result; + if (PySys_Audit("os.remove", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS @@ -4855,6 +4920,11 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, } #endif + if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, @@ -5156,8 +5226,7 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) return NULL; } - if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, - argv, Py_None) < 0) { + if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) { free_string_array(argvlist, argc); return NULL; } @@ -5233,8 +5302,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) if (envlist == NULL) goto fail_0; - if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None, - argv, env) < 0) { + if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) { goto fail_1; } @@ -5587,8 +5655,7 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a } attrp = &attr; - if (PySys_Audit("os.posix_spawn", "OOO", - path->object ? path->object : Py_None, argv, env) < 0) { + if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) { goto exit; } @@ -5832,8 +5899,7 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) mode = _P_OVERLAY; #endif - if (PySys_Audit("os.spawn", "iOOO", mode, - path->object ? path->object : Py_None, argv, + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, Py_None) < 0) { free_string_array(argvlist, argc); return NULL; @@ -5948,8 +6014,7 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, mode = _P_OVERLAY; #endif - if (PySys_Audit("os.spawn", "iOOO", mode, - path->object ? path->object : Py_None, argv, env) < 0) { + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) { goto fail_2; } @@ -6104,6 +6169,9 @@ os_fork_impl(PyObject *module) PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } + if (PySys_Audit("os.fork", NULL) < 0) { + return NULL; + } PyOS_BeforeFork(); pid = fork(); if (pid == 0) { @@ -6709,6 +6777,9 @@ os_forkpty_impl(PyObject *module) PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } + if (PySys_Audit("os.forkpty", NULL) < 0) { + return NULL; + } PyOS_BeforeFork(); pid = forkpty(&master_fd, NULL, NULL, NULL); if (pid == 0) { @@ -7230,14 +7301,15 @@ Kill a process with a signal. static PyObject * os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) /*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/ -#ifndef MS_WINDOWS { + if (PySys_Audit("os.kill", "in", pid, signal) < 0) { + return NULL; + } +#ifndef MS_WINDOWS if (kill(pid, (int)signal) == -1) return posix_error(); Py_RETURN_NONE; -} #else /* !MS_WINDOWS */ -{ PyObject *result; DWORD sig = (DWORD)signal; DWORD err; @@ -7272,8 +7344,8 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) CloseHandle(handle); return result; -} #endif /* !MS_WINDOWS */ +} #endif /* HAVE_KILL */ @@ -7292,6 +7364,9 @@ static PyObject * os_killpg_impl(PyObject *module, pid_t pgid, int signal) /*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/ { + if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) { + return NULL; + } /* XXX some man pages make the `pgid` parameter an int, others a pid_t. Since getpgrp() returns a pid_t, we assume killpg should take the same type. Moreover, pid_t is always at least as wide as @@ -8035,6 +8110,11 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, int result; #endif + if (PySys_Audit("os.symlink", "OOi", src->object, dst->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + #ifdef MS_WINDOWS if (windows_has_symlink_unprivileged_flag) { @@ -8638,6 +8718,10 @@ os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) { int res; + if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS res = lockf(fd, command, length); Py_END_ALLOW_THREADS @@ -10070,6 +10154,9 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); return NULL; } + if (PySys_Audit("os.putenv", "OO", name, value) < 0) { + return NULL; + } bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); if (bytes == NULL) { return NULL; @@ -10105,6 +10192,10 @@ os_unsetenv_impl(PyObject *module, PyObject *name) int err; #endif + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; + } + #ifdef HAVE_BROKEN_UNSETENV unsetenv(PyBytes_AS_STRING(name)); #else @@ -11637,9 +11728,7 @@ os_startfile_impl(PyObject *module, path_t *filepath, "startfile not available on this platform"); } - if (PySys_Audit("os.startfile", "Ou", - filepath->object ? filepath->object : Py_None, - operation) < 0) { + if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) { return NULL; } @@ -11817,6 +11906,10 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) { + return NULL; + } + for (i = 0; ; i++) { void *ptr; ssize_t result; @@ -11888,6 +11981,11 @@ os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object, + value->buf, value->len, flags) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS; if (path->fd > -1) result = fsetxattr(path->fd, attribute->narrow, @@ -11936,6 +12034,10 @@ os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) return NULL; + if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS; if (path->fd > -1) result = fremovexattr(path->fd, attribute->narrow); @@ -11981,6 +12083,11 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) goto exit; + if (PySys_Audit("os.listxattr", "(O)", + path->object ? path->object : Py_None) < 0) { + return NULL; + } + name = path->narrow ? path->narrow : "."; for (i = 0; ; i++) { @@ -13494,6 +13601,10 @@ os__add_dll_directory_impl(PyObject *module, path_t *path) DLL_DIRECTORY_COOKIE cookie = 0; DWORD err = 0; + if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) { + return NULL; + } + /* For Windows 7, we have to load this. As this will be a fairly infrequent operation, just do it each time. Kernel32 is always loaded. */ diff --git a/Modules/resource.c b/Modules/resource.c index 87c72e7409895..afde03c6c7e55 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -224,6 +224,11 @@ resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits) return NULL; } + if (PySys_Audit("resource.setrlimit", "iO", resource, + limits ? limits : Py_None) < 0) { + return NULL; + } + if (py2rlimit(limits, &rl) < 0) { return NULL; } @@ -269,6 +274,11 @@ resource_prlimit_impl(PyObject *module, pid_t pid, int resource, return NULL; } + if (PySys_Audit("resource.prlimit", "iiO", pid, resource, + limits ? limits : Py_None) < 0) { + return NULL; + } + if (group_right_1) { if (py2rlimit(limits, &new_limit) < 0) { return NULL; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9aca70599689b..0c9a2671fe19b 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1233,6 +1233,10 @@ signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, { int err; + if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) { + return NULL; + } + err = pthread_kill((pthread_t)thread_id, signalnum); if (err != 0) { errno = err; diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index b2ea73baa1be4..66ea2703fc84a 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -144,6 +144,10 @@ syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) return NULL; } + if (PySys_Audit("syslog.openlog", "sll", ident, logopt, facility) < 0) { + return NULL; + } + openlog(ident, logopt, facility); S_log_open = 1; @@ -170,6 +174,10 @@ syslog_syslog(PyObject * self, PyObject * args) if (message == NULL) return NULL; + if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) { + return NULL; + } + /* if log is not opened, open it now */ if (!S_log_open) { PyObject *openargs; @@ -194,6 +202,9 @@ syslog_syslog(PyObject * self, PyObject * args) static PyObject * syslog_closelog(PyObject *self, PyObject *unused) { + if (PySys_Audit("syslog.closelog", NULL) < 0) { + return NULL; + } if (S_log_open) { closelog(); Py_CLEAR(S_ident_o); @@ -209,6 +220,9 @@ syslog_setlogmask(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) return NULL; + if (PySys_Audit("syslog.setlogmask", "(O)", args ? args : Py_None) < 0) { + return NULL; + } omaskpri = setlogmask(maskpri); return PyLong_FromLong(omaskpri); } diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index c4113e54c2b8f..5c06ec2621ea6 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -116,6 +116,10 @@ msvcrt_locking_impl(PyObject *module, int fd, int mode, long nbytes) { int err; + if (PySys_Audit("msvcrt.locking", "iil", fd, mode, nbytes) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH err = _locking(fd, mode, nbytes); @@ -175,6 +179,10 @@ msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags) { int fd; + if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) { + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH fd = _open_osfhandle((intptr_t)handle, flags); _Py_END_SUPPRESS_IPH @@ -201,6 +209,10 @@ msvcrt_get_osfhandle_impl(PyObject *module, int fd) { intptr_t handle = -1; + if (PySys_Audit("msvcrt.get_osfhandle", "(i)", fd) < 0) { + return NULL; + } + _Py_BEGIN_SUPPRESS_IPH handle = _get_osfhandle(fd); _Py_END_SUPPRESS_IPH From webhook-mailer at python.org Thu Feb 13 03:43:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 13 Feb 2020 08:43:28 -0000 Subject: [Python-checkins] [3.8] bpo-39606: allow closing async generators that are already closed (GH-18475) (GH-18501) Message-ID: https://github.com/python/cpython/commit/8dbdf5f275c6462bb522bcf3a29054239d72989d commit: 8dbdf5f275c6462bb522bcf3a29054239d72989d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-13T00:43:23-08:00 summary: [3.8] bpo-39606: allow closing async generators that are already closed (GH-18475) (GH-18501) The fix for [bpo-39386](https://bugs.python.org/issue39386) attempted to make it so you couldn't reuse a agen.aclose() coroutine object. It accidentally also prevented you from calling aclose() at all on an async generator that was already closed or exhausted. This commit fixes it so we're only blocking the actually illegal cases, while allowing the legal cases. The new tests failed before this patch. Also confirmed that this fixes the test failures we were seeing in Trio with Python dev builds: https://github.com/python-trio/trio/pull/1396 https://bugs.python.org/issue39606 (cherry picked from commit 925dc7fb1d0db85dc137afa4cd14211bf0d67414) Co-authored-by: Nathaniel J. Smith https://bugs.python.org/issue39606 Automerge-Triggered-By: @njsmith files: A Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.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 24b20bec2b2d1..fb6321d2264f3 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1128,7 +1128,7 @@ def exception_handler(loop, context): self.assertEqual([], messages) - def test_async_gen_await_anext_twice(self): + def test_async_gen_await_same_anext_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1147,7 +1147,7 @@ def test_async_gen_await_anext_twice(self): self.loop.run_until_complete(run()) - def test_async_gen_await_aclose_twice(self): + def test_async_gen_await_same_aclose_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1164,6 +1164,32 @@ def test_async_gen_await_aclose_twice(self): self.loop.run_until_complete(run()) + def test_async_gen_aclose_twice_with_different_coros(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + await it.aclose() + await it.aclose() + + self.loop.run_until_complete(run()) + + def test_async_gen_aclose_after_exhaustion(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + async for _ in it: + pass + await it.aclose() + + self.loop.run_until_complete(run()) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst new file mode 100644 index 0000000000000..b7cbe4e91f59c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst @@ -0,0 +1,2 @@ +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. diff --git a/Objects/genobject.c b/Objects/genobject.c index 72aa872c6b59f..2c06bdcc72642 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1812,16 +1812,22 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) PyFrameObject *f = gen->gi_frame; PyObject *retval; - if (f == NULL || f->f_stacktop == NULL || - o->agt_state == AWAITABLE_STATE_CLOSED) { + if (o->agt_state == AWAITABLE_STATE_CLOSED) { PyErr_SetString( PyExc_RuntimeError, "cannot reuse already awaited aclose()/athrow()"); return NULL; } + if (f == NULL || f->f_stacktop == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + if (o->agt_state == AWAITABLE_STATE_INIT) { if (o->agt_gen->ag_running_async) { + o->agt_state = AWAITABLE_STATE_CLOSED; if (o->agt_args == NULL) { PyErr_SetString( PyExc_RuntimeError, @@ -1893,7 +1899,6 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) /* aclose() mode */ if (retval) { if (_PyAsyncGenWrappedValue_CheckExact(retval)) { - o->agt_gen->ag_running_async = 0; Py_DECREF(retval); goto yield_close; } @@ -1908,16 +1913,17 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) yield_close: o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetString( PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; check_error: o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { - o->agt_state = AWAITABLE_STATE_CLOSED; if (o->agt_args == NULL) { /* when aclose() is called we don't want to propagate StopAsyncIteration or GeneratorExit; just raise @@ -1951,6 +1957,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) /* aclose() mode */ if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; From webhook-mailer at python.org Thu Feb 13 04:33:42 2020 From: webhook-mailer at python.org (Nathaniel J. Smith) Date: Thu, 13 Feb 2020 09:33:42 -0000 Subject: [Python-checkins] bpo-39606: allow closing async generators that are already closed (GH-18475) (GH-18502) Message-ID: https://github.com/python/cpython/commit/f464edf3239f7867fe31c9cd238a68fb3b90feaa commit: f464edf3239f7867fe31c9cd238a68fb3b90feaa branch: 3.7 author: Nathaniel J. Smith committer: GitHub date: 2020-02-13T01:33:35-08:00 summary: bpo-39606: allow closing async generators that are already closed (GH-18475) (GH-18502) The fix for [bpo-39386](https://bugs.python.org/issue39386) attempted to make it so you couldn't reuse a agen.aclose() coroutine object. It accidentally also prevented you from calling aclose() at all on an async generator that was already closed or exhausted. This commit fixes it so we're only blocking the actually illegal cases, while allowing the legal cases. The new tests failed before this patch. Also confirmed that this fixes the test failures we were seeing in Trio with Python dev builds: https://github.com/python-trio/trio/pull/1396 https://bugs.python.org/issue39606 (cherry picked from commit 925dc7fb1d0db85dc137afa4cd14211bf0d67414) files: A Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.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 426d5d1161423..5a292fb5d64e1 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1117,7 +1117,7 @@ def exception_handler(loop, context): self.assertEqual([], messages) - def test_async_gen_await_anext_twice(self): + def test_async_gen_await_same_anext_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1136,7 +1136,7 @@ def test_async_gen_await_anext_twice(self): self.loop.run_until_complete(run()) - def test_async_gen_await_aclose_twice(self): + def test_async_gen_await_same_aclose_coro_twice(self): async def async_iterate(): yield 1 yield 2 @@ -1153,6 +1153,32 @@ def test_async_gen_await_aclose_twice(self): self.loop.run_until_complete(run()) + def test_async_gen_aclose_twice_with_different_coros(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + await it.aclose() + await it.aclose() + + self.loop.run_until_complete(run()) + + def test_async_gen_aclose_after_exhaustion(self): + # Regression test for https://bugs.python.org/issue39606 + async def async_iterate(): + yield 1 + yield 2 + + async def run(): + it = async_iterate() + async for _ in it: + pass + await it.aclose() + + self.loop.run_until_complete(run()) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst new file mode 100644 index 0000000000000..b7cbe4e91f59c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst @@ -0,0 +1,2 @@ +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. diff --git a/Objects/genobject.c b/Objects/genobject.c index a42169f82e4d7..dd7d44bd427df 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1804,14 +1804,19 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) PyFrameObject *f = gen->gi_frame; PyObject *retval; - if (f == NULL || f->f_stacktop == NULL || - o->agt_state == AWAITABLE_STATE_CLOSED) { + if (o->agt_state == AWAITABLE_STATE_CLOSED) { PyErr_SetString( PyExc_RuntimeError, "cannot reuse already awaited aclose()/athrow()"); return NULL; } + if (f == NULL || f->f_stacktop == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + if (o->agt_state == AWAITABLE_STATE_INIT) { if (o->agt_gen->ag_closed) { PyErr_SetNone(PyExc_StopIteration); @@ -1882,6 +1887,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) } yield_close: + o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetString( PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; @@ -1924,6 +1930,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) } else { /* aclose() mode */ if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { + o->agt_state = AWAITABLE_STATE_CLOSED; Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; From webhook-mailer at python.org Thu Feb 13 12:35:09 2020 From: webhook-mailer at python.org (Brandt Bucher) Date: Thu, 13 Feb 2020 17:35:09 -0000 Subject: [Python-checkins] bpo-39573: Fix bad copy-paste in Py_SET_SIZE (GH-18496) Message-ID: https://github.com/python/cpython/commit/968dcd9e7a4d3aa9aaa1dfca693adf60d6b71ce7 commit: 968dcd9e7a4d3aa9aaa1dfca693adf60d6b71ce7 branch: master author: Brandt Bucher committer: GitHub date: 2020-02-13T18:34:45+01:00 summary: bpo-39573: Fix bad copy-paste in Py_SET_SIZE (GH-18496) files: M Doc/c-api/structures.rst M Include/object.h diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 75e2383beb216..083c3740531e4 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -103,7 +103,7 @@ the definition of all other Python objects. .. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size) - Set the object *o* size of *size*. + Set the object *o* size to *size*. .. versionadded:: 3.9 diff --git a/Include/object.h b/Include/object.h index 68200f7666f17..11539ee080503 100644 --- a/Include/object.h +++ b/Include/object.h @@ -133,10 +133,10 @@ static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) -static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t refcnt) { - ob->ob_size = refcnt; +static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { + ob->ob_size = size; } -#define Py_SET_SIZE(ob, refcnt) _Py_SET_SIZE(_PyVarObject_CAST(ob), refcnt) +#define Py_SET_SIZE(ob, size) _Py_SET_SIZE(_PyVarObject_CAST(ob), size) /* From webhook-mailer at python.org Thu Feb 13 12:37:22 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Thu, 13 Feb 2020 17:37:22 -0000 Subject: [Python-checkins] bpo-39573: Add Py_IS_TYPE() function (GH-18488) Message-ID: https://github.com/python/cpython/commit/d905df766c367c350f20c46ccd99d4da19ed57d8 commit: d905df766c367c350f20c46ccd99d4da19ed57d8 branch: master author: Dong-hee Na committer: GitHub date: 2020-02-13T18:37:17+01:00 summary: bpo-39573: Add Py_IS_TYPE() function (GH-18488) Co-Author: Neil Schemenauer files: A Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m.rst M Doc/c-api/structures.rst M Include/boolobject.h M Include/bytearrayobject.h M Include/bytesobject.h M Include/cellobject.h M Include/code.h M Include/complexobject.h M Include/context.h M Include/datetime.h M Include/dictobject.h M Include/floatobject.h M Include/funcobject.h M Include/genobject.h M Include/internal/pycore_hamt.h M Include/iterobject.h M Include/listobject.h M Include/memoryobject.h M Include/methodobject.h M Include/moduleobject.h M Include/object.h M Include/odictobject.h M Include/pycapsule.h M Include/rangeobject.h M Include/setobject.h M Include/sliceobject.h M Include/symtable.h M Include/traceback.h M Include/tupleobject.h M Include/unicodeobject.h M Include/weakrefobject.h M Objects/genobject.c diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 083c3740531e4..fc3467bee4d3c 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -70,6 +70,14 @@ the definition of all other Python objects. (((PyObject*)(o))->ob_type) +.. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type) + + Return non-zero if the object *o* type is *type*. Return zero otherwise. + Equivalent to: ``Py_TYPE(o) == type``. + + .. versionadded:: 3.9 + + .. c:function:: void Py_SET_TYPE(PyObject *o, PyTypeObject *type) Set the object *o* type to *type*. diff --git a/Include/boolobject.h b/Include/boolobject.h index 7cc2f1fe23937..bb8044a2b02cf 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,7 +9,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyBool_Type; -#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) +#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type) /* Py_False and Py_True are the only two bools in existence. Don't forget to apply Py_INCREF() when returning either!!! */ diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h index 341ab38a15d5a..9e95433f0f26f 100644 --- a/Include/bytearrayobject.h +++ b/Include/bytearrayobject.h @@ -24,7 +24,7 @@ PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; /* Type check macros */ #define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) +#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type) /* Direct API functions */ PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 27c31ee342c88..5062d8d123ad3 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -32,7 +32,7 @@ PyAPI_DATA(PyTypeObject) PyBytesIter_Type; #define PyBytes_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) -#define PyBytes_CheckExact(op) (Py_TYPE(op) == &PyBytes_Type) +#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type) PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); diff --git a/Include/cellobject.h b/Include/cellobject.h index 2f9b5b75d998a..f12aa90a42a8f 100644 --- a/Include/cellobject.h +++ b/Include/cellobject.h @@ -13,7 +13,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCell_Type; -#define PyCell_Check(op) (Py_TYPE(op) == &PyCell_Type) +#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type) PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); diff --git a/Include/code.h b/Include/code.h index 3afddd20c80d7..107eba4b9c431 100644 --- a/Include/code.h +++ b/Include/code.h @@ -115,7 +115,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCode_Type; -#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type) +#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type) #define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) /* Public interface */ diff --git a/Include/complexobject.h b/Include/complexobject.h index cb8c52c580085..9221f9c51d65b 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -39,7 +39,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyComplex_Type; #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) -#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) +#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type) #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); diff --git a/Include/context.h b/Include/context.h index 9581285247b39..619746d501efd 100644 --- a/Include/context.h +++ b/Include/context.h @@ -17,9 +17,9 @@ PyAPI_DATA(PyTypeObject) PyContextToken_Type; typedef struct _pycontexttokenobject PyContextToken; -#define PyContext_CheckExact(o) (Py_TYPE(o) == &PyContext_Type) -#define PyContextVar_CheckExact(o) (Py_TYPE(o) == &PyContextVar_Type) -#define PyContextToken_CheckExact(o) (Py_TYPE(o) == &PyContextToken_Type) +#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type) +#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type) +#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type) PyAPI_FUNC(PyObject *) PyContext_New(void); diff --git a/Include/datetime.h b/Include/datetime.h index 00507cb85cc04..5d9f2558f924d 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -196,19 +196,19 @@ static PyDateTime_CAPI *PyDateTimeAPI = NULL; /* Macros for type checking when not building the Python core. */ #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) -#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType) #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) -#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType) #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) -#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType) #define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) -#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType) #define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) -#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType) /* Macros for accessing constructors in a simplified fashion. */ diff --git a/Include/dictobject.h b/Include/dictobject.h index b37573ad48c00..c88b0aa0a5d0f 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -16,7 +16,7 @@ PyAPI_DATA(PyTypeObject) PyDict_Type; #define PyDict_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) -#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) +#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type) PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); diff --git a/Include/floatobject.h b/Include/floatobject.h index 0fb9fc4e0fae7..917dfcc26445c 100644 --- a/Include/floatobject.h +++ b/Include/floatobject.h @@ -21,7 +21,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFloat_Type; #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) -#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) +#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type) #ifdef Py_NAN #define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) diff --git a/Include/funcobject.h b/Include/funcobject.h index c6dd67d6124d3..c5cc9d261a314 100644 --- a/Include/funcobject.h +++ b/Include/funcobject.h @@ -43,7 +43,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFunction_Type; -#define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type) +#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type) PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); diff --git a/Include/genobject.h b/Include/genobject.h index 5ee9a2831d12b..b87a6485631c0 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -38,7 +38,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyGen_Type; #define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) -#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) +#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *, @@ -58,7 +58,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCoro_Type; PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; -#define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type) +#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type) PyObject *_PyCoro_GetAwaitableIter(PyObject *o); PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *, PyObject *name, PyObject *qualname); @@ -89,7 +89,7 @@ PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; PyAPI_FUNC(PyObject *) PyAsyncGen_New(struct _frame *, PyObject *name, PyObject *qualname); -#define PyAsyncGen_CheckExact(op) (Py_TYPE(op) == &PyAsyncGen_Type) +#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type) PyObject *_PyAsyncGenValueWrapperNew(PyObject *); diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h index e65aef5e21a95..aaf655909551a 100644 --- a/Include/internal/pycore_hamt.h +++ b/Include/internal/pycore_hamt.h @@ -8,7 +8,7 @@ #define _Py_HAMT_MAX_TREE_DEPTH 7 -#define PyHamt_Check(o) (Py_TYPE(o) == &_PyHamt_Type) +#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type) /* Abstract tree node. */ diff --git a/Include/iterobject.h b/Include/iterobject.h index eec2ee271eb67..51139bf187408 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -8,12 +8,12 @@ extern "C" { PyAPI_DATA(PyTypeObject) PySeqIter_Type; PyAPI_DATA(PyTypeObject) PyCallIter_Type; -#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type) +#define PySeqIter_Check(op) Py_IS_TYPE(op, &PySeqIter_Type) PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); -#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type) +#define PyCallIter_Check(op) Py_IS_TYPE(op, &PyCallIter_Type) PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); diff --git a/Include/listobject.h b/Include/listobject.h index 34dfcf92ec93a..2a8a25525d1d7 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -23,7 +23,7 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; #define PyList_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) -#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) +#define PyList_CheckExact(op) Py_IS_TYPE(op, &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); diff --git a/Include/memoryobject.h b/Include/memoryobject.h index 990a716f22039..306028f4b225d 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -11,7 +11,7 @@ PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; #endif PyAPI_DATA(PyTypeObject) PyMemoryView_Type; -#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) +#define PyMemoryView_Check(op) Py_IS_TYPE(op, &PyMemoryView_Type) #ifndef Py_LIMITED_API /* Get a pointer to the memoryview's private copy of the exporter's buffer. */ diff --git a/Include/methodobject.h b/Include/methodobject.h index d9f8d4f80c2cd..adb2d9e884fbb 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -13,7 +13,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyCFunction_Type; -#define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) +#define PyCFunction_Check(op) Py_IS_TYPE(op, &PyCFunction_Type) typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); diff --git a/Include/moduleobject.h b/Include/moduleobject.h index e246fd2faf918..cf9ad40c0a17a 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -10,7 +10,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyModule_Type; #define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) -#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) +#define PyModule_CheckExact(op) Py_IS_TYPE(op, &PyModule_Type) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_NewObject( diff --git a/Include/object.h b/Include/object.h index 11539ee080503..3d0da52c2b6b1 100644 --- a/Include/object.h +++ b/Include/object.h @@ -123,6 +123,11 @@ typedef struct { #define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type) #define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size) +static inline int _Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { + return ob->ob_type == type; +} +#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type) + static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { ob->ob_refcnt = refcnt; } @@ -211,7 +216,7 @@ PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ - (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + (Py_IS_TYPE(ob, tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ @@ -623,7 +628,7 @@ static inline int _PyType_Check(PyObject *op) { #define PyType_Check(op) _PyType_Check(_PyObject_CAST(op)) static inline int _PyType_CheckExact(PyObject *op) { - return (Py_TYPE(op) == &PyType_Type); + return Py_IS_TYPE(op, &PyType_Type); } #define PyType_CheckExact(op) _PyType_CheckExact(_PyObject_CAST(op)) diff --git a/Include/odictobject.h b/Include/odictobject.h index 35aff8a29a6e3..e070413017d80 100644 --- a/Include/odictobject.h +++ b/Include/odictobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyODictItems_Type; PyAPI_DATA(PyTypeObject) PyODictValues_Type; #define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) -#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) +#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type) #define PyODict_SIZE(op) PyDict_GET_SIZE((op)) PyAPI_FUNC(PyObject *) PyODict_New(void); diff --git a/Include/pycapsule.h b/Include/pycapsule.h index d9ecda7a4b6e4..fb5d503fea73f 100644 --- a/Include/pycapsule.h +++ b/Include/pycapsule.h @@ -22,7 +22,7 @@ PyAPI_DATA(PyTypeObject) PyCapsule_Type; typedef void (*PyCapsule_Destructor)(PyObject *); -#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type) +#define PyCapsule_CheckExact(op) Py_IS_TYPE(op, &PyCapsule_Type) PyAPI_FUNC(PyObject *) PyCapsule_New( diff --git a/Include/rangeobject.h b/Include/rangeobject.h index 7e4dc28894b04..d6af8473f9e8d 100644 --- a/Include/rangeobject.h +++ b/Include/rangeobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyRange_Type; PyAPI_DATA(PyTypeObject) PyRangeIter_Type; PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; -#define PyRange_Check(op) (Py_TYPE(op) == &PyRange_Type) +#define PyRange_Check(op) Py_IS_TYPE(op, &PyRange_Type) #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index fc0ea83925f92..05a097eba7f7d 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -88,18 +88,18 @@ PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE(ob, &PyFrozenSet_Type) #define PyAnySet_CheckExact(ob) \ - (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) + (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type)) #define PyAnySet_Check(ob) \ - (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ + (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #define PySet_Check(ob) \ - (Py_TYPE(ob) == &PySet_Type || \ + (Py_IS_TYPE(ob, &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) #define PyFrozenSet_Check(ob) \ - (Py_TYPE(ob) == &PyFrozenSet_Type || \ + (Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #ifdef __cplusplus diff --git a/Include/sliceobject.h b/Include/sliceobject.h index aae6f3cc7945e..2c889508b4b49 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -28,7 +28,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PySlice_Type; PyAPI_DATA(PyTypeObject) PyEllipsis_Type; -#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) +#define PySlice_Check(op) Py_IS_TYPE(op, &PySlice_Type) PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); diff --git a/Include/symtable.h b/Include/symtable.h index 5dcfa7e2c2bb6..abd19a7923e1b 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -69,7 +69,7 @@ typedef struct _symtable_entry { PyAPI_DATA(PyTypeObject) PySTEntry_Type; -#define PySTEntry_Check(op) (Py_TYPE(op) == &PySTEntry_Type) +#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); diff --git a/Include/traceback.h b/Include/traceback.h index b451927fafa3a..0efbae8a76a2f 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -13,7 +13,7 @@ PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; -#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) +#define PyTraceBack_Check(v) Py_IS_TYPE(v, &PyTraceBack_Type) #ifndef Py_LIMITED_API diff --git a/Include/tupleobject.h b/Include/tupleobject.h index 590902de9d021..d3504b0501f9e 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -25,7 +25,7 @@ PyAPI_DATA(PyTypeObject) PyTupleIter_Type; #define PyTuple_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) -#define PyTuple_CheckExact(op) (Py_TYPE(op) == &PyTuple_Type) +#define PyTuple_CheckExact(op) Py_IS_TYPE(op, &PyTuple_Type) PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 4dea494218122..500ce242e9f0e 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -113,7 +113,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) -#define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) +#define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) /* --- Constants ---------------------------------------------------------- */ diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h index 17051568f3a6e..ac4b4821c8a14 100644 --- a/Include/weakrefobject.h +++ b/Include/weakrefobject.h @@ -46,10 +46,10 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; #define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) #define PyWeakref_CheckRefExact(op) \ - (Py_TYPE(op) == &_PyWeakref_RefType) + Py_IS_TYPE(op, &_PyWeakref_RefType) #define PyWeakref_CheckProxy(op) \ - ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \ - (Py_TYPE(op) == &_PyWeakref_CallableProxyType)) + (Py_IS_TYPE(op, &_PyWeakref_ProxyType) || \ + Py_IS_TYPE(op, &_PyWeakref_CallableProxyType)) #define PyWeakref_Check(op) \ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m.rst new file mode 100644 index 0000000000000..56e7e1ba3242c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m.rst @@ -0,0 +1,2 @@ +Add :c:func:`Py_IS_TYPE` static inline function to check +whether the object *o* type is *type*. diff --git a/Objects/genobject.c b/Objects/genobject.c index 0efd57de7a5a3..0837698fd784c 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -255,7 +255,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) if (PyCoro_CheckExact(gen)) { msg = "coroutine raised StopIteration"; } - else if PyAsyncGen_CheckExact(gen) { + else if (PyAsyncGen_CheckExact(gen)) { msg = "async generator raised StopIteration"; } _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); From webhook-mailer at python.org Thu Feb 13 13:32:14 2020 From: webhook-mailer at python.org (mpheath) Date: Thu, 13 Feb 2020 18:32:14 -0000 Subject: [Python-checkins] bpo-39524: Fixed doc-string in ast._pad_whitespace (GH-18340) Message-ID: https://github.com/python/cpython/commit/fbeba8f2481411d608a616366394e07cdc52e0bb commit: fbeba8f2481411d608a616366394e07cdc52e0bb branch: master author: mpheath <58158242+mpheath at users.noreply.github.com> committer: GitHub date: 2020-02-13T20:32:09+02:00 summary: bpo-39524: Fixed doc-string in ast._pad_whitespace (GH-18340) files: M Lib/ast.py diff --git a/Lib/ast.py b/Lib/ast.py index 495c0d618f12c..511f0956a00b0 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -302,7 +302,7 @@ def _splitlines_no_ff(source): def _pad_whitespace(source): - """Replace all chars except '\f\t' in a line with spaces.""" + r"""Replace all chars except '\f\t' in a line with spaces.""" result = '' for c in source: if c in '\f\t': From webhook-mailer at python.org Thu Feb 13 14:53:34 2020 From: webhook-mailer at python.org (Vlad Emelianov) Date: Thu, 13 Feb 2020 19:53:34 -0000 Subject: [Python-checkins] bpo-39627: Fix TypedDict totality check for inherited keys (#18503) Message-ID: https://github.com/python/cpython/commit/10e87e5ef4c1b4fb8415d9ddc362e2591f2f0b6c commit: 10e87e5ef4c1b4fb8415d9ddc362e2591f2f0b6c branch: master author: Vlad Emelianov committer: GitHub date: 2020-02-13T11:53:29-08:00 summary: bpo-39627: Fix TypedDict totality check for inherited keys (#18503) (Adapted from https://github.com/python/typing/pull/700) files: A Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.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 bc6a3db4e0064..6b0a905048cea 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3809,6 +3809,38 @@ class Point2Dor3D(Point2D, total=False): assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y']) assert Point2Dor3D.__optional_keys__ == frozenset(['z']) + def test_keys_inheritance(self): + class BaseAnimal(TypedDict): + name: str + + class Animal(BaseAnimal, total=False): + voice: str + tail: bool + + class Cat(Animal): + fur_color: str + + assert BaseAnimal.__required_keys__ == frozenset(['name']) + assert BaseAnimal.__optional_keys__ == frozenset([]) + assert BaseAnimal.__annotations__ == {'name': str} + + assert Animal.__required_keys__ == frozenset(['name']) + assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) + assert Animal.__annotations__ == { + 'name': str, + 'tail': bool, + 'voice': str, + } + + assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) + assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) + assert Cat.__annotations__ == { + 'fur_color': str, + 'name': str, + 'tail': bool, + 'voice': str, + } + class IOTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 8886b08c2ec6f..6da145fcdb83a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1828,23 +1828,30 @@ def __new__(cls, name, bases, ns, total=True): ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns) - anns = ns.get('__annotations__', {}) + annotations = {} + own_annotations = ns.get('__annotations__', {}) + own_annotation_keys = set(own_annotations.keys()) 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) + own_annotations = { + n: _type_check(tp, msg) for n, tp in own_annotations.items() + } + required_keys = set() + optional_keys = set() for base in bases: - base_anns = base.__dict__.get('__annotations__', {}) - anns.update(base_anns) - if getattr(base, '__total__', True): - required.update(base_anns) - else: - optional.update(base_anns) + annotations.update(base.__dict__.get('__annotations__', {})) + required_keys.update(base.__dict__.get('__required_keys__', ())) + optional_keys.update(base.__dict__.get('__optional_keys__', ())) + + annotations.update(own_annotations) + if total: + required_keys.update(own_annotation_keys) + else: + optional_keys.update(own_annotation_keys) - tp_dict.__annotations__ = anns - tp_dict.__required_keys__ = frozenset(required) - tp_dict.__optional_keys__ = frozenset(optional) + tp_dict.__annotations__ = annotations + tp_dict.__required_keys__ = frozenset(required_keys) + tp_dict.__optional_keys__ = frozenset(optional_keys) if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total return tp_dict diff --git a/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst b/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst new file mode 100644 index 0000000000000..4806aa67d9535 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst @@ -0,0 +1 @@ +Fixed TypedDict totality check for inherited keys. \ No newline at end of file From webhook-mailer at python.org Thu Feb 13 18:54:07 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 13 Feb 2020 23:54:07 -0000 Subject: [Python-checkins] bpo-39545: Document restrictions on "await" and "async for" in f-strings. (GH-18459) Message-ID: https://github.com/python/cpython/commit/cebe9ee988837b292f2c571e194ed11e7cd4abbb commit: cebe9ee988837b292f2c571e194ed11e7cd4abbb branch: 3.6 author: Serhiy Storchaka committer: GitHub date: 2020-02-13T18:53:59-05:00 summary: bpo-39545: Document restrictions on "await" and "async for" in f-strings. (GH-18459) files: M Doc/reference/compound_stmts.rst M Doc/reference/lexical_analysis.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index b4e95b90dbc70..8d050a69a931d 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -730,7 +730,7 @@ Functions defined with ``async def`` syntax are always coroutine functions, even if they do not contain ``await`` or ``async`` keywords. It is a :exc:`SyntaxError` to use ``yield from`` expressions in -``async def`` coroutines. Using ``await`` in :keyword:`f-strings` will also produce a :exc:`SyntaxError`. +``async def`` coroutines. An example of a coroutine function:: diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index bee02443e621f..3a03b94716231 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -683,6 +683,15 @@ can contain line breaks (e.g. in triple-quoted strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. +.. index:: + keyword: await + single: async for; in comprehensions + +An :keyword:`await` expression and comprehensions containing an +:keyword:`async for` clause are illegal in the expression in formatted +string literals. (The reason is a problem with the implementation --- +this restriction is lifted in Python 3.7). + If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. From webhook-mailer at python.org Thu Feb 13 18:57:40 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 13 Feb 2020 23:57:40 -0000 Subject: [Python-checkins] bpo-39545: Document changes in the support of await in f-strings. (GH-18456) Message-ID: https://github.com/python/cpython/commit/f632736023502816f2e6bd714d1b48c81aa2ccc1 commit: f632736023502816f2e6bd714d1b48c81aa2ccc1 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-13T15:57:35-08:00 summary: bpo-39545: Document changes in the support of await in f-strings. (GH-18456) https://bugs.python.org/issue39545 files: M Doc/reference/lexical_analysis.rst M Doc/whatsnew/3.7.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index c0e13b53698e6..3d4b03e6bd459 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -685,6 +685,11 @@ strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. +.. versionchanged:: 3.7 + Prior to Python 3.7, an :keyword:`await` expression and comprehensions + containing an :keyword:`async for` clause were illegal in the expressions + in formatted string literals due to a problem with the implementation. + If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 04cfa57e1446f..59b96621bdd4b 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -493,6 +493,11 @@ description. Other Language Changes ====================== +* An :keyword:`await` expression and comprehensions containing an + :keyword:`async for` clause were illegal in the expressions in + :ref:`formatted string literals ` due to a problem with the + implementation. In Python 3.7 this restriction was lifted. + * More than 255 arguments can now be passed to a function, and a function can now have more than 255 parameters. (Contributed by Serhiy Storchaka in :issue:`12844` and :issue:`18896`.) From webhook-mailer at python.org Thu Feb 13 19:03:20 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 14 Feb 2020 00:03:20 -0000 Subject: [Python-checkins] bpo-39545: Document changes in the support of await in f-strings. (GH-18456) Message-ID: https://github.com/python/cpython/commit/46cf4fc8a5646ca35f7d1ac06d2ef33eb9efca1d commit: 46cf4fc8a5646ca35f7d1ac06d2ef33eb9efca1d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-13T16:03:12-08:00 summary: bpo-39545: Document changes in the support of await in f-strings. (GH-18456) https://bugs.python.org/issue39545 (cherry picked from commit f632736023502816f2e6bd714d1b48c81aa2ccc1) Co-authored-by: Serhiy Storchaka files: M Doc/reference/lexical_analysis.rst M Doc/whatsnew/3.7.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 7b90f3b31c37b..9f51f41edd501 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -683,6 +683,11 @@ can contain line breaks (e.g. in triple-quoted strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. +.. versionchanged:: 3.7 + Prior to Python 3.7, an :keyword:`await` expression and comprehensions + containing an :keyword:`async for` clause were illegal in the expressions + in formatted string literals due to a problem with the implementation. + If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index c7e3230db29e6..9644a4f31a957 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -493,6 +493,11 @@ of this mode. Other Language Changes ====================== +* An :keyword:`await` expression and comprehensions containing an + :keyword:`async for` clause were illegal in the expressions in + :ref:`formatted string literals ` due to a problem with the + implementation. In Python 3.7 this restriction was lifted. + * More than 255 arguments can now be passed to a function, and a function can now have more than 255 parameters. (Contributed by Serhiy Storchaka in :issue:`12844` and :issue:`18896`.) From webhook-mailer at python.org Thu Feb 13 19:04:04 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 14 Feb 2020 00:04:04 -0000 Subject: [Python-checkins] bpo-39545: Document changes in the support of await in f-strings. (GH-18456) Message-ID: https://github.com/python/cpython/commit/581b8606ca0609cf36c4eb9a5bb025eb77540e5e commit: 581b8606ca0609cf36c4eb9a5bb025eb77540e5e branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-13T16:03:59-08:00 summary: bpo-39545: Document changes in the support of await in f-strings. (GH-18456) https://bugs.python.org/issue39545 (cherry picked from commit f632736023502816f2e6bd714d1b48c81aa2ccc1) Co-authored-by: Serhiy Storchaka files: M Doc/reference/lexical_analysis.rst M Doc/whatsnew/3.7.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index c0e13b53698e6..3d4b03e6bd459 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -685,6 +685,11 @@ strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. +.. versionchanged:: 3.7 + Prior to Python 3.7, an :keyword:`await` expression and comprehensions + containing an :keyword:`async for` clause were illegal in the expressions + in formatted string literals due to a problem with the implementation. + If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 8a70fe22d52bd..b9b50216d23a6 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -493,6 +493,11 @@ of this mode. Other Language Changes ====================== +* An :keyword:`await` expression and comprehensions containing an + :keyword:`async for` clause were illegal in the expressions in + :ref:`formatted string literals ` due to a problem with the + implementation. In Python 3.7 this restriction was lifted. + * More than 255 arguments can now be passed to a function, and a function can now have more than 255 parameters. (Contributed by Serhiy Storchaka in :issue:`12844` and :issue:`18896`.) From webhook-mailer at python.org Thu Feb 13 22:09:18 2020 From: webhook-mailer at python.org (Ian Norton) Date: Fri, 14 Feb 2020 03:09:18 -0000 Subject: [Python-checkins] closes bpo-39619 Fix os.chroot on HP-UX 11.31 (GH-18495) Message-ID: https://github.com/python/cpython/commit/a9edf44a2de9b23a1690b36cdfeed7b41ab763bd commit: a9edf44a2de9b23a1690b36cdfeed7b41ab763bd branch: master author: Ian Norton committer: GitHub date: 2020-02-13T19:09:11-08:00 summary: closes bpo-39619 Fix os.chroot on HP-UX 11.31 (GH-18495) Setting `-D_XOPEN_SOURCE=700` on HP-UX causes system functions such as chroot to be undefined. This change stops `_XOPEN_SOURCE` begin set on HP-UX Co-authored-by: Benjamin Peterson files: A Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst new file mode 100644 index 0000000000000..18f32f7e804bd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst @@ -0,0 +1 @@ +Enable use of :func:`os.chroot` on HP-UX systems. diff --git a/configure b/configure index 595c129814d29..846116e1128ee 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] @@ -3427,6 +3439,12 @@ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h define_xopen_source=no ;; + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + esac if test $define_xopen_source = yes diff --git a/configure.ac b/configure.ac index fee605eec2aa5..840caf352d1dd 100644 --- a/configure.ac +++ b/configure.ac @@ -533,6 +533,12 @@ case $ac_sys_system/$ac_sys_release in define_xopen_source=no ;; + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + esac if test $define_xopen_source = yes From webhook-mailer at python.org Thu Feb 13 22:27:32 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 14 Feb 2020 03:27:32 -0000 Subject: [Python-checkins] closes bpo-39619 Fix os.chroot on HP-UX 11.31 (GH-18495) Message-ID: https://github.com/python/cpython/commit/28fc1bac0fbe1f4ae2e3dcba1dee38d2c063a539 commit: 28fc1bac0fbe1f4ae2e3dcba1dee38d2c063a539 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-13T19:27:28-08:00 summary: closes bpo-39619 Fix os.chroot on HP-UX 11.31 (GH-18495) Setting `-D_XOPEN_SOURCE=700` on HP-UX causes system functions such as chroot to be undefined. This change stops `_XOPEN_SOURCE` begin set on HP-UX Co-authored-by: Benjamin Peterson (cherry picked from commit a9edf44a2de9b23a1690b36cdfeed7b41ab763bd) Co-authored-by: Ian Norton files: A Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst new file mode 100644 index 0000000000000..18f32f7e804bd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master_chroot.rst @@ -0,0 +1 @@ +Enable use of :func:`os.chroot` on HP-UX systems. diff --git a/configure b/configure index 0914e24704383..a979363acffc4 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] @@ -3405,6 +3417,12 @@ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h define_xopen_source=no ;; + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + esac if test $define_xopen_source = yes diff --git a/configure.ac b/configure.ac index 7051dc109a725..e57ef7c38bf7f 100644 --- a/configure.ac +++ b/configure.ac @@ -521,6 +521,12 @@ case $ac_sys_system/$ac_sys_release in define_xopen_source=no ;; + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + esac if test $define_xopen_source = yes From webhook-mailer at python.org Thu Feb 13 23:43:16 2020 From: webhook-mailer at python.org (Andy Lester) Date: Fri, 14 Feb 2020 04:43:16 -0000 Subject: [Python-checkins] closes bpo-39630: Update pointers to string literals to be const char *. (GH-18510) Message-ID: https://github.com/python/cpython/commit/7386a70746cf9aaf2d95db75d9201fb124f085df commit: 7386a70746cf9aaf2d95db75d9201fb124f085df branch: master author: Andy Lester committer: GitHub date: 2020-02-13T20:42:56-08:00 summary: closes bpo-39630: Update pointers to string literals to be const char *. (GH-18510) files: M Objects/frameobject.c M Objects/genobject.c M Python/codecs.c M Python/errors.c diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 4469e3c20cd2f..64f5754fe2013 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -475,7 +475,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore 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; + const char *msg; if (target_kind == POP_EXCEPT) { msg = "can't jump into an 'except' block as there's no exception"; } diff --git a/Objects/genobject.c b/Objects/genobject.c index 0837698fd784c..ef892bb0366b8 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -12,10 +12,10 @@ static PyObject *gen_close(PyGenObject *, PyObject *); static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *); -static char *NON_INIT_CORO_MSG = "can't send non-None value to a " +static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " "just-started coroutine"; -static char *ASYNC_GEN_IGNORED_EXIT_MSG = +static const char *ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit"; static inline int diff --git a/Python/codecs.c b/Python/codecs.c index ce86cb20ccccc..e5bcdb09fc596 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1407,7 +1407,7 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) static int _PyCodecRegistry_Init(void) { static struct { - char *name; + const char *name; PyMethodDef def; } methods[] = { diff --git a/Python/errors.c b/Python/errors.c index f11b66e7958ea..61dc597916d72 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -614,7 +614,7 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P #ifndef MS_WINDOWS if (i != 0) { - char *s = strerror(i); + const char *s = strerror(i); message = PyUnicode_DecodeLocale(s, "surrogateescape"); } else { From webhook-mailer at python.org Fri Feb 14 00:05:08 2020 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 14 Feb 2020 05:05:08 -0000 Subject: [Python-checkins] [3.8] closes bpo-39630: Update pointers to string literals to be const char *. (GH-18511) Message-ID: https://github.com/python/cpython/commit/0d860dd43c72dc7046a5d18fc72d495cadd4a2df commit: 0d860dd43c72dc7046a5d18fc72d495cadd4a2df branch: 3.8 author: Benjamin Peterson committer: GitHub date: 2020-02-13T21:05:00-08:00 summary: [3.8] closes bpo-39630: Update pointers to string literals to be const char *. (GH-18511) (cherry picked from commit 7386a70746cf9aaf2d95db75d9201fb124f085df) Co-authored-by: Andy Lester files: M Objects/genobject.c M Python/codecs.c M Python/errors.c diff --git a/Objects/genobject.c b/Objects/genobject.c index 2c06bdcc72642..ce7dd48a17cfb 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -11,10 +11,10 @@ static PyObject *gen_close(PyGenObject *, PyObject *); static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *); -static char *NON_INIT_CORO_MSG = "can't send non-None value to a " +static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " "just-started coroutine"; -static char *ASYNC_GEN_IGNORED_EXIT_MSG = +static const char *ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit"; static inline int diff --git a/Python/codecs.c b/Python/codecs.c index d4b34f8397f05..4bd28ec9c761c 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1415,7 +1415,7 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) static int _PyCodecRegistry_Init(void) { static struct { - char *name; + const char *name; PyMethodDef def; } methods[] = { diff --git a/Python/errors.c b/Python/errors.c index 197d9779b390c..1360c0d91a33f 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -584,7 +584,7 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P #ifndef MS_WINDOWS if (i != 0) { - char *s = strerror(i); + const char *s = strerror(i); message = PyUnicode_DecodeLocale(s, "surrogateescape"); } else { From webhook-mailer at python.org Fri Feb 14 02:48:35 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Fri, 14 Feb 2020 07:48:35 -0000 Subject: [Python-checkins] bpo-39573: PyXXX_Check() macros use Py_IS_TYPE() (GH-18508) Message-ID: https://github.com/python/cpython/commit/d212c3c55d414203b0579e000d9f340f8cd11be7 commit: d212c3c55d414203b0579e000d9f340f8cd11be7 branch: master author: Dong-hee Na committer: GitHub date: 2020-02-14T08:48:12+01:00 summary: bpo-39573: PyXXX_Check() macros use Py_IS_TYPE() (GH-18508) Update PyXXX_Check() macros in Include/ to use the new Py_IS_TYPE function. files: M Include/classobject.h M Include/picklebufobject.h diff --git a/Include/classobject.h b/Include/classobject.h index 8742720720550..1952f673b7d86 100644 --- a/Include/classobject.h +++ b/Include/classobject.h @@ -19,7 +19,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyMethod_Type; -#define PyMethod_Check(op) (Py_TYPE(op)== &PyMethod_Type) +#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type) PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); @@ -40,7 +40,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; -#define PyInstanceMethod_Check(op) (Py_TYPE(op) == &PyInstanceMethod_Type) +#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type) PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); diff --git a/Include/picklebufobject.h b/Include/picklebufobject.h index f07e900bf26da..0df2561dceaea 100644 --- a/Include/picklebufobject.h +++ b/Include/picklebufobject.h @@ -12,7 +12,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; -#define PyPickleBuffer_Check(op) (Py_TYPE(op) == &PyPickleBuffer_Type) +#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type) /* Create a PickleBuffer redirecting to the given buffer-enabled object */ PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); From webhook-mailer at python.org Fri Feb 14 02:50:23 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Fri, 14 Feb 2020 07:50:23 -0000 Subject: [Python-checkins] bpo-39573: Update clinic to use Py_IS_TYPE() function (GH-18507) Message-ID: https://github.com/python/cpython/commit/9aeb0ef9309384099e2f23bcee2240fbc096568e commit: 9aeb0ef9309384099e2f23bcee2240fbc096568e branch: master author: Dong-hee Na committer: GitHub date: 2020-02-14T08:50:19+01:00 summary: bpo-39573: Update clinic to use Py_IS_TYPE() function (GH-18507) files: A Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M.rst M Modules/_io/clinic/bufferedio.c.h M Modules/clinic/_bz2module.c.h M Objects/clinic/listobject.c.h M Tools/clinic/clinic.py diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M.rst new file mode 100644 index 0000000000000..23396d3bd2b73 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M.rst @@ -0,0 +1 @@ +Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Dong-hee Na. diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 72841fcb6779c..56d6332a25058 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -578,7 +578,7 @@ _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *writer; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - if ((Py_TYPE(self) == &PyBufferedRWPair_Type) && + if (Py_IS_TYPE(self, &PyBufferedRWPair_Type) && !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { goto exit; } @@ -672,4 +672,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=7246104f6c7d3167 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7d9ad40c95bdd808 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index ac826bd9b5986..0eb6280d6e029 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -85,7 +85,7 @@ _bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) int return_value = -1; int compresslevel = 9; - if ((Py_TYPE(self) == &BZ2Compressor_Type) && + if (Py_IS_TYPE(self, &BZ2Compressor_Type) && !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { goto exit; } @@ -207,11 +207,11 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && !_PyArg_NoPositional("BZ2Decompressor", args)) { goto exit; } - if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { goto exit; } @@ -220,4 +220,4 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=ec3d1b3652c98823 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f3f1e788fe28ee1 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 57f0a48eb0838..ed137c95a8e10 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -314,7 +314,7 @@ list___init__(PyObject *self, PyObject *args, PyObject *kwargs) int return_value = -1; PyObject *iterable = NULL; - if ((Py_TYPE(self) == &PyList_Type) && + if (Py_IS_TYPE(self, &PyList_Type) && !_PyArg_NoKeywords("list", kwargs)) { goto exit; } @@ -367,4 +367,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=73718c0c33798c62 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1ff61490c091d165 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index b503932e2624b..382e29a28ab48 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -3585,17 +3585,14 @@ def set_template_dict(self, template_dict): cls = self.function.cls if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef): + type_object = self.function.cls.type_object if kind == METHOD_NEW: - passed_in_type = self.name + type_check = '({} == {})'.format(self.name, type_object) else: - passed_in_type = 'Py_TYPE({})'.format(self.name) - - line = '({passed_in_type} == {type_object}) &&\n ' - d = { - 'type_object': self.function.cls.type_object, - 'passed_in_type': passed_in_type - } - template_dict['self_type_check'] = line.format_map(d) + type_check = 'Py_IS_TYPE({}, {})'.format(self.name, type_object) + + line = '{} &&\n '.format(type_check) + template_dict['self_type_check'] = line From webhook-mailer at python.org Fri Feb 14 17:02:22 2020 From: webhook-mailer at python.org (Vinay Sajip) Date: Fri, 14 Feb 2020 22:02:22 -0000 Subject: [Python-checkins] bpo-12915: Add pkgutil.resolve_name (GH-18310) Message-ID: https://github.com/python/cpython/commit/1ed61617a4a6632905ad6a0b440cd2cafb8b6414 commit: 1ed61617a4a6632905ad6a0b440cd2cafb8b6414 branch: master author: Vinay Sajip committer: GitHub date: 2020-02-14T22:02:13Z summary: bpo-12915: Add pkgutil.resolve_name (GH-18310) files: A Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst M Doc/library/pkgutil.rst M Lib/pkgutil.py M Lib/test/test_pkgutil.py diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 78a5157345858..2066cbb9fc57c 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -227,3 +227,44 @@ support. then ``None`` is returned. In particular, the :term:`loader` for :term:`namespace packages ` does not support :meth:`get_data `. + + +.. function:: resolve_name(name) + + Resolve a name to an object. + + This functionality is used in numerous places in the standard library (see + :issue:`12915`) - and equivalent functionality is also in widely used + third-party packages such as setuptools, Django and Pyramid. + + It is expected that *name* will be a string in one of the following + formats, where W is shorthand for a valid Python identifier and dot stands + for a literal period in these pseudo-regexes: + + * ``W(.W)*`` + * ``W(.W)*:(W(.W)*)?`` + + The first form is intended for backward compatibility only. It assumes that + some part of the dotted name is a package, and the rest is an object + somewhere within that package, possibly nested inside other objects. + Because the place where the package stops and the object hierarchy starts + can't be inferred by inspection, repeated attempts to import must be done + with this form. + + In the second form, the caller makes the division point clear through the + provision of a single colon: the dotted name to the left of the colon is a + package to be imported, and the dotted name to the right is the object + hierarchy within that package. Only one import is needed in this form. If + it ends with the colon, then a module object is returned. + + The function will return an object (which might be a module), or raise one + of the following exceptions: + + :exc:`ValueError` -- if *name* isn't in a recognised format. + + :exc:`ImportError` -- if an import failed when it shouldn't have. + + :exc:`AttributeError` -- If a failure occurred when traversing the object + hierarchy within the imported package to get to the desired object. + + .. versionadded:: 3.9 diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 8474a773e7c73..4bc3083ac197e 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -7,6 +7,7 @@ import importlib.machinery import os import os.path +import re import sys from types import ModuleType import warnings @@ -635,3 +636,71 @@ def get_data(package, resource): parts.insert(0, os.path.dirname(mod.__file__)) resource_name = os.path.join(*parts) return loader.get_data(resource_name) + + +_DOTTED_WORDS = r'[a-z_]\w*(\.[a-z_]\w*)*' +_NAME_PATTERN = re.compile(f'^({_DOTTED_WORDS})(:({_DOTTED_WORDS})?)?$', re.I) +del _DOTTED_WORDS + +def resolve_name(name): + """ + Resolve a name to an object. + + It is expected that `name` will be a string in one of the following + formats, where W is shorthand for a valid Python identifier and dot stands + for a literal period in these pseudo-regexes: + + W(.W)* + W(.W)*:(W(.W)*)? + + The first form is intended for backward compatibility only. It assumes that + some part of the dotted name is a package, and the rest is an object + somewhere within that package, possibly nested inside other objects. + Because the place where the package stops and the object hierarchy starts + can't be inferred by inspection, repeated attempts to import must be done + with this form. + + In the second form, the caller makes the division point clear through the + provision of a single colon: the dotted name to the left of the colon is a + package to be imported, and the dotted name to the right is the object + hierarchy within that package. Only one import is needed in this form. If + it ends with the colon, then a module object is returned. + + The function will return an object (which might be a module), or raise one + of the following exceptions: + + ValueError - if `name` isn't in a recognised format + ImportError - if an import failed when it shouldn't have + AttributeError - if a failure occurred when traversing the object hierarchy + within the imported package to get to the desired object) + """ + m = _NAME_PATTERN.match(name) + if not m: + raise ValueError(f'invalid format: {name!r}') + groups = m.groups() + if groups[2]: + # there is a colon - a one-step import is all that's needed + mod = importlib.import_module(groups[0]) + parts = groups[3].split('.') if groups[3] else [] + else: + # no colon - have to iterate to find the package boundary + parts = name.split('.') + modname = parts.pop(0) + # first part *must* be a module/package. + mod = importlib.import_module(modname) + while parts: + p = parts[0] + s = f'{modname}.{p}' + try: + mod = importlib.import_module(s) + parts.pop(0) + modname = s + except ImportError: + break + # if we reach this point, mod is the module, already imported, and + # parts is the list of parts in the object hierarchy to be traversed, or + # an empty list if just the module is wanted. + result = mod + for p in parts: + result = getattr(result, p) + return result diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index 2887ce6cc055d..906150b10495b 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -186,6 +186,61 @@ def test_walk_packages_raises_on_string_or_bytes_input(self): with self.assertRaises((TypeError, ValueError)): list(pkgutil.walk_packages(bytes_input)) + def test_name_resolution(self): + import logging + import logging.handlers + + success_cases = ( + ('os', os), + ('os.path', os.path), + ('os.path:pathsep', os.path.pathsep), + ('logging', logging), + ('logging:', logging), + ('logging.handlers', logging.handlers), + ('logging.handlers:', logging.handlers), + ('logging.handlers:SysLogHandler', logging.handlers.SysLogHandler), + ('logging.handlers.SysLogHandler', logging.handlers.SysLogHandler), + ('logging.handlers:SysLogHandler.LOG_ALERT', + logging.handlers.SysLogHandler.LOG_ALERT), + ('logging.handlers.SysLogHandler.LOG_ALERT', + logging.handlers.SysLogHandler.LOG_ALERT), + ('builtins.int', int), + ('builtins:int', int), + ('builtins.int.from_bytes', int.from_bytes), + ('builtins:int.from_bytes', int.from_bytes), + ('builtins.ZeroDivisionError', ZeroDivisionError), + ('builtins:ZeroDivisionError', ZeroDivisionError), + ('os:path', os.path), + ) + + failure_cases = ( + (None, TypeError), + (1, TypeError), + (2.0, TypeError), + (True, TypeError), + ('', ValueError), + ('?abc', ValueError), + ('abc/foo', ValueError), + ('foo', ImportError), + ('os.foo', AttributeError), + ('os.foo:', ImportError), + ('os.pth:pathsep', ImportError), + ('logging.handlers:NoSuchHandler', AttributeError), + ('logging.handlers:SysLogHandler.NO_SUCH_VALUE', AttributeError), + ('logging.handlers.SysLogHandler.NO_SUCH_VALUE', AttributeError), + ('ZeroDivisionError', ImportError), + ) + + for s, expected in success_cases: + with self.subTest(s=s): + o = pkgutil.resolve_name(s) + self.assertEqual(o, expected) + + for s, exc in failure_cases: + with self.subTest(s=s): + with self.assertRaises(exc): + pkgutil.resolve_name(s) + class PkgutilPEP302Tests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst b/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst new file mode 100644 index 0000000000000..90ee0bcac7915 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst @@ -0,0 +1,4 @@ +A new function ``resolve_name`` has been added to the ``pkgutil`` module. +This resolves a string of the form ``'a.b.c.d'`` or ``'a.b:c.d'`` to an +object. In the example, ``a.b`` is a package/module and ``c.d`` is an object +within that package/module reached via recursive attribute access. From webhook-mailer at python.org Sun Feb 16 13:09:30 2020 From: webhook-mailer at python.org (Thomas Moreau) Date: Sun, 16 Feb 2020 18:09:30 -0000 Subject: [Python-checkins] bpo-39104: Fix hanging ProcessPoolExecutor on shutdown nowait with pickling failure (GH-17670) Message-ID: https://github.com/python/cpython/commit/a5cbab552d294d99fde864306632d7e511a75d3c commit: a5cbab552d294d99fde864306632d7e511a75d3c branch: master author: Thomas Moreau committer: GitHub date: 2020-02-16T10:09:26-08:00 summary: bpo-39104: Fix hanging ProcessPoolExecutor on shutdown nowait with pickling failure (GH-17670) As reported initially by @rad-pat in #6084, the following script causes a deadlock. ``` from concurrent.futures import ProcessPoolExecutor class ObjectWithPickleError(): """Triggers a RuntimeError when sending job to the workers""" def __reduce__(self): raise RuntimeError() if __name__ == "__main__": e = ProcessPoolExecutor() f = e.submit(id, ObjectWithPickleError()) e.shutdown(wait=False) f.result() # Deadlock on get ``` This is caused by the fact that the main process is closing communication channels that might be necessary to the `queue_management_thread` later. To avoid this, this PR let the `queue_management_thread` manage all the closing. https://bugs.python.org/issue39104 Automerge-Triggered-By: @pitrou files: A Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst M Lib/concurrent/futures/process.py M Lib/test/test_concurrent_futures.py diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index fd9f572b6c711..d77322831a6c6 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -80,18 +80,23 @@ class _ThreadWakeup: def __init__(self): + self._closed = False self._reader, self._writer = mp.Pipe(duplex=False) def close(self): - self._writer.close() - self._reader.close() + if not self._closed: + self._closed = True + self._writer.close() + self._reader.close() def wakeup(self): - self._writer.send_bytes(b"") + if not self._closed: + self._writer.send_bytes(b"") def clear(self): - while self._reader.poll(): - self._reader.recv_bytes() + if not self._closed: + while self._reader.poll(): + self._reader.recv_bytes() def _python_exit(): @@ -160,8 +165,9 @@ def __init__(self, work_id, fn, args, kwargs): class _SafeQueue(Queue): """Safe Queue set exception to the future object linked to a job""" - def __init__(self, max_size=0, *, ctx, pending_work_items): + def __init__(self, max_size=0, *, ctx, pending_work_items, thread_wakeup): self.pending_work_items = pending_work_items + self.thread_wakeup = thread_wakeup super().__init__(max_size, ctx=ctx) def _on_queue_feeder_error(self, e, obj): @@ -169,6 +175,7 @@ def _on_queue_feeder_error(self, e, obj): tb = traceback.format_exception(type(e), e, e.__traceback__) e.__cause__ = _RemoteTraceback('\n"""\n{}"""'.format(''.join(tb))) work_item = self.pending_work_items.pop(obj.work_id, None) + self.thread_wakeup.wakeup() # work_item can be None if another process terminated. In this case, # the queue_manager_thread fails all work_items with BrokenProcessPool if work_item is not None: @@ -339,6 +346,8 @@ def shutdown_worker(): # Release the queue's resources as soon as possible. call_queue.close() + call_queue.join_thread() + thread_wakeup.close() # If .join() is not called on the created processes then # some ctx.Queue methods may deadlock on Mac OS X. for p in processes.values(): @@ -566,6 +575,14 @@ def __init__(self, max_workers=None, mp_context=None, self._pending_work_items = {} self._cancel_pending_futures = False + # _ThreadWakeup is a communication channel used to interrupt the wait + # of the main loop of queue_manager_thread from another thread (e.g. + # when calling executor.submit or executor.shutdown). We do not use the + # _result_queue to send the wakeup signal to the queue_manager_thread + # as it could result in a deadlock if a worker process dies with the + # _result_queue write lock still acquired. + self._queue_management_thread_wakeup = _ThreadWakeup() + # Create communication channels for the executor # Make the call queue slightly larger than the number of processes to # prevent the worker processes from idling. But don't make it too big @@ -573,7 +590,8 @@ def __init__(self, max_workers=None, mp_context=None, queue_size = self._max_workers + EXTRA_QUEUED_CALLS self._call_queue = _SafeQueue( max_size=queue_size, ctx=self._mp_context, - pending_work_items=self._pending_work_items) + pending_work_items=self._pending_work_items, + thread_wakeup=self._queue_management_thread_wakeup) # Killed worker processes can produce spurious "broken pipe" # tracebacks in the queue's own worker thread. But we detect killed # processes anyway, so silence the tracebacks. @@ -581,14 +599,6 @@ def __init__(self, max_workers=None, mp_context=None, self._result_queue = mp_context.SimpleQueue() self._work_ids = queue.Queue() - # _ThreadWakeup is a communication channel used to interrupt the wait - # of the main loop of queue_manager_thread from another thread (e.g. - # when calling executor.submit or executor.shutdown). We do not use the - # _result_queue to send the wakeup signal to the queue_manager_thread - # as it could result in a deadlock if a worker process dies with the - # _result_queue write lock still acquired. - self._queue_management_thread_wakeup = _ThreadWakeup() - def _start_queue_management_thread(self): if self._queue_management_thread is None: # When the executor gets garbarge collected, the weakref callback @@ -692,16 +702,11 @@ def shutdown(self, wait=True, *, cancel_futures=False): # To reduce the risk of opening too many files, remove references to # objects that use file descriptors. self._queue_management_thread = None - if self._call_queue is not None: - self._call_queue.close() - if wait: - self._call_queue.join_thread() - self._call_queue = None + self._call_queue = None self._result_queue = None self._processes = None if self._queue_management_thread_wakeup: - self._queue_management_thread_wakeup.close() self._queue_management_thread_wakeup = None shutdown.__doc__ = _base.Executor.shutdown.__doc__ diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index af77f81341910..a7381f9d13eb1 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -415,13 +415,32 @@ def test_context_manager_shutdown(self): def test_del_shutdown(self): executor = futures.ThreadPoolExecutor(max_workers=5) - executor.map(abs, range(-5, 5)) + res = executor.map(abs, range(-5, 5)) threads = executor._threads del executor for t in threads: t.join() + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the threads when calling + # shutdown with wait=False + executor = futures.ThreadPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + threads = executor._threads + executor.shutdown(wait=False) + for t in threads: + t.join() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_thread_names_assigned(self): executor = futures.ThreadPoolExecutor( max_workers=5, thread_name_prefix='SpecialPool') @@ -488,7 +507,7 @@ def test_context_manager_shutdown(self): def test_del_shutdown(self): executor = futures.ProcessPoolExecutor(max_workers=5) - list(executor.map(abs, range(-5, 5))) + res = executor.map(abs, range(-5, 5)) queue_management_thread = executor._queue_management_thread processes = executor._processes call_queue = executor._call_queue @@ -502,6 +521,31 @@ def test_del_shutdown(self): p.join() call_queue.join_thread() + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the processes when calling + # shutdown with wait=False + executor = futures.ProcessPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + processes = executor._processes + call_queue = executor._call_queue + queue_management_thread = executor._queue_management_thread + executor.shutdown(wait=False) + + # Make sure that all the executor resources were properly cleaned by + # the shutdown process + queue_management_thread.join() + for p in processes.values(): + p.join() + call_queue.join_thread() + + # Make sure the results were all computed before the executor got + # shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + create_executor_tests(ProcessPoolShutdownTest, executor_mixins=(ProcessPoolForkMixin, @@ -1086,6 +1130,32 @@ def test_shutdown_deadlock(self): with self.assertRaises(BrokenProcessPool): f.result() + def test_shutdown_deadlock_pickle(self): + # Test that the pool calling shutdown with wait=False does not cause + # a deadlock if a task fails at pickle after the shutdown call. + # Reported in bpo-39104. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=get_context(self.ctx)) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + + # Start the executor and get the queue_management_thread to collect + # the threads and avoid dangling thread that should be cleaned up + # asynchronously. + executor.submit(id, 42).result() + queue_manager = executor._queue_management_thread + + # Submit a task that fails at pickle and shutdown the executor + # without waiting + f = executor.submit(id, ErrorAtPickle()) + executor.shutdown(wait=False) + with self.assertRaises(PicklingError): + f.result() + + # Make sure the executor is eventually shutdown and do not leave + # dangling threads + queue_manager.join() + create_executor_tests(ExecutorDeadlockTest, executor_mixins=(ProcessPoolForkMixin, diff --git a/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst b/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst new file mode 100644 index 0000000000000..52779bf098232 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst @@ -0,0 +1,2 @@ +Fix hanging ProcessPoolExcutor on ``shutdown(wait=False)`` when a task has +failed pickling. From webhook-mailer at python.org Sun Feb 16 14:18:08 2020 From: webhook-mailer at python.org (idomic) Date: Sun, 16 Feb 2020 19:18:08 -0000 Subject: [Python-checkins] bpo-37970: update and improve urlparse and urlsplit doc-strings (GH-16458) Message-ID: https://github.com/python/cpython/commit/c33bdbb20cf55b3a2aa7a91bd3d91fcb59796fad commit: c33bdbb20cf55b3a2aa7a91bd3d91fcb59796fad branch: master author: idomic committer: GitHub date: 2020-02-16T21:17:58+02:00 summary: bpo-37970: update and improve urlparse and urlsplit doc-strings (GH-16458) files: M Lib/urllib/parse.py diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 34d5f95dd79bd..779278bac598a 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -366,9 +366,23 @@ def _fix_result_transcoding(): def urlparse(url, scheme='', allow_fragments=True): """Parse a URL into 6 components: :///;?# - Return a 6-tuple: (scheme, netloc, path, params, query, fragment). - Note that we don't break the components up in smaller bits - (e.g. netloc is a single string) and we don't expand % escapes.""" + + The result is a named 6-tuple with fields corresponding to the + above. It is either a ParseResult or ParseResultBytes object, + depending on the type of the url parameter. + + The username, password, hostname, and port sub-components of netloc + can also be accessed as attributes of the returned object. + + The scheme argument provides the default value of the scheme + component when no scheme is found in url. + + If allow_fragments is False, no attempt is made to separate the + fragment component from the previous component, which can be either + path or query. + + Note that % escapes are not expanded. + """ url, scheme, _coerce_result = _coerce_args(url, scheme) splitresult = urlsplit(url, scheme, allow_fragments) scheme, netloc, url, query, fragment = splitresult @@ -417,9 +431,24 @@ def _checknetloc(netloc): def urlsplit(url, scheme='', allow_fragments=True): """Parse a URL into 5 components: :///?# - Return a 5-tuple: (scheme, netloc, path, query, fragment). - Note that we don't break the components up in smaller bits - (e.g. netloc is a single string) and we don't expand % escapes.""" + + The result is a named 5-tuple with fields corresponding to the + above. It is either a SplitResult or SplitResultBytes object, + depending on the type of the url parameter. + + The username, password, hostname, and port sub-components of netloc + can also be accessed as attributes of the returned object. + + The scheme argument provides the default value of the scheme + component when no scheme is found in url. + + If allow_fragments is False, no attempt is made to separate the + fragment component from the previous component, which can be either + path or query. + + Note that % escapes are not expanded. + """ + url, scheme, _coerce_result = _coerce_args(url, scheme) allow_fragments = bool(allow_fragments) key = url, scheme, allow_fragments, type(url), type(scheme) From webhook-mailer at python.org Sun Feb 16 16:07:30 2020 From: webhook-mailer at python.org (Senthil Kumaran) Date: Sun, 16 Feb 2020 21:07:30 -0000 Subject: [Python-checkins] Revert "bpo-27657: Fix urlparse() with numeric paths (GH-661)" (#18526) Message-ID: https://github.com/python/cpython/commit/505b6015a1579fc50d9697e4a285ecc64976397a commit: 505b6015a1579fc50d9697e4a285ecc64976397a branch: 3.7 author: Senthil Kumaran committer: GitHub date: 2020-02-16T13:07:25-08:00 summary: Revert "bpo-27657: Fix urlparse() with numeric paths (GH-661)" (#18526) This reverts commit 82b5f6b16e051f8a2ac6e87ba86b082fa1c4a77f. The change broke the backwards compatibility of parsing behavior in a patch release of Python (3.7.6). A decision was taken to revert this patch in 3.7.7. In https://bugs.python.org/issue27657 it was decided that the previous behavior like >>> urlparse('localhost:8080') ParseResult(scheme='', netloc='', path='localhost:8080', params='', query='', fragment='') >>> urlparse('undefined:8080') ParseResult(scheme='', netloc='', path='undefined:8080', params='', query='', fragment='') needs to be preserved in patch releases as number of users rely upon it. Explicitly mention the releases involved with the revert in NEWS. Adopt the wording suggested by @ned-deily. files: A Misc/NEWS.d/next/Library/2020-02-16-07-47-55.bpo-27657.9kZchc.rst M Lib/test/test_urlparse.py M Lib/urllib/parse.py diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 999272d3e3ad6..68f633ca3a7db 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -709,17 +709,15 @@ def test_withoutscheme(self): def test_portseparator(self): # Issue 754016 makes changes for port separator ':' from scheme separator - self.assertEqual(urllib.parse.urlparse("http:80"), ('http','','80','','','')) - self.assertEqual(urllib.parse.urlparse("https:80"), ('https','','80','','','')) - self.assertEqual(urllib.parse.urlparse("path:80"), ('path','','80','','','')) + self.assertEqual(urllib.parse.urlparse("path:80"), + ('','','path:80','','','')) self.assertEqual(urllib.parse.urlparse("http:"),('http','','','','','')) self.assertEqual(urllib.parse.urlparse("https:"),('https','','','','','')) self.assertEqual(urllib.parse.urlparse("http://www.python.org:80"), ('http','www.python.org:80','','','','')) # As usual, need to check bytes input as well - self.assertEqual(urllib.parse.urlparse(b"http:80"), (b'http',b'',b'80',b'',b'',b'')) - self.assertEqual(urllib.parse.urlparse(b"https:80"), (b'https',b'',b'80',b'',b'',b'')) - self.assertEqual(urllib.parse.urlparse(b"path:80"), (b'path',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"path:80"), + (b'',b'',b'path:80',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http:"),(b'http',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"https:"),(b'https',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http://www.python.org:80"), diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index dc3de51a5c2cb..94df275c4677e 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -426,11 +426,31 @@ def urlsplit(url, scheme='', allow_fragments=True): netloc = query = fragment = '' i = url.find(':') if i > 0: + if url[:i] == 'http': # optimize the common case + url = url[i+1:] + if url[:2] == '//': + netloc, url = _splitnetloc(url, 2) + if (('[' in netloc and ']' not in netloc) or + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: + url, query = url.split('?', 1) + _checknetloc(netloc) + v = SplitResult('http', netloc, url, query, fragment) + _parse_cache[key] = v + return _coerce_result(v) for c in url[:i]: if c not in scheme_chars: break else: - scheme, url = url[:i].lower(), url[i+1:] + # make sure "url" is not actually a port number (in which case + # "scheme" is really part of the path) + rest = url[i+1:] + if not rest or any(c not in '0123456789' for c in rest): + # not a port number + scheme, url = url[:i].lower(), rest if url[:2] == '//': netloc, url = _splitnetloc(url, 2) diff --git a/Misc/NEWS.d/next/Library/2020-02-16-07-47-55.bpo-27657.9kZchc.rst b/Misc/NEWS.d/next/Library/2020-02-16-07-47-55.bpo-27657.9kZchc.rst new file mode 100644 index 0000000000000..2a0aca855c2ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-16-07-47-55.bpo-27657.9kZchc.rst @@ -0,0 +1,5 @@ +The original fix for bpo-27657, "Fix urlparse() with numeric paths" (GH-16839) +included in 3.7.6, inadvertently introduced a behavior change that broke +several third-party packages relying on the original undefined parsing +behavior. The change is reverted in 3.7.7, restoring the behavior of 3.7.5 and +earlier releases. From webhook-mailer at python.org Sun Feb 16 16:47:26 2020 From: webhook-mailer at python.org (Senthil Kumaran) Date: Sun, 16 Feb 2020 21:47:26 -0000 Subject: [Python-checkins] Revert "[3.8] bpo-27657: Fix urlparse() with numeric paths (GH-16839)" (GH-18525) Message-ID: https://github.com/python/cpython/commit/ea316fd21527dec53e704a5b04833ac462ce3863 commit: ea316fd21527dec53e704a5b04833ac462ce3863 branch: 3.8 author: Senthil Kumaran committer: GitHub date: 2020-02-16T13:47:21-08:00 summary: Revert "[3.8] bpo-27657: Fix urlparse() with numeric paths (GH-16839)" (GH-18525) This reverts commit 0f3187c1ce3b3ace60f6c1691dfa3d4e744f0384. The change broke the backwards compatibility of parsing behavior in a patch release of Python (3.8.1). A decision was taken to revert this patch in 3.8.2. In https://bugs.python.org/issue27657 it was decided that the previous behavior like >>> urlparse('localhost:8080') ParseResult(scheme='', netloc='', path='localhost:8080', params='', query='', fragment='') >>> urlparse('undefined:8080') ParseResult(scheme='', netloc='', path='undefined:8080', params='', query='', fragment='') needs to be preserved in patch releases as number of users rely upon it. Explicitly mention the releases involved with the revert in NEWS. Adopt the wording suggested by @ned-deily. files: A Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst M Lib/test/test_urlparse.py M Lib/urllib/parse.py diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 762500789f73a..4ae6ed33858ce 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -709,17 +709,15 @@ def test_withoutscheme(self): def test_portseparator(self): # Issue 754016 makes changes for port separator ':' from scheme separator - self.assertEqual(urllib.parse.urlparse("http:80"), ('http','','80','','','')) - self.assertEqual(urllib.parse.urlparse("https:80"), ('https','','80','','','')) - self.assertEqual(urllib.parse.urlparse("path:80"), ('path','','80','','','')) + self.assertEqual(urllib.parse.urlparse("path:80"), + ('','','path:80','','','')) self.assertEqual(urllib.parse.urlparse("http:"),('http','','','','','')) self.assertEqual(urllib.parse.urlparse("https:"),('https','','','','','')) self.assertEqual(urllib.parse.urlparse("http://www.python.org:80"), ('http','www.python.org:80','','','','')) # As usual, need to check bytes input as well - self.assertEqual(urllib.parse.urlparse(b"http:80"), (b'http',b'',b'80',b'',b'',b'')) - self.assertEqual(urllib.parse.urlparse(b"https:80"), (b'https',b'',b'80',b'',b'',b'')) - self.assertEqual(urllib.parse.urlparse(b"path:80"), (b'path',b'',b'80',b'',b'',b'')) + self.assertEqual(urllib.parse.urlparse(b"path:80"), + (b'',b'',b'path:80',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http:"),(b'http',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"https:"),(b'https',b'',b'',b'',b'',b'')) self.assertEqual(urllib.parse.urlparse(b"http://www.python.org:80"), diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 0b39b6eaf7ded..e2b6f133e1cd9 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -431,11 +431,31 @@ def urlsplit(url, scheme='', allow_fragments=True): netloc = query = fragment = '' i = url.find(':') if i > 0: + if url[:i] == 'http': # optimize the common case + url = url[i+1:] + if url[:2] == '//': + netloc, url = _splitnetloc(url, 2) + if (('[' in netloc and ']' not in netloc) or + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: + url, query = url.split('?', 1) + _checknetloc(netloc) + v = SplitResult('http', netloc, url, query, fragment) + _parse_cache[key] = v + return _coerce_result(v) for c in url[:i]: if c not in scheme_chars: break else: - scheme, url = url[:i].lower(), url[i+1:] + # make sure "url" is not actually a port number (in which case + # "scheme" is really part of the path) + rest = url[i+1:] + if not rest or any(c not in '0123456789' for c in rest): + # not a port number + scheme, url = url[:i].lower(), rest if url[:2] == '//': netloc, url = _splitnetloc(url, 2) diff --git a/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst b/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst new file mode 100644 index 0000000000000..50bf8b28217b1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst @@ -0,0 +1,5 @@ +The original fix for bpo-27657, "Fix urlparse() with numeric paths" (GH-16839) +included in 3.8.1, inadvertently introduced a behavior change that broke +several third-party packages relying on the original undefined parsing +behavior. The change is reverted in 3.8.2, restoring the behavior of 3.8.0 and +earlier releases. From webhook-mailer at python.org Mon Feb 17 04:03:30 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Mon, 17 Feb 2020 09:03:30 -0000 Subject: [Python-checkins] bpo-32892: Update the documentation for handling constants in AST. (GH-18514) Message-ID: https://github.com/python/cpython/commit/85a2eef473a2c9ed3ab9c6ee339891fe99adbbc9 commit: 85a2eef473a2c9ed3ab9c6ee339891fe99adbbc9 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-17T11:03:00+02:00 summary: bpo-32892: Update the documentation for handling constants in AST. (GH-18514) files: M Doc/library/ast.rst M Doc/whatsnew/3.8.rst diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 2cee8738e5834..bfd571deb4fd1 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -101,12 +101,16 @@ Node classes node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0) +.. versionchanged:: 3.8 + + Class :class:`ast.Constant` is now used for all constants. + .. deprecated:: 3.8 - Class :class:`ast.Constant` is now used for all constants. Old classes - :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, + Old classes :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, :class:`ast.NameConstant` and :class:`ast.Ellipsis` are still available, - but they will be removed in future Python releases. + but they will be removed in future Python releases. In the meanwhile, + instantiating them will return an instance of a different class. .. _abstract-grammar: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index cb4c518662d6b..09047c460df01 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1940,6 +1940,12 @@ Changes in the Python API :exc:`dbm.gnu.error` or :exc:`dbm.ndbm.error`) instead of :exc:`KeyError`. (Contributed by Xiang Zhang in :issue:`33106`.) +* Simplified AST for literals. All constants will be represented as + :class:`ast.Constant` instances. Instantiating old classes ``Num``, + ``Str``, ``Bytes``, ``NameConstant`` and ``Ellipsis`` will return + an instance of ``Constant``. + (Contributed by Serhiy Storchaka in :issue:`32892`.) + * :func:`~os.path.expanduser` on Windows now prefers the :envvar:`USERPROFILE` environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. From webhook-mailer at python.org Mon Feb 17 04:05:16 2020 From: webhook-mailer at python.org (idomic) Date: Mon, 17 Feb 2020 09:05:16 -0000 Subject: [Python-checkins] bpo-38691 Added a switch to ignore PYTHONCASEOK when -E or -I flags passed (#18314) Message-ID: https://github.com/python/cpython/commit/d83b6600b25487e4ebffd7949d0f478de9538875 commit: d83b6600b25487e4ebffd7949d0f478de9538875 branch: master author: idomic committer: GitHub date: 2020-02-17T10:05:11+01:00 summary: bpo-38691 Added a switch to ignore PYTHONCASEOK when -E or -I flags passed (#18314) * Hard reset + cherry piciking the changes. * ?? Added by blurb_it. * Added @vstinner News * Update Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst Co-Authored-By: Victor Stinner * Hard reset to master * Hard reset to master + latest changes Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst M Doc/library/functions.rst M Doc/whatsnew/3.9.rst M Lib/importlib/_bootstrap_external.py M Python/importlib_external.h diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index cc48597ef91d5..ba5c388622c18 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1829,6 +1829,9 @@ are always available. They are listed here in alphabetical order. Negative values for *level* are no longer supported (which also changes the default value to 0). + .. versionchanged:: 3.9 + When the command line options :option:`-E` or :option:`-I` are being used, + the environment variable :envvar:`PYTHONCASEOK` is now ignored. .. rubric:: Footnotes diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ec179845aee7c..23f0e4306ee63 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -589,6 +589,9 @@ Changes in the Python API since the *buffering* parameter has been removed. (Contributed by Victor Stinner in :issue:`39357`.) +* The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK` + environment variable when the :option:`-E` or :option:`-I` command line + options are being used. CPython bytecode changes ------------------------ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 2434cf06fd444..13f0191839cda 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -35,7 +35,7 @@ def _make_relax_case(): def _relax_case(): """True if filenames must be checked case-insensitively.""" - return key in _os.environ + return not sys.flags.ignore_environment and key in _os.environ else: def _relax_case(): """True if filenames must be checked case-insensitively.""" diff --git a/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst b/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst new file mode 100644 index 0000000000000..913c8ccb1c21c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst @@ -0,0 +1,2 @@ +The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK` +environment variable when :option:`-E` or :option:`-I` command line option is used. diff --git a/Python/importlib_external.h b/Python/importlib_external.h index d67c2a8fee4ea..9662ace50f43c 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -69,2667 +69,2670 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 78,67,65,83,69,79,75,115,12,0,0,0,80,89,84,72, 79,78,67,65,83,69,79,75,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,19,0,0, - 0,115,10,0,0,0,136,0,116,0,106,1,118,0,83,0, - 41,1,250,53,84,114,117,101,32,105,102,32,102,105,108,101, - 110,97,109,101,115,32,109,117,115,116,32,98,101,32,99,104, - 101,99,107,101,100,32,99,97,115,101,45,105,110,115,101,110, - 115,105,116,105,118,101,108,121,46,41,2,218,3,95,111,115, - 90,7,101,110,118,105,114,111,110,169,0,169,1,218,3,107, - 101,121,114,3,0,0,0,250,38,60,102,114,111,122,101,110, - 32,105,109,112,111,114,116,108,105,98,46,95,98,111,111,116, - 115,116,114,97,112,95,101,120,116,101,114,110,97,108,62,218, - 11,95,114,101,108,97,120,95,99,97,115,101,36,0,0,0, - 115,2,0,0,0,0,2,122,37,95,109,97,107,101,95,114, - 101,108,97,120,95,99,97,115,101,46,60,108,111,99,97,108, - 115,62,46,95,114,101,108,97,120,95,99,97,115,101,99,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,83,0,0,0,115,4,0,0,0,100,1,83,0, - 41,2,114,1,0,0,0,70,114,3,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,7,0,0,0,40,0,0,0,115,2,0,0,0,0, - 2,41,5,218,3,115,121,115,218,8,112,108,97,116,102,111, - 114,109,218,10,115,116,97,114,116,115,119,105,116,104,218,27, - 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,218,35,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,83,84,82,95,75,69,89, - 41,1,114,7,0,0,0,114,3,0,0,0,114,4,0,0, - 0,114,6,0,0,0,218,16,95,109,97,107,101,95,114,101, - 108,97,120,95,99,97,115,101,29,0,0,0,115,14,0,0, - 0,0,1,12,1,12,1,6,2,4,2,14,4,8,3,114, - 13,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,20,0, - 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, - 100,3,161,2,83,0,41,4,122,42,67,111,110,118,101,114, - 116,32,97,32,51,50,45,98,105,116,32,105,110,116,101,103, - 101,114,32,116,111,32,108,105,116,116,108,101,45,101,110,100, - 105,97,110,46,236,3,0,0,0,255,127,255,127,3,0,233, - 4,0,0,0,218,6,108,105,116,116,108,101,41,2,218,3, - 105,110,116,218,8,116,111,95,98,121,116,101,115,41,1,218, - 1,120,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,12,95,112,97,99,107,95,117,105,110,116,51,50,46, - 0,0,0,115,2,0,0,0,0,2,114,20,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,116,0,124, - 0,131,1,100,1,107,2,115,16,74,0,130,1,116,1,160, - 2,124,0,100,2,161,2,83,0,41,3,122,47,67,111,110, - 118,101,114,116,32,52,32,98,121,116,101,115,32,105,110,32, - 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, - 32,97,110,32,105,110,116,101,103,101,114,46,114,15,0,0, - 0,114,16,0,0,0,169,3,218,3,108,101,110,114,17,0, - 0,0,218,10,102,114,111,109,95,98,121,116,101,115,169,1, - 218,4,100,97,116,97,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,14,95,117,110,112,97,99,107,95,117, - 105,110,116,51,50,51,0,0,0,115,4,0,0,0,0,2, - 16,1,114,26,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,116,0,124,0,131,1,100,1,107,2,115, - 16,74,0,130,1,116,1,160,2,124,0,100,2,161,2,83, - 0,41,3,122,47,67,111,110,118,101,114,116,32,50,32,98, - 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, - 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, - 103,101,114,46,233,2,0,0,0,114,16,0,0,0,114,21, - 0,0,0,114,24,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,14,95,117,110,112,97,99,107, - 95,117,105,110,116,49,54,56,0,0,0,115,4,0,0,0, - 0,2,16,1,114,28,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,4,0,0,0,71,0, - 0,0,115,20,0,0,0,116,0,160,1,100,1,100,2,132, - 0,124,0,68,0,131,1,161,1,83,0,41,3,122,31,82, - 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, - 115,46,112,97,116,104,46,106,111,105,110,40,41,46,99,1, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, - 0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,0, - 93,18,125,1,124,1,114,4,124,1,160,0,116,1,161,1, - 145,2,113,4,83,0,114,3,0,0,0,41,2,218,6,114, - 115,116,114,105,112,218,15,112,97,116,104,95,115,101,112,97, - 114,97,116,111,114,115,41,2,218,2,46,48,218,4,112,97, - 114,116,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,10,60,108,105,115,116,99,111,109,112,62,64,0,0, - 0,115,6,0,0,0,6,1,2,0,4,255,122,30,95,112, - 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, - 62,46,60,108,105,115,116,99,111,109,112,62,41,2,218,8, - 112,97,116,104,95,115,101,112,218,4,106,111,105,110,41,1, - 218,10,112,97,116,104,95,112,97,114,116,115,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, - 116,104,95,106,111,105,110,62,0,0,0,115,6,0,0,0, - 0,2,10,1,2,255,114,37,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, - 67,0,0,0,115,96,0,0,0,116,0,116,1,131,1,100, - 1,107,2,114,36,124,0,160,2,116,3,161,1,92,3,125, - 1,125,2,125,3,124,1,124,3,102,2,83,0,116,4,124, - 0,131,1,68,0,93,42,125,4,124,4,116,1,118,0,114, - 44,124,0,106,5,124,4,100,1,100,2,141,2,92,2,125, - 1,125,3,124,1,124,3,102,2,2,0,1,0,83,0,113, - 44,100,3,124,0,102,2,83,0,41,4,122,32,82,101,112, - 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, - 112,97,116,104,46,115,112,108,105,116,40,41,46,233,1,0, - 0,0,41,1,90,8,109,97,120,115,112,108,105,116,218,0, - 41,6,114,22,0,0,0,114,30,0,0,0,218,10,114,112, - 97,114,116,105,116,105,111,110,114,34,0,0,0,218,8,114, - 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, - 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, - 95,218,4,116,97,105,108,114,19,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,11,95,112,97, - 116,104,95,115,112,108,105,116,68,0,0,0,115,16,0,0, - 0,0,2,12,1,16,1,8,1,12,1,8,1,18,1,14, - 1,114,46,0,0,0,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, - 10,0,0,0,116,0,160,1,124,0,161,1,83,0,41,1, - 122,126,83,116,97,116,32,116,104,101,32,112,97,116,104,46, - 10,10,32,32,32,32,77,97,100,101,32,97,32,115,101,112, - 97,114,97,116,101,32,102,117,110,99,116,105,111,110,32,116, - 111,32,109,97,107,101,32,105,116,32,101,97,115,105,101,114, - 32,116,111,32,111,118,101,114,114,105,100,101,32,105,110,32, - 101,120,112,101,114,105,109,101,110,116,115,10,32,32,32,32, - 40,101,46,103,46,32,99,97,99,104,101,32,115,116,97,116, - 32,114,101,115,117,108,116,115,41,46,10,10,32,32,32,32, - 41,2,114,2,0,0,0,90,4,115,116,97,116,169,1,114, - 43,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,10,95,112,97,116,104,95,115,116,97,116,80, - 0,0,0,115,2,0,0,0,0,7,114,48,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,48,0,0,0,122,12,116, - 0,124,0,131,1,125,2,87,0,110,20,4,0,116,1,121, - 32,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,115,112, - 101,99,105,102,105,101,100,32,109,111,100,101,32,116,121,112, - 101,46,70,105,0,240,0,0,41,3,114,48,0,0,0,218, - 7,79,83,69,114,114,111,114,218,7,115,116,95,109,111,100, - 101,41,3,114,43,0,0,0,218,4,109,111,100,101,90,9, - 115,116,97,116,95,105,110,102,111,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,18,95,112,97,116,104,95, - 105,115,95,109,111,100,101,95,116,121,112,101,90,0,0,0, - 115,10,0,0,0,0,2,2,1,12,1,12,1,8,1,114, - 52,0,0,0,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,10,0, - 0,0,116,0,124,0,100,1,131,2,83,0,41,2,122,31, - 82,101,112,108,97,99,101,109,101,110,116,32,102,111,114,32, - 111,115,46,112,97,116,104,46,105,115,102,105,108,101,46,105, - 0,128,0,0,41,1,114,52,0,0,0,114,47,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 12,95,112,97,116,104,95,105,115,102,105,108,101,99,0,0, - 0,115,2,0,0,0,0,2,114,53,0,0,0,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,22,0,0,0,124,0,115,12,116, - 0,160,1,161,0,125,0,116,2,124,0,100,1,131,2,83, - 0,41,2,122,30,82,101,112,108,97,99,101,109,101,110,116, - 32,102,111,114,32,111,115,46,112,97,116,104,46,105,115,100, - 105,114,46,105,0,64,0,0,41,3,114,2,0,0,0,218, - 6,103,101,116,99,119,100,114,52,0,0,0,114,47,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,11,95,112,97,116,104,95,105,115,100,105,114,104,0,0, - 0,115,6,0,0,0,0,2,4,1,8,1,114,55,0,0, + 0,115,20,0,0,0,116,0,106,1,106,2,12,0,111,18, + 136,0,116,3,106,4,118,0,83,0,41,1,250,53,84,114, + 117,101,32,105,102,32,102,105,108,101,110,97,109,101,115,32, + 109,117,115,116,32,98,101,32,99,104,101,99,107,101,100,32, + 99,97,115,101,45,105,110,115,101,110,115,105,116,105,118,101, + 108,121,46,41,5,218,3,115,121,115,218,5,102,108,97,103, + 115,218,18,105,103,110,111,114,101,95,101,110,118,105,114,111, + 110,109,101,110,116,218,3,95,111,115,90,7,101,110,118,105, + 114,111,110,169,0,169,1,218,3,107,101,121,114,6,0,0, + 0,250,38,60,102,114,111,122,101,110,32,105,109,112,111,114, + 116,108,105,98,46,95,98,111,111,116,115,116,114,97,112,95, + 101,120,116,101,114,110,97,108,62,218,11,95,114,101,108,97, + 120,95,99,97,115,101,36,0,0,0,115,2,0,0,0,0, + 2,122,37,95,109,97,107,101,95,114,101,108,97,120,95,99, + 97,115,101,46,60,108,111,99,97,108,115,62,46,95,114,101, + 108,97,120,95,99,97,115,101,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,83,0,0, + 0,115,4,0,0,0,100,1,83,0,41,2,114,1,0,0, + 0,70,114,6,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,114,10,0,0,0, + 40,0,0,0,115,2,0,0,0,0,2,41,5,114,2,0, + 0,0,218,8,112,108,97,116,102,111,114,109,218,10,115,116, + 97,114,116,115,119,105,116,104,218,27,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,218,35,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,83,84,82,95,75,69,89,41,1,114,10,0,0, + 0,114,6,0,0,0,114,7,0,0,0,114,9,0,0,0, + 218,16,95,109,97,107,101,95,114,101,108,97,120,95,99,97, + 115,101,29,0,0,0,115,14,0,0,0,0,1,12,1,12, + 1,6,2,4,2,14,4,8,3,114,15,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,20,0,0,0,116,0,124,0, + 131,1,100,1,64,0,160,1,100,2,100,3,161,2,83,0, + 41,4,122,42,67,111,110,118,101,114,116,32,97,32,51,50, + 45,98,105,116,32,105,110,116,101,103,101,114,32,116,111,32, + 108,105,116,116,108,101,45,101,110,100,105,97,110,46,236,3, + 0,0,0,255,127,255,127,3,0,233,4,0,0,0,218,6, + 108,105,116,116,108,101,41,2,218,3,105,110,116,218,8,116, + 111,95,98,121,116,101,115,41,1,218,1,120,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,218,12,95,112,97, + 99,107,95,117,105,110,116,51,50,46,0,0,0,115,2,0, + 0,0,0,2,114,22,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,116,0,124,0,131,1,100,1,107, + 2,115,16,74,0,130,1,116,1,160,2,124,0,100,2,161, + 2,83,0,41,3,122,47,67,111,110,118,101,114,116,32,52, + 32,98,121,116,101,115,32,105,110,32,108,105,116,116,108,101, + 45,101,110,100,105,97,110,32,116,111,32,97,110,32,105,110, + 116,101,103,101,114,46,114,17,0,0,0,114,18,0,0,0, + 169,3,218,3,108,101,110,114,19,0,0,0,218,10,102,114, + 111,109,95,98,121,116,101,115,169,1,218,4,100,97,116,97, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, + 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,51, + 0,0,0,115,4,0,0,0,0,2,16,1,114,28,0,0, 0,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,26,0,0,0,124, - 0,160,0,116,1,161,1,112,24,124,0,100,1,100,2,133, - 2,25,0,116,2,118,0,83,0,41,3,122,142,82,101,112, - 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, - 112,97,116,104,46,105,115,97,98,115,46,10,10,32,32,32, - 32,67,111,110,115,105,100,101,114,115,32,97,32,87,105,110, - 100,111,119,115,32,100,114,105,118,101,45,114,101,108,97,116, - 105,118,101,32,112,97,116,104,32,40,110,111,32,100,114,105, - 118,101,44,32,98,117,116,32,115,116,97,114,116,115,32,119, - 105,116,104,32,115,108,97,115,104,41,32,116,111,10,32,32, - 32,32,115,116,105,108,108,32,98,101,32,34,97,98,115,111, - 108,117,116,101,34,46,10,32,32,32,32,114,38,0,0,0, - 233,3,0,0,0,41,3,114,10,0,0,0,114,30,0,0, - 0,218,20,95,112,97,116,104,115,101,112,115,95,119,105,116, - 104,95,99,111,108,111,110,114,47,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,11,95,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,178,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,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,54,4,0,116,11,121,172,1,0,1,0,1,0,122, - 14,116,2,160,12,124,3,161,1,1,0,87,0,110,18,4, - 0,116,11,121,164,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,12,1,2,1,14,1,12,1,6,1,114,68,0,0, - 0,105,97,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,117,1,114,52,116,0,160,1, - 100,2,116,2,161,2,1,0,124,2,100,1,117,1,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,117,0,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,117,0,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,117,1,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,118,1,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,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, + 0,0,4,0,0,0,67,0,0,0,115,28,0,0,0,116, + 0,124,0,131,1,100,1,107,2,115,16,74,0,130,1,116, + 1,160,2,124,0,100,2,161,2,83,0,41,3,122,47,67, + 111,110,118,101,114,116,32,50,32,98,121,116,101,115,32,105, + 110,32,108,105,116,116,108,101,45,101,110,100,105,97,110,32, + 116,111,32,97,110,32,105,110,116,101,103,101,114,46,233,2, + 0,0,0,114,18,0,0,0,114,23,0,0,0,114,26,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,218,14,95,117,110,112,97,99,107,95,117,105,110,116,49, + 54,56,0,0,0,115,4,0,0,0,0,2,16,1,114,30, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,4,0,0,0,71,0,0,0,115,20,0,0, + 0,116,0,160,1,100,1,100,2,132,0,124,0,68,0,131, + 1,161,1,83,0,41,3,122,31,82,101,112,108,97,99,101, + 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104, + 46,106,111,105,110,40,41,46,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,5,0,0,0,83,0,0, + 0,115,26,0,0,0,103,0,124,0,93,18,125,1,124,1, + 114,4,124,1,160,0,116,1,161,1,145,2,113,4,83,0, + 114,6,0,0,0,41,2,218,6,114,115,116,114,105,112,218, + 15,112,97,116,104,95,115,101,112,97,114,97,116,111,114,115, + 41,2,218,2,46,48,218,4,112,97,114,116,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,218,10,60,108,105, + 115,116,99,111,109,112,62,64,0,0,0,115,6,0,0,0, + 6,1,2,0,4,255,122,30,95,112,97,116,104,95,106,111, + 105,110,46,60,108,111,99,97,108,115,62,46,60,108,105,115, + 116,99,111,109,112,62,41,2,218,8,112,97,116,104,95,115, + 101,112,218,4,106,111,105,110,41,1,218,10,112,97,116,104, + 95,112,97,114,116,115,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,10,95,112,97,116,104,95,106,111,105, + 110,62,0,0,0,115,6,0,0,0,0,2,10,1,2,255, + 114,39,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,96, + 0,0,0,116,0,116,1,131,1,100,1,107,2,114,36,124, + 0,160,2,116,3,161,1,92,3,125,1,125,2,125,3,124, + 1,124,3,102,2,83,0,116,4,124,0,131,1,68,0,93, + 42,125,4,124,4,116,1,118,0,114,44,124,0,106,5,124, + 4,100,1,100,2,141,2,92,2,125,1,125,3,124,1,124, + 3,102,2,2,0,1,0,83,0,113,44,100,3,124,0,102, + 2,83,0,41,4,122,32,82,101,112,108,97,99,101,109,101, + 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,115, + 112,108,105,116,40,41,46,233,1,0,0,0,41,1,90,8, + 109,97,120,115,112,108,105,116,218,0,41,6,114,24,0,0, + 0,114,32,0,0,0,218,10,114,112,97,114,116,105,116,105, + 111,110,114,36,0,0,0,218,8,114,101,118,101,114,115,101, + 100,218,6,114,115,112,108,105,116,41,5,218,4,112,97,116, + 104,90,5,102,114,111,110,116,218,1,95,218,4,116,97,105, + 108,114,21,0,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,11,95,112,97,116,104,95,115,112,108, + 105,116,68,0,0,0,115,16,0,0,0,0,2,12,1,16, + 1,8,1,12,1,8,1,18,1,14,1,114,48,0,0,0, + 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,10,0,0,0,116,0, + 160,1,124,0,161,1,83,0,41,1,122,126,83,116,97,116, + 32,116,104,101,32,112,97,116,104,46,10,10,32,32,32,32, + 77,97,100,101,32,97,32,115,101,112,97,114,97,116,101,32, + 102,117,110,99,116,105,111,110,32,116,111,32,109,97,107,101, + 32,105,116,32,101,97,115,105,101,114,32,116,111,32,111,118, + 101,114,114,105,100,101,32,105,110,32,101,120,112,101,114,105, + 109,101,110,116,115,10,32,32,32,32,40,101,46,103,46,32, + 99,97,99,104,101,32,115,116,97,116,32,114,101,115,117,108, + 116,115,41,46,10,10,32,32,32,32,41,2,114,5,0,0, + 0,90,4,115,116,97,116,169,1,114,45,0,0,0,114,6, + 0,0,0,114,6,0,0,0,114,9,0,0,0,218,10,95, + 112,97,116,104,95,115,116,97,116,80,0,0,0,115,2,0, + 0,0,0,7,114,50,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,48,0,0,0,122,12,116,0,124,0,131,1,125, + 2,87,0,110,20,4,0,116,1,121,32,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,115,112,101,99,105,102,105,101, + 100,32,109,111,100,101,32,116,121,112,101,46,70,105,0,240, + 0,0,41,3,114,50,0,0,0,218,7,79,83,69,114,114, + 111,114,218,7,115,116,95,109,111,100,101,41,3,114,45,0, + 0,0,218,4,109,111,100,101,90,9,115,116,97,116,95,105, + 110,102,111,114,6,0,0,0,114,6,0,0,0,114,9,0, + 0,0,218,18,95,112,97,116,104,95,105,115,95,109,111,100, + 101,95,116,121,112,101,90,0,0,0,115,10,0,0,0,0, + 2,2,1,12,1,12,1,8,1,114,54,0,0,0,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,10,0,0,0,116,0,124,0, + 100,1,131,2,83,0,41,2,122,31,82,101,112,108,97,99, + 101,109,101,110,116,32,102,111,114,32,111,115,46,112,97,116, + 104,46,105,115,102,105,108,101,46,105,0,128,0,0,41,1, + 114,54,0,0,0,114,49,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,218,12,95,112,97,116,104, + 95,105,115,102,105,108,101,99,0,0,0,115,2,0,0,0, + 0,2,114,55,0,0,0,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,22,0,0,0,124,0,115,12,116,0,160,1,161,0,125, + 0,116,2,124,0,100,1,131,2,83,0,41,2,122,30,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,105,115,100,105,114,46,105,0,64, + 0,0,41,3,114,5,0,0,0,218,6,103,101,116,99,119, + 100,114,54,0,0,0,114,49,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,218,11,95,112,97,116, + 104,95,105,115,100,105,114,104,0,0,0,115,6,0,0,0, + 0,2,4,1,8,1,114,57,0,0,0,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,26,0,0,0,124,0,160,0,116,1,161, + 1,112,24,124,0,100,1,100,2,133,2,25,0,116,2,118, + 0,83,0,41,3,122,142,82,101,112,108,97,99,101,109,101, + 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, + 115,97,98,115,46,10,10,32,32,32,32,67,111,110,115,105, + 100,101,114,115,32,97,32,87,105,110,100,111,119,115,32,100, + 114,105,118,101,45,114,101,108,97,116,105,118,101,32,112,97, + 116,104,32,40,110,111,32,100,114,105,118,101,44,32,98,117, + 116,32,115,116,97,114,116,115,32,119,105,116,104,32,115,108, + 97,115,104,41,32,116,111,10,32,32,32,32,115,116,105,108, + 108,32,98,101,32,34,97,98,115,111,108,117,116,101,34,46, + 10,32,32,32,32,114,40,0,0,0,233,3,0,0,0,41, + 3,114,12,0,0,0,114,32,0,0,0,218,20,95,112,97, + 116,104,115,101,112,115,95,119,105,116,104,95,99,111,108,111, + 110,114,49,0,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,11,95,112,97,116,104,95,105,115,97, + 98,115,111,0,0,0,115,2,0,0,0,0,6,114,60,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,178,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,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,54,4,0,116, + 11,121,172,1,0,1,0,1,0,122,14,116,2,160,12,124, + 3,161,1,1,0,87,0,110,18,4,0,116,11,121,164,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,61,0,0,0,90,2,119,98,78,41,13, + 218,6,102,111,114,109,97,116,218,2,105,100,114,5,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, + 51,0,0,0,90,6,117,110,108,105,110,107,41,6,114,45, + 0,0,0,114,27,0,0,0,114,53,0,0,0,90,8,112, + 97,116,104,95,116,109,112,90,2,102,100,218,4,102,105,108, + 101,114,6,0,0,0,114,6,0,0,0,114,9,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,12,1,2,1, + 14,1,12,1,6,1,114,70,0,0,0,105,97,13,0,0, + 114,29,0,0,0,114,18,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,117,1,114,52,116,0,160,1,100,2,116,2,161,2, + 1,0,124,2,100,1,117,1,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,117,0,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,117,0,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, + 117,1,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,118,1,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,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,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,45,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,117,0,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,117,1, - 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,118,1,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,116,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,124,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, - 34,4,0,116,4,116,5,102,2,121,106,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,120,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,156,1,0,0,115,20,0,0,0,0, - 7,12,1,4,1,16,1,24,1,4,1,2,1,12,1,16, - 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,72,0,0,0,124,0,160,0,116,1,116,2,131,1, - 161,1,114,46,122,10,116,3,124,0,131,1,87,0,83,0, - 4,0,116,4,121,42,1,0,1,0,1,0,89,0,113,68, - 48,0,110,22,124,0,160,0,116,1,116,5,131,1,161,1, - 114,64,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,175,1,0,0,115, - 16,0,0,0,0,1,14,1,2,1,10,1,12,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,50,0,0,0,122,14,116,0,124,0,131,1,106, - 1,125,1,87,0,110,22,4,0,116,2,121,36,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,187,1,0,0,115,12,0,0,0,0,2,2,1,14, - 1,12,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,66,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,26,4,0,116,2,121,50,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,72,0,0,0,124,1,100,0,117, - 0,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,103,2,124,2,162,1,82,0,105,0,124,3,164,1,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,207,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,218,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,199,1,0,0,115,14,0,0,0,0,8,14, - 7,2,1,10,1,12,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, - 117,0,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,227,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,166,0,0,0,124, - 0,100,1,100,2,133,2,25,0,125,3,124,3,116,0,107, - 3,114,64,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,105,0,124,2,164,1,142,1,130,1,116, - 4,124,0,131,1,100,6,107,0,114,106,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, - 162,100,10,124,5,155,2,100,11,124,1,155,2,157,4,125, - 4,116,3,124,4,102,1,105,0,124,2,164,1,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,244,1,0,0,115, - 28,0,0,0,0,16,12,1,8,1,16,1,12,1,16,1, - 12,1,10,1,12,1,8,1,16,2,8,1,16,1,16,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,120, - 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,62,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,105,0,124,4,164,1,142,1,130, - 1,124,2,100,6,117,1,114,116,116,0,124,0,100,2,100, - 7,133,2,25,0,131,1,124,2,100,3,64,0,107,3,114, - 116,116,3,100,4,124,3,155,2,157,2,102,1,105,0,124, - 4,164,1,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,21,2,0,0,115,16, - 0,0,0,0,19,24,1,10,1,12,1,16,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,4,0,0,0,67,0,0, - 0,115,42,0,0,0,124,0,100,1,100,2,133,2,25,0, - 124,1,107,3,114,38,116,0,100,3,124,2,155,2,157,2, - 102,1,105,0,124,3,164,1,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,49,2,0, - 0,115,12,0,0,0,0,17,16,1,2,1,8,255,4,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,117,1,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,73,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,86,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,96,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,107,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,12,1,0,0,124,1,100,1,117, - 0,114,58,100,2,125,1,116,0,124,2,100,3,131,2,114, - 68,122,14,124,2,160,1,124,0,161,1,125,1,87,0,113, - 68,4,0,116,2,121,54,1,0,1,0,1,0,89,0,113, - 68,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,117,0,114,152,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,104,124,5,124,0,124,1,131, - 2,125,2,124,2,124,4,95,11,1,0,113,152,113,104,100, - 1,83,0,124,3,116,12,117,0,114,216,116,0,124,2,100, - 6,131,2,114,222,122,14,124,2,160,13,124,0,161,1,125, - 7,87,0,110,18,4,0,116,2,121,202,1,0,1,0,1, - 0,89,0,113,222,48,0,124,7,114,222,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,8,124,1,144,1,114,8,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,124,2,0,0,115,62,0, - 0,0,0,12,8,4,4,1,10,2,2,1,14,1,12,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,12,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,54,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,121,48,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,204,2,0,0,115,8,0,0,0,0,2,2,1,16,1, - 12,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,132,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,20,4,0,116,9,121,126,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,211,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,12,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,120,0,0,0,124,0, - 160,0,124,1,161,1,125,4,124,4,100,0,117,0,114,22, - 100,0,83,0,122,12,116,1,124,4,131,1,1,0,87,0, - 110,20,4,0,116,2,121,54,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,62,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,62,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,226,2,0,0, - 115,28,0,0,0,0,2,10,1,8,1,4,1,2,1,12, - 1,12,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, - 117,1,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, + 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,41,0,0,0,114,40,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,29,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,5,0, + 0,0,218,6,102,115,112,97,116,104,114,48,0,0,0,114, + 42,0,0,0,114,2,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,37,0,0,0,114,3, + 0,0,0,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,63,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,60,0,0,0,114,39,0,0,0,114, + 56,0,0,0,114,32,0,0,0,218,6,108,115,116,114,105, + 112,218,8,95,80,89,67,65,67,72,69,41,12,114,45,0, + 0,0,90,14,100,101,98,117,103,95,111,118,101,114,114,105, + 100,101,114,71,0,0,0,218,7,109,101,115,115,97,103,101, + 218,4,104,101,97,100,114,47,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,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,218,17,99,97,99, + 104,101,95,102,114,111,109,95,115,111,117,114,99,101,45,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, + 98,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,117,0,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,117,1,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, + 118,1,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,73,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,72, + 0,0,0,62,2,0,0,0,114,29,0,0,0,114,58,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,58,0,0,0,114,29,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,74,0,0,0, + 41,22,114,2,0,0,0,114,81,0,0,0,114,82,0,0, + 0,114,83,0,0,0,114,5,0,0,0,114,80,0,0,0, + 114,48,0,0,0,114,90,0,0,0,114,31,0,0,0,114, + 32,0,0,0,114,12,0,0,0,114,36,0,0,0,114,24, + 0,0,0,114,92,0,0,0,114,87,0,0,0,218,5,99, + 111,117,110,116,114,44,0,0,0,114,88,0,0,0,114,86, + 0,0,0,218,9,112,97,114,116,105,116,105,111,110,114,39, + 0,0,0,218,15,83,79,85,82,67,69,95,83,85,70,70, + 73,88,69,83,41,10,114,45,0,0,0,114,94,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,71, + 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,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,218,17,115,111, + 117,114,99,101,95,102,114,111,109,95,99,97,99,104,101,116, + 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,103,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,124,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,34,4,0,116,4,116,5,102, + 2,121,106,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,120,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,74,0,0,0, + 78,114,72,0,0,0,233,253,255,255,255,233,255,255,255,255, + 90,2,112,121,41,7,114,24,0,0,0,114,42,0,0,0, + 218,5,108,111,119,101,114,114,103,0,0,0,114,83,0,0, + 0,114,87,0,0,0,114,55,0,0,0,41,5,218,13,98, + 121,116,101,99,111,100,101,95,112,97,116,104,114,96,0,0, + 0,114,46,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,6, + 0,0,0,114,6,0,0,0,114,9,0,0,0,218,15,95, + 103,101,116,95,115,111,117,114,99,101,102,105,108,101,156,1, + 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, + 1,4,1,2,1,12,1,16,1,18,1,114,109,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,72,0,0,0,124,0, + 160,0,116,1,116,2,131,1,161,1,114,46,122,10,116,3, + 124,0,131,1,87,0,83,0,4,0,116,4,121,42,1,0, + 1,0,1,0,89,0,113,68,48,0,110,22,124,0,160,0, + 116,1,116,5,131,1,161,1,114,64,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,102,0,0, + 0,114,98,0,0,0,114,83,0,0,0,114,89,0,0,0, + 41,1,114,97,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,9,0,0,0,218,11,95,103,101,116,95,99,97,99, + 104,101,100,175,1,0,0,115,16,0,0,0,0,1,14,1, + 2,1,10,1,12,1,8,1,14,1,4,2,114,113,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,50,0,0,0,122, + 14,116,0,124,0,131,1,106,1,125,1,87,0,110,22,4, + 0,116,2,121,36,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,61,0,0,0,233,128,0, + 0,0,41,3,114,50,0,0,0,114,52,0,0,0,114,51, + 0,0,0,41,2,114,45,0,0,0,114,53,0,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,10, + 95,99,97,108,99,95,109,111,100,101,187,1,0,0,115,12, + 0,0,0,0,2,2,1,14,1,12,1,10,3,8,1,114, + 115,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,66,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,26,4,0,116,2, + 121,50,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,72, + 0,0,0,124,1,100,0,117,0,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,103,2,124,2,162,1,82, + 0,105,0,124,3,164,1,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,117,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,117,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, + 6,0,0,0,114,9,0,0,0,218,19,95,99,104,101,99, + 107,95,110,97,109,101,95,119,114,97,112,112,101,114,207,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,68,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,218,5,95,119,114,97, + 112,218,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, + 134,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, + 3,114,123,0,0,0,114,124,0,0,0,114,134,0,0,0, + 114,6,0,0,0,114,122,0,0,0,114,9,0,0,0,218, + 11,95,99,104,101,99,107,95,110,97,109,101,199,1,0,0, + 115,14,0,0,0,0,8,14,7,2,1,10,1,12,2,14, + 5,10,1,114,137,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,117,0,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,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,242,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,192,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,5,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,13,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,117,0,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,16,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,24,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,0,3,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,31,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,39,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,53,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, + 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,74,0,0,0,41,6,218,11,102,105,110,100,95,108,111, + 97,100,101,114,114,24,0,0,0,114,76,0,0,0,114,77, + 0,0,0,114,63,0,0,0,218,13,73,109,112,111,114,116, + 87,97,114,110,105,110,103,41,5,114,119,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, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,17, + 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, + 109,227,1,0,0,115,10,0,0,0,0,10,14,1,16,1, + 4,1,22,1,114,144,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,166,0,0,0,124,0,100,1,100,2,133,2,25, + 0,125,3,124,3,116,0,107,3,114,64,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,105,0,124, + 2,164,1,142,1,130,1,116,4,124,0,131,1,100,6,107, + 0,114,106,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,162,100,10,124,5,155,2,100, + 11,124,1,155,2,157,4,125,4,116,3,124,4,102,1,105, + 0,124,2,164,1,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,17,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,135,0,0,0, + 218,16,95,118,101,114,98,111,115,101,95,109,101,115,115,97, + 103,101,114,118,0,0,0,114,24,0,0,0,218,8,69,79, + 70,69,114,114,111,114,114,28,0,0,0,41,6,114,27,0, + 0,0,114,117,0,0,0,218,11,101,120,99,95,100,101,116, + 97,105,108,115,90,5,109,97,103,105,99,114,93,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,6,0,0,0,114, + 9,0,0,0,218,13,95,99,108,97,115,115,105,102,121,95, + 112,121,99,244,1,0,0,115,28,0,0,0,0,16,12,1, + 8,1,16,1,12,1,16,1,12,1,10,1,12,1,8,1, + 16,2,8,1,16,1,16,1,114,153,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,120,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,62,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,105, + 0,124,4,164,1,142,1,130,1,124,2,100,6,117,1,114, + 116,116,0,124,0,100,2,100,7,133,2,25,0,131,1,124, + 2,100,3,64,0,107,3,114,116,116,3,100,4,124,3,155, + 2,157,2,102,1,105,0,124,4,164,1,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,147,0,0,0,233,12,0,0,0,114,16,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,145,0,0,0,78,114,146, + 0,0,0,41,4,114,28,0,0,0,114,135,0,0,0,114, + 150,0,0,0,114,118,0,0,0,41,6,114,27,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,117,0,0,0, + 114,152,0,0,0,114,93,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,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,21,2,0,0,115,16,0,0,0,0,19,24,1,10, + 1,12,1,16,1,8,1,22,255,2,2,114,157,0,0,0, + 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,42,0,0,0,124,0, + 100,1,100,2,133,2,25,0,124,1,107,3,114,38,116,0, + 100,3,124,2,155,2,157,2,102,1,105,0,124,3,164,1, + 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,147,0,0,0,114,146,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, + 118,0,0,0,41,4,114,27,0,0,0,218,11,115,111,117, + 114,99,101,95,104,97,115,104,114,117,0,0,0,114,152,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,218,18,95,118,97,108,105,100,97,116,101,95,104,97,115, + 104,95,112,121,99,49,2,0,0,115,12,0,0,0,0,17, + 16,1,2,1,8,255,4,2,2,254,114,159,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,117,1,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,117,0,0,0,114,45,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,135,0,0,0, + 114,150,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,118,0, + 0,0,114,63,0,0,0,41,5,114,27,0,0,0,114,117, + 0,0,0,114,107,0,0,0,114,108,0,0,0,218,4,99, + 111,100,101,114,6,0,0,0,114,6,0,0,0,114,9,0, + 0,0,218,17,95,99,111,109,112,105,108,101,95,98,121,116, + 101,99,111,100,101,73,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,166,0,0,0,114,74,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, + 74,0,0,0,41,6,218,9,98,121,116,101,97,114,114,97, + 121,114,149,0,0,0,218,6,101,120,116,101,110,100,114,22, + 0,0,0,114,161,0,0,0,218,5,100,117,109,112,115,41, + 4,114,165,0,0,0,218,5,109,116,105,109,101,114,156,0, + 0,0,114,27,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,9,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,86,2, + 0,0,115,12,0,0,0,0,2,8,1,14,1,14,1,14, + 1,16,1,114,171,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,40,0,0,0,114,147,0,0,0,41,7,114,167,0, + 0,0,114,149,0,0,0,114,168,0,0,0,114,22,0,0, + 0,114,24,0,0,0,114,161,0,0,0,114,169,0,0,0, + 41,5,114,165,0,0,0,114,158,0,0,0,90,7,99,104, + 101,99,107,101,100,114,27,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,17, + 95,99,111,100,101,95,116,111,95,104,97,115,104,95,112,121, + 99,96,2,0,0,115,14,0,0,0,0,2,8,1,12,1, + 14,1,16,1,10,1,16,1,114,172,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,74,0,0,0,78,84,41,7,218, + 8,116,111,107,101,110,105,122,101,114,65,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,173,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,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,218,13,100,101,99, + 111,100,101,95,115,111,117,114,99,101,107,2,0,0,115,10, + 0,0,0,0,5,8,1,12,1,10,1,12,1,114,177,0, + 0,0,169,2,114,141,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,12, + 1,0,0,124,1,100,1,117,0,114,58,100,2,125,1,116, + 0,124,2,100,3,131,2,114,68,122,14,124,2,160,1,124, + 0,161,1,125,1,87,0,113,68,4,0,116,2,121,54,1, + 0,1,0,1,0,89,0,113,68,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,117,0,114,152,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, + 104,124,5,124,0,124,1,131,2,125,2,124,2,124,4,95, + 11,1,0,113,152,113,104,100,1,83,0,124,3,116,12,117, + 0,114,216,116,0,124,2,100,6,131,2,114,222,122,14,124, + 2,160,13,124,0,161,1,125,7,87,0,110,18,4,0,116, + 2,121,202,1,0,1,0,1,0,89,0,113,222,48,0,124, + 7,114,222,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,8,124,1,144, + 1,114,8,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,74,0,0,0,41,17,114,129,0,0,0, + 114,180,0,0,0,114,118,0,0,0,114,5,0,0,0,114, + 80,0,0,0,114,135,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,111,0,0,0,114,112,0,0,0,114,141,0,0,0, + 218,9,95,80,79,80,85,76,65,84,69,114,183,0,0,0, + 114,179,0,0,0,114,48,0,0,0,218,6,97,112,112,101, + 110,100,41,9,114,117,0,0,0,90,8,108,111,99,97,116, + 105,111,110,114,141,0,0,0,114,179,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,183,0,0,0, + 90,7,100,105,114,110,97,109,101,114,6,0,0,0,114,6, + 0,0,0,114,9,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,124,2,0,0,115,62,0,0,0,0,12,8,4,4,1, + 10,2,2,1,14,1,12,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,12,1,6,2,4,1,8,2,6,1, + 12,1,6,1,12,1,12,2,114,191,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,54, + 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,121,48,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,110,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,51,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,8,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,218,14,95,111,112,101,110, + 95,114,101,103,105,115,116,114,121,204,2,0,0,115,8,0, + 0,0,0,2,2,1,16,1,12,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,132,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,20,4,0,116,9,121,126, + 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,29,0,0, + 0,41,2,114,140,0,0,0,90,11,115,121,115,95,118,101, + 114,115,105,111,110,114,41,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,63,0,0,0, + 114,2,0,0,0,218,12,118,101,114,115,105,111,110,95,105, + 110,102,111,114,195,0,0,0,114,193,0,0,0,90,10,81, + 117,101,114,121,86,97,108,117,101,114,51,0,0,0,41,6, + 114,194,0,0,0,114,140,0,0,0,90,12,114,101,103,105, + 115,116,114,121,95,107,101,121,114,8,0,0,0,90,4,104, + 107,101,121,218,8,102,105,108,101,112,97,116,104,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,218,16,95,115, + 101,97,114,99,104,95,114,101,103,105,115,116,114,121,211,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,12,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,120,0,0,0,124,0,160,0,124,1,161,1,125,4, + 124,4,100,0,117,0,114,22,100,0,83,0,122,12,116,1, + 124,4,131,1,1,0,87,0,110,20,4,0,116,2,121,54, + 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,62,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,62,100,0,83,0,41,2, + 78,114,181,0,0,0,41,8,114,201,0,0,0,114,50,0, + 0,0,114,51,0,0,0,114,185,0,0,0,114,111,0,0, + 0,114,112,0,0,0,114,135,0,0,0,218,16,115,112,101, + 99,95,102,114,111,109,95,108,111,97,100,101,114,41,8,114, + 194,0,0,0,114,140,0,0,0,114,45,0,0,0,218,6, + 116,97,114,103,101,116,114,200,0,0,0,114,141,0,0,0, + 114,190,0,0,0,114,188,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,218,9,102,105,110,100,95, + 115,112,101,99,226,2,0,0,115,28,0,0,0,0,2,10, + 1,8,1,4,1,2,1,12,1,12,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,117,1,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,204,0, + 0,0,114,141,0,0,0,169,4,114,194,0,0,0,114,140, + 0,0,0,114,45,0,0,0,114,188,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,218,11,102,105, + 110,100,95,109,111,100,117,108,101,242,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,126,0,0,0,114,125,0,0,0, + 114,127,0,0,0,114,128,0,0,0,114,198,0,0,0,114, + 197,0,0,0,114,196,0,0,0,218,11,99,108,97,115,115, + 109,101,116,104,111,100,114,195,0,0,0,114,201,0,0,0, + 114,204,0,0,0,114,207,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,192, + 0,0,0,192,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,192,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,40,0,0,0,114,72,0,0,0,114,74,0,0,0,114, + 29,0,0,0,218,8,95,95,105,110,105,116,95,95,41,4, + 114,48,0,0,0,114,180,0,0,0,114,44,0,0,0,114, + 42,0,0,0,41,5,114,119,0,0,0,114,140,0,0,0, + 114,97,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, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,183, + 0,0,0,5,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, + 6,0,0,0,169,2,114,119,0,0,0,114,188,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, + 13,99,114,101,97,116,101,95,109,111,100,117,108,101,13,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,117,0,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,126,0,0,0,114,118,0,0,0, + 114,63,0,0,0,114,135,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,132,0,0,0, + 41,3,114,119,0,0,0,218,6,109,111,100,117,108,101,114, + 165,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, + 0,0,0,218,11,101,120,101,99,95,109,111,100,117,108,101, + 16,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,135,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,119,0,0,0,114,140,0,0,0,114,6, + 0,0,0,114,6,0,0,0,114,9,0,0,0,218,11,108, + 111,97,100,95,109,111,100,117,108,101,24,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,126,0,0,0,114,125,0,0,0,114,127,0, + 0,0,114,128,0,0,0,114,183,0,0,0,114,213,0,0, + 0,114,218,0,0,0,114,221,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, + 209,0,0,0,0,3,0,0,115,10,0,0,0,8,2,4, + 3,8,8,8,3,8,8,114,209,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,51,0,0,0,169,2,114,119,0, + 0,0,114,45,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,9,0,0,0,218,10,112,97,116,104,95,109,116,105, + 109,101,31,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,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,63,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,84,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,50,4,0,116,2,121,74,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,70,3,0,0,115, - 20,0,0,0,0,2,10,1,2,1,14,1,14,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,80,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,24,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,24,4,0,116,2,121,66, - 1,0,1,0,1,0,100,1,125,8,89,0,144,1,110,42, - 48,0,122,14,124,0,160,3,124,2,161,1,125,9,87,0, - 110,20,4,0,116,4,121,102,1,0,1,0,1,0,89,0, - 144,1,110,6,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,18,4,0,116,4,121,148,1,0,1,0,1,0,89,0, - 110,216,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,30,124,12, - 100,9,64,0,100,8,107,3,125,7,116,9,106,10,100,10, - 107,3,144,1,114,50,124,7,115,248,116,9,106,10,100,11, - 107,2,144,1,114,50,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,24,4,0,116,15,116,16,102,2,144,1,121,76, - 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,117,0, - 144,1,114,128,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,20,124,8, - 100,1,117,1,144,2,114,20,124,3,100,1,117,1,144,2, - 114,20,124,6,144,1,114,220,124,5,100,1,117,0,144,1, - 114,206,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,20,4,0, - 116,2,144,2,121,18,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, + 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,170,0,0,0,41,1,114,224, + 0,0,0,114,223,0,0,0,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,218,10,112,97,116,104,95,115,116, + 97,116,115,39,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,119,0,0,0,114,108,0,0, + 0,90,10,99,97,99,104,101,95,112,97,116,104,114,27,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,218,15,95,99,97,99,104,101,95,98,121,116,101,99,111, + 100,101,53,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,6,0,0,0,41,3,114, + 119,0,0,0,114,45,0,0,0,114,27,0,0,0,114,6, + 0,0,0,114,6,0,0,0,114,9,0,0,0,114,226,0, + 0,0,63,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,84,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,50,4,0,116,2, + 121,74,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,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,88,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,12,1,12, - 2,2,1,14,1,12,1,8,2,12,1,2,1,14,1,12, - 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,18,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,14, - 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,29,3,0,0,115,14,0,0, - 0,8,2,8,8,8,14,8,10,8,7,8,10,14,8,114, - 221,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,0,0,0,0,115,124,0, + 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,116,0,0,0,78,41,5,114, + 180,0,0,0,218,8,103,101,116,95,100,97,116,97,114,51, + 0,0,0,114,118,0,0,0,114,177,0,0,0,41,5,114, + 119,0,0,0,114,140,0,0,0,114,45,0,0,0,114,175, + 0,0,0,218,3,101,120,99,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,218,10,103,101,116,95,115,111,117, + 114,99,101,70,3,0,0,115,20,0,0,0,0,2,10,1, + 2,1,14,1,14,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,105,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,216,0,0,0,84,41,2,218,12,100, + 111,110,116,95,105,110,104,101,114,105,116,114,84,0,0,0, + 41,3,114,135,0,0,0,114,215,0,0,0,218,7,99,111, + 109,112,105,108,101,41,4,114,119,0,0,0,114,27,0,0, + 0,114,45,0,0,0,114,231,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,218,14,115,111,117,114, + 99,101,95,116,111,95,99,111,100,101,80,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,24,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,24,4,0,116,2,121,66,1,0,1,0,1,0,100,1, + 125,8,89,0,144,1,110,42,48,0,122,14,124,0,160,3, + 124,2,161,1,125,9,87,0,110,20,4,0,116,4,121,102, + 1,0,1,0,1,0,89,0,144,1,110,6,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,18,4,0,116,4,121,148, + 1,0,1,0,1,0,89,0,110,216,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,30,124,12,100,9,64,0,100,8,107,3, + 125,7,116,9,106,10,100,10,107,3,144,1,114,50,124,7, + 115,248,116,9,106,10,100,11,107,2,144,1,114,50,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,24,4,0,116,15, + 116,16,102,2,144,1,121,76,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,117,0,144,1,114,128,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,20,124,8,100,1,117,1,144,2,114,20, + 124,3,100,1,117,1,144,2,114,20,124,6,144,1,114,220, + 124,5,100,1,117,0,144,1,114,206,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,20,4,0,116,2,144,2,121,18,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,170,0,0,0,114,160,0,0,0,114,146,0, + 0,0,114,40,0,0,0,114,74,0,0,0,114,29,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,117,0,0,0,114,107,0,0, + 0,114,108,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,180,0, + 0,0,114,98,0,0,0,114,83,0,0,0,114,225,0,0, + 0,114,51,0,0,0,114,19,0,0,0,114,228,0,0,0, + 114,153,0,0,0,218,10,109,101,109,111,114,121,118,105,101, + 119,114,164,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,158,0, + 0,0,218,17,95,82,65,87,95,77,65,71,73,67,95,78, + 85,77,66,69,82,114,159,0,0,0,114,157,0,0,0,114, + 118,0,0,0,114,151,0,0,0,114,135,0,0,0,114,150, + 0,0,0,114,166,0,0,0,114,234,0,0,0,114,2,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,172,0,0,0,114,171,0,0, + 0,114,24,0,0,0,114,227,0,0,0,41,15,114,119,0, + 0,0,114,140,0,0,0,114,108,0,0,0,114,155,0,0, + 0,114,175,0,0,0,114,158,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,107,0,0,0,218,2,115,116,114,27, + 0,0,0,114,152,0,0,0,114,3,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,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,114,214,0,0,0,88,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,12,1,12,2,2,1,14,1,12,1,8, + 2,12,1,2,1,14,1,12,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,18,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,14,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,126,0,0,0,114,125,0,0,0,114, + 127,0,0,0,114,224,0,0,0,114,225,0,0,0,114,227, + 0,0,0,114,226,0,0,0,114,230,0,0,0,114,234,0, + 0,0,114,214,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,114,222,0,0,0, + 29,3,0,0,115,14,0,0,0,8,2,8,8,8,14,8, + 10,8,7,8,10,14,8,114,222,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,160,0,0,0, + 41,3,114,119,0,0,0,114,140,0,0,0,114,45,0,0, + 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, + 114,210,0,0,0,178,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,110,0, + 0,0,169,2,218,9,95,95,99,108,97,115,115,95,95,114, + 132,0,0,0,169,2,114,119,0,0,0,90,5,111,116,104, + 101,114,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,218,6,95,95,101,113,95,95,184,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,110,0, + 0,0,169,3,218,4,104,97,115,104,114,117,0,0,0,114, + 45,0,0,0,169,1,114,119,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,218,8,95,95,104,97, + 115,104,95,95,188,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,240,0,0,0,114,221,0,0,0,114,220,0, + 0,0,169,1,114,242,0,0,0,114,6,0,0,0,114,9, + 0,0,0,114,221,0,0,0,191,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,49,0, + 0,0,114,220,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,9,0,0,0,114,180,0,0,0,203,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,162,0,0, + 0,114,222,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,65,0,0,0, + 90,9,111,112,101,110,95,99,111,100,101,114,85,0,0,0, + 90,4,114,101,97,100,114,66,0,0,0,41,3,114,119,0, + 0,0,114,45,0,0,0,114,69,0,0,0,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,114,228,0,0,0, + 208,3,0,0,115,10,0,0,0,0,2,14,1,16,1,40, + 2,14,1,122,19,70,105,108,101,76,111,97,100,101,114,46, + 103,101,116,95,100,97,116,97,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,18,0,0,0,124,0,160,0,124,1,161,1,114,14, + 124,0,83,0,100,0,83,0,114,110,0,0,0,41,1,114, + 183,0,0,0,169,2,114,119,0,0,0,114,217,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, + 19,103,101,116,95,114,101,115,111,117,114,99,101,95,114,101, + 97,100,101,114,219,3,0,0,115,6,0,0,0,0,2,10, + 1,4,1,122,30,70,105,108,101,76,111,97,100,101,114,46, + 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, + 100,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,4,0,0,0,67,0,0,0,115,32,0,0, + 0,116,0,116,1,124,0,106,2,131,1,100,1,25,0,124, + 1,131,2,125,2,116,3,160,4,124,2,100,2,161,2,83, + 0,41,3,78,114,74,0,0,0,114,252,0,0,0,41,5, + 114,39,0,0,0,114,48,0,0,0,114,45,0,0,0,114, + 65,0,0,0,114,66,0,0,0,169,3,114,119,0,0,0, + 90,8,114,101,115,111,117,114,99,101,114,45,0,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,13, + 111,112,101,110,95,114,101,115,111,117,114,99,101,225,3,0, + 0,115,4,0,0,0,0,1,20,1,122,24,70,105,108,101, + 76,111,97,100,101,114,46,111,112,101,110,95,114,101,115,111, + 117,114,99,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,3,0,0,0,67,0,0,0,115,38,0, + 0,0,124,0,160,0,124,1,161,1,115,14,116,1,130,1, + 116,2,116,3,124,0,106,4,131,1,100,1,25,0,124,1, + 131,2,125,2,124,2,83,0,169,2,78,114,74,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,39,0,0,0,114,48,0,0,0,114,45,0,0, + 0,114,0,1,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,13,114,101,115,111,117,114,99,101,95, + 112,97,116,104,229,3,0,0,115,8,0,0,0,0,1,10, + 1,4,1,20,1,122,24,70,105,108,101,76,111,97,100,101, + 114,46,114,101,115,111,117,114,99,101,95,112,97,116,104,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,67,0,0,0,115,40,0,0,0,116,0,124, + 1,118,0,114,12,100,1,83,0,116,1,116,2,124,0,106, + 3,131,1,100,2,25,0,124,1,131,2,125,2,116,4,124, + 2,131,1,83,0,41,3,78,70,114,74,0,0,0,41,5, + 114,36,0,0,0,114,39,0,0,0,114,48,0,0,0,114, + 45,0,0,0,114,55,0,0,0,169,3,114,119,0,0,0, + 114,117,0,0,0,114,45,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,114,3,1,0,0,235,3, + 0,0,115,8,0,0,0,0,1,8,1,4,1,20,1,122, + 22,70,105,108,101,76,111,97,100,101,114,46,105,115,95,114, + 101,115,111,117,114,99,101,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0, + 115,24,0,0,0,116,0,116,1,160,2,116,3,124,0,106, + 4,131,1,100,1,25,0,161,1,131,1,83,0,114,2,1, + 0,0,41,5,218,4,105,116,101,114,114,5,0,0,0,218, + 7,108,105,115,116,100,105,114,114,48,0,0,0,114,45,0, + 0,0,114,247,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,9,0,0,0,218,8,99,111,110,116,101,110,116,115, + 241,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108, + 101,76,111,97,100,101,114,46,99,111,110,116,101,110,116,115, + 41,17,114,126,0,0,0,114,125,0,0,0,114,127,0,0, + 0,114,128,0,0,0,114,210,0,0,0,114,244,0,0,0, + 114,248,0,0,0,114,137,0,0,0,114,221,0,0,0,114, + 180,0,0,0,114,228,0,0,0,114,255,0,0,0,114,1, + 1,0,0,114,5,1,0,0,114,3,1,0,0,114,9,1, + 0,0,90,13,95,95,99,108,97,115,115,99,101,108,108,95, + 95,114,6,0,0,0,114,6,0,0,0,114,250,0,0,0, + 114,9,0,0,0,114,240,0,0,0,173,3,0,0,115,30, + 0,0,0,8,2,4,3,8,6,8,4,8,3,2,1,14, + 11,2,1,10,4,8,11,2,1,10,5,8,4,8,6,8, + 6,114,240,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,170,0,0,0,114,235,0,0,0,41,3,114,50,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,119,0,0,0,114,45,0,0, + 0,114,239,0,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,114,225,0,0,0,249,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,115,0,0,0,114,226,0, + 0,0,41,5,114,119,0,0,0,114,108,0,0,0,114,107, + 0,0,0,114,27,0,0,0,114,53,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,227,0,0, + 0,254,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,61,0,0,0,114,12,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,104,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,121,110,1,0,1,0,1,0,89,0, + 113,60,89,0,113,60,4,0,116,8,121,162,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,52,4,0,116,8, + 144,0,121,246,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,48,0,0,0,114,57,0,0,0,114,187,0,0,0, + 114,43,0,0,0,114,39,0,0,0,114,5,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,51,0,0,0,114,135,0,0, + 0,114,150,0,0,0,114,70,0,0,0,41,9,114,119,0, + 0,0,114,45,0,0,0,114,27,0,0,0,114,13,1,0, + 0,218,6,112,97,114,101,110,116,114,97,0,0,0,114,38, + 0,0,0,114,34,0,0,0,114,229,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,226,0,0, + 0,3,4,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,12,2, + 8,1,14,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,126,0,0,0,114,125,0, + 0,0,114,127,0,0,0,114,128,0,0,0,114,225,0,0, + 0,114,227,0,0,0,114,226,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, + 10,1,0,0,245,3,0,0,115,8,0,0,0,8,2,4, + 2,8,5,8,5,114,10,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,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,160,0,0,0,114,146,0,0,0,41,2, + 114,117,0,0,0,114,107,0,0,0,41,5,114,180,0,0, + 0,114,228,0,0,0,114,153,0,0,0,114,166,0,0,0, + 114,236,0,0,0,41,5,114,119,0,0,0,114,140,0,0, + 0,114,45,0,0,0,114,27,0,0,0,114,152,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, + 214,0,0,0,38,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,6,0,0,0,114,220,0,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,114,230,0,0,0,54,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,126,0, + 0,0,114,125,0,0,0,114,127,0,0,0,114,128,0,0, + 0,114,214,0,0,0,114,230,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, + 16,1,0,0,34,4,0,0,115,6,0,0,0,8,2,4, + 2,8,16,114,16,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,253,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,110,0,0,0,114,160,0,0,0, + 114,6,1,0,0,114,6,0,0,0,114,6,0,0,0,114, + 9,0,0,0,114,210,0,0,0,71,4,0,0,115,4,0, + 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, + 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,0, + 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, + 106,1,124,1,106,1,107,2,83,0,114,110,0,0,0,114, + 241,0,0,0,114,243,0,0,0,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,114,244,0,0,0,75,4,0, + 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, + 0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,0, + 124,0,106,2,131,1,65,0,83,0,114,110,0,0,0,114, + 245,0,0,0,114,247,0,0,0,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,114,248,0,0,0,79,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,135,0,0, + 0,114,215,0,0,0,114,164,0,0,0,90,14,99,114,101, + 97,116,101,95,100,121,110,97,109,105,99,114,150,0,0,0, + 114,117,0,0,0,114,45,0,0,0,41,3,114,119,0,0, + 0,114,188,0,0,0,114,217,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,213,0,0,0,82, + 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,135, + 0,0,0,114,215,0,0,0,114,164,0,0,0,90,12,101, + 120,101,99,95,100,121,110,97,109,105,99,114,150,0,0,0, + 114,117,0,0,0,114,45,0,0,0,114,254,0,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,218, + 0,0,0,90,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,40, + 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,210,0, + 0,0,78,114,6,0,0,0,169,2,114,33,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,6,0,0,0,114,9,0,0,0,218,9, + 60,103,101,110,101,120,112,114,62,99,4,0,0,115,4,0, + 0,0,4,1,2,255,122,49,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, + 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, + 60,103,101,110,101,120,112,114,62,41,4,114,48,0,0,0, + 114,45,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,220, + 0,0,0,114,6,0,0,0,114,19,1,0,0,114,9,0, + 0,0,114,183,0,0,0,96,4,0,0,115,8,0,0,0, + 0,2,14,1,12,1,2,255,122,30,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, + 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,1,83,0,41,2,122,63,82,101, + 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, + 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,6, + 0,0,0,114,220,0,0,0,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,114,214,0,0,0,102,4,0,0, + 115,2,0,0,0,0,2,122,28,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,122,53,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,101,120,116,101,110,115, + 105,111,110,32,109,111,100,117,108,101,115,32,104,97,118,101, + 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, + 78,114,6,0,0,0,114,220,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,230,0,0,0,106, + 4,0,0,115,2,0,0,0,0,2,122,30,69,120,116,101, + 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,6,0,0,0,124,0,106,0,83,0,114,251, + 0,0,0,114,49,0,0,0,114,220,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,180,0,0, + 0,110,4,0,0,115,2,0,0,0,0,3,122,32,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, + 14,114,126,0,0,0,114,125,0,0,0,114,127,0,0,0, + 114,128,0,0,0,114,210,0,0,0,114,244,0,0,0,114, + 248,0,0,0,114,213,0,0,0,114,218,0,0,0,114,183, + 0,0,0,114,214,0,0,0,114,230,0,0,0,114,137,0, + 0,0,114,180,0,0,0,114,6,0,0,0,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,114,253,0,0,0, + 63,4,0,0,115,22,0,0,0,8,2,4,6,8,4,8, + 4,8,3,8,8,8,6,8,6,8,4,8,4,2,1,114, + 253,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,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,178,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,184,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,188,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, - 191,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,203,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,208,3,0,0,115,10,0,0, - 0,0,2,14,1,16,1,40,2,14,1,122,19,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,100,97,116,97, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,3,0,0,0,67,0,0,0,115,18,0,0,0,124,0, - 160,0,124,1,161,1,114,14,124,0,83,0,100,0,83,0, - 114,109,0,0,0,41,1,114,182,0,0,0,169,2,114,118, - 0,0,0,114,216,0,0,0,114,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,219,3,0,0, - 115,6,0,0,0,0,2,10,1,4,1,122,30,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,114,101,115,111, - 117,114,99,101,95,114,101,97,100,101,114,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, - 67,0,0,0,115,32,0,0,0,116,0,116,1,124,0,106, - 2,131,1,100,1,25,0,124,1,131,2,125,2,116,3,160, - 4,124,2,100,2,161,2,83,0,41,3,78,114,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,225,3,0,0,115,4,0,0,0,0,1, - 20,1,122,24,70,105,108,101,76,111,97,100,101,114,46,111, - 112,101,110,95,114,101,115,111,117,114,99,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, - 0,67,0,0,0,115,38,0,0,0,124,0,160,0,124,1, - 161,1,115,14,116,1,130,1,116,2,116,3,124,0,106,4, - 131,1,100,1,25,0,124,1,131,2,125,2,124,2,83,0, - 169,2,78,114,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,229,3,0,0, - 115,8,0,0,0,0,1,10,1,4,1,20,1,122,24,70, - 105,108,101,76,111,97,100,101,114,46,114,101,115,111,117,114, - 99,101,95,112,97,116,104,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, - 115,40,0,0,0,116,0,124,1,118,0,114,12,100,1,83, - 0,116,1,116,2,124,0,106,3,131,1,100,2,25,0,124, - 1,131,2,125,2,116,4,124,2,131,1,83,0,41,3,78, - 70,114,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,235,3,0,0,115,8,0,0,0,0, - 1,8,1,4,1,20,1,122,22,70,105,108,101,76,111,97, - 100,101,114,46,105,115,95,114,101,115,111,117,114,99,101,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 5,0,0,0,67,0,0,0,115,24,0,0,0,116,0,116, - 1,160,2,116,3,124,0,106,4,131,1,100,1,25,0,161, - 1,131,1,83,0,114,1,1,0,0,41,5,218,4,105,116, - 101,114,114,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,241,3,0,0,115,2,0,0, - 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, - 99,111,110,116,101,110,116,115,41,17,114,125,0,0,0,114, - 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,209, - 0,0,0,114,243,0,0,0,114,247,0,0,0,114,136,0, - 0,0,114,220,0,0,0,114,179,0,0,0,114,227,0,0, - 0,114,254,0,0,0,114,0,1,0,0,114,4,1,0,0, - 114,2,1,0,0,114,8,1,0,0,90,13,95,95,99,108, - 97,115,115,99,101,108,108,95,95,114,3,0,0,0,114,3, - 0,0,0,114,249,0,0,0,114,6,0,0,0,114,239,0, - 0,0,173,3,0,0,115,30,0,0,0,8,2,4,3,8, - 6,8,4,8,3,2,1,14,11,2,1,10,4,8,11,2, - 1,10,5,8,4,8,6,8,6,114,239,0,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,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,249,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,254,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,104,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,121,110, - 1,0,1,0,1,0,89,0,113,60,89,0,113,60,4,0, - 116,8,121,162,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,52,4,0,116,8,144,0,121,246,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,3,4,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,12,2,8,1,14,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,245,3,0,0, - 115,8,0,0,0,8,2,4,2,8,5,8,5,114,9,1, + 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,110,0,0,0,41,6, + 218,5,95,110,97,109,101,218,5,95,112,97,116,104,114,112, + 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,119,0,0,0,114,117,0, + 0,0,114,45,0,0,0,90,11,112,97,116,104,95,102,105, + 110,100,101,114,114,6,0,0,0,114,6,0,0,0,114,9, + 0,0,0,114,210,0,0,0,123,4,0,0,115,8,0,0, + 0,0,1,6,1,6,1,14,1,122,23,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,95,105,110,105,116, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 124,0,106,0,160,1,100,1,161,1,92,3,125,1,125,2, + 125,3,124,2,100,2,107,2,114,30,100,3,83,0,124,1, + 100,4,102,2,83,0,41,5,122,62,82,101,116,117,114,110, + 115,32,97,32,116,117,112,108,101,32,111,102,32,40,112,97, + 114,101,110,116,45,109,111,100,117,108,101,45,110,97,109,101, + 44,32,112,97,114,101,110,116,45,112,97,116,104,45,97,116, + 116,114,45,110,97,109,101,41,114,72,0,0,0,114,41,0, + 0,0,41,2,114,2,0,0,0,114,45,0,0,0,90,8, + 95,95,112,97,116,104,95,95,41,2,114,24,1,0,0,114, + 42,0,0,0,41,4,114,119,0,0,0,114,15,1,0,0, + 218,3,100,111,116,90,2,109,101,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,218,23,95,102,105,110,100,95, + 112,97,114,101,110,116,95,112,97,116,104,95,110,97,109,101, + 115,129,4,0,0,115,8,0,0,0,0,2,18,1,8,2, + 4,3,122,38,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,102,105,110,100,95,112,97,114,101,110,116,95, + 112,97,116,104,95,110,97,109,101,115,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,28,0,0,0,124,0,160,0,161,0,92,2, + 125,1,125,2,116,1,116,2,106,3,124,1,25,0,124,2, + 131,2,83,0,114,110,0,0,0,41,4,114,31,1,0,0, + 114,131,0,0,0,114,2,0,0,0,218,7,109,111,100,117, + 108,101,115,41,3,114,119,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,6, + 0,0,0,114,6,0,0,0,114,9,0,0,0,114,26,1, + 0,0,139,4,0,0,115,4,0,0,0,0,1,12,1,122, + 31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,4,0,0,0,67,0,0,0,115,80,0,0,0,116,0, + 124,0,160,1,161,0,131,1,125,1,124,1,124,0,106,2, + 107,3,114,74,124,0,160,3,124,0,106,4,124,1,161,2, + 125,2,124,2,100,0,117,1,114,68,124,2,106,5,100,0, + 117,0,114,68,124,2,106,6,114,68,124,2,106,6,124,0, + 95,7,124,1,124,0,95,2,124,0,106,7,83,0,114,110, + 0,0,0,41,8,114,112,0,0,0,114,26,1,0,0,114, + 27,1,0,0,114,28,1,0,0,114,24,1,0,0,114,141, + 0,0,0,114,179,0,0,0,114,25,1,0,0,41,3,114, + 119,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116, + 104,114,188,0,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,12,95,114,101,99,97,108,99,117,108, + 97,116,101,143,4,0,0,115,16,0,0,0,0,2,12,1, + 10,1,14,3,18,1,6,1,8,1,6,1,122,27,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101, + 99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, + 1,83,0,114,110,0,0,0,41,2,114,7,1,0,0,114, + 33,1,0,0,114,247,0,0,0,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,218,8,95,95,105,116,101,114, + 95,95,156,4,0,0,115,2,0,0,0,0,1,122,23,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, + 105,116,101,114,95,95,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 12,0,0,0,124,0,160,0,161,0,124,1,25,0,83,0, + 114,110,0,0,0,169,1,114,33,1,0,0,41,2,114,119, + 0,0,0,218,5,105,110,100,101,120,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,218,11,95,95,103,101,116, + 105,116,101,109,95,95,159,4,0,0,115,2,0,0,0,0, + 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,95,95,103,101,116,105,116,101,109,95,95,99,3,0, + 0,0,0,0,0,0,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,110,0,0,0,41,1, + 114,25,1,0,0,41,3,114,119,0,0,0,114,36,1,0, + 0,114,45,0,0,0,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,11,95,95,115,101,116,105,116,101,109, + 95,95,162,4,0,0,115,2,0,0,0,0,1,122,26,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, + 115,101,116,105,116,101,109,95,95,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, + 1,83,0,114,110,0,0,0,41,2,114,24,0,0,0,114, + 33,1,0,0,114,247,0,0,0,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,218,7,95,95,108,101,110,95, + 95,165,4,0,0,115,2,0,0,0,0,1,122,22,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,108, + 101,110,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,12,0, + 0,0,100,1,160,0,124,0,106,1,161,1,83,0,41,2, + 78,122,20,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,40,123,33,114,125,41,41,2,114,63,0,0,0,114,25, + 1,0,0,114,247,0,0,0,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,218,8,95,95,114,101,112,114,95, + 95,168,4,0,0,115,2,0,0,0,0,1,122,23,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114, + 101,112,114,95,95,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,12, + 0,0,0,124,1,124,0,160,0,161,0,118,0,83,0,114, + 110,0,0,0,114,35,1,0,0,169,2,114,119,0,0,0, + 218,4,105,116,101,109,114,6,0,0,0,114,6,0,0,0, + 114,9,0,0,0,218,12,95,95,99,111,110,116,97,105,110, + 115,95,95,171,4,0,0,115,2,0,0,0,0,1,122,27, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, + 95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,16,0,0,0,124,0,106,0,160,1,124, + 1,161,1,1,0,100,0,83,0,114,110,0,0,0,41,2, + 114,25,1,0,0,114,187,0,0,0,114,41,1,0,0,114, + 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,187, + 0,0,0,174,4,0,0,115,2,0,0,0,0,1,122,21, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,97, + 112,112,101,110,100,78,41,15,114,126,0,0,0,114,125,0, + 0,0,114,127,0,0,0,114,128,0,0,0,114,210,0,0, + 0,114,31,1,0,0,114,26,1,0,0,114,33,1,0,0, + 114,34,1,0,0,114,37,1,0,0,114,38,1,0,0,114, + 39,1,0,0,114,40,1,0,0,114,43,1,0,0,114,187, + 0,0,0,114,6,0,0,0,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,114,23,1,0,0,116,4,0,0, + 115,24,0,0,0,8,1,4,6,8,6,8,10,8,4,8, + 13,8,3,8,3,8,3,8,3,8,3,8,3,114,23,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,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,38,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,54,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,34,4,0,0, - 115,6,0,0,0,8,2,4,2,8,16,114,15,1,0,0, - 99,0,0,0,0,0,0,0,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,71,4,0,0,115,4,0,0,0,0,1,6,1,122,28, - 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, - 100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, - 0,67,0,0,0,115,24,0,0,0,124,0,106,0,124,1, - 106,0,107,2,111,22,124,0,106,1,124,1,106,1,107,2, - 83,0,114,109,0,0,0,114,240,0,0,0,114,242,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,243,0,0,0,75,4,0,0,115,6,0,0,0,0,1, - 12,1,10,255,122,26,69,120,116,101,110,115,105,111,110,70, - 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,20,0,0,0,116,0, - 124,0,106,1,131,1,116,0,124,0,106,2,131,1,65,0, - 83,0,114,109,0,0,0,114,244,0,0,0,114,246,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,247,0,0,0,79,4,0,0,115,2,0,0,0,0,1, - 122,28,69,120,116,101,110,115,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,82,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,90,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,99,4,0,0,115,4,0,0,0,4,1,2,255,122,49, - 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, - 100,101,114,46,105,115,95,112,97,99,107,97,103,101,46,60, - 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, - 62,41,4,114,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,96, - 4,0,0,115,8,0,0,0,0,2,14,1,12,1,2,255, - 122,30,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,46,105,115,95,112,97,99,107,97,103,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, - 83,0,41,2,122,63,82,101,116,117,114,110,32,78,111,110, - 101,32,97,115,32,97,110,32,101,120,116,101,110,115,105,111, - 110,32,109,111,100,117,108,101,32,99,97,110,110,111,116,32, - 99,114,101,97,116,101,32,97,32,99,111,100,101,32,111,98, - 106,101,99,116,46,78,114,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,102,4,0,0,115,2,0,0,0,0,2,122, - 28,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,103,101,116,95,99,111,100,101,99,2,0, + 0,0,0,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,110,0,0,0,41,2,114,23,1,0,0, + 114,25,1,0,0,114,29,1,0,0,114,6,0,0,0,114, + 6,0,0,0,114,9,0,0,0,114,210,0,0,0,180,4, + 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, + 115,112,97,99,101,76,111,97,100,101,114,46,95,95,105,110, + 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,67,0,0,0,115,12,0, + 0,0,100,1,160,0,124,1,106,1,161,1,83,0,41,2, + 122,115,82,101,116,117,114,110,32,114,101,112,114,32,102,111, + 114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,111, + 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, + 32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,99, + 104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,32, + 106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,32, + 32,32,32,32,32,122,25,60,109,111,100,117,108,101,32,123, + 33,114,125,32,40,110,97,109,101,115,112,97,99,101,41,62, + 41,2,114,63,0,0,0,114,126,0,0,0,41,2,114,194, + 0,0,0,114,217,0,0,0,114,6,0,0,0,114,6,0, + 0,0,114,9,0,0,0,218,11,109,111,100,117,108,101,95, + 114,101,112,114,183,4,0,0,115,2,0,0,0,0,7,122, + 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,109,111,100,117,108,101,95,114,101,112,114,99,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,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,106,4,0,0,115,2,0,0,0, - 0,2,122,30,69,120,116,101,110,115,105,111,110,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,6,0,0,0, - 124,0,106,0,83,0,114,250,0,0,0,114,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,110,4,0,0,115,2,0, - 0,0,0,3,122,32,69,120,116,101,110,115,105,111,110,70, - 105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105, - 108,101,110,97,109,101,78,41,14,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,209,0, - 0,0,114,243,0,0,0,114,247,0,0,0,114,212,0,0, - 0,114,217,0,0,0,114,182,0,0,0,114,213,0,0,0, - 114,229,0,0,0,114,136,0,0,0,114,179,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,252,0,0,0,63,4,0,0,115,22,0,0, - 0,8,2,4,6,8,4,8,4,8,3,8,8,8,6,8, - 6,8,4,8,4,2,1,114,252,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,64,0,0,0,115,104,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, - 100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8, - 100,9,132,0,90,7,100,10,100,11,132,0,90,8,100,12, - 100,13,132,0,90,9,100,14,100,15,132,0,90,10,100,16, - 100,17,132,0,90,11,100,18,100,19,132,0,90,12,100,20, - 100,21,132,0,90,13,100,22,100,23,132,0,90,14,100,24, - 83,0,41,25,218,14,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,97,38,1,0,0,82,101,112,114,101,115,101, - 110,116,115,32,97,32,110,97,109,101,115,112,97,99,101,32, - 112,97,99,107,97,103,101,39,115,32,112,97,116,104,46,32, - 32,73,116,32,117,115,101,115,32,116,104,101,32,109,111,100, - 117,108,101,32,110,97,109,101,10,32,32,32,32,116,111,32, - 102,105,110,100,32,105,116,115,32,112,97,114,101,110,116,32, - 109,111,100,117,108,101,44,32,97,110,100,32,102,114,111,109, - 32,116,104,101,114,101,32,105,116,32,108,111,111,107,115,32, - 117,112,32,116,104,101,32,112,97,114,101,110,116,39,115,10, - 32,32,32,32,95,95,112,97,116,104,95,95,46,32,32,87, - 104,101,110,32,116,104,105,115,32,99,104,97,110,103,101,115, - 44,32,116,104,101,32,109,111,100,117,108,101,39,115,32,111, - 119,110,32,112,97,116,104,32,105,115,32,114,101,99,111,109, - 112,117,116,101,100,44,10,32,32,32,32,117,115,105,110,103, - 32,112,97,116,104,95,102,105,110,100,101,114,46,32,32,70, - 111,114,32,116,111,112,45,108,101,118,101,108,32,109,111,100, - 117,108,101,115,44,32,116,104,101,32,112,97,114,101,110,116, - 32,109,111,100,117,108,101,39,115,32,112,97,116,104,10,32, - 32,32,32,105,115,32,115,121,115,46,112,97,116,104,46,99, - 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 3,0,0,0,67,0,0,0,115,36,0,0,0,124,1,124, - 0,95,0,124,2,124,0,95,1,116,2,124,0,160,3,161, - 0,131,1,124,0,95,4,124,3,124,0,95,5,100,0,83, - 0,114,109,0,0,0,41,6,218,5,95,110,97,109,101,218, - 5,95,112,97,116,104,114,111,0,0,0,218,16,95,103,101, - 116,95,112,97,114,101,110,116,95,112,97,116,104,218,17,95, - 108,97,115,116,95,112,97,114,101,110,116,95,112,97,116,104, - 218,12,95,112,97,116,104,95,102,105,110,100,101,114,169,4, - 114,118,0,0,0,114,116,0,0,0,114,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, - 123,4,0,0,115,8,0,0,0,0,1,6,1,6,1,14, - 1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,105,110,105,116,95,95,99,1,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,124,0,106,0,160,1,100,1, - 161,1,92,3,125,1,125,2,125,3,124,2,100,2,107,2, - 114,30,100,3,83,0,124,1,100,4,102,2,83,0,41,5, - 122,62,82,101,116,117,114,110,115,32,97,32,116,117,112,108, - 101,32,111,102,32,40,112,97,114,101,110,116,45,109,111,100, - 117,108,101,45,110,97,109,101,44,32,112,97,114,101,110,116, - 45,112,97,116,104,45,97,116,116,114,45,110,97,109,101,41, - 114,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,129,4,0,0,115,8,0, - 0,0,0,2,18,1,8,2,4,3,122,38,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,102,105,110,100, - 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, - 101,115,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,28,0,0,0, - 124,0,160,0,161,0,92,2,125,1,125,2,116,1,116,2, - 106,3,124,1,25,0,124,2,131,2,83,0,114,109,0,0, - 0,41,4,114,30,1,0,0,114,130,0,0,0,114,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,139,4,0,0,115,4, - 0,0,0,0,1,12,1,122,31,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,103,101,116,95,112,97,114, - 101,110,116,95,112,97,116,104,99,1,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0, - 0,115,80,0,0,0,116,0,124,0,160,1,161,0,131,1, - 125,1,124,1,124,0,106,2,107,3,114,74,124,0,160,3, - 124,0,106,4,124,1,161,2,125,2,124,2,100,0,117,1, - 114,68,124,2,106,5,100,0,117,0,114,68,124,2,106,6, - 114,68,124,2,106,6,124,0,95,7,124,1,124,0,95,2, - 124,0,106,7,83,0,114,109,0,0,0,41,8,114,111,0, - 0,0,114,25,1,0,0,114,26,1,0,0,114,27,1,0, - 0,114,23,1,0,0,114,140,0,0,0,114,178,0,0,0, - 114,24,1,0,0,41,3,114,118,0,0,0,90,11,112,97, - 114,101,110,116,95,112,97,116,104,114,187,0,0,0,114,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,143,4,0,0,115, - 16,0,0,0,0,2,12,1,10,1,14,3,18,1,6,1, - 8,1,6,1,122,27,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,114,101,99,97,108,99,117,108,97,116, - 101,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,116, - 0,124,0,160,1,161,0,131,1,83,0,114,109,0,0,0, - 41,2,114,6,1,0,0,114,32,1,0,0,114,246,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,8,95,95,105,116,101,114,95,95,156,4,0,0,115,2, - 0,0,0,0,1,122,23,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,105,116,101,114,95,95,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,0,67,0,0,0,115,12,0,0,0,124,0,160,0, - 161,0,124,1,25,0,83,0,114,109,0,0,0,169,1,114, - 32,1,0,0,41,2,114,118,0,0,0,218,5,105,110,100, - 101,120,114,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,159,4, - 0,0,115,2,0,0,0,0,1,122,26,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,95,103,101,116,105, - 116,101,109,95,95,99,3,0,0,0,0,0,0,0,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,162,4,0,0,115,2, - 0,0,0,0,1,122,26,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,115,101,116,105,116,101,109,95, - 95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,116, - 0,124,0,160,1,161,0,131,1,83,0,114,109,0,0,0, - 41,2,114,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,165,4,0,0,115,2,0, - 0,0,0,1,122,22,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,95,108,101,110,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,12,0,0,0,100,1,160,0,124,0, - 106,1,161,1,83,0,41,2,78,122,20,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,40,123,33,114,125,41,41, - 2,114,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,168,4,0,0,115,2,0, - 0,0,0,1,122,23,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,95,114,101,112,114,95,95,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,67,0,0,0,115,12,0,0,0,124,1,124,0,160, - 0,161,0,118,0,83,0,114,109,0,0,0,114,34,1,0, - 0,169,2,114,118,0,0,0,218,4,105,116,101,109,114,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,171,4,0,0,115, - 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,95,99,111,110,116,97,105,110, - 115,95,95,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,3,0,0,0,67,0,0,0,115,16,0,0, - 0,124,0,106,0,160,1,124,1,161,1,1,0,100,0,83, - 0,114,109,0,0,0,41,2,114,24,1,0,0,114,186,0, - 0,0,114,40,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,186,0,0,0,174,4,0,0,115, - 2,0,0,0,0,1,122,21,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,97,112,112,101,110,100,78,41,15, - 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, - 127,0,0,0,114,209,0,0,0,114,30,1,0,0,114,25, - 1,0,0,114,32,1,0,0,114,33,1,0,0,114,36,1, - 0,0,114,37,1,0,0,114,38,1,0,0,114,39,1,0, - 0,114,42,1,0,0,114,186,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 22,1,0,0,116,4,0,0,115,24,0,0,0,8,1,4, - 6,8,6,8,10,8,4,8,13,8,3,8,3,8,3,8, - 3,8,3,8,3,114,22,1,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, - 0,0,0,115,80,0,0,0,101,0,90,1,100,0,90,2, - 100,1,100,2,132,0,90,3,101,4,100,3,100,4,132,0, - 131,1,90,5,100,5,100,6,132,0,90,6,100,7,100,8, - 132,0,90,7,100,9,100,10,132,0,90,8,100,11,100,12, - 132,0,90,9,100,13,100,14,132,0,90,10,100,15,100,16, - 132,0,90,11,100,17,83,0,41,18,218,16,95,78,97,109, - 101,115,112,97,99,101,76,111,97,100,101,114,99,4,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, - 0,67,0,0,0,115,18,0,0,0,116,0,124,1,124,2, - 124,3,131,3,124,0,95,1,100,0,83,0,114,109,0,0, - 0,41,2,114,22,1,0,0,114,24,1,0,0,114,28,1, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,209,0,0,0,180,4,0,0,115,2,0,0,0,0, + 2,78,84,114,6,0,0,0,114,220,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,183,0,0, + 0,192,4,0,0,115,2,0,0,0,0,1,122,27,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,78,114,41, + 0,0,0,114,6,0,0,0,114,220,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,230,0,0, + 0,195,4,0,0,115,2,0,0,0,0,1,122,27,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, + 0,0,115,16,0,0,0,116,0,100,1,100,2,100,3,100, + 4,100,5,141,4,83,0,41,6,78,114,41,0,0,0,122, + 8,60,115,116,114,105,110,103,62,114,216,0,0,0,84,41, + 1,114,232,0,0,0,41,1,114,233,0,0,0,114,220,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,114,214,0,0,0,198,4,0,0,115,2,0,0,0,0, 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,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,183,4,0,0, - 115,2,0,0,0,0,7,122,28,95,78,97,109,101,115,112, - 97,99,101,76,111,97,100,101,114,46,109,111,100,117,108,101, - 95,114,101,112,114,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, - 0,0,0,100,1,83,0,41,2,78,84,114,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,192,4,0,0,115,2,0, - 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,83,0,41,2,78,114,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,195,4,0,0,115,2,0, - 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,6,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,100,1,100,2,100,3,100,4,100,5,141,4,83,0,41, - 6,78,114,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,198,4, - 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, - 0,0,100,1,83,0,114,210,0,0,0,114,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,201,4,0,0,115,2,0, - 0,0,0,1,122,30,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,99,114,101,97,116,101,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, - 0,0,100,0,83,0,114,109,0,0,0,114,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,204,4,0,0,115,2,0, - 0,0,0,1,122,28,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,67,0,0,0,115,26,0,0,0, - 116,0,160,1,100,1,124,0,106,2,161,2,1,0,116,0, - 160,3,124,0,124,1,161,2,83,0,41,2,122,98,76,111, - 97,100,32,97,32,110,97,109,101,115,112,97,99,101,32,109, - 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, - 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, - 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 122,38,110,97,109,101,115,112,97,99,101,32,109,111,100,117, - 108,101,32,108,111,97,100,101,100,32,119,105,116,104,32,112, - 97,116,104,32,123,33,114,125,41,4,114,134,0,0,0,114, - 149,0,0,0,114,24,1,0,0,114,218,0,0,0,114,219, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,220,0,0,0,207,4,0,0,115,8,0,0,0, - 0,7,6,1,4,255,4,2,122,28,95,78,97,109,101,115, - 112,97,99,101,76,111,97,100,101,114,46,108,111,97,100,95, - 109,111,100,117,108,101,78,41,12,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,209,0,0,0,114,207,0, - 0,0,114,44,1,0,0,114,182,0,0,0,114,229,0,0, - 0,114,213,0,0,0,114,212,0,0,0,114,217,0,0,0, - 114,220,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,43,1,0,0,179,4, - 0,0,115,18,0,0,0,8,1,8,3,2,1,10,8,8, - 3,8,3,8,3,8,3,8,3,114,43,1,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,64,0,0,0,115,118,0,0,0,101,0,90,1, - 100,0,90,2,100,1,90,3,101,4,100,2,100,3,132,0, - 131,1,90,5,101,4,100,4,100,5,132,0,131,1,90,6, - 101,4,100,6,100,7,132,0,131,1,90,7,101,4,100,8, - 100,9,132,0,131,1,90,8,101,4,100,19,100,11,100,12, - 132,1,131,1,90,9,101,4,100,20,100,13,100,14,132,1, - 131,1,90,10,101,4,100,21,100,15,100,16,132,1,131,1, - 90,11,101,4,100,17,100,18,132,0,131,1,90,12,100,10, - 83,0,41,22,218,10,80,97,116,104,70,105,110,100,101,114, - 122,62,77,101,116,97,32,112,97,116,104,32,102,105,110,100, - 101,114,32,102,111,114,32,115,121,115,46,112,97,116,104,32, - 97,110,100,32,112,97,99,107,97,103,101,32,95,95,112,97, - 116,104,95,95,32,97,116,116,114,105,98,117,116,101,115,46, - 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,64,0,0,0,116,0, - 116,1,106,2,160,3,161,0,131,1,68,0,93,44,92,2, - 125,1,125,2,124,2,100,1,117,0,114,40,116,1,106,2, - 124,1,61,0,113,14,116,4,124,2,100,2,131,2,114,14, - 124,2,160,5,161,0,1,0,113,14,100,1,83,0,41,3, - 122,125,67,97,108,108,32,116,104,101,32,105,110,118,97,108, - 105,100,97,116,101,95,99,97,99,104,101,115,40,41,32,109, - 101,116,104,111,100,32,111,110,32,97,108,108,32,112,97,116, - 104,32,101,110,116,114,121,32,102,105,110,100,101,114,115,10, - 32,32,32,32,32,32,32,32,115,116,111,114,101,100,32,105, - 110,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, - 116,101,114,95,99,97,99,104,101,115,32,40,119,104,101,114, - 101,32,105,109,112,108,101,109,101,110,116,101,100,41,46,78, - 218,17,105,110,118,97,108,105,100,97,116,101,95,99,97,99, - 104,101,115,41,6,218,4,108,105,115,116,114,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,225,4, - 0,0,115,10,0,0,0,0,4,22,1,8,1,10,1,10, - 1,122,28,80,97,116,104,70,105,110,100,101,114,46,105,110, - 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 9,0,0,0,67,0,0,0,115,82,0,0,0,116,0,106, - 1,100,1,117,1,114,28,116,0,106,1,115,28,116,2,160, - 3,100,2,116,4,161,2,1,0,116,0,106,1,68,0,93, - 42,125,2,122,14,124,2,124,1,131,1,87,0,2,0,1, - 0,83,0,4,0,116,5,121,74,1,0,1,0,1,0,89, - 0,113,34,89,0,113,34,48,0,113,34,100,1,83,0,41, - 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, - 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, - 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, - 107,115,32,105,115,32,101,109,112,116,121,41,6,114,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, - 235,4,0,0,115,16,0,0,0,0,3,16,1,12,1,10, - 1,2,1,14,1,12,1,12,2,122,22,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, - 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,8,0,0,0,67,0,0,0,115,100,0,0,0,124, - 1,100,1,107,2,114,42,122,12,116,0,160,1,161,0,125, - 1,87,0,110,20,4,0,116,2,121,40,1,0,1,0,1, - 0,89,0,100,2,83,0,48,0,122,14,116,3,106,4,124, - 1,25,0,125,2,87,0,110,38,4,0,116,5,121,94,1, - 0,1,0,1,0,124,0,160,6,124,1,161,1,125,2,124, - 2,116,3,106,4,124,1,60,0,89,0,110,2,48,0,124, - 2,83,0,41,3,122,210,71,101,116,32,116,104,101,32,102, - 105,110,100,101,114,32,102,111,114,32,116,104,101,32,112,97, - 116,104,32,101,110,116,114,121,32,102,114,111,109,32,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,248, - 4,0,0,115,22,0,0,0,0,8,8,1,2,1,12,1, - 12,3,8,1,2,1,14,1,12,1,10,1,16,1,122,31, - 80,97,116,104,70,105,110,100,101,114,46,95,112,97,116,104, - 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,99, - 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, - 4,0,0,0,67,0,0,0,115,82,0,0,0,116,0,124, - 2,100,1,131,2,114,26,124,2,160,1,124,1,161,1,92, - 2,125,3,125,4,110,14,124,2,160,2,124,1,161,1,125, - 3,103,0,125,4,124,3,100,0,117,1,114,60,116,3,160, - 4,124,1,124,3,161,2,83,0,116,3,160,5,124,1,100, - 0,161,2,125,5,124,4,124,5,95,6,124,5,83,0,41, - 2,78,114,137,0,0,0,41,7,114,128,0,0,0,114,137, - 0,0,0,114,206,0,0,0,114,134,0,0,0,114,201,0, - 0,0,114,183,0,0,0,114,178,0,0,0,41,6,114,193, - 0,0,0,114,139,0,0,0,114,50,1,0,0,114,140,0, - 0,0,114,141,0,0,0,114,187,0,0,0,114,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,14,5,0, - 0,115,18,0,0,0,0,4,10,1,16,2,10,1,4,1, - 8,1,12,1,12,1,6,1,122,27,80,97,116,104,70,105, - 110,100,101,114,46,95,108,101,103,97,99,121,95,103,101,116, - 95,115,112,101,99,78,99,4,0,0,0,0,0,0,0,0, - 0,0,0,9,0,0,0,5,0,0,0,67,0,0,0,115, - 166,0,0,0,103,0,125,4,124,2,68,0,93,134,125,5, - 116,0,124,5,116,1,116,2,102,2,131,2,115,28,113,8, - 124,0,160,3,124,5,161,1,125,6,124,6,100,1,117,1, - 114,8,116,4,124,6,100,2,131,2,114,70,124,6,160,5, - 124,1,124,3,161,2,125,7,110,12,124,0,160,6,124,1, - 124,6,161,2,125,7,124,7,100,1,117,0,114,92,113,8, - 124,7,106,7,100,1,117,1,114,110,124,7,2,0,1,0, - 83,0,124,7,106,8,125,8,124,8,100,1,117,0,114,132, - 116,9,100,3,131,1,130,1,124,4,160,10,124,8,161,1, - 1,0,113,8,116,11,160,12,124,1,100,1,161,2,125,7, - 124,4,124,7,95,8,124,7,83,0,41,4,122,63,70,105, - 110,100,32,116,104,101,32,108,111,97,100,101,114,32,111,114, - 32,110,97,109,101,115,112,97,99,101,95,112,97,116,104,32, - 102,111,114,32,116,104,105,115,32,109,111,100,117,108,101,47, - 112,97,99,107,97,103,101,32,110,97,109,101,46,78,114,203, - 0,0,0,122,19,115,112,101,99,32,109,105,115,115,105,110, - 103,32,108,111,97,100,101,114,41,13,114,161,0,0,0,114, - 84,0,0,0,218,5,98,121,116,101,115,114,54,1,0,0, - 114,128,0,0,0,114,203,0,0,0,114,55,1,0,0,114, - 140,0,0,0,114,178,0,0,0,114,117,0,0,0,114,167, - 0,0,0,114,134,0,0,0,114,183,0,0,0,41,9,114, - 193,0,0,0,114,139,0,0,0,114,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,29,5,0,0,115,40,0,0,0,0,5,4,1, - 8,1,14,1,2,1,10,1,8,1,10,1,14,2,12,1, - 8,1,2,1,10,1,8,1,6,1,8,1,8,5,12,2, - 12,1,6,1,122,20,80,97,116,104,70,105,110,100,101,114, - 46,95,103,101,116,95,115,112,101,99,99,4,0,0,0,0, - 0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,67, - 0,0,0,115,100,0,0,0,124,2,100,1,117,0,114,14, - 116,0,106,1,125,2,124,0,160,2,124,1,124,2,124,3, - 161,3,125,4,124,4,100,1,117,0,114,40,100,1,83,0, - 124,4,106,3,100,1,117,0,114,92,124,4,106,4,125,5, - 124,5,114,86,100,1,124,4,95,5,116,6,124,1,124,5, - 124,0,106,2,131,3,124,4,95,4,124,4,83,0,100,1, - 83,0,110,4,124,4,83,0,100,1,83,0,41,2,122,141, - 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, - 101,99,32,102,111,114,32,39,102,117,108,108,110,97,109,101, - 39,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, - 32,39,112,97,116,104,39,46,10,10,32,32,32,32,32,32, - 32,32,84,104,101,32,115,101,97,114,99,104,32,105,115,32, - 98,97,115,101,100,32,111,110,32,115,121,115,46,112,97,116, - 104,95,104,111,111,107,115,32,97,110,100,32,115,121,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,61,5,0,0,115,26,0,0,0, - 0,6,8,1,6,1,14,1,8,1,4,1,10,1,6,1, - 4,3,6,1,16,1,4,2,6,2,122,20,80,97,116,104, - 70,105,110,100,101,114,46,102,105,110,100,95,115,112,101,99, - 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,4,0,0,0,67,0,0,0,115,30,0,0,0,124,0, - 160,0,124,1,124,2,161,2,125,3,124,3,100,1,117,0, - 114,24,100,1,83,0,124,3,106,1,83,0,41,2,122,170, - 102,105,110,100,32,116,104,101,32,109,111,100,117,108,101,32, - 111,110,32,115,121,115,46,112,97,116,104,32,111,114,32,39, - 112,97,116,104,39,32,98,97,115,101,100,32,111,110,32,115, - 121,115,46,112,97,116,104,95,104,111,111,107,115,32,97,110, - 100,10,32,32,32,32,32,32,32,32,115,121,115,46,112,97, + 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,211, + 0,0,0,114,6,0,0,0,114,212,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,213,0,0, + 0,201,4,0,0,115,2,0,0,0,0,1,122,30,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,99, + 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,0,83,0,114,110, + 0,0,0,114,6,0,0,0,114,254,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,218,0,0, + 0,204,4,0,0,115,2,0,0,0,0,1,122,28,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, + 0,0,0,115,26,0,0,0,116,0,160,1,100,1,124,0, + 106,2,161,2,1,0,116,0,160,3,124,0,124,1,161,2, + 83,0,41,2,122,98,76,111,97,100,32,97,32,110,97,109, + 101,115,112,97,99,101,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100, + 117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10, + 32,32,32,32,32,32,32,32,122,38,110,97,109,101,115,112, + 97,99,101,32,109,111,100,117,108,101,32,108,111,97,100,101, + 100,32,119,105,116,104,32,112,97,116,104,32,123,33,114,125, + 41,4,114,135,0,0,0,114,150,0,0,0,114,25,1,0, + 0,114,219,0,0,0,114,220,0,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,221,0,0,0,207, + 4,0,0,115,8,0,0,0,0,7,6,1,4,255,4,2, + 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, + 101,114,46,108,111,97,100,95,109,111,100,117,108,101,78,41, + 12,114,126,0,0,0,114,125,0,0,0,114,127,0,0,0, + 114,210,0,0,0,114,208,0,0,0,114,45,1,0,0,114, + 183,0,0,0,114,230,0,0,0,114,214,0,0,0,114,213, + 0,0,0,114,218,0,0,0,114,221,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,114,44,1,0,0,179,4,0,0,115,18,0,0,0,8, + 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, + 3,114,44,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, + 118,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 101,4,100,2,100,3,132,0,131,1,90,5,101,4,100,4, + 100,5,132,0,131,1,90,6,101,4,100,6,100,7,132,0, + 131,1,90,7,101,4,100,8,100,9,132,0,131,1,90,8, + 101,4,100,19,100,11,100,12,132,1,131,1,90,9,101,4, + 100,20,100,13,100,14,132,1,131,1,90,10,101,4,100,21, + 100,15,100,16,132,1,131,1,90,11,101,4,100,17,100,18, + 132,0,131,1,90,12,100,10,83,0,41,22,218,10,80,97, + 116,104,70,105,110,100,101,114,122,62,77,101,116,97,32,112, + 97,116,104,32,102,105,110,100,101,114,32,102,111,114,32,115, + 121,115,46,112,97,116,104,32,97,110,100,32,112,97,99,107, + 97,103,101,32,95,95,112,97,116,104,95,95,32,97,116,116, + 114,105,98,117,116,101,115,46,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0, + 0,115,64,0,0,0,116,0,116,1,106,2,160,3,161,0, + 131,1,68,0,93,44,92,2,125,1,125,2,124,2,100,1, + 117,0,114,40,116,1,106,2,124,1,61,0,113,14,116,4, + 124,2,100,2,131,2,114,14,124,2,160,5,161,0,1,0, + 113,14,100,1,83,0,41,3,122,125,67,97,108,108,32,116, + 104,101,32,105,110,118,97,108,105,100,97,116,101,95,99,97, + 99,104,101,115,40,41,32,109,101,116,104,111,100,32,111,110, + 32,97,108,108,32,112,97,116,104,32,101,110,116,114,121,32, + 102,105,110,100,101,114,115,10,32,32,32,32,32,32,32,32, + 115,116,111,114,101,100,32,105,110,32,115,121,115,46,112,97, 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,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,85,5,0,0,115,8,0, - 0,0,0,8,12,1,8,1,4,1,122,22,80,97,116,104, - 70,105,110,100,101,114,46,102,105,110,100,95,109,111,100,117, - 108,101,99,1,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,4,0,0,0,79,0,0,0,115,28,0,0,0, - 100,1,100,2,108,0,109,1,125,3,1,0,124,3,106,2, - 124,1,105,0,124,2,164,1,142,1,83,0,41,3,97,32, - 1,0,0,10,32,32,32,32,32,32,32,32,70,105,110,100, - 32,100,105,115,116,114,105,98,117,116,105,111,110,115,46,10, - 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,32, - 97,110,32,105,116,101,114,97,98,108,101,32,111,102,32,97, - 108,108,32,68,105,115,116,114,105,98,117,116,105,111,110,32, - 105,110,115,116,97,110,99,101,115,32,99,97,112,97,98,108, - 101,32,111,102,10,32,32,32,32,32,32,32,32,108,111,97, - 100,105,110,103,32,116,104,101,32,109,101,116,97,100,97,116, - 97,32,102,111,114,32,112,97,99,107,97,103,101,115,32,109, - 97,116,99,104,105,110,103,32,96,96,99,111,110,116,101,120, - 116,46,110,97,109,101,96,96,10,32,32,32,32,32,32,32, - 32,40,111,114,32,97,108,108,32,110,97,109,101,115,32,105, - 102,32,96,96,78,111,110,101,96,96,32,105,110,100,105,99, - 97,116,101,100,41,32,97,108,111,110,103,32,116,104,101,32, - 112,97,116,104,115,32,105,110,32,116,104,101,32,108,105,115, - 116,10,32,32,32,32,32,32,32,32,111,102,32,100,105,114, - 101,99,116,111,114,105,101,115,32,96,96,99,111,110,116,101, - 120,116,46,112,97,116,104,96,96,46,10,32,32,32,32,32, - 32,32,32,114,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,98,5,0,0,115,4,0,0,0, - 0,10,12,1,122,29,80,97,116,104,70,105,110,100,101,114, - 46,102,105,110,100,95,100,105,115,116,114,105,98,117,116,105, - 111,110,115,41,1,78,41,2,78,78,41,1,78,41,13,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,207,0,0,0,114,46,1,0,0,114,52,1, - 0,0,114,54,1,0,0,114,55,1,0,0,114,58,1,0, - 0,114,203,0,0,0,114,206,0,0,0,114,60,1,0,0, - 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,45,1,0,0,221,4,0,0,115,34,0, - 0,0,8,2,4,2,2,1,10,9,2,1,10,12,2,1, - 10,21,2,1,10,14,2,1,12,31,2,1,12,23,2,1, - 12,12,2,1,114,45,1,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, - 0,0,115,90,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,101,6,90,7,100,6,100,7,132,0,90,8,100, - 8,100,9,132,0,90,9,100,19,100,11,100,12,132,1,90, - 10,100,13,100,14,132,0,90,11,101,12,100,15,100,16,132, - 0,131,1,90,13,100,17,100,18,132,0,90,14,100,10,83, - 0,41,20,218,10,70,105,108,101,70,105,110,100,101,114,122, - 172,70,105,108,101,45,98,97,115,101,100,32,102,105,110,100, - 101,114,46,10,10,32,32,32,32,73,110,116,101,114,97,99, - 116,105,111,110,115,32,119,105,116,104,32,116,104,101,32,102, - 105,108,101,32,115,121,115,116,101,109,32,97,114,101,32,99, - 97,99,104,101,100,32,102,111,114,32,112,101,114,102,111,114, - 109,97,110,99,101,44,32,98,101,105,110,103,10,32,32,32, - 32,114,101,102,114,101,115,104,101,100,32,119,104,101,110,32, - 116,104,101,32,100,105,114,101,99,116,111,114,121,32,116,104, - 101,32,102,105,110,100,101,114,32,105,115,32,104,97,110,100, - 108,105,110,103,32,104,97,115,32,98,101,101,110,32,109,111, - 100,105,102,105,101,100,46,10,10,32,32,32,32,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0, - 0,0,7,0,0,0,115,84,0,0,0,103,0,125,3,124, - 2,68,0,93,32,92,2,137,0,125,4,124,3,160,0,135, - 0,102,1,100,1,100,2,132,8,124,4,68,0,131,1,161, - 1,1,0,113,8,124,3,124,0,95,1,124,1,112,54,100, - 3,124,0,95,2,100,4,124,0,95,3,116,4,131,0,124, - 0,95,5,116,4,131,0,124,0,95,6,100,5,83,0,41, - 6,122,154,73,110,105,116,105,97,108,105,122,101,32,119,105, - 116,104,32,116,104,101,32,112,97,116,104,32,116,111,32,115, - 101,97,114,99,104,32,111,110,32,97,110,100,32,97,32,118, - 97,114,105,97,98,108,101,32,110,117,109,98,101,114,32,111, - 102,10,32,32,32,32,32,32,32,32,50,45,116,117,112,108, - 101,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104, - 101,32,108,111,97,100,101,114,32,97,110,100,32,116,104,101, - 32,102,105,108,101,32,115,117,102,102,105,120,101,115,32,116, - 104,101,32,108,111,97,100,101,114,10,32,32,32,32,32,32, - 32,32,114,101,99,111,103,110,105,122,101,115,46,99,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,127,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,121,5, - 0,0,115,16,0,0,0,0,4,4,1,12,1,26,1,6, - 2,10,1,6,1,8,1,122,19,70,105,108,101,70,105,110, - 100,101,114,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0, - 0,67,0,0,0,115,10,0,0,0,100,1,124,0,95,0, - 100,2,83,0,41,3,122,31,73,110,118,97,108,105,100,97, - 116,101,32,116,104,101,32,100,105,114,101,99,116,111,114,121, - 32,109,116,105,109,101,46,114,104,0,0,0,78,41,1,114, - 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,135,5,0, - 0,115,2,0,0,0,0,2,122,28,70,105,108,101,70,105, - 110,100,101,114,46,105,110,118,97,108,105,100,97,116,101,95, - 99,97,99,104,101,115,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, - 42,0,0,0,124,0,160,0,124,1,161,1,125,2,124,2, - 100,1,117,0,114,26,100,1,103,0,102,2,83,0,124,2, - 106,1,124,2,106,2,112,38,103,0,102,2,83,0,41,2, - 122,197,84,114,121,32,116,111,32,102,105,110,100,32,97,32, - 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,44, - 32,111,114,32,116,104,101,32,110,97,109,101,115,112,97,99, - 101,10,32,32,32,32,32,32,32,32,112,97,99,107,97,103, - 101,32,112,111,114,116,105,111,110,115,46,32,82,101,116,117, - 114,110,115,32,40,108,111,97,100,101,114,44,32,108,105,115, - 116,45,111,102,45,112,111,114,116,105,111,110,115,41,46,10, - 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, - 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, - 101,100,46,32,32,85,115,101,32,102,105,110,100,95,115,112, - 101,99,40,41,32,105,110,115,116,101,97,100,46,10,10,32, - 32,32,32,32,32,32,32,78,41,3,114,203,0,0,0,114, - 140,0,0,0,114,178,0,0,0,41,3,114,118,0,0,0, - 114,139,0,0,0,114,187,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,137,0,0,0,141,5, - 0,0,115,8,0,0,0,0,7,10,1,8,1,8,1,122, - 22,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100, - 95,108,111,97,100,101,114,99,6,0,0,0,0,0,0,0, - 0,0,0,0,7,0,0,0,6,0,0,0,67,0,0,0, - 115,26,0,0,0,124,1,124,2,124,3,131,2,125,6,116, - 0,124,2,124,3,124,6,124,4,100,1,141,4,83,0,41, - 2,78,114,177,0,0,0,41,1,114,190,0,0,0,41,7, - 114,118,0,0,0,114,188,0,0,0,114,139,0,0,0,114, - 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,153,5,0,0,115,8,0,0, - 0,0,1,10,1,8,1,2,255,122,20,70,105,108,101,70, - 105,110,100,101,114,46,95,103,101,116,95,115,112,101,99,78, - 99,3,0,0,0,0,0,0,0,0,0,0,0,14,0,0, - 0,8,0,0,0,67,0,0,0,115,96,1,0,0,100,1, - 125,3,124,1,160,0,100,2,161,1,100,3,25,0,125,4, - 122,24,116,1,124,0,106,2,112,34,116,3,160,4,161,0, - 131,1,106,5,125,5,87,0,110,22,4,0,116,6,121,64, - 1,0,1,0,1,0,100,4,125,5,89,0,110,2,48,0, - 124,5,124,0,106,7,107,3,114,90,124,0,160,8,161,0, - 1,0,124,5,124,0,95,7,116,9,131,0,114,112,124,0, - 106,10,125,6,124,4,160,11,161,0,125,7,110,10,124,0, - 106,12,125,6,124,4,125,7,124,7,124,6,118,0,114,216, - 116,13,124,0,106,2,124,4,131,2,125,8,124,0,106,14, - 68,0,93,58,92,2,125,9,125,10,100,5,124,9,23,0, - 125,11,116,13,124,8,124,11,131,2,125,12,116,15,124,12, - 131,1,114,148,124,0,160,16,124,10,124,1,124,12,124,8, - 103,1,124,2,161,5,2,0,1,0,83,0,113,148,116,17, - 124,8,131,1,125,3,124,0,106,14,68,0,93,82,92,2, - 125,9,125,10,116,13,124,0,106,2,124,4,124,9,23,0, - 131,2,125,12,116,18,106,19,100,6,124,12,100,3,100,7, - 141,3,1,0,124,7,124,9,23,0,124,6,118,0,114,222, - 116,15,124,12,131,1,114,222,124,0,160,16,124,10,124,1, - 124,12,100,8,124,2,161,5,2,0,1,0,83,0,113,222, - 124,3,144,1,114,92,116,18,160,19,100,9,124,8,161,2, - 1,0,116,18,160,20,124,1,100,8,161,2,125,13,124,8, - 103,1,124,13,95,21,124,13,83,0,100,8,83,0,41,10, - 122,111,84,114,121,32,116,111,32,102,105,110,100,32,97,32, - 115,112,101,99,32,102,111,114,32,116,104,101,32,115,112,101, - 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,82,101,116,117,114,110,115,32, - 116,104,101,32,109,97,116,99,104,105,110,103,32,115,112,101, - 99,44,32,111,114,32,78,111,110,101,32,105,102,32,110,111, - 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, - 32,70,114,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, - 158,5,0,0,115,74,0,0,0,0,5,4,1,14,1,2, - 1,24,1,12,1,10,1,10,1,8,1,6,2,6,1,6, - 1,10,2,6,1,4,2,8,1,12,1,14,1,8,1,10, - 1,8,1,26,4,8,2,14,1,16,1,16,1,12,1,8, - 1,10,1,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,188,0,0,0,124,0,106,0,125,1,122,22,116, - 1,160,2,124,1,112,22,116,1,160,3,161,0,161,1,125, - 2,87,0,110,28,4,0,116,4,116,5,116,6,102,3,121, - 56,1,0,1,0,1,0,103,0,125,2,89,0,110,2,48, - 0,116,7,106,8,160,9,100,1,161,1,115,82,116,10,124, - 2,131,1,124,0,95,11,110,74,116,10,131,0,125,3,124, - 2,68,0,93,56,125,4,124,4,160,12,100,2,161,1,92, - 3,125,5,125,6,125,7,124,6,114,134,100,3,160,13,124, - 5,124,7,160,14,161,0,161,2,125,8,110,4,124,5,125, - 8,124,3,160,15,124,8,161,1,1,0,113,92,124,3,124, - 0,95,11,116,7,106,8,160,9,116,16,161,1,114,184,100, - 4,100,5,132,0,124,2,68,0,131,1,124,0,95,17,100, - 6,83,0,41,7,122,68,70,105,108,108,32,116,104,101,32, - 99,97,99,104,101,32,111,102,32,112,111,116,101,110,116,105, - 97,108,32,109,111,100,117,108,101,115,32,97,110,100,32,112, - 97,99,107,97,103,101,115,32,102,111,114,32,116,104,105,115, - 32,100,105,114,101,99,116,111,114,121,46,114,0,0,0,0, - 114,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,235,5,0, - 0,115,4,0,0,0,6,0,2,0,122,41,70,105,108,101, + 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,2,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,129,0,0,0,114,47,1,0,0,41,3, + 114,194,0,0,0,114,117,0,0,0,218,6,102,105,110,100, + 101,114,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,114,47,1,0,0,225,4,0,0,115,10,0,0,0,0, + 4,22,1,8,1,10,1,10,1,122,28,80,97,116,104,70, + 105,110,100,101,114,46,105,110,118,97,108,105,100,97,116,101, + 95,99,97,99,104,101,115,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,9,0,0,0,67,0,0,0, + 115,82,0,0,0,116,0,106,1,100,1,117,1,114,28,116, + 0,106,1,115,28,116,2,160,3,100,2,116,4,161,2,1, + 0,116,0,106,1,68,0,93,42,125,2,122,14,124,2,124, + 1,131,1,87,0,2,0,1,0,83,0,4,0,116,5,121, + 74,1,0,1,0,1,0,89,0,113,34,89,0,113,34,48, + 0,113,34,100,1,83,0,41,3,122,46,83,101,97,114,99, + 104,32,115,121,115,46,112,97,116,104,95,104,111,111,107,115, + 32,102,111,114,32,97,32,102,105,110,100,101,114,32,102,111, + 114,32,39,112,97,116,104,39,46,78,122,23,115,121,115,46, + 112,97,116,104,95,104,111,111,107,115,32,105,115,32,101,109, + 112,116,121,41,6,114,2,0,0,0,218,10,112,97,116,104, + 95,104,111,111,107,115,114,76,0,0,0,114,77,0,0,0, + 114,139,0,0,0,114,118,0,0,0,41,3,114,194,0,0, + 0,114,45,0,0,0,90,4,104,111,111,107,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,218,11,95,112,97, + 116,104,95,104,111,111,107,115,235,4,0,0,115,16,0,0, + 0,0,3,16,1,12,1,10,1,2,1,14,1,12,1,12, + 2,122,22,80,97,116,104,70,105,110,100,101,114,46,95,112, + 97,116,104,95,104,111,111,107,115,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,8,0,0,0,67,0, + 0,0,115,100,0,0,0,124,1,100,1,107,2,114,42,122, + 12,116,0,160,1,161,0,125,1,87,0,110,20,4,0,116, + 2,121,40,1,0,1,0,1,0,89,0,100,2,83,0,48, + 0,122,14,116,3,106,4,124,1,25,0,125,2,87,0,110, + 38,4,0,116,5,121,94,1,0,1,0,1,0,124,0,160, + 6,124,1,161,1,125,2,124,2,116,3,106,4,124,1,60, + 0,89,0,110,2,48,0,124,2,83,0,41,3,122,210,71, + 101,116,32,116,104,101,32,102,105,110,100,101,114,32,102,111, + 114,32,116,104,101,32,112,97,116,104,32,101,110,116,114,121, + 32,102,114,111,109,32,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,41,0,0,0,78,41,7,114,5,0,0,0,114,56, + 0,0,0,114,4,1,0,0,114,2,0,0,0,114,49,1, + 0,0,218,8,75,101,121,69,114,114,111,114,114,53,1,0, + 0,41,3,114,194,0,0,0,114,45,0,0,0,114,51,1, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,218,20,95,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,248,4,0,0,115,22,0,0,0, + 0,8,8,1,2,1,12,1,12,3,8,1,2,1,14,1, + 12,1,10,1,16,1,122,31,80,97,116,104,70,105,110,100, + 101,114,46,95,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,99,3,0,0,0,0,0,0,0, + 0,0,0,0,6,0,0,0,4,0,0,0,67,0,0,0, + 115,82,0,0,0,116,0,124,2,100,1,131,2,114,26,124, + 2,160,1,124,1,161,1,92,2,125,3,125,4,110,14,124, + 2,160,2,124,1,161,1,125,3,103,0,125,4,124,3,100, + 0,117,1,114,60,116,3,160,4,124,1,124,3,161,2,83, + 0,116,3,160,5,124,1,100,0,161,2,125,5,124,4,124, + 5,95,6,124,5,83,0,41,2,78,114,138,0,0,0,41, + 7,114,129,0,0,0,114,138,0,0,0,114,207,0,0,0, + 114,135,0,0,0,114,202,0,0,0,114,184,0,0,0,114, + 179,0,0,0,41,6,114,194,0,0,0,114,140,0,0,0, + 114,51,1,0,0,114,141,0,0,0,114,142,0,0,0,114, + 188,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, + 0,0,0,218,16,95,108,101,103,97,99,121,95,103,101,116, + 95,115,112,101,99,14,5,0,0,115,18,0,0,0,0,4, + 10,1,16,2,10,1,4,1,8,1,12,1,12,1,6,1, + 122,27,80,97,116,104,70,105,110,100,101,114,46,95,108,101, + 103,97,99,121,95,103,101,116,95,115,112,101,99,78,99,4, + 0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,5, + 0,0,0,67,0,0,0,115,166,0,0,0,103,0,125,4, + 124,2,68,0,93,134,125,5,116,0,124,5,116,1,116,2, + 102,2,131,2,115,28,113,8,124,0,160,3,124,5,161,1, + 125,6,124,6,100,1,117,1,114,8,116,4,124,6,100,2, + 131,2,114,70,124,6,160,5,124,1,124,3,161,2,125,7, + 110,12,124,0,160,6,124,1,124,6,161,2,125,7,124,7, + 100,1,117,0,114,92,113,8,124,7,106,7,100,1,117,1, + 114,110,124,7,2,0,1,0,83,0,124,7,106,8,125,8, + 124,8,100,1,117,0,114,132,116,9,100,3,131,1,130,1, + 124,4,160,10,124,8,161,1,1,0,113,8,116,11,160,12, + 124,1,100,1,161,2,125,7,124,4,124,7,95,8,124,7, + 83,0,41,4,122,63,70,105,110,100,32,116,104,101,32,108, + 111,97,100,101,114,32,111,114,32,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,32,102,111,114,32,116,104,105,115, + 32,109,111,100,117,108,101,47,112,97,99,107,97,103,101,32, + 110,97,109,101,46,78,114,204,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,162,0,0,0,114,85,0,0,0,218,5,98,121, + 116,101,115,114,55,1,0,0,114,129,0,0,0,114,204,0, + 0,0,114,56,1,0,0,114,141,0,0,0,114,179,0,0, + 0,114,118,0,0,0,114,168,0,0,0,114,135,0,0,0, + 114,184,0,0,0,41,9,114,194,0,0,0,114,140,0,0, + 0,114,45,0,0,0,114,203,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,51,1,0,0,114,188,0,0,0,114,142,0,0, + 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, + 218,9,95,103,101,116,95,115,112,101,99,29,5,0,0,115, + 40,0,0,0,0,5,4,1,8,1,14,1,2,1,10,1, + 8,1,10,1,14,2,12,1,8,1,2,1,10,1,8,1, + 6,1,8,1,8,5,12,2,12,1,6,1,122,20,80,97, + 116,104,70,105,110,100,101,114,46,95,103,101,116,95,115,112, + 101,99,99,4,0,0,0,0,0,0,0,0,0,0,0,6, + 0,0,0,5,0,0,0,67,0,0,0,115,100,0,0,0, + 124,2,100,1,117,0,114,14,116,0,106,1,125,2,124,0, + 160,2,124,1,124,2,124,3,161,3,125,4,124,4,100,1, + 117,0,114,40,100,1,83,0,124,4,106,3,100,1,117,0, + 114,92,124,4,106,4,125,5,124,5,114,86,100,1,124,4, + 95,5,116,6,124,1,124,5,124,0,106,2,131,3,124,4, + 95,4,124,4,83,0,100,1,83,0,110,4,124,4,83,0, + 100,1,83,0,41,2,122,141,84,114,121,32,116,111,32,102, + 105,110,100,32,97,32,115,112,101,99,32,102,111,114,32,39, + 102,117,108,108,110,97,109,101,39,32,111,110,32,115,121,115, + 46,112,97,116,104,32,111,114,32,39,112,97,116,104,39,46, + 10,10,32,32,32,32,32,32,32,32,84,104,101,32,115,101, + 97,114,99,104,32,105,115,32,98,97,115,101,100,32,111,110, + 32,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, + 97,110,100,32,115,121,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,2,0,0,0,114,45,0, + 0,0,114,59,1,0,0,114,141,0,0,0,114,179,0,0, + 0,114,182,0,0,0,114,23,1,0,0,41,6,114,194,0, + 0,0,114,140,0,0,0,114,45,0,0,0,114,203,0,0, + 0,114,188,0,0,0,114,58,1,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,204,0,0,0,61, + 5,0,0,115,26,0,0,0,0,6,8,1,6,1,14,1, + 8,1,4,1,10,1,6,1,4,3,6,1,16,1,4,2, + 6,2,122,20,80,97,116,104,70,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0, + 0,115,30,0,0,0,124,0,160,0,124,1,124,2,161,2, + 125,3,124,3,100,1,117,0,114,24,100,1,83,0,124,3, + 106,1,83,0,41,2,122,170,102,105,110,100,32,116,104,101, + 32,109,111,100,117,108,101,32,111,110,32,115,121,115,46,112, + 97,116,104,32,111,114,32,39,112,97,116,104,39,32,98,97, + 115,101,100,32,111,110,32,115,121,115,46,112,97,116,104,95, + 104,111,111,107,115,32,97,110,100,10,32,32,32,32,32,32, + 32,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, + 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, + 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, + 32,32,78,114,205,0,0,0,114,206,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,207,0,0, + 0,85,5,0,0,115,8,0,0,0,0,8,12,1,8,1, + 4,1,122,22,80,97,116,104,70,105,110,100,101,114,46,102, + 105,110,100,95,109,111,100,117,108,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,79, + 0,0,0,115,28,0,0,0,100,1,100,2,108,0,109,1, + 125,3,1,0,124,3,106,2,124,1,105,0,124,2,164,1, + 142,1,83,0,41,3,97,32,1,0,0,10,32,32,32,32, + 32,32,32,32,70,105,110,100,32,100,105,115,116,114,105,98, + 117,116,105,111,110,115,46,10,10,32,32,32,32,32,32,32, + 32,82,101,116,117,114,110,32,97,110,32,105,116,101,114,97, + 98,108,101,32,111,102,32,97,108,108,32,68,105,115,116,114, + 105,98,117,116,105,111,110,32,105,110,115,116,97,110,99,101, + 115,32,99,97,112,97,98,108,101,32,111,102,10,32,32,32, + 32,32,32,32,32,108,111,97,100,105,110,103,32,116,104,101, + 32,109,101,116,97,100,97,116,97,32,102,111,114,32,112,97, + 99,107,97,103,101,115,32,109,97,116,99,104,105,110,103,32, + 96,96,99,111,110,116,101,120,116,46,110,97,109,101,96,96, + 10,32,32,32,32,32,32,32,32,40,111,114,32,97,108,108, + 32,110,97,109,101,115,32,105,102,32,96,96,78,111,110,101, + 96,96,32,105,110,100,105,99,97,116,101,100,41,32,97,108, + 111,110,103,32,116,104,101,32,112,97,116,104,115,32,105,110, + 32,116,104,101,32,108,105,115,116,10,32,32,32,32,32,32, + 32,32,111,102,32,100,105,114,101,99,116,111,114,105,101,115, + 32,96,96,99,111,110,116,101,120,116,46,112,97,116,104,96, + 96,46,10,32,32,32,32,32,32,32,32,114,74,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,60,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,194,0,0,0,114,120,0,0, + 0,114,121,0,0,0,114,60,1,0,0,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,61,1,0,0,98, + 5,0,0,115,4,0,0,0,0,10,12,1,122,29,80,97, + 116,104,70,105,110,100,101,114,46,102,105,110,100,95,100,105, + 115,116,114,105,98,117,116,105,111,110,115,41,1,78,41,2, + 78,78,41,1,78,41,13,114,126,0,0,0,114,125,0,0, + 0,114,127,0,0,0,114,128,0,0,0,114,208,0,0,0, + 114,47,1,0,0,114,53,1,0,0,114,55,1,0,0,114, + 56,1,0,0,114,59,1,0,0,114,204,0,0,0,114,207, + 0,0,0,114,61,1,0,0,114,6,0,0,0,114,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,46,1,0, + 0,221,4,0,0,115,34,0,0,0,8,2,4,2,2,1, + 10,9,2,1,10,12,2,1,10,21,2,1,10,14,2,1, + 12,31,2,1,12,23,2,1,12,12,2,1,114,46,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,110,0,0,0,114,6, + 0,0,0,114,17,1,0,0,169,1,114,141,0,0,0,114, + 6,0,0,0,114,9,0,0,0,114,20,1,0,0,127,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,72,0,0,0,114,105,0,0,0,78,41,7, + 114,168,0,0,0,218,8,95,108,111,97,100,101,114,115,114, + 45,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,119,0,0,0,114, + 45,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,190,0, + 0,0,114,6,0,0,0,114,63,1,0,0,114,9,0,0, + 0,114,210,0,0,0,121,5,0,0,115,16,0,0,0,0, + 4,4,1,12,1,26,1,6,2,10,1,6,1,8,1,122, + 19,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, + 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,115,10,0, + 0,0,100,1,124,0,95,0,100,2,83,0,41,3,122,31, + 73,110,118,97,108,105,100,97,116,101,32,116,104,101,32,100, + 105,114,101,99,116,111,114,121,32,109,116,105,109,101,46,114, + 105,0,0,0,78,41,1,114,65,1,0,0,114,247,0,0, + 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, + 114,47,1,0,0,135,5,0,0,115,2,0,0,0,0,2, + 122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,118, + 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, + 0,0,0,67,0,0,0,115,42,0,0,0,124,0,160,0, + 124,1,161,1,125,2,124,2,100,1,117,0,114,26,100,1, + 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, + 103,0,102,2,83,0,41,2,122,197,84,114,121,32,116,111, + 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, + 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, + 32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,32, + 110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,32, + 32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,111, + 110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,97, + 100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,114, + 116,105,111,110,115,41,46,10,10,32,32,32,32,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, + 41,3,114,204,0,0,0,114,141,0,0,0,114,179,0,0, + 0,41,3,114,119,0,0,0,114,140,0,0,0,114,188,0, + 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, + 0,114,138,0,0,0,141,5,0,0,115,8,0,0,0,0, + 7,10,1,8,1,8,1,122,22,70,105,108,101,70,105,110, + 100,101,114,46,102,105,110,100,95,108,111,97,100,101,114,99, + 6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, + 6,0,0,0,67,0,0,0,115,26,0,0,0,124,1,124, + 2,124,3,131,2,125,6,116,0,124,2,124,3,124,6,124, + 4,100,1,141,4,83,0,41,2,78,114,178,0,0,0,41, + 1,114,191,0,0,0,41,7,114,119,0,0,0,114,189,0, + 0,0,114,140,0,0,0,114,45,0,0,0,90,4,115,109, + 115,108,114,203,0,0,0,114,141,0,0,0,114,6,0,0, + 0,114,6,0,0,0,114,9,0,0,0,114,59,1,0,0, + 153,5,0,0,115,8,0,0,0,0,1,10,1,8,1,2, + 255,122,20,70,105,108,101,70,105,110,100,101,114,46,95,103, + 101,116,95,115,112,101,99,78,99,3,0,0,0,0,0,0, + 0,0,0,0,0,14,0,0,0,8,0,0,0,67,0,0, + 0,115,96,1,0,0,100,1,125,3,124,1,160,0,100,2, + 161,1,100,3,25,0,125,4,122,24,116,1,124,0,106,2, + 112,34,116,3,160,4,161,0,131,1,106,5,125,5,87,0, + 110,22,4,0,116,6,121,64,1,0,1,0,1,0,100,4, + 125,5,89,0,110,2,48,0,124,5,124,0,106,7,107,3, + 114,90,124,0,160,8,161,0,1,0,124,5,124,0,95,7, + 116,9,131,0,114,112,124,0,106,10,125,6,124,4,160,11, + 161,0,125,7,110,10,124,0,106,12,125,6,124,4,125,7, + 124,7,124,6,118,0,114,216,116,13,124,0,106,2,124,4, + 131,2,125,8,124,0,106,14,68,0,93,58,92,2,125,9, + 125,10,100,5,124,9,23,0,125,11,116,13,124,8,124,11, + 131,2,125,12,116,15,124,12,131,1,114,148,124,0,160,16, + 124,10,124,1,124,12,124,8,103,1,124,2,161,5,2,0, + 1,0,83,0,113,148,116,17,124,8,131,1,125,3,124,0, + 106,14,68,0,93,82,92,2,125,9,125,10,116,13,124,0, + 106,2,124,4,124,9,23,0,131,2,125,12,116,18,106,19, + 100,6,124,12,100,3,100,7,141,3,1,0,124,7,124,9, + 23,0,124,6,118,0,114,222,116,15,124,12,131,1,114,222, + 124,0,160,16,124,10,124,1,124,12,100,8,124,2,161,5, + 2,0,1,0,83,0,113,222,124,3,144,1,114,92,116,18, + 160,19,100,9,124,8,161,2,1,0,116,18,160,20,124,1, + 100,8,161,2,125,13,124,8,103,1,124,13,95,21,124,13, + 83,0,100,8,83,0,41,10,122,111,84,114,121,32,116,111, + 32,102,105,110,100,32,97,32,115,112,101,99,32,102,111,114, + 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 82,101,116,117,114,110,115,32,116,104,101,32,109,97,116,99, + 104,105,110,103,32,115,112,101,99,44,32,111,114,32,78,111, + 110,101,32,105,102,32,110,111,116,32,102,111,117,110,100,46, + 10,32,32,32,32,32,32,32,32,70,114,72,0,0,0,114, + 29,0,0,0,114,105,0,0,0,114,210,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,42,0,0,0,114,50,0,0,0,114,45, + 0,0,0,114,5,0,0,0,114,56,0,0,0,114,11,1, + 0,0,114,51,0,0,0,114,65,1,0,0,218,11,95,102, + 105,108,108,95,99,97,99,104,101,114,10,0,0,0,114,68, + 1,0,0,114,106,0,0,0,114,67,1,0,0,114,39,0, + 0,0,114,64,1,0,0,114,55,0,0,0,114,59,1,0, + 0,114,57,0,0,0,114,135,0,0,0,114,150,0,0,0, + 114,184,0,0,0,114,179,0,0,0,41,14,114,119,0,0, + 0,114,140,0,0,0,114,203,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,170,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,18,1,0,0, + 114,189,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, + 188,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, + 0,0,0,114,204,0,0,0,158,5,0,0,115,74,0,0, + 0,0,5,4,1,14,1,2,1,24,1,12,1,10,1,10, + 1,8,1,6,2,6,1,6,1,10,2,6,1,4,2,8, + 1,12,1,14,1,8,1,10,1,8,1,26,4,8,2,14, + 1,16,1,16,1,12,1,8,1,10,1,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,188,0,0,0,124, + 0,106,0,125,1,122,22,116,1,160,2,124,1,112,22,116, + 1,160,3,161,0,161,1,125,2,87,0,110,28,4,0,116, + 4,116,5,116,6,102,3,121,56,1,0,1,0,1,0,103, + 0,125,2,89,0,110,2,48,0,116,7,106,8,160,9,100, + 1,161,1,115,82,116,10,124,2,131,1,124,0,95,11,110, + 74,116,10,131,0,125,3,124,2,68,0,93,56,125,4,124, + 4,160,12,100,2,161,1,92,3,125,5,125,6,125,7,124, + 6,114,134,100,3,160,13,124,5,124,7,160,14,161,0,161, + 2,125,8,110,4,124,5,125,8,124,3,160,15,124,8,161, + 1,1,0,113,92,124,3,124,0,95,11,116,7,106,8,160, + 9,116,16,161,1,114,184,100,4,100,5,132,0,124,2,68, + 0,131,1,124,0,95,17,100,6,83,0,41,7,122,68,70, + 105,108,108,32,116,104,101,32,99,97,99,104,101,32,111,102, + 32,112,111,116,101,110,116,105,97,108,32,109,111,100,117,108, + 101,115,32,97,110,100,32,112,97,99,107,97,103,101,115,32, + 102,111,114,32,116,104,105,115,32,100,105,114,101,99,116,111, + 114,121,46,114,0,0,0,0,114,72,0,0,0,114,62,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,6,0,0,0,41,1,114,106,0,0,0, + 41,2,114,33,0,0,0,90,2,102,110,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,218,9,60,115,101,116, + 99,111,109,112,62,235,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,45,0,0,0,114,5,0,0,0,114,8,1,0,0,114, + 56,0,0,0,114,4,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,2, + 0,0,0,114,11,0,0,0,114,12,0,0,0,114,66,1, + 0,0,114,67,1,0,0,114,101,0,0,0,114,63,0,0, + 0,114,106,0,0,0,218,3,97,100,100,114,13,0,0,0, + 114,68,1,0,0,41,9,114,119,0,0,0,114,45,0,0, + 0,114,9,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,42,1, + 0,0,114,117,0,0,0,114,30,1,0,0,114,18,1,0, + 0,90,8,110,101,119,95,110,97,109,101,114,6,0,0,0, + 114,6,0,0,0,114,9,0,0,0,114,70,1,0,0,206, + 5,0,0,115,34,0,0,0,0,2,6,1,2,1,22,1, + 18,3,10,3,12,1,12,7,6,1,8,1,16,1,4,1, + 18,2,4,1,12,1,6,1,12,1,122,22,70,105,108,101, 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, - 104,101,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,206,5,0,0,115,34,0,0,0, - 0,2,6,1,2,1,22,1,18,3,10,3,12,1,12,7, - 6,1,8,1,16,1,4,1,18,2,4,1,12,1,6,1, - 12,1,122,22,70,105,108,101,70,105,110,100,101,114,46,95, - 102,105,108,108,95,99,97,99,104,101,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,7, - 0,0,0,115,18,0,0,0,135,0,135,1,102,2,100,1, - 100,2,132,8,125,2,124,2,83,0,41,3,97,20,1,0, - 0,65,32,99,108,97,115,115,32,109,101,116,104,111,100,32, - 119,104,105,99,104,32,114,101,116,117,114,110,115,32,97,32, - 99,108,111,115,117,114,101,32,116,111,32,117,115,101,32,111, - 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,10, - 32,32,32,32,32,32,32,32,119,104,105,99,104,32,119,105, - 108,108,32,114,101,116,117,114,110,32,97,110,32,105,110,115, - 116,97,110,99,101,32,117,115,105,110,103,32,116,104,101,32, - 115,112,101,99,105,102,105,101,100,32,108,111,97,100,101,114, - 115,32,97,110,100,32,116,104,101,32,112,97,116,104,10,32, - 32,32,32,32,32,32,32,99,97,108,108,101,100,32,111,110, - 32,116,104,101,32,99,108,111,115,117,114,101,46,10,10,32, - 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, - 116,104,32,99,97,108,108,101,100,32,111,110,32,116,104,101, - 32,99,108,111,115,117,114,101,32,105,115,32,110,111,116,32, - 97,32,100,105,114,101,99,116,111,114,121,44,32,73,109,112, - 111,114,116,69,114,114,111,114,32,105,115,10,32,32,32,32, - 32,32,32,32,114,97,105,115,101,100,46,10,10,32,32,32, - 32,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,4,0,0,0,19,0,0,0,115,36, - 0,0,0,116,0,124,0,131,1,115,20,116,1,100,1,124, - 0,100,2,141,2,130,1,136,0,124,0,103,1,136,1,162, - 1,82,0,142,0,83,0,41,3,122,45,80,97,116,104,32, - 104,111,111,107,32,102,111,114,32,105,109,112,111,114,116,108, - 105,98,46,109,97,99,104,105,110,101,114,121,46,70,105,108, - 101,70,105,110,100,101,114,46,122,30,111,110,108,121,32,100, - 105,114,101,99,116,111,114,105,101,115,32,97,114,101,32,115, - 117,112,112,111,114,116,101,100,114,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,247,5, - 0,0,115,6,0,0,0,0,2,8,1,12,1,122,54,70, - 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, - 111,111,107,46,60,108,111,99,97,108,115,62,46,112,97,116, - 104,95,104,111,111,107,95,102,111,114,95,70,105,108,101,70, - 105,110,100,101,114,114,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,237,5,0,0,115,4,0,0,0,0,10, - 14,6,122,20,70,105,108,101,70,105,110,100,101,114,46,112, - 97,116,104,95,104,111,111,107,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,12,0,0,0,100,1,160,0,124,0,106,1,161,1, - 83,0,41,2,78,122,16,70,105,108,101,70,105,110,100,101, - 114,40,123,33,114,125,41,41,2,114,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,255,5,0,0, - 115,2,0,0,0,0,1,122,19,70,105,108,101,70,105,110, - 100,101,114,46,95,95,114,101,112,114,95,95,41,1,78,41, - 15,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,209,0,0,0,114,46,1,0,0,114, - 143,0,0,0,114,206,0,0,0,114,137,0,0,0,114,58, - 1,0,0,114,203,0,0,0,114,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,112,5,0,0,115,22,0,0,0,8,2, - 4,7,8,14,8,4,4,2,8,12,8,5,10,48,8,31, - 2,1,10,17,114,61,1,0,0,99,4,0,0,0,0,0, - 0,0,0,0,0,0,6,0,0,0,8,0,0,0,67,0, - 0,0,115,144,0,0,0,124,0,160,0,100,1,161,1,125, - 4,124,0,160,0,100,2,161,1,125,5,124,4,115,66,124, - 5,114,36,124,5,106,1,125,4,110,30,124,2,124,3,107, - 2,114,56,116,2,124,1,124,2,131,2,125,4,110,10,116, - 3,124,1,124,2,131,2,125,4,124,5,115,84,116,4,124, - 1,124,2,124,4,100,3,141,3,125,5,122,36,124,5,124, - 0,100,2,60,0,124,4,124,0,100,1,60,0,124,2,124, - 0,100,4,60,0,124,3,124,0,100,5,60,0,87,0,110, - 18,4,0,116,5,121,138,1,0,1,0,1,0,89,0,110, - 2,48,0,100,0,83,0,41,6,78,218,10,95,95,108,111, - 97,100,101,114,95,95,218,8,95,95,115,112,101,99,95,95, - 114,62,1,0,0,90,8,95,95,102,105,108,101,95,95,90, - 10,95,95,99,97,99,104,101,100,95,95,41,6,218,3,103, - 101,116,114,140,0,0,0,114,15,1,0,0,114,9,1,0, - 0,114,190,0,0,0,218,9,69,120,99,101,112,116,105,111, - 110,41,6,90,2,110,115,114,116,0,0,0,90,8,112,97, - 116,104,110,97,109,101,90,9,99,112,97,116,104,110,97,109, - 101,114,140,0,0,0,114,187,0,0,0,114,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,5,6,0,0,115,34, - 0,0,0,0,2,10,1,10,1,4,1,4,1,8,1,8, - 1,12,2,10,1,4,1,14,1,2,1,8,1,8,1,8, - 1,12,1,12,2,114,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,28,6,0,0,115,8,0, - 0,0,0,5,12,1,8,1,8,1,114,184,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, - 9,0,0,0,67,0,0,0,115,176,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,118,1,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,108,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,118,0,114,170,116,1,106,3,124,5,25,0,125, - 8,1,0,113,224,113,106,122,20,116,0,160,5,124,5,161, - 1,125,8,87,0,1,0,113,224,87,0,113,106,4,0,116, - 8,121,212,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,108,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,172,116, - 14,160,15,100,22,161,1,1,0,100,23,116,11,118,0,144, - 1,114,172,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,64,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,80,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,39, - 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, - 12,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,104,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,20,16,1,12,2,4,1,4,2,6,2,6,2,8, - 2,16,71,8,40,8,19,8,12,8,12,8,28,8,17,8, - 33,8,28,8,24,10,13,10,10,10,11,8,14,6,3,4, - 1,2,255,12,68,14,64,14,29,16,127,0,17,14,72,18, - 45,18,26,4,3,18,53,14,63,14,42,14,127,0,20,14, - 127,0,22,10,23,8,11,8,65, + 104,101,99,1,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,7,0,0,0,115,18,0,0,0, + 135,0,135,1,102,2,100,1,100,2,132,8,125,2,124,2, + 83,0,41,3,97,20,1,0,0,65,32,99,108,97,115,115, + 32,109,101,116,104,111,100,32,119,104,105,99,104,32,114,101, + 116,117,114,110,115,32,97,32,99,108,111,115,117,114,101,32, + 116,111,32,117,115,101,32,111,110,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,10,32,32,32,32,32,32,32,32, + 119,104,105,99,104,32,119,105,108,108,32,114,101,116,117,114, + 110,32,97,110,32,105,110,115,116,97,110,99,101,32,117,115, + 105,110,103,32,116,104,101,32,115,112,101,99,105,102,105,101, + 100,32,108,111,97,100,101,114,115,32,97,110,100,32,116,104, + 101,32,112,97,116,104,10,32,32,32,32,32,32,32,32,99, + 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, + 115,117,114,101,46,10,10,32,32,32,32,32,32,32,32,73, + 102,32,116,104,101,32,112,97,116,104,32,99,97,108,108,101, + 100,32,111,110,32,116,104,101,32,99,108,111,115,117,114,101, + 32,105,115,32,110,111,116,32,97,32,100,105,114,101,99,116, + 111,114,121,44,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,115,10,32,32,32,32,32,32,32,32,114,97,105,115, + 101,100,46,10,10,32,32,32,32,32,32,32,32,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, + 0,0,19,0,0,0,115,36,0,0,0,116,0,124,0,131, + 1,115,20,116,1,100,1,124,0,100,2,141,2,130,1,136, + 0,124,0,103,1,136,1,162,1,82,0,142,0,83,0,41, + 3,122,45,80,97,116,104,32,104,111,111,107,32,102,111,114, + 32,105,109,112,111,114,116,108,105,98,46,109,97,99,104,105, + 110,101,114,121,46,70,105,108,101,70,105,110,100,101,114,46, + 122,30,111,110,108,121,32,100,105,114,101,99,116,111,114,105, + 101,115,32,97,114,101,32,115,117,112,112,111,114,116,101,100, + 114,49,0,0,0,41,2,114,57,0,0,0,114,118,0,0, + 0,114,49,0,0,0,169,2,114,194,0,0,0,114,69,1, + 0,0,114,6,0,0,0,114,9,0,0,0,218,24,112,97, + 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, + 70,105,110,100,101,114,247,5,0,0,115,6,0,0,0,0, + 2,8,1,12,1,122,54,70,105,108,101,70,105,110,100,101, + 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, + 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, + 111,114,95,70,105,108,101,70,105,110,100,101,114,114,6,0, + 0,0,41,3,114,194,0,0,0,114,69,1,0,0,114,76, + 1,0,0,114,6,0,0,0,114,75,1,0,0,114,9,0, + 0,0,218,9,112,97,116,104,95,104,111,111,107,237,5,0, + 0,115,4,0,0,0,0,10,14,6,122,20,70,105,108,101, + 70,105,110,100,101,114,46,112,97,116,104,95,104,111,111,107, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, + 160,0,124,0,106,1,161,1,83,0,41,2,78,122,16,70, + 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, + 2,114,63,0,0,0,114,45,0,0,0,114,247,0,0,0, + 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, + 40,1,0,0,255,5,0,0,115,2,0,0,0,0,1,122, + 19,70,105,108,101,70,105,110,100,101,114,46,95,95,114,101, + 112,114,95,95,41,1,78,41,15,114,126,0,0,0,114,125, + 0,0,0,114,127,0,0,0,114,128,0,0,0,114,210,0, + 0,0,114,47,1,0,0,114,144,0,0,0,114,207,0,0, + 0,114,138,0,0,0,114,59,1,0,0,114,204,0,0,0, + 114,70,1,0,0,114,208,0,0,0,114,77,1,0,0,114, + 40,1,0,0,114,6,0,0,0,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,114,62,1,0,0,112,5,0, + 0,115,22,0,0,0,8,2,4,7,8,14,8,4,4,2, + 8,12,8,5,10,48,8,31,2,1,10,17,114,62,1,0, + 0,99,4,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,8,0,0,0,67,0,0,0,115,144,0,0,0,124, + 0,160,0,100,1,161,1,125,4,124,0,160,0,100,2,161, + 1,125,5,124,4,115,66,124,5,114,36,124,5,106,1,125, + 4,110,30,124,2,124,3,107,2,114,56,116,2,124,1,124, + 2,131,2,125,4,110,10,116,3,124,1,124,2,131,2,125, + 4,124,5,115,84,116,4,124,1,124,2,124,4,100,3,141, + 3,125,5,122,36,124,5,124,0,100,2,60,0,124,4,124, + 0,100,1,60,0,124,2,124,0,100,4,60,0,124,3,124, + 0,100,5,60,0,87,0,110,18,4,0,116,5,121,138,1, + 0,1,0,1,0,89,0,110,2,48,0,100,0,83,0,41, + 6,78,218,10,95,95,108,111,97,100,101,114,95,95,218,8, + 95,95,115,112,101,99,95,95,114,63,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,141,0,0,0,114, + 16,1,0,0,114,10,1,0,0,114,191,0,0,0,218,9, + 69,120,99,101,112,116,105,111,110,41,6,90,2,110,115,114, + 117,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,141,0,0,0,114,188, + 0,0,0,114,6,0,0,0,114,6,0,0,0,114,9,0, + 0,0,218,14,95,102,105,120,95,117,112,95,109,111,100,117, + 108,101,5,6,0,0,115,34,0,0,0,0,2,10,1,10, + 1,4,1,4,1,8,1,8,1,12,2,10,1,4,1,14, + 1,2,1,8,1,8,1,8,1,12,1,12,2,114,82,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 116,0,116,1,160,2,161,0,102,2,125,0,116,3,116,4, + 102,2,125,1,116,5,116,6,102,2,125,2,124,0,124,1, + 124,2,103,3,83,0,41,1,122,95,82,101,116,117,114,110, + 115,32,97,32,108,105,115,116,32,111,102,32,102,105,108,101, + 45,98,97,115,101,100,32,109,111,100,117,108,101,32,108,111, + 97,100,101,114,115,46,10,10,32,32,32,32,69,97,99,104, + 32,105,116,101,109,32,105,115,32,97,32,116,117,112,108,101, + 32,40,108,111,97,100,101,114,44,32,115,117,102,102,105,120, + 101,115,41,46,10,32,32,32,32,41,7,114,253,0,0,0, + 114,164,0,0,0,218,18,101,120,116,101,110,115,105,111,110, + 95,115,117,102,102,105,120,101,115,114,10,1,0,0,114,102, + 0,0,0,114,16,1,0,0,114,89,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,6,0, + 0,0,114,6,0,0,0,114,9,0,0,0,114,185,0,0, + 0,28,6,0,0,115,8,0,0,0,0,5,12,1,8,1, + 8,1,114,185,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,176,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,118,1,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, + 108,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,118,0,114,170,116, + 1,106,3,124,5,25,0,125,8,1,0,113,224,113,106,122, + 20,116,0,160,5,124,5,161,1,125,8,87,0,1,0,113, + 224,87,0,113,106,4,0,116,8,121,212,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,108,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,172,116,14,160,15,100,22,161,1,1, + 0,100,23,116,11,118,0,144,1,114,172,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,65,0,0,0,114,76,0, + 0,0,218,8,98,117,105,108,116,105,110,115,114,161,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,40,0,0, + 0,78,41,1,114,24,0,0,0,41,2,114,33,0,0,0, + 114,95,0,0,0,114,6,0,0,0,114,6,0,0,0,114, + 9,0,0,0,114,20,1,0,0,64,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,74,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,5,0,0,0,114,36,0,0,0, + 114,32,0,0,0,114,41,0,0,0,114,59,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,75,0,0,0,114,6,0,0,0,41, + 2,114,33,0,0,0,218,1,115,114,6,0,0,0,114,6, + 0,0,0,114,9,0,0,0,114,71,1,0,0,80,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,193,0,0,0,114,10,0,0,0,122,4,46,112,121,119, + 122,6,95,100,46,112,121,100,84,78,41,18,114,135,0,0, + 0,114,2,0,0,0,114,164,0,0,0,114,32,1,0,0, + 114,126,0,0,0,90,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,114,130,0,0,0,218,3, + 97,108,108,114,118,0,0,0,114,37,0,0,0,114,15,0, + 0,0,114,22,1,0,0,114,168,0,0,0,114,83,1,0, + 0,114,102,0,0,0,114,187,0,0,0,114,192,0,0,0, + 114,196,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,32,0, + 0,0,114,36,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,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, + 6,95,115,101,116,117,112,39,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,12,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,90, + 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,90,1,0,0,114,185,0,0,0,114,2,0, + 0,0,114,52,1,0,0,114,168,0,0,0,114,62,1,0, + 0,114,77,1,0,0,218,9,109,101,116,97,95,112,97,116, + 104,114,187,0,0,0,114,46,1,0,0,41,2,114,89,1, + 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, + 97,100,101,114,115,114,6,0,0,0,114,6,0,0,0,114, + 9,0,0,0,218,8,95,105,110,115,116,97,108,108,104,6, + 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, + 92,1,0,0,41,1,114,61,0,0,0,41,1,78,41,3, + 78,78,78,41,2,114,74,0,0,0,114,74,0,0,0,41, + 1,84,41,1,78,41,1,78,41,63,114,128,0,0,0,114, + 14,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,13,0,0,0, + 114,15,0,0,0,114,22,0,0,0,114,28,0,0,0,114, + 30,0,0,0,114,39,0,0,0,114,48,0,0,0,114,50, + 0,0,0,114,54,0,0,0,114,55,0,0,0,114,57,0, + 0,0,114,60,0,0,0,114,70,0,0,0,218,4,116,121, + 112,101,218,8,95,95,99,111,100,101,95,95,114,163,0,0, + 0,114,20,0,0,0,114,149,0,0,0,114,19,0,0,0, + 114,25,0,0,0,114,237,0,0,0,114,92,0,0,0,114, + 88,0,0,0,114,102,0,0,0,114,89,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,98,0,0,0,114,103,0,0,0,114,109, + 0,0,0,114,113,0,0,0,114,115,0,0,0,114,137,0, + 0,0,114,144,0,0,0,114,153,0,0,0,114,157,0,0, + 0,114,159,0,0,0,114,166,0,0,0,114,171,0,0,0, + 114,172,0,0,0,114,177,0,0,0,218,6,111,98,106,101, + 99,116,114,186,0,0,0,114,191,0,0,0,114,192,0,0, + 0,114,209,0,0,0,114,222,0,0,0,114,240,0,0,0, + 114,10,1,0,0,114,16,1,0,0,114,22,1,0,0,114, + 253,0,0,0,114,23,1,0,0,114,44,1,0,0,114,46, + 1,0,0,114,62,1,0,0,114,82,1,0,0,114,185,0, + 0,0,114,90,1,0,0,114,92,1,0,0,114,6,0,0, + 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, + 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,126, + 0,0,0,4,22,4,1,4,1,2,1,2,255,4,4,8, + 17,8,5,8,5,8,6,8,6,8,12,8,10,8,9,8, + 5,8,7,8,9,10,22,10,127,0,20,16,1,12,2,4, + 1,4,2,6,2,6,2,8,2,16,71,8,40,8,19,8, + 12,8,12,8,28,8,17,8,33,8,28,8,24,10,13,10, + 10,10,11,8,14,6,3,4,1,2,255,12,68,14,64,14, + 29,16,127,0,17,14,72,18,45,18,26,4,3,18,53,14, + 63,14,42,14,127,0,20,14,127,0,22,10,23,8,11,8, + 65, }; From webhook-mailer at python.org Mon Feb 17 04:09:54 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 17 Feb 2020 09:09:54 -0000 Subject: [Python-checkins] bpo-32892: Update the documentation for handling constants in AST. (GH-18514) Message-ID: https://github.com/python/cpython/commit/988aeba94bf1dab81dd52fc7b02dca7a57ea8ba0 commit: 988aeba94bf1dab81dd52fc7b02dca7a57ea8ba0 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-17T01:09:49-08:00 summary: bpo-32892: Update the documentation for handling constants in AST. (GH-18514) (cherry picked from commit 85a2eef473a2c9ed3ab9c6ee339891fe99adbbc9) Co-authored-by: Serhiy Storchaka files: M Doc/library/ast.rst M Doc/whatsnew/3.8.rst diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index a5dd0e1cc70dd..80afbbce4167e 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -101,12 +101,16 @@ Node classes node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0) +.. versionchanged:: 3.8 + + Class :class:`ast.Constant` is now used for all constants. + .. deprecated:: 3.8 - Class :class:`ast.Constant` is now used for all constants. Old classes - :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, + Old classes :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, :class:`ast.NameConstant` and :class:`ast.Ellipsis` are still available, - but they will be removed in future Python releases. + but they will be removed in future Python releases. In the meanwhile, + instantiating them will return an instance of a different class. .. _abstract-grammar: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 9b61e1f05542d..3ef97c98ca907 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1942,6 +1942,12 @@ Changes in the Python API :exc:`dbm.gnu.error` or :exc:`dbm.ndbm.error`) instead of :exc:`KeyError`. (Contributed by Xiang Zhang in :issue:`33106`.) +* Simplified AST for literals. All constants will be represented as + :class:`ast.Constant` instances. Instantiating old classes ``Num``, + ``Str``, ``Bytes``, ``NameConstant`` and ``Ellipsis`` will return + an instance of ``Constant``. + (Contributed by Serhiy Storchaka in :issue:`32892`.) + * :func:`~os.path.expanduser` on Windows now prefers the :envvar:`USERPROFILE` environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. From webhook-mailer at python.org Mon Feb 17 04:11:38 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 17 Feb 2020 09:11:38 -0000 Subject: [Python-checkins] bpo-1635741: Port _crypt extension module to multiphase initialization (PEP 489) (GH-18404) Message-ID: https://github.com/python/cpython/commit/b2b6e27bcab44e914d0a0b170e915d6f1604a76d commit: b2b6e27bcab44e914d0a0b170e915d6f1604a76d branch: master author: Hai Shi committer: GitHub date: 2020-02-17T10:11:34+01:00 summary: bpo-1635741: Port _crypt extension module to multiphase initialization (PEP 489) (GH-18404) files: A Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6gq.rst M Modules/_cryptmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6gq.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6gq.rst new file mode 100644 index 0000000000000..6b35bdc474fbe --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6gq.rst @@ -0,0 +1 @@ +Port _crypt extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c index 00c1f4f69841b..a95f55a63c306 100644 --- a/Modules/_cryptmodule.c +++ b/Modules/_cryptmodule.c @@ -54,14 +54,17 @@ static PyMethodDef crypt_methods[] = { {NULL, NULL} /* sentinel */ }; +static PyModuleDef_Slot _crypt_slots[] = { + {0, NULL} +}; static struct PyModuleDef cryptmodule = { PyModuleDef_HEAD_INIT, "_crypt", NULL, - -1, + 0, crypt_methods, - NULL, + _crypt_slots, NULL, NULL, NULL @@ -70,5 +73,5 @@ static struct PyModuleDef cryptmodule = { PyMODINIT_FUNC PyInit__crypt(void) { - return PyModule_Create(&cryptmodule); + return PyModuleDef_Init(&cryptmodule); } From webhook-mailer at python.org Mon Feb 17 04:13:56 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Mon, 17 Feb 2020 09:13:56 -0000 Subject: [Python-checkins] [3.8] bpo-39453: Fix contains method of list to hold strong references (GH-18204) Message-ID: https://github.com/python/cpython/commit/f64abd10563c25a94011f9e3335fd8a1cf47c205 commit: f64abd10563c25a94011f9e3335fd8a1cf47c205 branch: 3.8 author: Dong-hee Na committer: GitHub date: 2020-02-17T10:13:52+01:00 summary: [3.8] bpo-39453: Fix contains method of list to hold strong references (GH-18204) files: A Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst M Lib/test/test_list.py M Objects/listobject.c diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index f4dcced9c167f..105ef650eee99 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -216,6 +216,13 @@ def __eq__(self, other): with self.assertRaises(ValueError): lst.remove(lst) + # bpo-39453: list.__contains__ was not holding strong references + # to list elements while calling PyObject_RichCompareBool(). + lst = [X(), X()] + 3 in lst + lst = [X(), X()] + X() in lst + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst new file mode 100644 index 0000000000000..8c2e49f9474c4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst @@ -0,0 +1,2 @@ +Fixed a possible crash in :meth:`list.__contains__` when a list is changed +during comparing items. Patch by Dong-hee Na. diff --git a/Objects/listobject.c b/Objects/listobject.c index 73afc44c39e36..30444089ffaf9 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -445,12 +445,16 @@ list_length(PyListObject *a) static int list_contains(PyListObject *a, PyObject *el) { + PyObject *item; Py_ssize_t i; int cmp; - for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) - cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i), - Py_EQ); + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) { + item = PyList_GET_ITEM(a, i); + Py_INCREF(item); + cmp = PyObject_RichCompareBool(el, item, Py_EQ); + Py_DECREF(item); + } return cmp; } From webhook-mailer at python.org Mon Feb 17 04:18:27 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 17 Feb 2020 09:18:27 -0000 Subject: [Python-checkins] bpo-36465: Update doc of init_config.rst (GH-18520) Message-ID: https://github.com/python/cpython/commit/a7847590f07655e794d7c62130aea245a110acef commit: a7847590f07655e794d7c62130aea245a110acef branch: master author: Hai Shi committer: GitHub date: 2020-02-17T10:18:19+01:00 summary: bpo-36465: Update doc of init_config.rst (GH-18520) files: M Doc/c-api/init_config.rst diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index c589a6fe3f0ab..a226814de805c 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -472,7 +472,7 @@ PyConfig If non-zero, dump all objects which are still alive at exit. - Require a debug build of Python (``Py_REF_DEBUG`` macro must be defined). + ``Py_TRACE_REFS`` macro must be defined in build. .. c:member:: wchar_t* exec_prefix From webhook-mailer at python.org Mon Feb 17 04:30:49 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 17 Feb 2020 09:30:49 -0000 Subject: [Python-checkins] [3.8] bpo-39453: Fix contains method of list to hold strong references (GH-18204) Message-ID: https://github.com/python/cpython/commit/3c57ca699910be74e7cf67d747b24bbc486932f1 commit: 3c57ca699910be74e7cf67d747b24bbc486932f1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-17T01:30:44-08:00 summary: [3.8] bpo-39453: Fix contains method of list to hold strong references (GH-18204) (cherry picked from commit f64abd10563c25a94011f9e3335fd8a1cf47c205) Co-authored-by: Dong-hee Na files: A Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst M Lib/test/test_list.py M Objects/listobject.c diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 553ac8c1cef81..32bf17564c9d9 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -212,6 +212,13 @@ def __eq__(self, other): with self.assertRaises(ValueError): lst.remove(lst) + # bpo-39453: list.__contains__ was not holding strong references + # to list elements while calling PyObject_RichCompareBool(). + lst = [X(), X()] + 3 in lst + lst = [X(), X()] + X() in lst + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst new file mode 100644 index 0000000000000..8c2e49f9474c4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst @@ -0,0 +1,2 @@ +Fixed a possible crash in :meth:`list.__contains__` when a list is changed +during comparing items. Patch by Dong-hee Na. diff --git a/Objects/listobject.c b/Objects/listobject.c index 856f3215e8855..158ca11d03299 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -397,12 +397,16 @@ list_length(PyListObject *a) static int list_contains(PyListObject *a, PyObject *el) { + PyObject *item; Py_ssize_t i; int cmp; - for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) - cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i), - Py_EQ); + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) { + item = PyList_GET_ITEM(a, i); + Py_INCREF(item); + cmp = PyObject_RichCompareBool(el, item, Py_EQ); + Py_DECREF(item); + } return cmp; } From webhook-mailer at python.org Mon Feb 17 05:09:25 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Mon, 17 Feb 2020 10:09:25 -0000 Subject: [Python-checkins] bpo-39573: Clean up modules and headers to use Py_IS_TYPE() function (GH-18521) Message-ID: https://github.com/python/cpython/commit/1b55b65638254aa78b005fbf0b71fb02499f1852 commit: 1b55b65638254aa78b005fbf0b71fb02499f1852 branch: master author: Dong-hee Na committer: GitHub date: 2020-02-17T11:09:15+01:00 summary: bpo-39573: Clean up modules and headers to use Py_IS_TYPE() function (GH-18521) files: M Include/cpython/frameobject.h M Include/longobject.h M Modules/_abc.c M Modules/_asynciomodule.c M Modules/_csv.c M Modules/_ctypes/ctypes.h M Modules/_ctypes/stgdict.c M Modules/_curses_panel.c M Modules/_datetimemodule.c M Modules/_dbmmodule.c M Modules/_decimal/_decimal.c M Modules/_elementtree.c M Modules/_functoolsmodule.c M Modules/_gdbmmodule.c M Modules/_json.c M Modules/_lsprof.c M Modules/_sre.c M Modules/_ssl.c M Modules/_struct.c M Modules/_testbuffer.c M Modules/_tkinter.c M Modules/arraymodule.c M Modules/parsermodule.c M Modules/sha256module.c M Modules/sha512module.c M Modules/timemodule.c M Modules/unicodedata.c M Modules/xxlimited.c M Modules/xxmodule.c M Objects/classobject.c M Objects/dictobject.c M Objects/typeobject.c M Python/hamt.c diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index cf8c00c3528e0..4ced96746aa39 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -51,7 +51,7 @@ typedef struct _frame { PyAPI_DATA(PyTypeObject) PyFrame_Type; -#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type) +#define PyFrame_Check(op) Py_IS_TYPE(op, &PyFrame_Type) PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); diff --git a/Include/longobject.h b/Include/longobject.h index 87b4d017d3234..1b288099da8c8 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -13,7 +13,7 @@ PyAPI_DATA(PyTypeObject) PyLong_Type; #define PyLong_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) -#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) +#define PyLong_CheckExact(op) Py_IS_TYPE(op, &PyLong_Type) PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); diff --git a/Modules/_abc.c b/Modules/_abc.c index 7b5d4180bf873..e21fe782d0a18 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -82,7 +82,7 @@ _get_impl(PyObject *self) if (impl == NULL) { return NULL; } - if (Py_TYPE(impl) != &_abc_data_type) { + if (!Py_IS_TYPE(impl, &_abc_data_type)) { PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type"); Py_DECREF(impl); return NULL; diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5aea74332c5ef..56743301d9eef 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -112,8 +112,8 @@ static PyTypeObject TaskType; static PyTypeObject PyRunningLoopHolder_Type; -#define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType) -#define Task_CheckExact(obj) (Py_TYPE(obj) == &TaskType) +#define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType) +#define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType) #define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) #define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) @@ -255,7 +255,7 @@ get_running_loop(PyObject **loop) cached_running_holder_tsid = ts->id; } - assert(Py_TYPE(rl) == &PyRunningLoopHolder_Type); + assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type)); PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; if (running_loop == Py_None) { diff --git a/Modules/_csv.c b/Modules/_csv.c index 42437728f2ed2..f820f55d80ce4 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -106,7 +106,7 @@ typedef struct { static PyTypeObject Reader_Type; -#define ReaderObject_Check(v) (Py_TYPE(v) == &Reader_Type) +#define ReaderObject_Check(v) Py_IS_TYPE(v, &Reader_Type) typedef struct { PyObject_HEAD diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index a93d573b72b2d..1effccf9cc5ff 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -68,7 +68,7 @@ typedef struct { ffi_type *atypes[1]; } CThunkObject; extern PyTypeObject PyCThunk_Type; -#define CThunk_CheckExact(v) (Py_TYPE(v) == &PyCThunk_Type) +#define CThunk_CheckExact(v) Py_IS_TYPE(v, &PyCThunk_Type) typedef struct { /* First part identical to tagCDataObject */ @@ -102,7 +102,7 @@ typedef struct { } PyCFuncPtrObject; extern PyTypeObject PyCStgDict_Type; -#define PyCStgDict_CheckExact(v) (Py_TYPE(v) == &PyCStgDict_Type) +#define PyCStgDict_CheckExact(v) Py_IS_TYPE(v, &PyCStgDict_Type) #define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); @@ -112,12 +112,12 @@ extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palig extern PyTypeObject PyCData_Type; -#define CDataObject_CheckExact(v) (Py_TYPE(v) == &PyCData_Type) +#define CDataObject_CheckExact(v) Py_IS_TYPE(v, &PyCData_Type) #define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) #define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) extern PyTypeObject PyCSimpleType_Type; -#define PyCSimpleTypeObject_CheckExact(v) (Py_TYPE(v) == &PyCSimpleType_Type) +#define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type) #define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) extern PyTypeObject PyCField_Type; @@ -314,7 +314,7 @@ struct tagPyCArgObject { }; extern PyTypeObject PyCArg_Type; -#define PyCArg_CheckExact(v) (Py_TYPE(v) == &PyCArg_Type) +#define PyCArg_CheckExact(v) Py_IS_TYPE(v, &PyCArg_Type) extern PyCArgObject *PyCArgObject_new(void); extern PyObject * diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index c8001a9781049..443951a6b0302 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -231,7 +231,7 @@ MakeFields(PyObject *type, CFieldObject *descr, Py_DECREF(fieldlist); return -1; } - if (Py_TYPE(fdescr) != &PyCField_Type) { + if (!Py_IS_TYPE(fdescr, &PyCField_Type)) { PyErr_SetString(PyExc_TypeError, "unexpected type"); Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -254,7 +254,7 @@ MakeFields(PyObject *type, CFieldObject *descr, Py_DECREF(fieldlist); return -1; } - assert(Py_TYPE(new_descr) == &PyCField_Type); + assert(Py_IS_TYPE(new_descr, &PyCField_Type)); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; @@ -304,7 +304,7 @@ MakeAnonFields(PyObject *type) Py_DECREF(anon_names); return -1; } - if (Py_TYPE(descr) != &PyCField_Type) { + if (!Py_IS_TYPE(descr, &PyCField_Type)) { PyErr_Format(PyExc_AttributeError, "'%U' is specified in _anonymous_ but not in " "_fields_", diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 53849e3a29cc0..c18af7eebd80a 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -83,7 +83,7 @@ typedef struct { } PyCursesPanelObject; #define PyCursesPanel_Check(v) \ - (Py_TYPE(v) == _curses_panelstate_global->PyCursesPanel_Type) + Py_IS_TYPE(v, _curses_panelstate_global->PyCursesPanel_Type) /* Some helper functions. The problem is that there's always a window associated with a panel. To ensure that Python's GC doesn't pull diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index bc03c504380de..4cafd14012558 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -18,19 +18,19 @@ #endif #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) -#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType) +#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType) #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) -#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType) #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) -#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType) +#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType) #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) -#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType) #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) -#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType) #define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 072e977523696..80a0503622c3f 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -45,7 +45,7 @@ typedef struct { static PyTypeObject Dbmtype; -#define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) +#define is_dbmobject(v) Py_IS_TYPE(v, &Dbmtype) #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ { PyErr_SetString(DbmError, "DBM object has already been closed"); \ return NULL; } diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 0fbbb73a6bdec..e2f6ea17f8927 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -96,9 +96,9 @@ static PyTypeObject PyDec_Type; static PyTypeObject *PyDecSignalDict_Type; static PyTypeObject PyDecContext_Type; static PyTypeObject PyDecContextManager_Type; -#define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type) +#define PyDec_CheckExact(v) Py_IS_TYPE(v, &PyDec_Type) #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) -#define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type) +#define PyDecSignalDict_Check(v) Py_IS_TYPE(v, PyDecSignalDict_Type) #define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type) #define MPD(v) (&((PyDecObject *)v)->dec) #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index a04b295378e4f..4498c5ffd54e0 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -209,7 +209,7 @@ typedef struct { } ElementObject; -#define Element_CheckExact(op) (Py_TYPE(op) == &Element_Type) +#define Element_CheckExact(op) Py_IS_TYPE(op, &Element_Type) #define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 88c02d82dca0a..ab0839cdc7473 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -41,7 +41,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) pargs = pkw = NULL; func = PyTuple_GET_ITEM(args, 0); - if (Py_TYPE(func) == &partial_type && type == &partial_type) { + if (Py_IS_TYPE(func, &partial_type) && type == &partial_type) { partialobject *part = (partialobject *)func; if (part->dict == NULL) { pargs = part->args; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index a815819ee90f3..7a9649b54119b 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -44,7 +44,7 @@ static PyTypeObject Dbmtype; #include "clinic/_gdbmmodule.c.h" -#define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) +#define is_dbmobject(v) Py_IS_TYPE(v, &Dbmtype) #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ { PyErr_SetString(DbmError, "GDBM object has already been closed"); \ return NULL; } diff --git a/Modules/_json.c b/Modules/_json.c index ee2070c043efc..d9346a783e40b 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -13,9 +13,9 @@ #include "pycore_accu.h" #define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) -#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) +#define PyScanner_CheckExact(op) Py_IS_TYPE(op, &PyScannerType) #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) -#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType) +#define PyEncoder_CheckExact(op) Py_IS_TYPE(op, &PyEncoderType) static PyTypeObject PyScannerType; static PyTypeObject PyEncoderType; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index c5a6f4445872c..2718c61944e0b 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -54,7 +54,7 @@ typedef struct { static PyTypeObject PyProfiler_Type; #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) -#define PyProfiler_CheckExact(op) (Py_TYPE(op) == &PyProfiler_Type) +#define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type) /*** External Timers ***/ diff --git a/Modules/_sre.c b/Modules/_sre.c index 80c4184922941..15950c6b60c5c 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2518,7 +2518,7 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op) Py_RETURN_NOTIMPLEMENTED; } - if (Py_TYPE(lefto) != &Pattern_Type || Py_TYPE(righto) != &Pattern_Type) { + if (!Py_IS_TYPE(lefto, &Pattern_Type) || !Py_IS_TYPE(righto, &Pattern_Type)) { Py_RETURN_NOTIMPLEMENTED; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a0d34b34baadc..ef047126361ed 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -508,9 +508,9 @@ static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); static int PySSL_set_session(PySSLSocket *, PyObject *, void *); -#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) -#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type) -#define PySSLSession_Check(v) (Py_TYPE(v) == &PySSLSession_Type) +#define PySSLSocket_Check(v) Py_IS_TYPE(v, &PySSLSocket_Type) +#define PySSLMemoryBIO_Check(v) Py_IS_TYPE(v, &PySSLMemoryBIO_Type) +#define PySSLSession_Check(v) Py_IS_TYPE(v, &PySSLSession_Type) typedef enum { SOCKET_IS_NONBLOCKING, diff --git a/Modules/_struct.c b/Modules/_struct.c index 0cdfe268e645f..eed3659ed884f 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -57,7 +57,7 @@ typedef struct { #define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType) -#define PyStruct_CheckExact(op) (Py_TYPE(op) == (PyTypeObject *)_structmodulestate_global->PyStructType) +#define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType) /* Define various structs to figure out the alignments of types */ diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 600a52aa872f8..f4c2b590ac9c3 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -24,7 +24,7 @@ static PyObject *simple_format = NULL; /**************************************************************************/ static PyTypeObject NDArray_Type; -#define NDArray_Check(v) (Py_TYPE(v) == &NDArray_Type) +#define NDArray_Check(v) Py_IS_TYPE(v, &NDArray_Type) #define CHECK_LIST_OR_TUPLE(v) \ if (!PyList_Check(v) && !PyTuple_Check(v)) { \ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 87bc7ae8aeeab..5f001c6e73c6d 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -833,7 +833,7 @@ typedef struct { } PyTclObject; static PyObject *PyTclObject_Type; -#define PyTclObject_Check(v) (Py_TYPE(v) == (PyTypeObject *) PyTclObject_Type) +#define PyTclObject_Check(v) Py_IS_TYPE(v, (PyTypeObject *) PyTclObject_Type) static PyObject * newPyTclObject(Tcl_Obj *arg) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index eeda714d6a935..b41ba0523b30b 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -106,7 +106,7 @@ enum machine_format_code { #include "clinic/arraymodule.c.h" #define array_Check(op) PyObject_TypeCheck(op, &Arraytype) -#define array_CheckExact(op) (Py_TYPE(op) == &Arraytype) +#define array_CheckExact(op) Py_IS_TYPE(op, &Arraytype) static int array_resize(arrayobject *self, Py_ssize_t newsize) diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index f00329b354182..24b0ffbe36a7d 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -256,7 +256,7 @@ PyTypeObject PyST_Type = { /* PyST_Type isn't subclassable, so just check ob_type */ -#define PyST_Object_Check(v) (Py_TYPE(v) == &PyST_Type) +#define PyST_Object_Check(v) Py_IS_TYPE(v, &PyST_Type) static int parser_compare_nodes(node *left, node *right) diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 0e0c4461880f0..eee582cdd35cc 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -413,7 +413,7 @@ SHA256Type_copy_impl(SHAobject *self) { SHAobject *newobj; - if (Py_TYPE(self) == &SHA256type) { + if (Py_IS_TYPE(self, &SHA256type)) { if ( (newobj = newSHA256object())==NULL) return NULL; } else { diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 07bf28351888b..b2e07273436e9 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -478,7 +478,7 @@ SHA512Type_copy_impl(SHAobject *self) { SHAobject *newobj; - if (Py_TYPE((PyObject*)self) == &SHA512type) { + if (Py_IS_TYPE((PyObject*)self, &SHA512type)) { if ( (newobj = newSHA512object())==NULL) return NULL; } else { diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 5e0010c8a8199..17097206506cf 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -550,7 +550,7 @@ gettmarg(PyObject *args, struct tm *p, const char *format) p->tm_wday = (p->tm_wday + 1) % 7; p->tm_yday--; #ifdef HAVE_STRUCT_TM_TM_ZONE - if (Py_TYPE(args) == &StructTimeType) { + if (Py_IS_TYPE(args, &StructTimeType)) { PyObject *item; item = PyStructSequence_GET_ITEM(args, 9); if (item != Py_None) { diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 58b1bc2d0a105..ce97bdf89f0ac 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -92,7 +92,7 @@ static PyMemberDef DB_members[] = { /* forward declaration */ static PyTypeObject UCD_Type; -#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type) +#define UCD_Check(o) Py_IS_TYPE(o, &UCD_Type) static PyObject* new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index ffc04e0310e39..7ce0b6ec88051 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -25,7 +25,7 @@ typedef struct { static PyObject *Xxo_Type; -#define XxoObject_Check(v) (Py_TYPE(v) == Xxo_Type) +#define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) static XxoObject * newXxoObject(PyObject *arg) diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index 0250031d722d3..17b049c4b9a37 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -25,7 +25,7 @@ typedef struct { static PyTypeObject Xxo_Type; -#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type) +#define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type) static XxoObject * newXxoObject(PyObject *arg) diff --git a/Objects/classobject.c b/Objects/classobject.c index 33afbcd874775..97f50fa1a1edc 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -37,7 +37,7 @@ static PyObject * method_vectorcall(PyObject *method, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - assert(Py_TYPE(method) == &PyMethod_Type); + assert(Py_IS_TYPE(method, &PyMethod_Type)); PyThreadState *tstate = _PyThreadState_GET(); PyObject *self = PyMethod_GET_SELF(method); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 8f6ce3996a172..86ac4ef4816d8 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -608,7 +608,7 @@ new_dict(PyDictKeysObject *keys, PyObject **values) if (numfree) { mp = free_list[--numfree]; assert (mp != NULL); - assert (Py_TYPE(mp) == &PyDict_Type); + assert (Py_IS_TYPE(mp, &PyDict_Type)); _Py_NewReference((PyObject *)mp); } else { @@ -2007,7 +2007,7 @@ dict_dealloc(PyDictObject *mp) assert(keys->dk_refcnt == 1); dictkeys_decref(keys); } - if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type) + if (numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) free_list[numfree++] = mp; else Py_TYPE(mp)->tp_free((PyObject *)mp); @@ -3864,15 +3864,15 @@ dictreviter_iternext(dictiterobject *di) di->di_pos = i-1; di->len--; - if (Py_TYPE(di) == &PyDictRevIterKey_Type) { + if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) { Py_INCREF(key); return key; } - else if (Py_TYPE(di) == &PyDictRevIterValue_Type) { + else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) { Py_INCREF(value); return value; } - else if (Py_TYPE(di) == &PyDictRevIterItem_Type) { + else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) { Py_INCREF(key); Py_INCREF(value); result = di->di_result; @@ -4236,7 +4236,7 @@ _PyDictView_Intersect(PyObject* self, PyObject *other) /* if other is a set and self is smaller than other, reuse set intersection logic */ - if (Py_TYPE(other) == &PySet_Type && len_self <= PyObject_Size(other)) { + if (Py_IS_TYPE(other, &PySet_Type) && len_self <= PyObject_Size(other)) { _Py_IDENTIFIER(intersection); return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f32ccb137987c..e51059b63267c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -302,7 +302,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { each subclass when their mro is recursively updated. */ Py_ssize_t i, n; - int custom = (Py_TYPE(type) != &PyType_Type); + int custom = !Py_IS_TYPE(type, &PyType_Type); int unbound; PyObject *mro_meth = NULL; PyObject *type_mro_meth = NULL; diff --git a/Python/hamt.c b/Python/hamt.c index a0fee4c7a63de..729981033f4a7 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -274,9 +274,9 @@ to introspect the tree: */ -#define IS_ARRAY_NODE(node) (Py_TYPE(node) == &_PyHamt_ArrayNode_Type) -#define IS_BITMAP_NODE(node) (Py_TYPE(node) == &_PyHamt_BitmapNode_Type) -#define IS_COLLISION_NODE(node) (Py_TYPE(node) == &_PyHamt_CollisionNode_Type) +#define IS_ARRAY_NODE(node) Py_IS_TYPE(node, &_PyHamt_ArrayNode_Type) +#define IS_BITMAP_NODE(node) Py_IS_TYPE(node, &_PyHamt_BitmapNode_Type) +#define IS_COLLISION_NODE(node) Py_IS_TYPE(node, &_PyHamt_CollisionNode_Type) /* Return type for 'find' (lookup a key) functions. From webhook-mailer at python.org Mon Feb 17 08:41:23 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 17 Feb 2020 13:41:23 -0000 Subject: [Python-checkins] bpo-39500: Fix compile warnings in unicodeobject.c (GH-18519) Message-ID: https://github.com/python/cpython/commit/3d235f5c5c5bce6e0caec44d2ce17f670c2ca2d7 commit: 3d235f5c5c5bce6e0caec44d2ce17f670c2ca2d7 branch: master author: Hai Shi committer: GitHub date: 2020-02-17T14:41:15+01:00 summary: bpo-39500: Fix compile warnings in unicodeobject.c (GH-18519) files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 11fa1fb5ff798..4475eca9432db 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -12207,8 +12207,8 @@ PyUnicode_IsIdentifier(PyObject *self) return 0; } - int kind; - void *data; + int kind = 0; + void *data = NULL; wchar_t *wstr; if (ready) { kind = PyUnicode_KIND(self); From webhook-mailer at python.org Mon Feb 17 08:49:34 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 17 Feb 2020 13:49:34 -0000 Subject: [Python-checkins] bpo-1635741: Port _contextvars module to multiphase initialization (PEP 489) (GH-18374) Message-ID: https://github.com/python/cpython/commit/7d7956833cc37a9d42807cbfeb7dcc041970f579 commit: 7d7956833cc37a9d42807cbfeb7dcc041970f579 branch: master author: Hai Shi committer: GitHub date: 2020-02-17T14:49:26+01:00 summary: bpo-1635741: Port _contextvars module to multiphase initialization (PEP 489) (GH-18374) files: A Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe1j.rst M Modules/_contextvarsmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe1j.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe1j.rst new file mode 100644 index 0000000000000..49336f02a3e40 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe1j.rst @@ -0,0 +1 @@ +Port _contextvars extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index 1abcdbfa921c2..d6d7f375d1230 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -27,33 +27,15 @@ static PyMethodDef _contextvars_methods[] = { {NULL, NULL} }; -static struct PyModuleDef _contextvarsmodule = { - PyModuleDef_HEAD_INIT, /* m_base */ - "_contextvars", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - _contextvars_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - -PyMODINIT_FUNC -PyInit__contextvars(void) +static int +_contextvars_exec(PyObject *m) { - PyObject *m = PyModule_Create(&_contextvarsmodule); - if (m == NULL) { - return NULL; - } - Py_INCREF(&PyContext_Type); if (PyModule_AddObject(m, "Context", (PyObject *)&PyContext_Type) < 0) { Py_DECREF(&PyContext_Type); - Py_DECREF(m); - return NULL; + return -1; } Py_INCREF(&PyContextVar_Type); @@ -61,8 +43,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextVar_Type) < 0) { Py_DECREF(&PyContextVar_Type); - Py_DECREF(m); - return NULL; + return -1; } Py_INCREF(&PyContextToken_Type); @@ -70,9 +51,31 @@ PyInit__contextvars(void) (PyObject *)&PyContextToken_Type) < 0) { Py_DECREF(&PyContextToken_Type); - Py_DECREF(m); - return NULL; + return -1; } - return m; + return 0; +} + +static struct PyModuleDef_Slot _contextvars_slots[] = { + {Py_mod_exec, _contextvars_exec}, + {0, NULL} +}; + +static struct PyModuleDef _contextvarsmodule = { + PyModuleDef_HEAD_INIT, /* m_base */ + "_contextvars", /* m_name */ + module_doc, /* m_doc */ + 0, /* m_size */ + _contextvars_methods, /* m_methods */ + _contextvars_slots, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__contextvars(void) +{ + return PyModuleDef_Init(&_contextvarsmodule); } From webhook-mailer at python.org Mon Feb 17 08:50:40 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 17 Feb 2020 13:50:40 -0000 Subject: [Python-checkins] bpo-1635741: Port _abc extension to multiphase initialization (PEP 489) (GH-18030) Message-ID: https://github.com/python/cpython/commit/4c1b6a6f4fc46add0097efb3026cf3f0c89f88a2 commit: 4c1b6a6f4fc46add0097efb3026cf3f0c89f88a2 branch: master author: Hai Shi committer: GitHub date: 2020-02-17T14:50:35+01:00 summary: bpo-1635741: Port _abc extension to multiphase initialization (PEP 489) (GH-18030) files: A Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqoBG.rst M Modules/_abc.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqoBG.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqoBG.rst new file mode 100644 index 0000000000000..4dd37a65b0e99 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqoBG.rst @@ -0,0 +1 @@ +Port _abc extension module to multiphase initialization (:pep:`489`). diff --git a/Modules/_abc.c b/Modules/_abc.c index e21fe782d0a18..c991295d311a1 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -807,26 +807,35 @@ static struct PyMethodDef module_functions[] = { {NULL, NULL} /* sentinel */ }; +static int +_abc_exec(PyObject *module) +{ + if (PyType_Ready(&_abc_data_type) < 0) { + return -1; + } + _abc_data_type.tp_doc = abc_data_doc; + return 0; +} + +static PyModuleDef_Slot _abc_slots[] = { + {Py_mod_exec, _abc_exec}, + {0, NULL} +}; + static struct PyModuleDef _abcmodule = { PyModuleDef_HEAD_INIT, "_abc", _abc__doc__, - -1, + 0, module_functions, - NULL, + _abc_slots, NULL, NULL, NULL }; - PyMODINIT_FUNC PyInit__abc(void) { - if (PyType_Ready(&_abc_data_type) < 0) { - return NULL; - } - _abc_data_type.tp_doc = abc_data_doc; - - return PyModule_Create(&_abcmodule); + return PyModuleDef_Init(&_abcmodule); } From webhook-mailer at python.org Mon Feb 17 21:48:14 2020 From: webhook-mailer at python.org (Cheryl Sabella) Date: Tue, 18 Feb 2020 02:48:14 -0000 Subject: [Python-checkins] bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Message-ID: https://github.com/python/cpython/commit/ffda25f6b825f3dee493b6f0746266a4dd6989f0 commit: ffda25f6b825f3dee493b6f0746266a4dd6989f0 branch: master author: Cheryl Sabella committer: GitHub date: 2020-02-17T21:47:52-05:00 summary: bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Test when find_good_parse_start should return 0. Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_pyparse.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 838120964b2d8..021e1f7710e0f 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2020-10-05? ====================================== +bpo-39663: Add tests for pyparse find_good_parse_start(). + bpo-39600: Remove duplicate font names from configuration list. bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index a2b13c38d80d5..f21baf7534420 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -58,6 +58,18 @@ def test_find_good_parse_start(self): p = self.parser setcode = p.set_code start = p.find_good_parse_start + def char_in_string_false(index): return False + + # First line starts with 'def' and ends with ':', then 0 is the pos. + setcode('def spam():\n') + eq(start(char_in_string_false), 0) + + # First line begins with a keyword in the list and ends + # with an open brace, then 0 is the pos. This is how + # hyperparser calls this function as the newline is not added + # in the editor, but rather on the call to setcode. + setcode('class spam( ' + ' \n') + eq(start(char_in_string_false), 0) # Split def across lines. setcode('"""This is a module docstring"""\n' @@ -79,7 +91,7 @@ def test_find_good_parse_start(self): # Make all text look like it's not in a string. This means that it # found a good start position. - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) # If the beginning of the def line is not in a string, then it # returns that as the index. @@ -98,7 +110,7 @@ def test_find_good_parse_start(self): ' def __init__(self, a, b=True):\n' ' pass\n' ) - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) eq(start(is_char_in_string=lambda index: index > 44), 44) eq(start(is_char_in_string=lambda index: index >= 44), 33) # When the def line isn't split, this returns which doesn't match the diff --git a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst new file mode 100644 index 0000000000000..19e16329ce0a0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst @@ -0,0 +1 @@ +Add tests for pyparse find_good_parse_start(). From webhook-mailer at python.org Mon Feb 17 22:05:20 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 18 Feb 2020 03:05:20 -0000 Subject: [Python-checkins] bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Message-ID: https://github.com/python/cpython/commit/fde0041089de2d13e7c473200fb74d3956203987 commit: fde0041089de2d13e7c473200fb74d3956203987 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-17T19:05:14-08:00 summary: bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Test when find_good_parse_start should return 0. Co-authored-by: Terry Jan Reedy (cherry picked from commit ffda25f6b825f3dee493b6f0746266a4dd6989f0) Co-authored-by: Cheryl Sabella files: A Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_pyparse.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 3b1168693c4b5..3c3367244852a 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39663: Add tests for pyparse find_good_parse_start(). + bpo-39600: Remove duplicate font names from configuration list. bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index a2b13c38d80d5..f21baf7534420 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -58,6 +58,18 @@ def test_find_good_parse_start(self): p = self.parser setcode = p.set_code start = p.find_good_parse_start + def char_in_string_false(index): return False + + # First line starts with 'def' and ends with ':', then 0 is the pos. + setcode('def spam():\n') + eq(start(char_in_string_false), 0) + + # First line begins with a keyword in the list and ends + # with an open brace, then 0 is the pos. This is how + # hyperparser calls this function as the newline is not added + # in the editor, but rather on the call to setcode. + setcode('class spam( ' + ' \n') + eq(start(char_in_string_false), 0) # Split def across lines. setcode('"""This is a module docstring"""\n' @@ -79,7 +91,7 @@ def test_find_good_parse_start(self): # Make all text look like it's not in a string. This means that it # found a good start position. - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) # If the beginning of the def line is not in a string, then it # returns that as the index. @@ -98,7 +110,7 @@ def test_find_good_parse_start(self): ' def __init__(self, a, b=True):\n' ' pass\n' ) - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) eq(start(is_char_in_string=lambda index: index > 44), 44) eq(start(is_char_in_string=lambda index: index >= 44), 33) # When the def line isn't split, this returns which doesn't match the diff --git a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst new file mode 100644 index 0000000000000..19e16329ce0a0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst @@ -0,0 +1 @@ +Add tests for pyparse find_good_parse_start(). From webhook-mailer at python.org Mon Feb 17 22:05:43 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 18 Feb 2020 03:05:43 -0000 Subject: [Python-checkins] bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Message-ID: https://github.com/python/cpython/commit/7fd752c1bc637aeca2bd122d07c0ebc379d0d8ca commit: 7fd752c1bc637aeca2bd122d07c0ebc379d0d8ca branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-17T19:05:39-08:00 summary: bpo-39663: IDLE: Add additional tests for pyparse (GH-18536) Test when find_good_parse_start should return 0. Co-authored-by: Terry Jan Reedy (cherry picked from commit ffda25f6b825f3dee493b6f0746266a4dd6989f0) Co-authored-by: Cheryl Sabella files: A Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_pyparse.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 9cf563401259d..fe1706ed5a8be 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39663: Add tests for pyparse find_good_parse_start(). + bpo-39600: Remove duplicate font names from configuration list. bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index a2b13c38d80d5..f21baf7534420 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -58,6 +58,18 @@ def test_find_good_parse_start(self): p = self.parser setcode = p.set_code start = p.find_good_parse_start + def char_in_string_false(index): return False + + # First line starts with 'def' and ends with ':', then 0 is the pos. + setcode('def spam():\n') + eq(start(char_in_string_false), 0) + + # First line begins with a keyword in the list and ends + # with an open brace, then 0 is the pos. This is how + # hyperparser calls this function as the newline is not added + # in the editor, but rather on the call to setcode. + setcode('class spam( ' + ' \n') + eq(start(char_in_string_false), 0) # Split def across lines. setcode('"""This is a module docstring"""\n' @@ -79,7 +91,7 @@ def test_find_good_parse_start(self): # Make all text look like it's not in a string. This means that it # found a good start position. - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) # If the beginning of the def line is not in a string, then it # returns that as the index. @@ -98,7 +110,7 @@ def test_find_good_parse_start(self): ' def __init__(self, a, b=True):\n' ' pass\n' ) - eq(start(is_char_in_string=lambda index: False), 44) + eq(start(char_in_string_false), 44) eq(start(is_char_in_string=lambda index: index > 44), 44) eq(start(is_char_in_string=lambda index: index >= 44), 33) # When the def line isn't split, this returns which doesn't match the diff --git a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst new file mode 100644 index 0000000000000..19e16329ce0a0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst @@ -0,0 +1 @@ +Add tests for pyparse find_good_parse_start(). From webhook-mailer at python.org Tue Feb 18 04:49:08 2020 From: webhook-mailer at python.org (Kyle Meyer) Date: Tue, 18 Feb 2020 09:49:08 -0000 Subject: [Python-checkins] bpo-39546: argparse: Honor allow_abbrev=False for specified prefix_chars (GH-18337) Message-ID: https://github.com/python/cpython/commit/8edfc47baec7ff4cb1b9db83dd35c8ffc1d498a4 commit: 8edfc47baec7ff4cb1b9db83dd35c8ffc1d498a4 branch: master author: Kyle Meyer committer: GitHub date: 2020-02-18T01:48:57-08:00 summary: bpo-39546: argparse: Honor allow_abbrev=False for specified prefix_chars (GH-18337) When `allow_abbrev` was first added, disabling the abbreviation of long options broke the grouping of short flags ([bpo-26967](https://bugs.python.org/issue26967)). As a fix, b1e4d1b603 (contained in v3.8) ignores `allow_abbrev=False` for a given argument string if the string does _not_ start with "--" (i.e. it doesn't look like a long option). This fix, however, doesn't take into account that long options can start with alternative characters specified via `prefix_chars`, introducing a regression: `allow_abbrev=False` has no effect on long options that start with an alternative prefix character. The most minimal fix would be to replace the "starts with --" check with a "starts with two prefix_chars characters". But `_get_option_tuples` already distinguishes between long and short options, so let's instead piggyback off of that check by moving the `allow_abbrev` condition into `_get_option_tuples`. https://bugs.python.org/issue39546 files: A Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst M Lib/argparse.py M Lib/test/test_argparse.py M Misc/ACKS diff --git a/Lib/argparse.py b/Lib/argparse.py index 5d3ce2ad709f0..9c710cef5b6aa 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2199,24 +2199,23 @@ def _parse_optional(self, arg_string): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - if self.allow_abbrev or not arg_string.startswith('--'): - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} - msg = _('ambiguous option: %(option)s could match %(matches)s') - self.error(msg % args) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple # if it was not found as an option, but it looks like a negative # number, it was meant to be positional @@ -2240,16 +2239,17 @@ def _get_option_tuples(self, option_string): # split at the '=' chars = self.prefix_chars if option_string[0] in chars and option_string[1] in chars: - if '=' in option_string: - option_prefix, explicit_arg = option_string.split('=', 1) - else: - option_prefix = option_string - explicit_arg = None - for option_string in self._option_string_actions: - if option_string.startswith(option_prefix): - action = self._option_string_actions[option_string] - tup = action, option_string, explicit_arg - result.append(tup) + if self.allow_abbrev: + if '=' in option_string: + option_prefix, explicit_arg = option_string.split('=', 1) + else: + option_prefix = option_string + explicit_arg = None + for option_string in self._option_string_actions: + if option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) # single character options can be concatenated with their arguments # but multiple character options always have to have their argument diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 60bf19918b79e..b095783a02e1e 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -810,6 +810,23 @@ class TestOptionalsDisallowLongAbbreviation(ParserTestCase): ] +class TestOptionalsDisallowLongAbbreviationPrefixChars(ParserTestCase): + """Disallowing abbreviations works with alternative prefix characters""" + + parser_signature = Sig(prefix_chars='+', allow_abbrev=False) + argument_signatures = [ + Sig('++foo'), + Sig('++foodle', action='store_true'), + Sig('++foonly'), + ] + failures = ['+foon 3', '++foon 3', '++food', '++food ++foo 2'] + successes = [ + ('', NS(foo=None, foodle=False, foonly=None)), + ('++foo 3', NS(foo='3', foodle=False, foonly=None)), + ('++foonly 7 ++foodle ++foo 2', NS(foo='2', foodle=True, foonly='7')), + ] + + class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): """Do not allow abbreviations of long options at all""" @@ -828,6 +845,26 @@ class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): ('-ccrcc', NS(r='cc', c=2)), ] + +class TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase): + """Short option grouping works with custom prefix and allow_abbrev=False""" + + parser_signature = Sig(prefix_chars='+', allow_abbrev=False) + argument_signatures = [ + Sig('+r'), + Sig('+c', action='count'), + ] + failures = ['+r', '+c +r'] + successes = [ + ('', NS(r=None, c=None)), + ('+ra', NS(r='a', c=None)), + ('+rcc', NS(r='cc', c=None)), + ('+cc', NS(r=None, c=2)), + ('+cc +ra', NS(r='a', c=2)), + ('+ccrcc', NS(r='cc', c=2)), + ] + + # ================ # Positional tests # ================ diff --git a/Misc/ACKS b/Misc/ACKS index 933402069b4fd..e8ce30310bfd8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1112,6 +1112,7 @@ Bruce Merry Alexis M?taireau Luke Mewburn Carl Meyer +Kyle Meyer Mike Meyer Piotr Meyer Steven Miale diff --git a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst new file mode 100644 index 0000000000000..8f035e79963e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst @@ -0,0 +1,3 @@ +Fix a regression in :class:`~argparse.ArgumentParser` where +``allow_abbrev=False`` was ignored for long options that used a prefix +character other than "-". From webhook-mailer at python.org Tue Feb 18 06:14:12 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 18 Feb 2020 11:14:12 -0000 Subject: [Python-checkins] [3.8] bpo-39546: argparse: Honor allow_abbrev=False for specified prefix_chars (GH-18337) (GH-18543) Message-ID: https://github.com/python/cpython/commit/e412cbba52e7cf6699720d99a4b88baef92db7b2 commit: e412cbba52e7cf6699720d99a4b88baef92db7b2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-18T03:14:07-08:00 summary: [3.8] bpo-39546: argparse: Honor allow_abbrev=False for specified prefix_chars (GH-18337) (GH-18543) When `allow_abbrev` was first added, disabling the abbreviation of long options broke the grouping of short flags ([bpo-26967](https://bugs.python.org/issue26967)). As a fix, b1e4d1b603 (contained in v3.8) ignores `allow_abbrev=False` for a given argument string if the string does _not_ start with "--" (i.e. it doesn't look like a long option). This fix, however, doesn't take into account that long options can start with alternative characters specified via `prefix_chars`, introducing a regression: `allow_abbrev=False` has no effect on long options that start with an alternative prefix character. The most minimal fix would be to replace the "starts with --" check with a "starts with two prefix_chars characters". But `_get_option_tuples` already distinguishes between long and short options, so let's instead piggyback off of that check by moving the `allow_abbrev` condition into `_get_option_tuples`. https://bugs.python.org/issue39546 (cherry picked from commit 8edfc47baec7ff4cb1b9db83dd35c8ffc1d498a4) Co-authored-by: Kyle Meyer https://bugs.python.org/issue39546 Automerge-Triggered-By: @encukou files: A Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst M Lib/argparse.py M Lib/test/test_argparse.py M Misc/ACKS diff --git a/Lib/argparse.py b/Lib/argparse.py index fd61bc78c2c3d..2dad5f123f390 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2144,24 +2144,23 @@ def _parse_optional(self, arg_string): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - if self.allow_abbrev or not arg_string.startswith('--'): - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} - msg = _('ambiguous option: %(option)s could match %(matches)s') - self.error(msg % args) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple # if it was not found as an option, but it looks like a negative # number, it was meant to be positional @@ -2185,16 +2184,17 @@ def _get_option_tuples(self, option_string): # split at the '=' chars = self.prefix_chars if option_string[0] in chars and option_string[1] in chars: - if '=' in option_string: - option_prefix, explicit_arg = option_string.split('=', 1) - else: - option_prefix = option_string - explicit_arg = None - for option_string in self._option_string_actions: - if option_string.startswith(option_prefix): - action = self._option_string_actions[option_string] - tup = action, option_string, explicit_arg - result.append(tup) + if self.allow_abbrev: + if '=' in option_string: + option_prefix, explicit_arg = option_string.split('=', 1) + else: + option_prefix = option_string + explicit_arg = None + for option_string in self._option_string_actions: + if option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) # single character options can be concatenated with their arguments # but multiple character options always have to have their argument diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 86ec6cca51acc..0753a4b59652d 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -786,6 +786,23 @@ class TestOptionalsDisallowLongAbbreviation(ParserTestCase): ] +class TestOptionalsDisallowLongAbbreviationPrefixChars(ParserTestCase): + """Disallowing abbreviations works with alternative prefix characters""" + + parser_signature = Sig(prefix_chars='+', allow_abbrev=False) + argument_signatures = [ + Sig('++foo'), + Sig('++foodle', action='store_true'), + Sig('++foonly'), + ] + failures = ['+foon 3', '++foon 3', '++food', '++food ++foo 2'] + successes = [ + ('', NS(foo=None, foodle=False, foonly=None)), + ('++foo 3', NS(foo='3', foodle=False, foonly=None)), + ('++foonly 7 ++foodle ++foo 2', NS(foo='2', foodle=True, foonly='7')), + ] + + class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): """Do not allow abbreviations of long options at all""" @@ -804,6 +821,26 @@ class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): ('-ccrcc', NS(r='cc', c=2)), ] + +class TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase): + """Short option grouping works with custom prefix and allow_abbrev=False""" + + parser_signature = Sig(prefix_chars='+', allow_abbrev=False) + argument_signatures = [ + Sig('+r'), + Sig('+c', action='count'), + ] + failures = ['+r', '+c +r'] + successes = [ + ('', NS(r=None, c=None)), + ('+ra', NS(r='a', c=None)), + ('+rcc', NS(r='cc', c=None)), + ('+cc', NS(r=None, c=2)), + ('+cc +ra', NS(r='a', c=2)), + ('+ccrcc', NS(r='cc', c=2)), + ] + + # ================ # Positional tests # ================ diff --git a/Misc/ACKS b/Misc/ACKS index 21ee85b4558ed..69ed251b988db 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1096,6 +1096,7 @@ Brian Merrell Alexis M?taireau Luke Mewburn Carl Meyer +Kyle Meyer Mike Meyer Piotr Meyer Steven Miale diff --git a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst new file mode 100644 index 0000000000000..8f035e79963e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst @@ -0,0 +1,3 @@ +Fix a regression in :class:`~argparse.ArgumentParser` where +``allow_abbrev=False`` was ignored for long options that used a prefix +character other than "-". From webhook-mailer at python.org Tue Feb 18 06:17:46 2020 From: webhook-mailer at python.org (Hai Shi) Date: Tue, 18 Feb 2020 11:17:46 -0000 Subject: [Python-checkins] bpo-1635741: Port _bz2 extension module to multiphase initialization(PEP 489) (GH-18050) Message-ID: https://github.com/python/cpython/commit/5d38517aa1836542a5417b724c093bcb245f0f47 commit: 5d38517aa1836542a5417b724c093bcb245f0f47 branch: master author: Hai Shi committer: GitHub date: 2020-02-18T03:17:38-08:00 summary: bpo-1635741: Port _bz2 extension module to multiphase initialization(PEP 489) (GH-18050) https://bugs.python.org/issue1635741 files: A Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKROOt.rst M Modules/_bz2module.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKROOt.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKROOt.rst new file mode 100644 index 0000000000000..d3f12a747963a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKROOt.rst @@ -0,0 +1 @@ +Port _bz2 extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index 31bbf66104119..fe5880989873e 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -728,13 +728,45 @@ static PyTypeObject BZ2Decompressor_Type = { /* Module initialization. */ +static int +_bz2_exec(PyObject *module) +{ + if (PyType_Ready(&BZ2Compressor_Type) < 0) { + return -1; + } + if (PyType_Ready(&BZ2Decompressor_Type) < 0) { + return -1; + } + + Py_INCREF(&BZ2Compressor_Type); + if (PyModule_AddObject(module, "BZ2Compressor", + (PyObject *)&BZ2Compressor_Type) < 0) { + Py_DECREF(&BZ2Compressor_Type); + return -1; + } + + Py_INCREF(&BZ2Decompressor_Type); + if (PyModule_AddObject(module, "BZ2Decompressor", + (PyObject *)&BZ2Decompressor_Type) < 0) { + Py_INCREF(&BZ2Decompressor_Type); + return -1; + } + + return 0; +} + +static struct PyModuleDef_Slot _bz2_slots[] = { + {Py_mod_exec, _bz2_exec}, + {0, NULL} +}; + static struct PyModuleDef _bz2module = { PyModuleDef_HEAD_INIT, "_bz2", NULL, - -1, - NULL, + 0, NULL, + _bz2_slots, NULL, NULL, NULL @@ -743,23 +775,5 @@ static struct PyModuleDef _bz2module = { PyMODINIT_FUNC PyInit__bz2(void) { - PyObject *m; - - if (PyType_Ready(&BZ2Compressor_Type) < 0) - return NULL; - if (PyType_Ready(&BZ2Decompressor_Type) < 0) - return NULL; - - m = PyModule_Create(&_bz2module); - if (m == NULL) - return NULL; - - Py_INCREF(&BZ2Compressor_Type); - PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Compressor_Type); - - Py_INCREF(&BZ2Decompressor_Type); - PyModule_AddObject(m, "BZ2Decompressor", - (PyObject *)&BZ2Decompressor_Type); - - return m; + return PyModuleDef_Init(&_bz2module); } From webhook-mailer at python.org Tue Feb 18 08:14:48 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 18 Feb 2020 13:14:48 -0000 Subject: [Python-checkins] bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150) (GH-18546) Message-ID: https://github.com/python/cpython/commit/5bf58cef151249f1cca92166d1b70693348da9d8 commit: 5bf58cef151249f1cca92166d1b70693348da9d8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-18T14:14:43+01:00 summary: bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150) (GH-18546) Make it export the correct init symbol also on Windows. https://bugs.python.org/issue39432 (cherry picked from commit 9538bc9185e934bee2bd5ae2cda2b2e92a61906d) Co-authored-by: Stefan Behnel files: A Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst M Lib/distutils/command/build_ext.py M Lib/distutils/tests/test_build_ext.py diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 2d7cdf063f01d..dbcd9d16f28c5 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -688,7 +688,15 @@ def get_export_symbols(self, ext): provided, "PyInit_" + module_name. Only relevant on Windows, where the .pyd file (DLL) must export the module "PyInit_" function. """ - initfunc_name = "PyInit_" + ext.name.split('.')[-1] + suffix = '_' + ext.name.split('.')[-1] + try: + # Unicode module name support as defined in PEP-489 + # https://www.python.org/dev/peps/pep-0489/#export-hook-name + suffix.encode('ascii') + except UnicodeEncodeError: + suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') + + initfunc_name = "PyInit" + suffix if initfunc_name not in ext.export_symbols: ext.export_symbols.append(initfunc_name) return ext.export_symbols diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 52d36b2484f41..7e3eafa8ef231 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -304,6 +304,19 @@ def test_get_source_files(self): cmd.ensure_finalized() self.assertEqual(cmd.get_source_files(), ['xxx']) + def test_unicode_module_names(self): + modules = [ + Extension('foo', ['aaa'], optional=False), + Extension('f??', ['uuu'], optional=False), + ] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = self.build_ext(dist) + cmd.ensure_finalized() + self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo\..*') + self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??\..*') + self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) + self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) + def test_compiler_option(self): # cmd.compiler is an option and # should not be overridden by a compiler instance diff --git a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst new file mode 100644 index 0000000000000..21c4ba8620755 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst @@ -0,0 +1 @@ +Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in distutils to make it export the correct init symbol also on Windows. From webhook-mailer at python.org Tue Feb 18 08:14:51 2020 From: webhook-mailer at python.org (Jeroen Demeyer) Date: Tue, 18 Feb 2020 13:14:51 -0000 Subject: [Python-checkins] bpo-36347: stop using RESTRICTED constants (GH-12684) Message-ID: https://github.com/python/cpython/commit/24bba8cf5b8db25c19bcd1d94e8e356874d1c723 commit: 24bba8cf5b8db25c19bcd1d94e8e356874d1c723 branch: master author: Jeroen Demeyer committer: GitHub date: 2020-02-18T05:14:46-08:00 summary: bpo-36347: stop using RESTRICTED constants (GH-12684) The constants `RESTRICTED` and `PY_WRITE_RESTRICTED` no longer have a meaning in Python 3. Therefore, CPython should not use them. CC @matrixise https://bugs.python.org/issue36347 files: M Objects/classobject.c M Objects/funcobject.c M Objects/methodobject.c diff --git a/Objects/classobject.c b/Objects/classobject.c index 97f50fa1a1edc..999b91c0a2dc8 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -145,9 +145,9 @@ static PyMethodDef method_methods[] = { #define MO_OFF(x) offsetof(PyMethodObject, x) static PyMemberDef method_memberlist[] = { - {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED, + {"__func__", T_OBJECT, MO_OFF(im_func), READONLY, "the function (or other callable) implementing a method"}, - {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED, + {"__self__", T_OBJECT, MO_OFF(im_self), READONLY, "the instance to which a method is bound"}, {NULL} /* Sentinel */ }; @@ -400,7 +400,7 @@ PyInstanceMethod_Function(PyObject *im) #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) static PyMemberDef instancemethod_memberlist[] = { - {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED, + {"__func__", T_OBJECT, IMO_OFF(func), READONLY, "the function (or other callable) implementing a method"}, {NULL} /* Sentinel */ }; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 419db33602a36..3ec949d573bf5 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -239,12 +239,10 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) #define OFF(x) offsetof(PyFunctionObject, x) static PyMemberDef func_memberlist[] = { - {"__closure__", T_OBJECT, OFF(func_closure), - RESTRICTED|READONLY}, - {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED}, - {"__globals__", T_OBJECT, OFF(func_globals), - RESTRICTED|READONLY}, - {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED}, + {"__closure__", T_OBJECT, OFF(func_closure), READONLY}, + {"__doc__", T_OBJECT, OFF(func_doc), 0}, + {"__globals__", T_OBJECT, OFF(func_globals), READONLY}, + {"__module__", T_OBJECT, OFF(func_module), 0}, {NULL} /* Sentinel */ }; diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 1d54c4cea6900..0d4570534b1ae 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -222,7 +222,7 @@ static PyGetSetDef meth_getsets [] = { #define OFF(x) offsetof(PyCFunctionObject, x) static PyMemberDef meth_members[] = { - {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED}, + {"__module__", T_OBJECT, OFF(m_module), 0}, {NULL} }; From webhook-mailer at python.org Tue Feb 18 10:13:25 2020 From: webhook-mailer at python.org (Petr Viktorin) Date: Tue, 18 Feb 2020 15:13:25 -0000 Subject: [Python-checkins] bpo-37207: Use vectorcall for range() (GH-18464) Message-ID: https://github.com/python/cpython/commit/6e35da976370e7c2e028165c65d7d7d42772a71f commit: 6e35da976370e7c2e028165c65d7d7d42772a71f branch: master author: Petr Viktorin committer: GitHub date: 2020-02-18T07:13:17-08:00 summary: bpo-37207: Use vectorcall for range() (GH-18464) This continues the `range()` part of #13930. The complete pull request is stalled on discussions around dicts, but `range()` should not be controversial. (And I plan to open PRs for other parts if this is merged.) On top of Mark's change, I unified `range_new` and `range_vectorcall`, which had a lot of duplicate code. https://bugs.python.org/issue37207 files: A Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR.rst M Objects/rangeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR.rst new file mode 100644 index 0000000000000..c20d48a493c34 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR.rst @@ -0,0 +1,2 @@ +Speed up calls to ``range()`` by about 30%, by using the +PEP 590 ``vectorcall`` calling convention. Patch by Mark Shannon. diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 343a80c76b0bc..123ca0b032e0e 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "structmember.h" +#include "pycore_tupleobject.h" /* Support objects whose length is > PY_SSIZE_T_MAX. @@ -71,34 +72,27 @@ make_range_object(PyTypeObject *type, PyObject *start, range(0, 5, -1) */ static PyObject * -range_new(PyTypeObject *type, PyObject *args, PyObject *kw) +range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) { rangeobject *obj; PyObject *start = NULL, *stop = NULL, *step = NULL; - if (!_PyArg_NoKeywords("range", kw)) - return NULL; - - Py_ssize_t num_args = PyTuple_GET_SIZE(args); switch (num_args) { case 3: - step = PyTuple_GET_ITEM(args, 2); + step = args[2]; /* fallthrough */ case 2: - start = PyTuple_GET_ITEM(args, 0); - start = PyNumber_Index(start); + /* Convert borrowed refs to owned refs */ + start = PyNumber_Index(args[0]); if (!start) { return NULL; } - - stop = PyTuple_GET_ITEM(args, 1); - stop = PyNumber_Index(stop); + stop = PyNumber_Index(args[1]); if (!stop) { Py_DECREF(start); return NULL; } - - step = validate_step(step); + step = validate_step(step); /* Caution, this can clear exceptions */ if (!step) { Py_DECREF(start); Py_DECREF(stop); @@ -106,8 +100,7 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) } break; case 1: - stop = PyTuple_GET_ITEM(args, 0); - stop = PyNumber_Index(stop); + stop = PyNumber_Index(args[0]); if (!stop) { return NULL; } @@ -126,10 +119,10 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) num_args); return NULL; } - obj = make_range_object(type, start, stop, step); - if (obj != NULL) + if (obj != NULL) { return (PyObject *) obj; + } /* Failed to create object, release attributes */ Py_DECREF(start); @@ -138,6 +131,28 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } +static PyObject * +range_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + if (!_PyArg_NoKeywords("range", kw)) + return NULL; + + return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args)); +} + + +static PyObject * +range_vectorcall(PyTypeObject *type, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) { + PyErr_Format(PyExc_TypeError, "range() takes no keyword arguments"); + return NULL; + } + return range_from_array(type, args, nargs); +} + PyDoc_STRVAR(range_doc, "range(stop) -> range object\n\ range(start, stop[, step]) -> range object\n\ @@ -719,6 +734,7 @@ PyTypeObject PyRange_Type = { 0, /* tp_init */ 0, /* tp_alloc */ range_new, /* tp_new */ + .tp_vectorcall = (vectorcallfunc)range_vectorcall }; /*********************** range Iterator **************************/ From webhook-mailer at python.org Tue Feb 18 10:29:01 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 18 Feb 2020 15:29:01 -0000 Subject: [Python-checkins] bpo-39674: Revert "bpo-25988: Do not expose abstract collection classes in the collections module. (GH-10596)" (GH-18545) Message-ID: https://github.com/python/cpython/commit/af5ee3ff610377ef446c2d88bbfcbb3dffaaf0c9 commit: af5ee3ff610377ef446c2d88bbfcbb3dffaaf0c9 branch: master author: Victor Stinner committer: GitHub date: 2020-02-18T16:28:53+01:00 summary: bpo-39674: Revert "bpo-25988: Do not expose abstract collection classes in the collections module. (GH-10596)" (GH-18545) This reverts commit ef092fe9905f61ca27889092ca1248a11aa74498. Update collections __getattr__() and documentation to defer aliases removal to Python 3.10. files: A Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst M Doc/library/collections.rst M Doc/whatsnew/3.9.rst M Lib/collections/__init__.py diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index a5e8d04099b22..65cdf34aa4e4f 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -33,7 +33,7 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`, :class:`UserString` wrapper around string objects for easier string subclassing ===================== ==================================================================== -.. deprecated-removed:: 3.3 3.9 +.. deprecated-removed:: 3.3 3.10 Moved :ref:`collections-abstract-base-classes` to the :mod:`collections.abc` module. For backwards compatibility, they continue to be visible in this module through Python 3.8. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 23f0e4306ee63..f7e279b379f12 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -471,11 +471,6 @@ Removed since Python 3.2. (Contributed by Victor Stinner in :issue:`38916`.) -* The abstract base classes in :mod:`collections.abc` no longer are - exposed in the regular :mod:`collections` module. This will help - create a clearer distinction between the concrete classes and the abstract - base classes. - * The undocumented ``sys.callstats()`` function has been removed. Since Python 3.7, it was deprecated and always returned :const:`None`. It required a special build option ``CALL_PROFILE`` which was already removed in Python 3.7. diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index cec6c9781a15e..178cdb1fa5ba0 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -39,6 +39,21 @@ pass +def __getattr__(name): + # For backwards compatibility, continue to make the collections ABCs + # through Python 3.6 available through the collections module. + # Note, no new collections ABCs were added in Python 3.7 + if name in _collections_abc.__all__: + obj = getattr(_collections_abc, name) + import warnings + warnings.warn("Using or importing the ABCs from 'collections' instead " + "of from 'collections.abc' is deprecated since Python 3.3, " + "and in 3.10 it will stop working", + DeprecationWarning, stacklevel=2) + globals()[name] = obj + return obj + raise AttributeError(f'module {__name__!r} has no attribute {name!r}') + ################################################################################ ### OrderedDict ################################################################################ diff --git a/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst b/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst new file mode 100644 index 0000000000000..1d0e906242ae1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst @@ -0,0 +1,4 @@ +Revert "Do not expose abstract collection classes in the collections module" +change (bpo-25988). Aliases to ABC like collections.Mapping are kept in +Python 3.9 to ease transition from Python 2.7, but will be removed in Python +3.10. From webhook-mailer at python.org Tue Feb 18 16:39:32 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 18 Feb 2020 21:39:32 -0000 Subject: [Python-checkins] bpo-39555: Fix distutils test to handle _d suffix on Windows debug build (GH-18357) (GH-18548) Message-ID: https://github.com/python/cpython/commit/d77e77116fa7a9fc85be1d9f417c7e9e33fe1296 commit: d77e77116fa7a9fc85be1d9f417c7e9e33fe1296 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-18T22:39:19+01:00 summary: bpo-39555: Fix distutils test to handle _d suffix on Windows debug build (GH-18357) (GH-18548) https://bugs.python.org/issue39555 Co-authored-by: Steve Dower (cherry picked from commit ab0d892288f3058856a8213333e8c3e4ed8a562b) files: M Lib/distutils/tests/test_build_ext.py diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 7e3eafa8ef231..5e47e0773a964 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -312,8 +312,8 @@ def test_unicode_module_names(self): dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = self.build_ext(dist) cmd.ensure_finalized() - self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo\..*') - self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??\..*') + self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo(_d)?\..*') + self.assertRegex(cmd.get_ext_filename(modules[1].name), r'f??(_d)?\..*') self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) From webhook-mailer at python.org Tue Feb 18 18:01:38 2020 From: webhook-mailer at python.org (Cheryl Sabella) Date: Tue, 18 Feb 2020 23:01:38 -0000 Subject: [Python-checkins] Include subsections in TOC for PDF version of docs. (GH-9629) Message-ID: https://github.com/python/cpython/commit/a4ba8a3983356fceb4aedabe0c338180666a79aa commit: a4ba8a3983356fceb4aedabe0c338180666a79aa branch: master author: Cheryl Sabella committer: GitHub date: 2020-02-19T00:01:15+01:00 summary: Include subsections in TOC for PDF version of docs. (GH-9629) files: A Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index abaa760c98c1a..32db34344a70a 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -127,6 +127,7 @@ } \let\Verbatim=\OriginalVerbatim \let\endVerbatim=\endOriginalVerbatim +\setcounter{tocdepth}{2} ''' # The paper size ('letter' or 'a4'). diff --git a/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst b/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst new file mode 100644 index 0000000000000..98e1c286e8613 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst @@ -0,0 +1 @@ +Include subsection in TOC for PDF version of docs. From webhook-mailer at python.org Tue Feb 18 23:33:13 2020 From: webhook-mailer at python.org (ananthan-123) Date: Wed, 19 Feb 2020 04:33:13 -0000 Subject: [Python-checkins] =?utf-8?q?bpo-39572=3A_Document_=E2=80=99total?= =?utf-8?q?=E2=80=99_flag_of_TypedDict_=28GH-18554=29?= Message-ID: https://github.com/python/cpython/commit/ab6423fe2de0ed5f8a0dc86a9c7070229326b0f0 commit: ab6423fe2de0ed5f8a0dc86a9c7070229326b0f0 branch: master author: ananthan-123 committer: GitHub date: 2020-02-18T20:33:05-08:00 summary: bpo-39572: Document ?total? flag of TypedDict (GH-18554) files: A Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst M Doc/library/typing.rst M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index d3bab94c6dd40..eac75ee8654f5 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -996,8 +996,20 @@ The module defines the following classes, functions and decorators: Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) - See :pep:`589` for more examples and detailed rules of using ``TypedDict`` - with type checkers. + By default, all keys must be present in a TypedDict. It is possible + to override this by specifying totality. + Usage:: + + class point2D(TypedDict, total=False): + x: int + y: int + + This means that a point2D TypedDict can have any of the keys omitted.A type + checker is only expected to support a literal False or True as the value of + the total argument. True is the default, and makes all items defined in the + class body be required. + + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 diff --git a/Lib/typing.py b/Lib/typing.py index 6da145fcdb83a..0a685d304bd96 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -13,7 +13,7 @@ * Public helper functions: get_type_hints, overload, cast, no_type_check, no_type_check_decorator. * Generic aliases for collections.abc ABCs and few additional protocols. -* Special types: NewType, NamedTuple, TypedDict (may be added soon). +* Special types: NewType, NamedTuple, TypedDict. * Wrapper submodules for re and io related types. """ @@ -1885,6 +1885,19 @@ class Point2D(TypedDict): Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + By default, all keys must be present in a TypedDict. It is possible + to override this by specifying totality. + Usage:: + + class point2D(TypedDict, total=False): + x: int + y: int + + This means that a point2D TypedDict can have any of the keys omitted.A type + checker is only expected to support a literal False or True as the value of + the total argument. True is the default, and makes all items defined in the + class body be required. + The class syntax is only supported in Python 3.6+, while two other syntax forms work for Python 2.7 and 3.2+ """ diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst new file mode 100644 index 0000000000000..d47bb455e71d1 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst @@ -0,0 +1 @@ +Updated documentation of ``total`` flag of TypeDict. From webhook-mailer at python.org Wed Feb 19 00:24:58 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 19 Feb 2020 05:24:58 -0000 Subject: [Python-checkins] =?utf-8?q?bpo-39572=3A_Document_=E2=80=99total?= =?utf-8?q?=E2=80=99_flag_of_TypedDict_=28GH-18554=29?= Message-ID: https://github.com/python/cpython/commit/44c690112d96a81fe02433de7900a4f8f9457012 commit: 44c690112d96a81fe02433de7900a4f8f9457012 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-18T21:24:51-08:00 summary: bpo-39572: Document ?total? flag of TypedDict (GH-18554) (cherry picked from commit ab6423fe2de0ed5f8a0dc86a9c7070229326b0f0) Co-authored-by: ananthan-123 files: A Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst M Doc/library/typing.rst M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 323dac2082201..a9c7c4756dd0d 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -996,8 +996,20 @@ The module defines the following classes, functions and decorators: Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) - See :pep:`589` for more examples and detailed rules of using ``TypedDict`` - with type checkers. + By default, all keys must be present in a TypedDict. It is possible + to override this by specifying totality. + Usage:: + + class point2D(TypedDict, total=False): + x: int + y: int + + This means that a point2D TypedDict can have any of the keys omitted.A type + checker is only expected to support a literal False or True as the value of + the total argument. True is the default, and makes all items defined in the + class body be required. + + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 diff --git a/Lib/typing.py b/Lib/typing.py index 83d310f3c0dd3..7aab8db065670 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -13,7 +13,7 @@ * Public helper functions: get_type_hints, overload, cast, no_type_check, no_type_check_decorator. * Generic aliases for collections.abc ABCs and few additional protocols. -* Special types: NewType, NamedTuple, TypedDict (may be added soon). +* Special types: NewType, NamedTuple, TypedDict. * Wrapper submodules for re and io related types. """ @@ -1779,6 +1779,19 @@ class Point2D(TypedDict): Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + By default, all keys must be present in a TypedDict. It is possible + to override this by specifying totality. + Usage:: + + class point2D(TypedDict, total=False): + x: int + y: int + + This means that a point2D TypedDict can have any of the keys omitted.A type + checker is only expected to support a literal False or True as the value of + the total argument. True is the default, and makes all items defined in the + class body be required. + The class syntax is only supported in Python 3.6+, while two other syntax forms work for Python 2.7 and 3.2+ """ diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst new file mode 100644 index 0000000000000..d47bb455e71d1 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst @@ -0,0 +1 @@ +Updated documentation of ``total`` flag of TypeDict. From webhook-mailer at python.org Wed Feb 19 08:24:01 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 19 Feb 2020 13:24:01 -0000 Subject: [Python-checkins] Revert "bpo-38691 Added a switch to ignore PYTHONCASEOK when -E or -I flags passed (#18314)" (GH-18553) Message-ID: https://github.com/python/cpython/commit/4dee92b0ad9f4e3ea2fbbbb5253340801bb92dc7 commit: 4dee92b0ad9f4e3ea2fbbbb5253340801bb92dc7 branch: master author: Victor Stinner committer: GitHub date: 2020-02-19T14:23:47+01:00 summary: Revert "bpo-38691 Added a switch to ignore PYTHONCASEOK when -E or -I flags passed (#18314)" (GH-18553) This reverts commit d83b6600b25487e4ebffd7949d0f478de9538875. files: D Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst M Doc/library/functions.rst M Doc/whatsnew/3.9.rst M Lib/importlib/_bootstrap_external.py M Python/importlib_external.h diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ba5c388622c18..cc48597ef91d5 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1829,9 +1829,6 @@ are always available. They are listed here in alphabetical order. Negative values for *level* are no longer supported (which also changes the default value to 0). - .. versionchanged:: 3.9 - When the command line options :option:`-E` or :option:`-I` are being used, - the environment variable :envvar:`PYTHONCASEOK` is now ignored. .. rubric:: Footnotes diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index f7e279b379f12..66eb9e77a7912 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -584,9 +584,6 @@ Changes in the Python API since the *buffering* parameter has been removed. (Contributed by Victor Stinner in :issue:`39357`.) -* The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK` - environment variable when the :option:`-E` or :option:`-I` command line - options are being used. CPython bytecode changes ------------------------ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 13f0191839cda..2434cf06fd444 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -35,7 +35,7 @@ def _make_relax_case(): def _relax_case(): """True if filenames must be checked case-insensitively.""" - return not sys.flags.ignore_environment and key in _os.environ + return key in _os.environ else: def _relax_case(): """True if filenames must be checked case-insensitively.""" diff --git a/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst b/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst deleted file mode 100644 index 913c8ccb1c21c..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-11-13-01-38.bpo-38691.oND8Sk.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK` -environment variable when :option:`-E` or :option:`-I` command line option is used. diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 9662ace50f43c..d67c2a8fee4ea 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -69,2670 +69,2667 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 78,67,65,83,69,79,75,115,12,0,0,0,80,89,84,72, 79,78,67,65,83,69,79,75,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,19,0,0, - 0,115,20,0,0,0,116,0,106,1,106,2,12,0,111,18, - 136,0,116,3,106,4,118,0,83,0,41,1,250,53,84,114, - 117,101,32,105,102,32,102,105,108,101,110,97,109,101,115,32, - 109,117,115,116,32,98,101,32,99,104,101,99,107,101,100,32, - 99,97,115,101,45,105,110,115,101,110,115,105,116,105,118,101, - 108,121,46,41,5,218,3,115,121,115,218,5,102,108,97,103, - 115,218,18,105,103,110,111,114,101,95,101,110,118,105,114,111, - 110,109,101,110,116,218,3,95,111,115,90,7,101,110,118,105, - 114,111,110,169,0,169,1,218,3,107,101,121,114,6,0,0, - 0,250,38,60,102,114,111,122,101,110,32,105,109,112,111,114, - 116,108,105,98,46,95,98,111,111,116,115,116,114,97,112,95, - 101,120,116,101,114,110,97,108,62,218,11,95,114,101,108,97, - 120,95,99,97,115,101,36,0,0,0,115,2,0,0,0,0, - 2,122,37,95,109,97,107,101,95,114,101,108,97,120,95,99, - 97,115,101,46,60,108,111,99,97,108,115,62,46,95,114,101, - 108,97,120,95,99,97,115,101,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,83,0,0, - 0,115,4,0,0,0,100,1,83,0,41,2,114,1,0,0, - 0,70,114,6,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,114,10,0,0,0, - 40,0,0,0,115,2,0,0,0,0,2,41,5,114,2,0, - 0,0,218,8,112,108,97,116,102,111,114,109,218,10,115,116, - 97,114,116,115,119,105,116,104,218,27,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,218,35,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,83,84,82,95,75,69,89,41,1,114,10,0,0, - 0,114,6,0,0,0,114,7,0,0,0,114,9,0,0,0, - 218,16,95,109,97,107,101,95,114,101,108,97,120,95,99,97, - 115,101,29,0,0,0,115,14,0,0,0,0,1,12,1,12, - 1,6,2,4,2,14,4,8,3,114,15,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,20,0,0,0,116,0,124,0, - 131,1,100,1,64,0,160,1,100,2,100,3,161,2,83,0, - 41,4,122,42,67,111,110,118,101,114,116,32,97,32,51,50, - 45,98,105,116,32,105,110,116,101,103,101,114,32,116,111,32, - 108,105,116,116,108,101,45,101,110,100,105,97,110,46,236,3, - 0,0,0,255,127,255,127,3,0,233,4,0,0,0,218,6, - 108,105,116,116,108,101,41,2,218,3,105,110,116,218,8,116, - 111,95,98,121,116,101,115,41,1,218,1,120,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,218,12,95,112,97, - 99,107,95,117,105,110,116,51,50,46,0,0,0,115,2,0, - 0,0,0,2,114,22,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,116,0,124,0,131,1,100,1,107, - 2,115,16,74,0,130,1,116,1,160,2,124,0,100,2,161, - 2,83,0,41,3,122,47,67,111,110,118,101,114,116,32,52, - 32,98,121,116,101,115,32,105,110,32,108,105,116,116,108,101, - 45,101,110,100,105,97,110,32,116,111,32,97,110,32,105,110, - 116,101,103,101,114,46,114,17,0,0,0,114,18,0,0,0, - 169,3,218,3,108,101,110,114,19,0,0,0,218,10,102,114, - 111,109,95,98,121,116,101,115,169,1,218,4,100,97,116,97, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,51, - 0,0,0,115,4,0,0,0,0,2,16,1,114,28,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,116, - 0,124,0,131,1,100,1,107,2,115,16,74,0,130,1,116, - 1,160,2,124,0,100,2,161,2,83,0,41,3,122,47,67, - 111,110,118,101,114,116,32,50,32,98,121,116,101,115,32,105, - 110,32,108,105,116,116,108,101,45,101,110,100,105,97,110,32, - 116,111,32,97,110,32,105,110,116,101,103,101,114,46,233,2, - 0,0,0,114,18,0,0,0,114,23,0,0,0,114,26,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,218,14,95,117,110,112,97,99,107,95,117,105,110,116,49, - 54,56,0,0,0,115,4,0,0,0,0,2,16,1,114,30, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,71,0,0,0,115,20,0,0, - 0,116,0,160,1,100,1,100,2,132,0,124,0,68,0,131, - 1,161,1,83,0,41,3,122,31,82,101,112,108,97,99,101, - 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104, - 46,106,111,105,110,40,41,46,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,5,0,0,0,83,0,0, - 0,115,26,0,0,0,103,0,124,0,93,18,125,1,124,1, - 114,4,124,1,160,0,116,1,161,1,145,2,113,4,83,0, - 114,6,0,0,0,41,2,218,6,114,115,116,114,105,112,218, - 15,112,97,116,104,95,115,101,112,97,114,97,116,111,114,115, - 41,2,218,2,46,48,218,4,112,97,114,116,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,218,10,60,108,105, - 115,116,99,111,109,112,62,64,0,0,0,115,6,0,0,0, - 6,1,2,0,4,255,122,30,95,112,97,116,104,95,106,111, - 105,110,46,60,108,111,99,97,108,115,62,46,60,108,105,115, - 116,99,111,109,112,62,41,2,218,8,112,97,116,104,95,115, - 101,112,218,4,106,111,105,110,41,1,218,10,112,97,116,104, - 95,112,97,114,116,115,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,10,95,112,97,116,104,95,106,111,105, - 110,62,0,0,0,115,6,0,0,0,0,2,10,1,2,255, - 114,39,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,96, - 0,0,0,116,0,116,1,131,1,100,1,107,2,114,36,124, - 0,160,2,116,3,161,1,92,3,125,1,125,2,125,3,124, - 1,124,3,102,2,83,0,116,4,124,0,131,1,68,0,93, - 42,125,4,124,4,116,1,118,0,114,44,124,0,106,5,124, - 4,100,1,100,2,141,2,92,2,125,1,125,3,124,1,124, - 3,102,2,2,0,1,0,83,0,113,44,100,3,124,0,102, - 2,83,0,41,4,122,32,82,101,112,108,97,99,101,109,101, - 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,115, - 112,108,105,116,40,41,46,233,1,0,0,0,41,1,90,8, - 109,97,120,115,112,108,105,116,218,0,41,6,114,24,0,0, - 0,114,32,0,0,0,218,10,114,112,97,114,116,105,116,105, - 111,110,114,36,0,0,0,218,8,114,101,118,101,114,115,101, - 100,218,6,114,115,112,108,105,116,41,5,218,4,112,97,116, - 104,90,5,102,114,111,110,116,218,1,95,218,4,116,97,105, - 108,114,21,0,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,11,95,112,97,116,104,95,115,112,108, - 105,116,68,0,0,0,115,16,0,0,0,0,2,12,1,16, - 1,8,1,12,1,8,1,18,1,14,1,114,48,0,0,0, - 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,10,0,0,0,116,0, - 160,1,124,0,161,1,83,0,41,1,122,126,83,116,97,116, - 32,116,104,101,32,112,97,116,104,46,10,10,32,32,32,32, - 77,97,100,101,32,97,32,115,101,112,97,114,97,116,101,32, - 102,117,110,99,116,105,111,110,32,116,111,32,109,97,107,101, - 32,105,116,32,101,97,115,105,101,114,32,116,111,32,111,118, - 101,114,114,105,100,101,32,105,110,32,101,120,112,101,114,105, - 109,101,110,116,115,10,32,32,32,32,40,101,46,103,46,32, - 99,97,99,104,101,32,115,116,97,116,32,114,101,115,117,108, - 116,115,41,46,10,10,32,32,32,32,41,2,114,5,0,0, - 0,90,4,115,116,97,116,169,1,114,45,0,0,0,114,6, - 0,0,0,114,6,0,0,0,114,9,0,0,0,218,10,95, - 112,97,116,104,95,115,116,97,116,80,0,0,0,115,2,0, - 0,0,0,7,114,50,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,48,0,0,0,122,12,116,0,124,0,131,1,125, - 2,87,0,110,20,4,0,116,1,121,32,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,115,112,101,99,105,102,105,101, - 100,32,109,111,100,101,32,116,121,112,101,46,70,105,0,240, - 0,0,41,3,114,50,0,0,0,218,7,79,83,69,114,114, - 111,114,218,7,115,116,95,109,111,100,101,41,3,114,45,0, - 0,0,218,4,109,111,100,101,90,9,115,116,97,116,95,105, - 110,102,111,114,6,0,0,0,114,6,0,0,0,114,9,0, - 0,0,218,18,95,112,97,116,104,95,105,115,95,109,111,100, - 101,95,116,121,112,101,90,0,0,0,115,10,0,0,0,0, - 2,2,1,12,1,12,1,8,1,114,54,0,0,0,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,10,0,0,0,116,0,124,0, - 100,1,131,2,83,0,41,2,122,31,82,101,112,108,97,99, - 101,109,101,110,116,32,102,111,114,32,111,115,46,112,97,116, - 104,46,105,115,102,105,108,101,46,105,0,128,0,0,41,1, - 114,54,0,0,0,114,49,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,218,12,95,112,97,116,104, - 95,105,115,102,105,108,101,99,0,0,0,115,2,0,0,0, - 0,2,114,55,0,0,0,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,22,0,0,0,124,0,115,12,116,0,160,1,161,0,125, - 0,116,2,124,0,100,1,131,2,83,0,41,2,122,30,82, + 0,115,10,0,0,0,136,0,116,0,106,1,118,0,83,0, + 41,1,250,53,84,114,117,101,32,105,102,32,102,105,108,101, + 110,97,109,101,115,32,109,117,115,116,32,98,101,32,99,104, + 101,99,107,101,100,32,99,97,115,101,45,105,110,115,101,110, + 115,105,116,105,118,101,108,121,46,41,2,218,3,95,111,115, + 90,7,101,110,118,105,114,111,110,169,0,169,1,218,3,107, + 101,121,114,3,0,0,0,250,38,60,102,114,111,122,101,110, + 32,105,109,112,111,114,116,108,105,98,46,95,98,111,111,116, + 115,116,114,97,112,95,101,120,116,101,114,110,97,108,62,218, + 11,95,114,101,108,97,120,95,99,97,115,101,36,0,0,0, + 115,2,0,0,0,0,2,122,37,95,109,97,107,101,95,114, + 101,108,97,120,95,99,97,115,101,46,60,108,111,99,97,108, + 115,62,46,95,114,101,108,97,120,95,99,97,115,101,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,83,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,114,1,0,0,0,70,114,3,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,7,0,0,0,40,0,0,0,115,2,0,0,0,0, + 2,41,5,218,3,115,121,115,218,8,112,108,97,116,102,111, + 114,109,218,10,115,116,97,114,116,115,119,105,116,104,218,27, + 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,218,35,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,83,84,82,95,75,69,89, + 41,1,114,7,0,0,0,114,3,0,0,0,114,4,0,0, + 0,114,6,0,0,0,218,16,95,109,97,107,101,95,114,101, + 108,97,120,95,99,97,115,101,29,0,0,0,115,14,0,0, + 0,0,1,12,1,12,1,6,2,4,2,14,4,8,3,114, + 13,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,20,0, + 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, + 100,3,161,2,83,0,41,4,122,42,67,111,110,118,101,114, + 116,32,97,32,51,50,45,98,105,116,32,105,110,116,101,103, + 101,114,32,116,111,32,108,105,116,116,108,101,45,101,110,100, + 105,97,110,46,236,3,0,0,0,255,127,255,127,3,0,233, + 4,0,0,0,218,6,108,105,116,116,108,101,41,2,218,3, + 105,110,116,218,8,116,111,95,98,121,116,101,115,41,1,218, + 1,120,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,12,95,112,97,99,107,95,117,105,110,116,51,50,46, + 0,0,0,115,2,0,0,0,0,2,114,20,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,116,0,124, + 0,131,1,100,1,107,2,115,16,74,0,130,1,116,1,160, + 2,124,0,100,2,161,2,83,0,41,3,122,47,67,111,110, + 118,101,114,116,32,52,32,98,121,116,101,115,32,105,110,32, + 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, + 32,97,110,32,105,110,116,101,103,101,114,46,114,15,0,0, + 0,114,16,0,0,0,169,3,218,3,108,101,110,114,17,0, + 0,0,218,10,102,114,111,109,95,98,121,116,101,115,169,1, + 218,4,100,97,116,97,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,14,95,117,110,112,97,99,107,95,117, + 105,110,116,51,50,51,0,0,0,115,4,0,0,0,0,2, + 16,1,114,26,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,116,0,124,0,131,1,100,1,107,2,115, + 16,74,0,130,1,116,1,160,2,124,0,100,2,161,2,83, + 0,41,3,122,47,67,111,110,118,101,114,116,32,50,32,98, + 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, + 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, + 103,101,114,46,233,2,0,0,0,114,16,0,0,0,114,21, + 0,0,0,114,24,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,14,95,117,110,112,97,99,107, + 95,117,105,110,116,49,54,56,0,0,0,115,4,0,0,0, + 0,2,16,1,114,28,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,71,0, + 0,0,115,20,0,0,0,116,0,160,1,100,1,100,2,132, + 0,124,0,68,0,131,1,161,1,83,0,41,3,122,31,82, 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, - 115,46,112,97,116,104,46,105,115,100,105,114,46,105,0,64, - 0,0,41,3,114,5,0,0,0,218,6,103,101,116,99,119, - 100,114,54,0,0,0,114,49,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,218,11,95,112,97,116, - 104,95,105,115,100,105,114,104,0,0,0,115,6,0,0,0, - 0,2,4,1,8,1,114,57,0,0,0,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,26,0,0,0,124,0,160,0,116,1,161, - 1,112,24,124,0,100,1,100,2,133,2,25,0,116,2,118, - 0,83,0,41,3,122,142,82,101,112,108,97,99,101,109,101, - 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, - 115,97,98,115,46,10,10,32,32,32,32,67,111,110,115,105, - 100,101,114,115,32,97,32,87,105,110,100,111,119,115,32,100, - 114,105,118,101,45,114,101,108,97,116,105,118,101,32,112,97, - 116,104,32,40,110,111,32,100,114,105,118,101,44,32,98,117, - 116,32,115,116,97,114,116,115,32,119,105,116,104,32,115,108, - 97,115,104,41,32,116,111,10,32,32,32,32,115,116,105,108, - 108,32,98,101,32,34,97,98,115,111,108,117,116,101,34,46, - 10,32,32,32,32,114,40,0,0,0,233,3,0,0,0,41, - 3,114,12,0,0,0,114,32,0,0,0,218,20,95,112,97, - 116,104,115,101,112,115,95,119,105,116,104,95,99,111,108,111, - 110,114,49,0,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,11,95,112,97,116,104,95,105,115,97, - 98,115,111,0,0,0,115,2,0,0,0,0,6,114,60,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,178,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,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,54,4,0,116, - 11,121,172,1,0,1,0,1,0,122,14,116,2,160,12,124, - 3,161,1,1,0,87,0,110,18,4,0,116,11,121,164,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,61,0,0,0,90,2,119,98,78,41,13, - 218,6,102,111,114,109,97,116,218,2,105,100,114,5,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, - 51,0,0,0,90,6,117,110,108,105,110,107,41,6,114,45, - 0,0,0,114,27,0,0,0,114,53,0,0,0,90,8,112, - 97,116,104,95,116,109,112,90,2,102,100,218,4,102,105,108, - 101,114,6,0,0,0,114,6,0,0,0,114,9,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,12,1,2,1, - 14,1,12,1,6,1,114,70,0,0,0,105,97,13,0,0, - 114,29,0,0,0,114,18,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,117,1,114,52,116,0,160,1,100,2,116,2,161,2, - 1,0,124,2,100,1,117,1,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,117,0,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,117,0,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, - 117,1,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,118,1,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,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, + 115,46,112,97,116,104,46,106,111,105,110,40,41,46,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, + 0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,0, + 93,18,125,1,124,1,114,4,124,1,160,0,116,1,161,1, + 145,2,113,4,83,0,114,3,0,0,0,41,2,218,6,114, + 115,116,114,105,112,218,15,112,97,116,104,95,115,101,112,97, + 114,97,116,111,114,115,41,2,218,2,46,48,218,4,112,97, + 114,116,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,10,60,108,105,115,116,99,111,109,112,62,64,0,0, + 0,115,6,0,0,0,6,1,2,0,4,255,122,30,95,112, + 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, + 62,46,60,108,105,115,116,99,111,109,112,62,41,2,218,8, + 112,97,116,104,95,115,101,112,218,4,106,111,105,110,41,1, + 218,10,112,97,116,104,95,112,97,114,116,115,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, + 116,104,95,106,111,105,110,62,0,0,0,115,6,0,0,0, + 0,2,10,1,2,255,114,37,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,96,0,0,0,116,0,116,1,131,1,100, + 1,107,2,114,36,124,0,160,2,116,3,161,1,92,3,125, + 1,125,2,125,3,124,1,124,3,102,2,83,0,116,4,124, + 0,131,1,68,0,93,42,125,4,124,4,116,1,118,0,114, + 44,124,0,106,5,124,4,100,1,100,2,141,2,92,2,125, + 1,125,3,124,1,124,3,102,2,2,0,1,0,83,0,113, + 44,100,3,124,0,102,2,83,0,41,4,122,32,82,101,112, + 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, + 112,97,116,104,46,115,112,108,105,116,40,41,46,233,1,0, + 0,0,41,1,90,8,109,97,120,115,112,108,105,116,218,0, + 41,6,114,22,0,0,0,114,30,0,0,0,218,10,114,112, + 97,114,116,105,116,105,111,110,114,34,0,0,0,218,8,114, + 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, + 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, + 95,218,4,116,97,105,108,114,19,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,11,95,112,97, + 116,104,95,115,112,108,105,116,68,0,0,0,115,16,0,0, + 0,0,2,12,1,16,1,8,1,12,1,8,1,18,1,14, + 1,114,46,0,0,0,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, + 10,0,0,0,116,0,160,1,124,0,161,1,83,0,41,1, + 122,126,83,116,97,116,32,116,104,101,32,112,97,116,104,46, + 10,10,32,32,32,32,77,97,100,101,32,97,32,115,101,112, + 97,114,97,116,101,32,102,117,110,99,116,105,111,110,32,116, + 111,32,109,97,107,101,32,105,116,32,101,97,115,105,101,114, + 32,116,111,32,111,118,101,114,114,105,100,101,32,105,110,32, + 101,120,112,101,114,105,109,101,110,116,115,10,32,32,32,32, + 40,101,46,103,46,32,99,97,99,104,101,32,115,116,97,116, + 32,114,101,115,117,108,116,115,41,46,10,10,32,32,32,32, + 41,2,114,2,0,0,0,90,4,115,116,97,116,169,1,114, + 43,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,10,95,112,97,116,104,95,115,116,97,116,80, + 0,0,0,115,2,0,0,0,0,7,114,48,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,48,0,0,0,122,12,116, + 0,124,0,131,1,125,2,87,0,110,20,4,0,116,1,121, + 32,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,115,112, + 101,99,105,102,105,101,100,32,109,111,100,101,32,116,121,112, + 101,46,70,105,0,240,0,0,41,3,114,48,0,0,0,218, + 7,79,83,69,114,114,111,114,218,7,115,116,95,109,111,100, + 101,41,3,114,43,0,0,0,218,4,109,111,100,101,90,9, + 115,116,97,116,95,105,110,102,111,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,18,95,112,97,116,104,95, + 105,115,95,109,111,100,101,95,116,121,112,101,90,0,0,0, + 115,10,0,0,0,0,2,2,1,12,1,12,1,8,1,114, + 52,0,0,0,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,10,0, + 0,0,116,0,124,0,100,1,131,2,83,0,41,2,122,31, + 82,101,112,108,97,99,101,109,101,110,116,32,102,111,114,32, + 111,115,46,112,97,116,104,46,105,115,102,105,108,101,46,105, + 0,128,0,0,41,1,114,52,0,0,0,114,47,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 12,95,112,97,116,104,95,105,115,102,105,108,101,99,0,0, + 0,115,2,0,0,0,0,2,114,53,0,0,0,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,22,0,0,0,124,0,115,12,116, + 0,160,1,161,0,125,0,116,2,124,0,100,1,131,2,83, + 0,41,2,122,30,82,101,112,108,97,99,101,109,101,110,116, + 32,102,111,114,32,111,115,46,112,97,116,104,46,105,115,100, + 105,114,46,105,0,64,0,0,41,3,114,2,0,0,0,218, + 6,103,101,116,99,119,100,114,52,0,0,0,114,47,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,11,95,112,97,116,104,95,105,115,100,105,114,104,0,0, + 0,115,6,0,0,0,0,2,4,1,8,1,114,55,0,0, + 0,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,26,0,0,0,124, + 0,160,0,116,1,161,1,112,24,124,0,100,1,100,2,133, + 2,25,0,116,2,118,0,83,0,41,3,122,142,82,101,112, + 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, + 112,97,116,104,46,105,115,97,98,115,46,10,10,32,32,32, + 32,67,111,110,115,105,100,101,114,115,32,97,32,87,105,110, + 100,111,119,115,32,100,114,105,118,101,45,114,101,108,97,116, + 105,118,101,32,112,97,116,104,32,40,110,111,32,100,114,105, + 118,101,44,32,98,117,116,32,115,116,97,114,116,115,32,119, + 105,116,104,32,115,108,97,115,104,41,32,116,111,10,32,32, + 32,32,115,116,105,108,108,32,98,101,32,34,97,98,115,111, + 108,117,116,101,34,46,10,32,32,32,32,114,38,0,0,0, + 233,3,0,0,0,41,3,114,10,0,0,0,114,30,0,0, + 0,218,20,95,112,97,116,104,115,101,112,115,95,119,105,116, + 104,95,99,111,108,111,110,114,47,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,11,95,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,178,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,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,54,4,0,116,11,121,172,1,0,1,0,1,0,122, + 14,116,2,160,12,124,3,161,1,1,0,87,0,110,18,4, + 0,116,11,121,164,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,12,1,2,1,14,1,12,1,6,1,114,68,0,0, + 0,105,97,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,117,1,114,52,116,0,160,1, + 100,2,116,2,161,2,1,0,124,2,100,1,117,1,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,117,0,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,117,0,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,117,1,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,118,1,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,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,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,41,0,0,0,114,40,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,29,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,5,0, - 0,0,218,6,102,115,112,97,116,104,114,48,0,0,0,114, - 42,0,0,0,114,2,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,37,0,0,0,114,3, - 0,0,0,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,63,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,60,0,0,0,114,39,0,0,0,114, - 56,0,0,0,114,32,0,0,0,218,6,108,115,116,114,105, - 112,218,8,95,80,89,67,65,67,72,69,41,12,114,45,0, - 0,0,90,14,100,101,98,117,103,95,111,118,101,114,114,105, - 100,101,114,71,0,0,0,218,7,109,101,115,115,97,103,101, - 218,4,104,101,97,100,114,47,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,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,218,17,99,97,99, - 104,101,95,102,114,111,109,95,115,111,117,114,99,101,45,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, - 98,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,117,0,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,117,1,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, - 118,1,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,73,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,72, - 0,0,0,62,2,0,0,0,114,29,0,0,0,114,58,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,58,0,0,0,114,29,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,74,0,0,0, - 41,22,114,2,0,0,0,114,81,0,0,0,114,82,0,0, - 0,114,83,0,0,0,114,5,0,0,0,114,80,0,0,0, - 114,48,0,0,0,114,90,0,0,0,114,31,0,0,0,114, - 32,0,0,0,114,12,0,0,0,114,36,0,0,0,114,24, - 0,0,0,114,92,0,0,0,114,87,0,0,0,218,5,99, - 111,117,110,116,114,44,0,0,0,114,88,0,0,0,114,86, - 0,0,0,218,9,112,97,114,116,105,116,105,111,110,114,39, - 0,0,0,218,15,83,79,85,82,67,69,95,83,85,70,70, - 73,88,69,83,41,10,114,45,0,0,0,114,94,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,71, - 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,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,218,17,115,111, - 117,114,99,101,95,102,114,111,109,95,99,97,99,104,101,116, - 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,103,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,124,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,34,4,0,116,4,116,5,102, - 2,121,106,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,120,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,74,0,0,0, - 78,114,72,0,0,0,233,253,255,255,255,233,255,255,255,255, - 90,2,112,121,41,7,114,24,0,0,0,114,42,0,0,0, - 218,5,108,111,119,101,114,114,103,0,0,0,114,83,0,0, - 0,114,87,0,0,0,114,55,0,0,0,41,5,218,13,98, - 121,116,101,99,111,100,101,95,112,97,116,104,114,96,0,0, - 0,114,46,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,6, - 0,0,0,114,6,0,0,0,114,9,0,0,0,218,15,95, - 103,101,116,95,115,111,117,114,99,101,102,105,108,101,156,1, - 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, - 1,4,1,2,1,12,1,16,1,18,1,114,109,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,72,0,0,0,124,0, - 160,0,116,1,116,2,131,1,161,1,114,46,122,10,116,3, - 124,0,131,1,87,0,83,0,4,0,116,4,121,42,1,0, - 1,0,1,0,89,0,113,68,48,0,110,22,124,0,160,0, - 116,1,116,5,131,1,161,1,114,64,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,102,0,0, - 0,114,98,0,0,0,114,83,0,0,0,114,89,0,0,0, - 41,1,114,97,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,9,0,0,0,218,11,95,103,101,116,95,99,97,99, - 104,101,100,175,1,0,0,115,16,0,0,0,0,1,14,1, - 2,1,10,1,12,1,8,1,14,1,4,2,114,113,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,50,0,0,0,122, - 14,116,0,124,0,131,1,106,1,125,1,87,0,110,22,4, - 0,116,2,121,36,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,61,0,0,0,233,128,0, - 0,0,41,3,114,50,0,0,0,114,52,0,0,0,114,51, - 0,0,0,41,2,114,45,0,0,0,114,53,0,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,10, - 95,99,97,108,99,95,109,111,100,101,187,1,0,0,115,12, - 0,0,0,0,2,2,1,14,1,12,1,10,3,8,1,114, - 115,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,66,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,26,4,0,116,2, - 121,50,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,72, - 0,0,0,124,1,100,0,117,0,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,103,2,124,2,162,1,82, - 0,105,0,124,3,164,1,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,117,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,117,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, - 6,0,0,0,114,9,0,0,0,218,19,95,99,104,101,99, - 107,95,110,97,109,101,95,119,114,97,112,112,101,114,207,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,68,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,218,5,95,119,114,97, - 112,218,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, - 134,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, - 3,114,123,0,0,0,114,124,0,0,0,114,134,0,0,0, - 114,6,0,0,0,114,122,0,0,0,114,9,0,0,0,218, - 11,95,99,104,101,99,107,95,110,97,109,101,199,1,0,0, - 115,14,0,0,0,0,8,14,7,2,1,10,1,12,2,14, - 5,10,1,114,137,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,117,0,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,74,0,0,0,41,6,218,11,102,105,110,100,95,108,111, - 97,100,101,114,114,24,0,0,0,114,76,0,0,0,114,77, - 0,0,0,114,63,0,0,0,218,13,73,109,112,111,114,116, - 87,97,114,110,105,110,103,41,5,114,119,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, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,17, - 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, - 109,227,1,0,0,115,10,0,0,0,0,10,14,1,16,1, - 4,1,22,1,114,144,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,166,0,0,0,124,0,100,1,100,2,133,2,25, - 0,125,3,124,3,116,0,107,3,114,64,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,105,0,124, - 2,164,1,142,1,130,1,116,4,124,0,131,1,100,6,107, - 0,114,106,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,162,100,10,124,5,155,2,100, - 11,124,1,155,2,157,4,125,4,116,3,124,4,102,1,105, - 0,124,2,164,1,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,17,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,135,0,0,0, - 218,16,95,118,101,114,98,111,115,101,95,109,101,115,115,97, - 103,101,114,118,0,0,0,114,24,0,0,0,218,8,69,79, - 70,69,114,114,111,114,114,28,0,0,0,41,6,114,27,0, - 0,0,114,117,0,0,0,218,11,101,120,99,95,100,101,116, - 97,105,108,115,90,5,109,97,103,105,99,114,93,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,6,0,0,0,114, - 9,0,0,0,218,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,244,1,0,0,115,28,0,0,0,0,16,12,1, - 8,1,16,1,12,1,16,1,12,1,10,1,12,1,8,1, - 16,2,8,1,16,1,16,1,114,153,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,120,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,62,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,105, - 0,124,4,164,1,142,1,130,1,124,2,100,6,117,1,114, - 116,116,0,124,0,100,2,100,7,133,2,25,0,131,1,124, - 2,100,3,64,0,107,3,114,116,116,3,100,4,124,3,155, - 2,157,2,102,1,105,0,124,4,164,1,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,147,0,0,0,233,12,0,0,0,114,16,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,145,0,0,0,78,114,146, - 0,0,0,41,4,114,28,0,0,0,114,135,0,0,0,114, - 150,0,0,0,114,118,0,0,0,41,6,114,27,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,117,0,0,0, - 114,152,0,0,0,114,93,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,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,21,2,0,0,115,16,0,0,0,0,19,24,1,10, - 1,12,1,16,1,8,1,22,255,2,2,114,157,0,0,0, - 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,42,0,0,0,124,0, - 100,1,100,2,133,2,25,0,124,1,107,3,114,38,116,0, - 100,3,124,2,155,2,157,2,102,1,105,0,124,3,164,1, - 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,147,0,0,0,114,146,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, - 118,0,0,0,41,4,114,27,0,0,0,218,11,115,111,117, - 114,99,101,95,104,97,115,104,114,117,0,0,0,114,152,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,218,18,95,118,97,108,105,100,97,116,101,95,104,97,115, - 104,95,112,121,99,49,2,0,0,115,12,0,0,0,0,17, - 16,1,2,1,8,255,4,2,2,254,114,159,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,117,1,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,117,0,0,0,114,45,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,135,0,0,0, - 114,150,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,118,0, - 0,0,114,63,0,0,0,41,5,114,27,0,0,0,114,117, - 0,0,0,114,107,0,0,0,114,108,0,0,0,218,4,99, - 111,100,101,114,6,0,0,0,114,6,0,0,0,114,9,0, - 0,0,218,17,95,99,111,109,112,105,108,101,95,98,121,116, - 101,99,111,100,101,73,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,166,0,0,0,114,74,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, - 74,0,0,0,41,6,218,9,98,121,116,101,97,114,114,97, - 121,114,149,0,0,0,218,6,101,120,116,101,110,100,114,22, - 0,0,0,114,161,0,0,0,218,5,100,117,109,112,115,41, - 4,114,165,0,0,0,218,5,109,116,105,109,101,114,156,0, - 0,0,114,27,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,9,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,86,2, - 0,0,115,12,0,0,0,0,2,8,1,14,1,14,1,14, - 1,16,1,114,171,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,40,0,0,0,114,147,0,0,0,41,7,114,167,0, - 0,0,114,149,0,0,0,114,168,0,0,0,114,22,0,0, - 0,114,24,0,0,0,114,161,0,0,0,114,169,0,0,0, - 41,5,114,165,0,0,0,114,158,0,0,0,90,7,99,104, - 101,99,107,101,100,114,27,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,17, - 95,99,111,100,101,95,116,111,95,104,97,115,104,95,112,121, - 99,96,2,0,0,115,14,0,0,0,0,2,8,1,12,1, - 14,1,16,1,10,1,16,1,114,172,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,74,0,0,0,78,84,41,7,218, - 8,116,111,107,101,110,105,122,101,114,65,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,173,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,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,218,13,100,101,99, - 111,100,101,95,115,111,117,114,99,101,107,2,0,0,115,10, - 0,0,0,0,5,8,1,12,1,10,1,12,1,114,177,0, - 0,0,169,2,114,141,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,12, - 1,0,0,124,1,100,1,117,0,114,58,100,2,125,1,116, - 0,124,2,100,3,131,2,114,68,122,14,124,2,160,1,124, - 0,161,1,125,1,87,0,113,68,4,0,116,2,121,54,1, - 0,1,0,1,0,89,0,113,68,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,117,0,114,152,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, - 104,124,5,124,0,124,1,131,2,125,2,124,2,124,4,95, - 11,1,0,113,152,113,104,100,1,83,0,124,3,116,12,117, - 0,114,216,116,0,124,2,100,6,131,2,114,222,122,14,124, - 2,160,13,124,0,161,1,125,7,87,0,110,18,4,0,116, - 2,121,202,1,0,1,0,1,0,89,0,113,222,48,0,124, - 7,114,222,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,8,124,1,144, - 1,114,8,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,74,0,0,0,41,17,114,129,0,0,0, - 114,180,0,0,0,114,118,0,0,0,114,5,0,0,0,114, - 80,0,0,0,114,135,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,111,0,0,0,114,112,0,0,0,114,141,0,0,0, - 218,9,95,80,79,80,85,76,65,84,69,114,183,0,0,0, - 114,179,0,0,0,114,48,0,0,0,218,6,97,112,112,101, - 110,100,41,9,114,117,0,0,0,90,8,108,111,99,97,116, - 105,111,110,114,141,0,0,0,114,179,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,183,0,0,0, - 90,7,100,105,114,110,97,109,101,114,6,0,0,0,114,6, - 0,0,0,114,9,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,124,2,0,0,115,62,0,0,0,0,12,8,4,4,1, - 10,2,2,1,14,1,12,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,12,1,6,2,4,1,8,2,6,1, - 12,1,6,1,12,1,12,2,114,191,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,54, - 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,121,48,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,110,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,51,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,8,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,218,14,95,111,112,101,110, - 95,114,101,103,105,115,116,114,121,204,2,0,0,115,8,0, - 0,0,0,2,2,1,16,1,12,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,132,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,20,4,0,116,9,121,126, - 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,29,0,0, - 0,41,2,114,140,0,0,0,90,11,115,121,115,95,118,101, - 114,115,105,111,110,114,41,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,63,0,0,0, - 114,2,0,0,0,218,12,118,101,114,115,105,111,110,95,105, - 110,102,111,114,195,0,0,0,114,193,0,0,0,90,10,81, - 117,101,114,121,86,97,108,117,101,114,51,0,0,0,41,6, - 114,194,0,0,0,114,140,0,0,0,90,12,114,101,103,105, - 115,116,114,121,95,107,101,121,114,8,0,0,0,90,4,104, - 107,101,121,218,8,102,105,108,101,112,97,116,104,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,218,16,95,115, - 101,97,114,99,104,95,114,101,103,105,115,116,114,121,211,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,12,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,120,0,0,0,124,0,160,0,124,1,161,1,125,4, - 124,4,100,0,117,0,114,22,100,0,83,0,122,12,116,1, - 124,4,131,1,1,0,87,0,110,20,4,0,116,2,121,54, - 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,62,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,62,100,0,83,0,41,2, - 78,114,181,0,0,0,41,8,114,201,0,0,0,114,50,0, - 0,0,114,51,0,0,0,114,185,0,0,0,114,111,0,0, - 0,114,112,0,0,0,114,135,0,0,0,218,16,115,112,101, - 99,95,102,114,111,109,95,108,111,97,100,101,114,41,8,114, - 194,0,0,0,114,140,0,0,0,114,45,0,0,0,218,6, - 116,97,114,103,101,116,114,200,0,0,0,114,141,0,0,0, - 114,190,0,0,0,114,188,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,218,9,102,105,110,100,95, - 115,112,101,99,226,2,0,0,115,28,0,0,0,0,2,10, - 1,8,1,4,1,2,1,12,1,12,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,117,1,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,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,45,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,117,0,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,117,1, + 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,118,1,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,116,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,124,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, + 34,4,0,116,4,116,5,102,2,121,106,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,120,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,156,1,0,0,115,20,0,0,0,0, + 7,12,1,4,1,16,1,24,1,4,1,2,1,12,1,16, + 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,72,0,0,0,124,0,160,0,116,1,116,2,131,1, + 161,1,114,46,122,10,116,3,124,0,131,1,87,0,83,0, + 4,0,116,4,121,42,1,0,1,0,1,0,89,0,113,68, + 48,0,110,22,124,0,160,0,116,1,116,5,131,1,161,1, + 114,64,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,175,1,0,0,115, + 16,0,0,0,0,1,14,1,2,1,10,1,12,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,50,0,0,0,122,14,116,0,124,0,131,1,106, + 1,125,1,87,0,110,22,4,0,116,2,121,36,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,187,1,0,0,115,12,0,0,0,0,2,2,1,14, + 1,12,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,66,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,26,4,0,116,2,121,50,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,72,0,0,0,124,1,100,0,117, + 0,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,103,2,124,2,162,1,82,0,105,0,124,3,164,1,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,207,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,218,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,199,1,0,0,115,14,0,0,0,0,8,14, + 7,2,1,10,1,12,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, + 117,0,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,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,204,0, - 0,0,114,141,0,0,0,169,4,114,194,0,0,0,114,140, - 0,0,0,114,45,0,0,0,114,188,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,218,11,102,105, - 110,100,95,109,111,100,117,108,101,242,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,126,0,0,0,114,125,0,0,0, - 114,127,0,0,0,114,128,0,0,0,114,198,0,0,0,114, - 197,0,0,0,114,196,0,0,0,218,11,99,108,97,115,115, - 109,101,116,104,111,100,114,195,0,0,0,114,201,0,0,0, - 114,204,0,0,0,114,207,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,192, - 0,0,0,192,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,192,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,40,0,0,0,114,72,0,0,0,114,74,0,0,0,114, - 29,0,0,0,218,8,95,95,105,110,105,116,95,95,41,4, - 114,48,0,0,0,114,180,0,0,0,114,44,0,0,0,114, - 42,0,0,0,41,5,114,119,0,0,0,114,140,0,0,0, - 114,97,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, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,183, - 0,0,0,5,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, - 6,0,0,0,169,2,114,119,0,0,0,114,188,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, - 13,99,114,101,97,116,101,95,109,111,100,117,108,101,13,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,117,0,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,126,0,0,0,114,118,0,0,0, - 114,63,0,0,0,114,135,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,132,0,0,0, - 41,3,114,119,0,0,0,218,6,109,111,100,117,108,101,114, - 165,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, - 0,0,0,218,11,101,120,101,99,95,109,111,100,117,108,101, - 16,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,135,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,119,0,0,0,114,140,0,0,0,114,6, - 0,0,0,114,6,0,0,0,114,9,0,0,0,218,11,108, - 111,97,100,95,109,111,100,117,108,101,24,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,126,0,0,0,114,125,0,0,0,114,127,0, - 0,0,114,128,0,0,0,114,183,0,0,0,114,213,0,0, - 0,114,218,0,0,0,114,221,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, - 209,0,0,0,0,3,0,0,115,10,0,0,0,8,2,4, - 3,8,8,8,3,8,8,114,209,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,51,0,0,0,169,2,114,119,0, - 0,0,114,45,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,9,0,0,0,218,10,112,97,116,104,95,109,116,105, - 109,101,31,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, + 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,227,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,166,0,0,0,124, + 0,100,1,100,2,133,2,25,0,125,3,124,3,116,0,107, + 3,114,64,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,105,0,124,2,164,1,142,1,130,1,116, + 4,124,0,131,1,100,6,107,0,114,106,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, + 162,100,10,124,5,155,2,100,11,124,1,155,2,157,4,125, + 4,116,3,124,4,102,1,105,0,124,2,164,1,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,244,1,0,0,115, + 28,0,0,0,0,16,12,1,8,1,16,1,12,1,16,1, + 12,1,10,1,12,1,8,1,16,2,8,1,16,1,16,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,120, + 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,62,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,105,0,124,4,164,1,142,1,130, + 1,124,2,100,6,117,1,114,116,116,0,124,0,100,2,100, + 7,133,2,25,0,131,1,124,2,100,3,64,0,107,3,114, + 116,116,3,100,4,124,3,155,2,157,2,102,1,105,0,124, + 4,164,1,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,21,2,0,0,115,16, + 0,0,0,0,19,24,1,10,1,12,1,16,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,4,0,0,0,67,0,0, + 0,115,42,0,0,0,124,0,100,1,100,2,133,2,25,0, + 124,1,107,3,114,38,116,0,100,3,124,2,155,2,157,2, + 102,1,105,0,124,3,164,1,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,49,2,0, + 0,115,12,0,0,0,0,17,16,1,2,1,8,255,4,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,117,1,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,73,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,86,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,96,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,107,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,12,1,0,0,124,1,100,1,117, + 0,114,58,100,2,125,1,116,0,124,2,100,3,131,2,114, + 68,122,14,124,2,160,1,124,0,161,1,125,1,87,0,113, + 68,4,0,116,2,121,54,1,0,1,0,1,0,89,0,113, + 68,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,117,0,114,152,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,104,124,5,124,0,124,1,131, + 2,125,2,124,2,124,4,95,11,1,0,113,152,113,104,100, + 1,83,0,124,3,116,12,117,0,114,216,116,0,124,2,100, + 6,131,2,114,222,122,14,124,2,160,13,124,0,161,1,125, + 7,87,0,110,18,4,0,116,2,121,202,1,0,1,0,1, + 0,89,0,113,222,48,0,124,7,114,222,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,8,124,1,144,1,114,8,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,124,2,0,0,115,62,0, + 0,0,0,12,8,4,4,1,10,2,2,1,14,1,12,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,12,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,54,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,121,48,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,204,2,0,0,115,8,0,0,0,0,2,2,1,16,1, + 12,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,132,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,20,4,0,116,9,121,126,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,211,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,12,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,120,0,0,0,124,0, + 160,0,124,1,161,1,125,4,124,4,100,0,117,0,114,22, + 100,0,83,0,122,12,116,1,124,4,131,1,1,0,87,0, + 110,20,4,0,116,2,121,54,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,62,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,62,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,226,2,0,0, + 115,28,0,0,0,0,2,10,1,8,1,4,1,2,1,12, + 1,12,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, + 117,1,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,242,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,192,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,5,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,13,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,117,0,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,16,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,24,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,0,3,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,31,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,39,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,53,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,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,170,0,0,0,41,1,114,224, - 0,0,0,114,223,0,0,0,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,218,10,112,97,116,104,95,115,116, - 97,116,115,39,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,119,0,0,0,114,108,0,0, - 0,90,10,99,97,99,104,101,95,112,97,116,104,114,27,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,218,15,95,99,97,99,104,101,95,98,121,116,101,99,111, - 100,101,53,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,6,0,0,0,41,3,114, - 119,0,0,0,114,45,0,0,0,114,27,0,0,0,114,6, - 0,0,0,114,6,0,0,0,114,9,0,0,0,114,226,0, - 0,0,63,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,84,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,50,4,0,116,2, - 121,74,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, + 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,63,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,84,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,50,4,0,116,2,121,74,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,70,3,0,0,115, + 20,0,0,0,0,2,10,1,2,1,14,1,14,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,80,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,24,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,24,4,0,116,2,121,66, + 1,0,1,0,1,0,100,1,125,8,89,0,144,1,110,42, + 48,0,122,14,124,0,160,3,124,2,161,1,125,9,87,0, + 110,20,4,0,116,4,121,102,1,0,1,0,1,0,89,0, + 144,1,110,6,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,18,4,0,116,4,121,148,1,0,1,0,1,0,89,0, + 110,216,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,30,124,12, + 100,9,64,0,100,8,107,3,125,7,116,9,106,10,100,10, + 107,3,144,1,114,50,124,7,115,248,116,9,106,10,100,11, + 107,2,144,1,114,50,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,24,4,0,116,15,116,16,102,2,144,1,121,76, + 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,117,0, + 144,1,114,128,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,20,124,8, + 100,1,117,1,144,2,114,20,124,3,100,1,117,1,144,2, + 114,20,124,6,144,1,114,220,124,5,100,1,117,0,144,1, + 114,206,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,20,4,0, + 116,2,144,2,121,18,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,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,116,0,0,0,78,41,5,114, - 180,0,0,0,218,8,103,101,116,95,100,97,116,97,114,51, - 0,0,0,114,118,0,0,0,114,177,0,0,0,41,5,114, - 119,0,0,0,114,140,0,0,0,114,45,0,0,0,114,175, - 0,0,0,218,3,101,120,99,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,218,10,103,101,116,95,115,111,117, - 114,99,101,70,3,0,0,115,20,0,0,0,0,2,10,1, - 2,1,14,1,14,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,105,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,216,0,0,0,84,41,2,218,12,100, - 111,110,116,95,105,110,104,101,114,105,116,114,84,0,0,0, - 41,3,114,135,0,0,0,114,215,0,0,0,218,7,99,111, - 109,112,105,108,101,41,4,114,119,0,0,0,114,27,0,0, - 0,114,45,0,0,0,114,231,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,218,14,115,111,117,114, - 99,101,95,116,111,95,99,111,100,101,80,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,24,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,24,4,0,116,2,121,66,1,0,1,0,1,0,100,1, - 125,8,89,0,144,1,110,42,48,0,122,14,124,0,160,3, - 124,2,161,1,125,9,87,0,110,20,4,0,116,4,121,102, - 1,0,1,0,1,0,89,0,144,1,110,6,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,18,4,0,116,4,121,148, - 1,0,1,0,1,0,89,0,110,216,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,30,124,12,100,9,64,0,100,8,107,3, - 125,7,116,9,106,10,100,10,107,3,144,1,114,50,124,7, - 115,248,116,9,106,10,100,11,107,2,144,1,114,50,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,24,4,0,116,15, - 116,16,102,2,144,1,121,76,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,117,0,144,1,114,128,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,20,124,8,100,1,117,1,144,2,114,20, - 124,3,100,1,117,1,144,2,114,20,124,6,144,1,114,220, - 124,5,100,1,117,0,144,1,114,206,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,20,4,0,116,2,144,2,121,18,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,170,0,0,0,114,160,0,0,0,114,146,0, - 0,0,114,40,0,0,0,114,74,0,0,0,114,29,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,117,0,0,0,114,107,0,0, - 0,114,108,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,180,0, - 0,0,114,98,0,0,0,114,83,0,0,0,114,225,0,0, - 0,114,51,0,0,0,114,19,0,0,0,114,228,0,0,0, - 114,153,0,0,0,218,10,109,101,109,111,114,121,118,105,101, - 119,114,164,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,158,0, - 0,0,218,17,95,82,65,87,95,77,65,71,73,67,95,78, - 85,77,66,69,82,114,159,0,0,0,114,157,0,0,0,114, - 118,0,0,0,114,151,0,0,0,114,135,0,0,0,114,150, - 0,0,0,114,166,0,0,0,114,234,0,0,0,114,2,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,172,0,0,0,114,171,0,0, - 0,114,24,0,0,0,114,227,0,0,0,41,15,114,119,0, - 0,0,114,140,0,0,0,114,108,0,0,0,114,155,0,0, - 0,114,175,0,0,0,114,158,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,107,0,0,0,218,2,115,116,114,27, - 0,0,0,114,152,0,0,0,114,3,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,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,114,214,0,0,0,88,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,12,1,12,2,2,1,14,1,12,1,8, - 2,12,1,2,1,14,1,12,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,18,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,14,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,126,0,0,0,114,125,0,0,0,114, - 127,0,0,0,114,224,0,0,0,114,225,0,0,0,114,227, - 0,0,0,114,226,0,0,0,114,230,0,0,0,114,234,0, - 0,0,114,214,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,114,222,0,0,0, - 29,3,0,0,115,14,0,0,0,8,2,8,8,8,14,8, - 10,8,7,8,10,14,8,114,222,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,160,0,0,0, - 41,3,114,119,0,0,0,114,140,0,0,0,114,45,0,0, - 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, - 114,210,0,0,0,178,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,110,0, - 0,0,169,2,218,9,95,95,99,108,97,115,115,95,95,114, - 132,0,0,0,169,2,114,119,0,0,0,90,5,111,116,104, - 101,114,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,218,6,95,95,101,113,95,95,184,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,110,0, - 0,0,169,3,218,4,104,97,115,104,114,117,0,0,0,114, - 45,0,0,0,169,1,114,119,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,218,8,95,95,104,97, - 115,104,95,95,188,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,240,0,0,0,114,221,0,0,0,114,220,0, - 0,0,169,1,114,242,0,0,0,114,6,0,0,0,114,9, - 0,0,0,114,221,0,0,0,191,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,49,0, - 0,0,114,220,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,9,0,0,0,114,180,0,0,0,203,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,162,0,0, - 0,114,222,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,65,0,0,0, - 90,9,111,112,101,110,95,99,111,100,101,114,85,0,0,0, - 90,4,114,101,97,100,114,66,0,0,0,41,3,114,119,0, - 0,0,114,45,0,0,0,114,69,0,0,0,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,114,228,0,0,0, - 208,3,0,0,115,10,0,0,0,0,2,14,1,16,1,40, - 2,14,1,122,19,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,100,97,116,97,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,18,0,0,0,124,0,160,0,124,1,161,1,114,14, - 124,0,83,0,100,0,83,0,114,110,0,0,0,41,1,114, - 183,0,0,0,169,2,114,119,0,0,0,114,217,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, - 19,103,101,116,95,114,101,115,111,117,114,99,101,95,114,101, - 97,100,101,114,219,3,0,0,115,6,0,0,0,0,2,10, - 1,4,1,122,30,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, - 100,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,4,0,0,0,67,0,0,0,115,32,0,0, - 0,116,0,116,1,124,0,106,2,131,1,100,1,25,0,124, - 1,131,2,125,2,116,3,160,4,124,2,100,2,161,2,83, - 0,41,3,78,114,74,0,0,0,114,252,0,0,0,41,5, - 114,39,0,0,0,114,48,0,0,0,114,45,0,0,0,114, - 65,0,0,0,114,66,0,0,0,169,3,114,119,0,0,0, - 90,8,114,101,115,111,117,114,99,101,114,45,0,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,218,13, - 111,112,101,110,95,114,101,115,111,117,114,99,101,225,3,0, - 0,115,4,0,0,0,0,1,20,1,122,24,70,105,108,101, - 76,111,97,100,101,114,46,111,112,101,110,95,114,101,115,111, - 117,114,99,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,38,0, - 0,0,124,0,160,0,124,1,161,1,115,14,116,1,130,1, - 116,2,116,3,124,0,106,4,131,1,100,1,25,0,124,1, - 131,2,125,2,124,2,83,0,169,2,78,114,74,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,39,0,0,0,114,48,0,0,0,114,45,0,0, - 0,114,0,1,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,13,114,101,115,111,117,114,99,101,95, - 112,97,116,104,229,3,0,0,115,8,0,0,0,0,1,10, - 1,4,1,20,1,122,24,70,105,108,101,76,111,97,100,101, - 114,46,114,101,115,111,117,114,99,101,95,112,97,116,104,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,40,0,0,0,116,0,124, - 1,118,0,114,12,100,1,83,0,116,1,116,2,124,0,106, - 3,131,1,100,2,25,0,124,1,131,2,125,2,116,4,124, - 2,131,1,83,0,41,3,78,70,114,74,0,0,0,41,5, - 114,36,0,0,0,114,39,0,0,0,114,48,0,0,0,114, - 45,0,0,0,114,55,0,0,0,169,3,114,119,0,0,0, - 114,117,0,0,0,114,45,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,114,3,1,0,0,235,3, - 0,0,115,8,0,0,0,0,1,8,1,4,1,20,1,122, - 22,70,105,108,101,76,111,97,100,101,114,46,105,115,95,114, - 101,115,111,117,114,99,101,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0, - 115,24,0,0,0,116,0,116,1,160,2,116,3,124,0,106, - 4,131,1,100,1,25,0,161,1,131,1,83,0,114,2,1, - 0,0,41,5,218,4,105,116,101,114,114,5,0,0,0,218, - 7,108,105,115,116,100,105,114,114,48,0,0,0,114,45,0, - 0,0,114,247,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,9,0,0,0,218,8,99,111,110,116,101,110,116,115, - 241,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108, - 101,76,111,97,100,101,114,46,99,111,110,116,101,110,116,115, - 41,17,114,126,0,0,0,114,125,0,0,0,114,127,0,0, - 0,114,128,0,0,0,114,210,0,0,0,114,244,0,0,0, - 114,248,0,0,0,114,137,0,0,0,114,221,0,0,0,114, - 180,0,0,0,114,228,0,0,0,114,255,0,0,0,114,1, - 1,0,0,114,5,1,0,0,114,3,1,0,0,114,9,1, - 0,0,90,13,95,95,99,108,97,115,115,99,101,108,108,95, - 95,114,6,0,0,0,114,6,0,0,0,114,250,0,0,0, - 114,9,0,0,0,114,240,0,0,0,173,3,0,0,115,30, - 0,0,0,8,2,4,3,8,6,8,4,8,3,2,1,14, - 11,2,1,10,4,8,11,2,1,10,5,8,4,8,6,8, - 6,114,240,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,170,0,0,0,114,235,0,0,0,41,3,114,50,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,119,0,0,0,114,45,0,0, - 0,114,239,0,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,114,225,0,0,0,249,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,115,0,0,0,114,226,0, - 0,0,41,5,114,119,0,0,0,114,108,0,0,0,114,107, - 0,0,0,114,27,0,0,0,114,53,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,227,0,0, - 0,254,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,61,0,0,0,114,12,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,104,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,121,110,1,0,1,0,1,0,89,0, - 113,60,89,0,113,60,4,0,116,8,121,162,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,52,4,0,116,8, - 144,0,121,246,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,48,0,0,0,114,57,0,0,0,114,187,0,0,0, - 114,43,0,0,0,114,39,0,0,0,114,5,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,51,0,0,0,114,135,0,0, - 0,114,150,0,0,0,114,70,0,0,0,41,9,114,119,0, - 0,0,114,45,0,0,0,114,27,0,0,0,114,13,1,0, - 0,218,6,112,97,114,101,110,116,114,97,0,0,0,114,38, - 0,0,0,114,34,0,0,0,114,229,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,226,0,0, - 0,3,4,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,12,2, - 8,1,14,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,126,0,0,0,114,125,0, - 0,0,114,127,0,0,0,114,128,0,0,0,114,225,0,0, - 0,114,227,0,0,0,114,226,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, - 10,1,0,0,245,3,0,0,115,8,0,0,0,8,2,4, - 2,8,5,8,5,114,10,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,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,160,0,0,0,114,146,0,0,0,41,2, - 114,117,0,0,0,114,107,0,0,0,41,5,114,180,0,0, - 0,114,228,0,0,0,114,153,0,0,0,114,166,0,0,0, - 114,236,0,0,0,41,5,114,119,0,0,0,114,140,0,0, - 0,114,45,0,0,0,114,27,0,0,0,114,152,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, - 214,0,0,0,38,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,6,0,0,0,114,220,0,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,114,230,0,0,0,54,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,126,0, - 0,0,114,125,0,0,0,114,127,0,0,0,114,128,0,0, - 0,114,214,0,0,0,114,230,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, - 16,1,0,0,34,4,0,0,115,6,0,0,0,8,2,4, - 2,8,16,114,16,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,253,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,110,0,0,0,114,160,0,0,0, - 114,6,1,0,0,114,6,0,0,0,114,6,0,0,0,114, - 9,0,0,0,114,210,0,0,0,71,4,0,0,115,4,0, - 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,0, - 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, - 106,1,124,1,106,1,107,2,83,0,114,110,0,0,0,114, - 241,0,0,0,114,243,0,0,0,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,114,244,0,0,0,75,4,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,0, - 124,0,106,2,131,1,65,0,83,0,114,110,0,0,0,114, - 245,0,0,0,114,247,0,0,0,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,114,248,0,0,0,79,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,135,0,0, - 0,114,215,0,0,0,114,164,0,0,0,90,14,99,114,101, - 97,116,101,95,100,121,110,97,109,105,99,114,150,0,0,0, - 114,117,0,0,0,114,45,0,0,0,41,3,114,119,0,0, - 0,114,188,0,0,0,114,217,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,213,0,0,0,82, - 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,135, - 0,0,0,114,215,0,0,0,114,164,0,0,0,90,12,101, - 120,101,99,95,100,121,110,97,109,105,99,114,150,0,0,0, - 114,117,0,0,0,114,45,0,0,0,114,254,0,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,218, - 0,0,0,90,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,40, - 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,210,0, - 0,0,78,114,6,0,0,0,169,2,114,33,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,6,0,0,0,114,9,0,0,0,218,9, - 60,103,101,110,101,120,112,114,62,99,4,0,0,115,4,0, - 0,0,4,1,2,255,122,49,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,4,114,48,0,0,0, - 114,45,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,220, - 0,0,0,114,6,0,0,0,114,19,1,0,0,114,9,0, - 0,0,114,183,0,0,0,96,4,0,0,115,8,0,0,0, - 0,2,14,1,12,1,2,255,122,30,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, - 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, - 0,115,4,0,0,0,100,1,83,0,41,2,122,63,82,101, - 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, - 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,6, - 0,0,0,114,220,0,0,0,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,114,214,0,0,0,102,4,0,0, - 115,2,0,0,0,0,2,122,28,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, - 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, - 0,0,0,100,1,83,0,41,2,122,53,82,101,116,117,114, - 110,32,78,111,110,101,32,97,115,32,101,120,116,101,110,115, - 105,111,110,32,109,111,100,117,108,101,115,32,104,97,118,101, - 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, - 78,114,6,0,0,0,114,220,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,230,0,0,0,106, - 4,0,0,115,2,0,0,0,0,2,122,30,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,6,0,0,0,124,0,106,0,83,0,114,251, - 0,0,0,114,49,0,0,0,114,220,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,180,0,0, - 0,110,4,0,0,115,2,0,0,0,0,3,122,32,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, - 14,114,126,0,0,0,114,125,0,0,0,114,127,0,0,0, - 114,128,0,0,0,114,210,0,0,0,114,244,0,0,0,114, - 248,0,0,0,114,213,0,0,0,114,218,0,0,0,114,183, - 0,0,0,114,214,0,0,0,114,230,0,0,0,114,137,0, - 0,0,114,180,0,0,0,114,6,0,0,0,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,114,253,0,0,0, - 63,4,0,0,115,22,0,0,0,8,2,4,6,8,4,8, - 4,8,3,8,8,8,6,8,6,8,4,8,4,2,1,114, - 253,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, + 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,88,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,12,1,12, + 2,2,1,14,1,12,1,8,2,12,1,2,1,14,1,12, + 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,18,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,14, + 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,29,3,0,0,115,14,0,0, + 0,8,2,8,8,8,14,8,10,8,7,8,10,14,8,114, + 221,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,0,0,0,0,115,124,0, 0,0,101,0,90,1,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,110,0,0,0,41,6, - 218,5,95,110,97,109,101,218,5,95,112,97,116,104,114,112, - 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,119,0,0,0,114,117,0, - 0,0,114,45,0,0,0,90,11,112,97,116,104,95,102,105, - 110,100,101,114,114,6,0,0,0,114,6,0,0,0,114,9, - 0,0,0,114,210,0,0,0,123,4,0,0,115,8,0,0, - 0,0,1,6,1,6,1,14,1,122,23,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 124,0,106,0,160,1,100,1,161,1,92,3,125,1,125,2, - 125,3,124,2,100,2,107,2,114,30,100,3,83,0,124,1, - 100,4,102,2,83,0,41,5,122,62,82,101,116,117,114,110, - 115,32,97,32,116,117,112,108,101,32,111,102,32,40,112,97, - 114,101,110,116,45,109,111,100,117,108,101,45,110,97,109,101, - 44,32,112,97,114,101,110,116,45,112,97,116,104,45,97,116, - 116,114,45,110,97,109,101,41,114,72,0,0,0,114,41,0, - 0,0,41,2,114,2,0,0,0,114,45,0,0,0,90,8, - 95,95,112,97,116,104,95,95,41,2,114,24,1,0,0,114, - 42,0,0,0,41,4,114,119,0,0,0,114,15,1,0,0, - 218,3,100,111,116,90,2,109,101,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,218,23,95,102,105,110,100,95, - 112,97,114,101,110,116,95,112,97,116,104,95,110,97,109,101, - 115,129,4,0,0,115,8,0,0,0,0,2,18,1,8,2, - 4,3,122,38,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,102,105,110,100,95,112,97,114,101,110,116,95, - 112,97,116,104,95,110,97,109,101,115,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,28,0,0,0,124,0,160,0,161,0,92,2, - 125,1,125,2,116,1,116,2,106,3,124,1,25,0,124,2, - 131,2,83,0,114,110,0,0,0,41,4,114,31,1,0,0, - 114,131,0,0,0,114,2,0,0,0,218,7,109,111,100,117, - 108,101,115,41,3,114,119,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,6, - 0,0,0,114,6,0,0,0,114,9,0,0,0,114,26,1, - 0,0,139,4,0,0,115,4,0,0,0,0,1,12,1,122, - 31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, - 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,80,0,0,0,116,0, - 124,0,160,1,161,0,131,1,125,1,124,1,124,0,106,2, - 107,3,114,74,124,0,160,3,124,0,106,4,124,1,161,2, - 125,2,124,2,100,0,117,1,114,68,124,2,106,5,100,0, - 117,0,114,68,124,2,106,6,114,68,124,2,106,6,124,0, - 95,7,124,1,124,0,95,2,124,0,106,7,83,0,114,110, - 0,0,0,41,8,114,112,0,0,0,114,26,1,0,0,114, - 27,1,0,0,114,28,1,0,0,114,24,1,0,0,114,141, - 0,0,0,114,179,0,0,0,114,25,1,0,0,41,3,114, - 119,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116, - 104,114,188,0,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,12,95,114,101,99,97,108,99,117,108, - 97,116,101,143,4,0,0,115,16,0,0,0,0,2,12,1, - 10,1,14,3,18,1,6,1,8,1,6,1,122,27,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101, - 99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,7,1,0,0,114, - 33,1,0,0,114,247,0,0,0,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,218,8,95,95,105,116,101,114, - 95,95,156,4,0,0,115,2,0,0,0,0,1,122,23,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 105,116,101,114,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, - 12,0,0,0,124,0,160,0,161,0,124,1,25,0,83,0, - 114,110,0,0,0,169,1,114,33,1,0,0,41,2,114,119, - 0,0,0,218,5,105,110,100,101,120,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,218,11,95,95,103,101,116, - 105,116,101,109,95,95,159,4,0,0,115,2,0,0,0,0, - 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,103,101,116,105,116,101,109,95,95,99,3,0, - 0,0,0,0,0,0,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,110,0,0,0,41,1, - 114,25,1,0,0,41,3,114,119,0,0,0,114,36,1,0, - 0,114,45,0,0,0,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,11,95,95,115,101,116,105,116,101,109, - 95,95,162,4,0,0,115,2,0,0,0,0,1,122,26,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 115,101,116,105,116,101,109,95,95,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,24,0,0,0,114, - 33,1,0,0,114,247,0,0,0,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,218,7,95,95,108,101,110,95, - 95,165,4,0,0,115,2,0,0,0,0,1,122,22,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,108, - 101,110,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,67,0,0,0,115,12,0, - 0,0,100,1,160,0,124,0,106,1,161,1,83,0,41,2, - 78,122,20,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,40,123,33,114,125,41,41,2,114,63,0,0,0,114,25, - 1,0,0,114,247,0,0,0,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,218,8,95,95,114,101,112,114,95, - 95,168,4,0,0,115,2,0,0,0,0,1,122,23,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114, - 101,112,114,95,95,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,12, - 0,0,0,124,1,124,0,160,0,161,0,118,0,83,0,114, - 110,0,0,0,114,35,1,0,0,169,2,114,119,0,0,0, - 218,4,105,116,101,109,114,6,0,0,0,114,6,0,0,0, - 114,9,0,0,0,218,12,95,95,99,111,110,116,97,105,110, - 115,95,95,171,4,0,0,115,2,0,0,0,0,1,122,27, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,16,0,0,0,124,0,106,0,160,1,124, - 1,161,1,1,0,100,0,83,0,114,110,0,0,0,41,2, - 114,25,1,0,0,114,187,0,0,0,114,41,1,0,0,114, - 6,0,0,0,114,6,0,0,0,114,9,0,0,0,114,187, - 0,0,0,174,4,0,0,115,2,0,0,0,0,1,122,21, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,97, - 112,112,101,110,100,78,41,15,114,126,0,0,0,114,125,0, - 0,0,114,127,0,0,0,114,128,0,0,0,114,210,0,0, - 0,114,31,1,0,0,114,26,1,0,0,114,33,1,0,0, - 114,34,1,0,0,114,37,1,0,0,114,38,1,0,0,114, - 39,1,0,0,114,40,1,0,0,114,43,1,0,0,114,187, - 0,0,0,114,6,0,0,0,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,114,23,1,0,0,116,4,0,0, - 115,24,0,0,0,8,1,4,6,8,6,8,10,8,4,8, - 13,8,3,8,3,8,3,8,3,8,3,8,3,114,23,1, + 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,178,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,184,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,188,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, + 191,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,203,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,208,3,0,0,115,10,0,0, + 0,0,2,14,1,16,1,40,2,14,1,122,19,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,100,97,116,97, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,67,0,0,0,115,18,0,0,0,124,0, + 160,0,124,1,161,1,114,14,124,0,83,0,100,0,83,0, + 114,109,0,0,0,41,1,114,182,0,0,0,169,2,114,118, + 0,0,0,114,216,0,0,0,114,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,219,3,0,0, + 115,6,0,0,0,0,2,10,1,4,1,122,30,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,114,101,115,111, + 117,114,99,101,95,114,101,97,100,101,114,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, + 67,0,0,0,115,32,0,0,0,116,0,116,1,124,0,106, + 2,131,1,100,1,25,0,124,1,131,2,125,2,116,3,160, + 4,124,2,100,2,161,2,83,0,41,3,78,114,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,225,3,0,0,115,4,0,0,0,0,1, + 20,1,122,24,70,105,108,101,76,111,97,100,101,114,46,111, + 112,101,110,95,114,101,115,111,117,114,99,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, + 0,67,0,0,0,115,38,0,0,0,124,0,160,0,124,1, + 161,1,115,14,116,1,130,1,116,2,116,3,124,0,106,4, + 131,1,100,1,25,0,124,1,131,2,125,2,124,2,83,0, + 169,2,78,114,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,229,3,0,0, + 115,8,0,0,0,0,1,10,1,4,1,20,1,122,24,70, + 105,108,101,76,111,97,100,101,114,46,114,101,115,111,117,114, + 99,101,95,112,97,116,104,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, + 115,40,0,0,0,116,0,124,1,118,0,114,12,100,1,83, + 0,116,1,116,2,124,0,106,3,131,1,100,2,25,0,124, + 1,131,2,125,2,116,4,124,2,131,1,83,0,41,3,78, + 70,114,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,235,3,0,0,115,8,0,0,0,0, + 1,8,1,4,1,20,1,122,22,70,105,108,101,76,111,97, + 100,101,114,46,105,115,95,114,101,115,111,117,114,99,101,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 5,0,0,0,67,0,0,0,115,24,0,0,0,116,0,116, + 1,160,2,116,3,124,0,106,4,131,1,100,1,25,0,161, + 1,131,1,83,0,114,1,1,0,0,41,5,218,4,105,116, + 101,114,114,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,241,3,0,0,115,2,0,0, + 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, + 99,111,110,116,101,110,116,115,41,17,114,125,0,0,0,114, + 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,209, + 0,0,0,114,243,0,0,0,114,247,0,0,0,114,136,0, + 0,0,114,220,0,0,0,114,179,0,0,0,114,227,0,0, + 0,114,254,0,0,0,114,0,1,0,0,114,4,1,0,0, + 114,2,1,0,0,114,8,1,0,0,90,13,95,95,99,108, + 97,115,115,99,101,108,108,95,95,114,3,0,0,0,114,3, + 0,0,0,114,249,0,0,0,114,6,0,0,0,114,239,0, + 0,0,173,3,0,0,115,30,0,0,0,8,2,4,3,8, + 6,8,4,8,3,2,1,14,11,2,1,10,4,8,11,2, + 1,10,5,8,4,8,6,8,6,114,239,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,249,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,254,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,104,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,121,110, + 1,0,1,0,1,0,89,0,113,60,89,0,113,60,4,0, + 116,8,121,162,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,52,4,0,116,8,144,0,121,246,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,3,4,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,12,2,8,1,14,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,245,3,0,0, + 115,8,0,0,0,8,2,4,2,8,5,8,5,114,9,1, 0,0,99,0,0,0,0,0,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,110,0,0,0,41,2,114,23,1,0,0, - 114,25,1,0,0,114,29,1,0,0,114,6,0,0,0,114, - 6,0,0,0,114,9,0,0,0,114,210,0,0,0,180,4, - 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,67,0,0,0,115,12,0, - 0,0,100,1,160,0,124,1,106,1,161,1,83,0,41,2, - 122,115,82,101,116,117,114,110,32,114,101,112,114,32,102,111, - 114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,99, - 104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,32, - 106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,32, - 32,32,32,32,32,122,25,60,109,111,100,117,108,101,32,123, - 33,114,125,32,40,110,97,109,101,115,112,97,99,101,41,62, - 41,2,114,63,0,0,0,114,126,0,0,0,41,2,114,194, - 0,0,0,114,217,0,0,0,114,6,0,0,0,114,6,0, - 0,0,114,9,0,0,0,218,11,109,111,100,117,108,101,95, - 114,101,112,114,183,4,0,0,115,2,0,0,0,0,7,122, - 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,46,109,111,100,117,108,101,95,114,101,112,114,99,2,0, + 0,0,0,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,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,38,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,54,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,34,4,0,0, + 115,6,0,0,0,8,2,4,2,8,16,114,15,1,0,0, + 99,0,0,0,0,0,0,0,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,71,4,0,0,115,4,0,0,0,0,1,6,1,122,28, + 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, + 100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, + 0,67,0,0,0,115,24,0,0,0,124,0,106,0,124,1, + 106,0,107,2,111,22,124,0,106,1,124,1,106,1,107,2, + 83,0,114,109,0,0,0,114,240,0,0,0,114,242,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,243,0,0,0,75,4,0,0,115,6,0,0,0,0,1, + 12,1,10,255,122,26,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,20,0,0,0,116,0, + 124,0,106,1,131,1,116,0,124,0,106,2,131,1,65,0, + 83,0,114,109,0,0,0,114,244,0,0,0,114,246,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,247,0,0,0,79,4,0,0,115,2,0,0,0,0,1, + 122,28,69,120,116,101,110,115,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,82,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,90,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,99,4,0,0,115,4,0,0,0,4,1,2,255,122,49, + 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, + 100,101,114,46,105,115,95,112,97,99,107,97,103,101,46,60, + 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, + 62,41,4,114,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,96, + 4,0,0,115,8,0,0,0,0,2,14,1,12,1,2,255, + 122,30,69,120,116,101,110,115,105,111,110,70,105,108,101,76, + 111,97,100,101,114,46,105,115,95,112,97,99,107,97,103,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,122,63,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,97,110,32,101,120,116,101,110,115,105,111, + 110,32,109,111,100,117,108,101,32,99,97,110,110,111,116,32, + 99,114,101,97,116,101,32,97,32,99,111,100,101,32,111,98, + 106,101,99,116,46,78,114,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,102,4,0,0,115,2,0,0,0,0,2,122, + 28,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,46,103,101,116,95,99,111,100,101,99,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,78,84,114,6,0,0,0,114,220,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,183,0,0, - 0,192,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,105, - 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,1,83,0,41,2,78,114,41, - 0,0,0,114,6,0,0,0,114,220,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,230,0,0, - 0,195,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, - 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, - 0,0,115,16,0,0,0,116,0,100,1,100,2,100,3,100, - 4,100,5,141,4,83,0,41,6,78,114,41,0,0,0,122, - 8,60,115,116,114,105,110,103,62,114,216,0,0,0,84,41, - 1,114,232,0,0,0,41,1,114,233,0,0,0,114,220,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,114,214,0,0,0,198,4,0,0,115,2,0,0,0,0, - 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,103,101,116,95,99,111,100,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,83,0,114,211, - 0,0,0,114,6,0,0,0,114,212,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,213,0,0, - 0,201,4,0,0,115,2,0,0,0,0,1,122,30,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,99, - 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,0,83,0,114,110, - 0,0,0,114,6,0,0,0,114,254,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,218,0,0, - 0,204,4,0,0,115,2,0,0,0,0,1,122,28,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, - 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,26,0,0,0,116,0,160,1,100,1,124,0, - 106,2,161,2,1,0,116,0,160,3,124,0,124,1,161,2, - 83,0,41,2,122,98,76,111,97,100,32,97,32,110,97,109, - 101,115,112,97,99,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100, - 117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10, - 32,32,32,32,32,32,32,32,122,38,110,97,109,101,115,112, - 97,99,101,32,109,111,100,117,108,101,32,108,111,97,100,101, - 100,32,119,105,116,104,32,112,97,116,104,32,123,33,114,125, - 41,4,114,135,0,0,0,114,150,0,0,0,114,25,1,0, - 0,114,219,0,0,0,114,220,0,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,221,0,0,0,207, - 4,0,0,115,8,0,0,0,0,7,6,1,4,255,4,2, - 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,78,41, - 12,114,126,0,0,0,114,125,0,0,0,114,127,0,0,0, - 114,210,0,0,0,114,208,0,0,0,114,45,1,0,0,114, - 183,0,0,0,114,230,0,0,0,114,214,0,0,0,114,213, - 0,0,0,114,218,0,0,0,114,221,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,114,44,1,0,0,179,4,0,0,115,18,0,0,0,8, - 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, - 3,114,44,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, + 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,106,4,0,0,115,2,0,0,0, + 0,2,122,30,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,6,0,0,0, + 124,0,106,0,83,0,114,250,0,0,0,114,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,110,4,0,0,115,2,0, + 0,0,0,3,122,32,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105, + 108,101,110,97,109,101,78,41,14,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,209,0, + 0,0,114,243,0,0,0,114,247,0,0,0,114,212,0,0, + 0,114,217,0,0,0,114,182,0,0,0,114,213,0,0,0, + 114,229,0,0,0,114,136,0,0,0,114,179,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,252,0,0,0,63,4,0,0,115,22,0,0, + 0,8,2,4,6,8,4,8,4,8,3,8,8,8,6,8, + 6,8,4,8,4,2,1,114,252,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,64,0,0,0,115,104,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, + 100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8, + 100,9,132,0,90,7,100,10,100,11,132,0,90,8,100,12, + 100,13,132,0,90,9,100,14,100,15,132,0,90,10,100,16, + 100,17,132,0,90,11,100,18,100,19,132,0,90,12,100,20, + 100,21,132,0,90,13,100,22,100,23,132,0,90,14,100,24, + 83,0,41,25,218,14,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,97,38,1,0,0,82,101,112,114,101,115,101, + 110,116,115,32,97,32,110,97,109,101,115,112,97,99,101,32, + 112,97,99,107,97,103,101,39,115,32,112,97,116,104,46,32, + 32,73,116,32,117,115,101,115,32,116,104,101,32,109,111,100, + 117,108,101,32,110,97,109,101,10,32,32,32,32,116,111,32, + 102,105,110,100,32,105,116,115,32,112,97,114,101,110,116,32, + 109,111,100,117,108,101,44,32,97,110,100,32,102,114,111,109, + 32,116,104,101,114,101,32,105,116,32,108,111,111,107,115,32, + 117,112,32,116,104,101,32,112,97,114,101,110,116,39,115,10, + 32,32,32,32,95,95,112,97,116,104,95,95,46,32,32,87, + 104,101,110,32,116,104,105,115,32,99,104,97,110,103,101,115, + 44,32,116,104,101,32,109,111,100,117,108,101,39,115,32,111, + 119,110,32,112,97,116,104,32,105,115,32,114,101,99,111,109, + 112,117,116,101,100,44,10,32,32,32,32,117,115,105,110,103, + 32,112,97,116,104,95,102,105,110,100,101,114,46,32,32,70, + 111,114,32,116,111,112,45,108,101,118,101,108,32,109,111,100, + 117,108,101,115,44,32,116,104,101,32,112,97,114,101,110,116, + 32,109,111,100,117,108,101,39,115,32,112,97,116,104,10,32, + 32,32,32,105,115,32,115,121,115,46,112,97,116,104,46,99, + 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 3,0,0,0,67,0,0,0,115,36,0,0,0,124,1,124, + 0,95,0,124,2,124,0,95,1,116,2,124,0,160,3,161, + 0,131,1,124,0,95,4,124,3,124,0,95,5,100,0,83, + 0,114,109,0,0,0,41,6,218,5,95,110,97,109,101,218, + 5,95,112,97,116,104,114,111,0,0,0,218,16,95,103,101, + 116,95,112,97,114,101,110,116,95,112,97,116,104,218,17,95, + 108,97,115,116,95,112,97,114,101,110,116,95,112,97,116,104, + 218,12,95,112,97,116,104,95,102,105,110,100,101,114,169,4, + 114,118,0,0,0,114,116,0,0,0,114,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, + 123,4,0,0,115,8,0,0,0,0,1,6,1,6,1,14, + 1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,95,95,105,110,105,116,95,95,99,1,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,124,0,106,0,160,1,100,1, + 161,1,92,3,125,1,125,2,125,3,124,2,100,2,107,2, + 114,30,100,3,83,0,124,1,100,4,102,2,83,0,41,5, + 122,62,82,101,116,117,114,110,115,32,97,32,116,117,112,108, + 101,32,111,102,32,40,112,97,114,101,110,116,45,109,111,100, + 117,108,101,45,110,97,109,101,44,32,112,97,114,101,110,116, + 45,112,97,116,104,45,97,116,116,114,45,110,97,109,101,41, + 114,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,129,4,0,0,115,8,0, + 0,0,0,2,18,1,8,2,4,3,122,38,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,102,105,110,100, + 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, + 101,115,99,1,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,67,0,0,0,115,28,0,0,0, + 124,0,160,0,161,0,92,2,125,1,125,2,116,1,116,2, + 106,3,124,1,25,0,124,2,131,2,83,0,114,109,0,0, + 0,41,4,114,30,1,0,0,114,130,0,0,0,114,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,139,4,0,0,115,4, + 0,0,0,0,1,12,1,122,31,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,46,95,103,101,116,95,112,97,114, + 101,110,116,95,112,97,116,104,99,1,0,0,0,0,0,0, 0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0, - 0,115,64,0,0,0,116,0,116,1,106,2,160,3,161,0, - 131,1,68,0,93,44,92,2,125,1,125,2,124,2,100,1, - 117,0,114,40,116,1,106,2,124,1,61,0,113,14,116,4, - 124,2,100,2,131,2,114,14,124,2,160,5,161,0,1,0, - 113,14,100,1,83,0,41,3,122,125,67,97,108,108,32,116, - 104,101,32,105,110,118,97,108,105,100,97,116,101,95,99,97, - 99,104,101,115,40,41,32,109,101,116,104,111,100,32,111,110, - 32,97,108,108,32,112,97,116,104,32,101,110,116,114,121,32, - 102,105,110,100,101,114,115,10,32,32,32,32,32,32,32,32, - 115,116,111,114,101,100,32,105,110,32,115,121,115,46,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,115,32,40,119,104,101,114,101,32,105,109,112,108,101,109, - 101,110,116,101,100,41,46,78,218,17,105,110,118,97,108,105, - 100,97,116,101,95,99,97,99,104,101,115,41,6,218,4,108, - 105,115,116,114,2,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,129,0,0,0,114,47,1,0,0,41,3, - 114,194,0,0,0,114,117,0,0,0,218,6,102,105,110,100, - 101,114,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,114,47,1,0,0,225,4,0,0,115,10,0,0,0,0, - 4,22,1,8,1,10,1,10,1,122,28,80,97,116,104,70, - 105,110,100,101,114,46,105,110,118,97,108,105,100,97,116,101, - 95,99,97,99,104,101,115,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,9,0,0,0,67,0,0,0, - 115,82,0,0,0,116,0,106,1,100,1,117,1,114,28,116, - 0,106,1,115,28,116,2,160,3,100,2,116,4,161,2,1, - 0,116,0,106,1,68,0,93,42,125,2,122,14,124,2,124, - 1,131,1,87,0,2,0,1,0,83,0,4,0,116,5,121, - 74,1,0,1,0,1,0,89,0,113,34,89,0,113,34,48, - 0,113,34,100,1,83,0,41,3,122,46,83,101,97,114,99, - 104,32,115,121,115,46,112,97,116,104,95,104,111,111,107,115, - 32,102,111,114,32,97,32,102,105,110,100,101,114,32,102,111, - 114,32,39,112,97,116,104,39,46,78,122,23,115,121,115,46, - 112,97,116,104,95,104,111,111,107,115,32,105,115,32,101,109, - 112,116,121,41,6,114,2,0,0,0,218,10,112,97,116,104, - 95,104,111,111,107,115,114,76,0,0,0,114,77,0,0,0, - 114,139,0,0,0,114,118,0,0,0,41,3,114,194,0,0, - 0,114,45,0,0,0,90,4,104,111,111,107,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,218,11,95,112,97, - 116,104,95,104,111,111,107,115,235,4,0,0,115,16,0,0, - 0,0,3,16,1,12,1,10,1,2,1,14,1,12,1,12, - 2,122,22,80,97,116,104,70,105,110,100,101,114,46,95,112, - 97,116,104,95,104,111,111,107,115,99,2,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,8,0,0,0,67,0, - 0,0,115,100,0,0,0,124,1,100,1,107,2,114,42,122, - 12,116,0,160,1,161,0,125,1,87,0,110,20,4,0,116, - 2,121,40,1,0,1,0,1,0,89,0,100,2,83,0,48, - 0,122,14,116,3,106,4,124,1,25,0,125,2,87,0,110, - 38,4,0,116,5,121,94,1,0,1,0,1,0,124,0,160, - 6,124,1,161,1,125,2,124,2,116,3,106,4,124,1,60, - 0,89,0,110,2,48,0,124,2,83,0,41,3,122,210,71, - 101,116,32,116,104,101,32,102,105,110,100,101,114,32,102,111, - 114,32,116,104,101,32,112,97,116,104,32,101,110,116,114,121, - 32,102,114,111,109,32,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,41,0,0,0,78,41,7,114,5,0,0,0,114,56, - 0,0,0,114,4,1,0,0,114,2,0,0,0,114,49,1, - 0,0,218,8,75,101,121,69,114,114,111,114,114,53,1,0, - 0,41,3,114,194,0,0,0,114,45,0,0,0,114,51,1, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,218,20,95,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,248,4,0,0,115,22,0,0,0, - 0,8,8,1,2,1,12,1,12,3,8,1,2,1,14,1, - 12,1,10,1,16,1,122,31,80,97,116,104,70,105,110,100, - 101,114,46,95,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,99,3,0,0,0,0,0,0,0, - 0,0,0,0,6,0,0,0,4,0,0,0,67,0,0,0, - 115,82,0,0,0,116,0,124,2,100,1,131,2,114,26,124, - 2,160,1,124,1,161,1,92,2,125,3,125,4,110,14,124, - 2,160,2,124,1,161,1,125,3,103,0,125,4,124,3,100, - 0,117,1,114,60,116,3,160,4,124,1,124,3,161,2,83, - 0,116,3,160,5,124,1,100,0,161,2,125,5,124,4,124, - 5,95,6,124,5,83,0,41,2,78,114,138,0,0,0,41, - 7,114,129,0,0,0,114,138,0,0,0,114,207,0,0,0, - 114,135,0,0,0,114,202,0,0,0,114,184,0,0,0,114, - 179,0,0,0,41,6,114,194,0,0,0,114,140,0,0,0, - 114,51,1,0,0,114,141,0,0,0,114,142,0,0,0,114, - 188,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, - 0,0,0,218,16,95,108,101,103,97,99,121,95,103,101,116, - 95,115,112,101,99,14,5,0,0,115,18,0,0,0,0,4, - 10,1,16,2,10,1,4,1,8,1,12,1,12,1,6,1, - 122,27,80,97,116,104,70,105,110,100,101,114,46,95,108,101, - 103,97,99,121,95,103,101,116,95,115,112,101,99,78,99,4, - 0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,5, - 0,0,0,67,0,0,0,115,166,0,0,0,103,0,125,4, - 124,2,68,0,93,134,125,5,116,0,124,5,116,1,116,2, - 102,2,131,2,115,28,113,8,124,0,160,3,124,5,161,1, - 125,6,124,6,100,1,117,1,114,8,116,4,124,6,100,2, - 131,2,114,70,124,6,160,5,124,1,124,3,161,2,125,7, - 110,12,124,0,160,6,124,1,124,6,161,2,125,7,124,7, - 100,1,117,0,114,92,113,8,124,7,106,7,100,1,117,1, - 114,110,124,7,2,0,1,0,83,0,124,7,106,8,125,8, - 124,8,100,1,117,0,114,132,116,9,100,3,131,1,130,1, - 124,4,160,10,124,8,161,1,1,0,113,8,116,11,160,12, - 124,1,100,1,161,2,125,7,124,4,124,7,95,8,124,7, - 83,0,41,4,122,63,70,105,110,100,32,116,104,101,32,108, - 111,97,100,101,114,32,111,114,32,110,97,109,101,115,112,97, - 99,101,95,112,97,116,104,32,102,111,114,32,116,104,105,115, - 32,109,111,100,117,108,101,47,112,97,99,107,97,103,101,32, - 110,97,109,101,46,78,114,204,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,162,0,0,0,114,85,0,0,0,218,5,98,121, - 116,101,115,114,55,1,0,0,114,129,0,0,0,114,204,0, - 0,0,114,56,1,0,0,114,141,0,0,0,114,179,0,0, - 0,114,118,0,0,0,114,168,0,0,0,114,135,0,0,0, - 114,184,0,0,0,41,9,114,194,0,0,0,114,140,0,0, - 0,114,45,0,0,0,114,203,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,51,1,0,0,114,188,0,0,0,114,142,0,0, - 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, - 218,9,95,103,101,116,95,115,112,101,99,29,5,0,0,115, - 40,0,0,0,0,5,4,1,8,1,14,1,2,1,10,1, - 8,1,10,1,14,2,12,1,8,1,2,1,10,1,8,1, - 6,1,8,1,8,5,12,2,12,1,6,1,122,20,80,97, - 116,104,70,105,110,100,101,114,46,95,103,101,116,95,115,112, - 101,99,99,4,0,0,0,0,0,0,0,0,0,0,0,6, - 0,0,0,5,0,0,0,67,0,0,0,115,100,0,0,0, - 124,2,100,1,117,0,114,14,116,0,106,1,125,2,124,0, - 160,2,124,1,124,2,124,3,161,3,125,4,124,4,100,1, - 117,0,114,40,100,1,83,0,124,4,106,3,100,1,117,0, - 114,92,124,4,106,4,125,5,124,5,114,86,100,1,124,4, - 95,5,116,6,124,1,124,5,124,0,106,2,131,3,124,4, - 95,4,124,4,83,0,100,1,83,0,110,4,124,4,83,0, - 100,1,83,0,41,2,122,141,84,114,121,32,116,111,32,102, - 105,110,100,32,97,32,115,112,101,99,32,102,111,114,32,39, - 102,117,108,108,110,97,109,101,39,32,111,110,32,115,121,115, - 46,112,97,116,104,32,111,114,32,39,112,97,116,104,39,46, - 10,10,32,32,32,32,32,32,32,32,84,104,101,32,115,101, - 97,114,99,104,32,105,115,32,98,97,115,101,100,32,111,110, - 32,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, - 97,110,100,32,115,121,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,2,0,0,0,114,45,0, - 0,0,114,59,1,0,0,114,141,0,0,0,114,179,0,0, - 0,114,182,0,0,0,114,23,1,0,0,41,6,114,194,0, - 0,0,114,140,0,0,0,114,45,0,0,0,114,203,0,0, - 0,114,188,0,0,0,114,58,1,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,204,0,0,0,61, - 5,0,0,115,26,0,0,0,0,6,8,1,6,1,14,1, - 8,1,4,1,10,1,6,1,4,3,6,1,16,1,4,2, - 6,2,122,20,80,97,116,104,70,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0, - 0,115,30,0,0,0,124,0,160,0,124,1,124,2,161,2, - 125,3,124,3,100,1,117,0,114,24,100,1,83,0,124,3, - 106,1,83,0,41,2,122,170,102,105,110,100,32,116,104,101, - 32,109,111,100,117,108,101,32,111,110,32,115,121,115,46,112, - 97,116,104,32,111,114,32,39,112,97,116,104,39,32,98,97, - 115,101,100,32,111,110,32,115,121,115,46,112,97,116,104,95, - 104,111,111,107,115,32,97,110,100,10,32,32,32,32,32,32, - 32,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, - 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, - 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, - 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,78,114,205,0,0,0,114,206,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,207,0,0, - 0,85,5,0,0,115,8,0,0,0,0,8,12,1,8,1, - 4,1,122,22,80,97,116,104,70,105,110,100,101,114,46,102, - 105,110,100,95,109,111,100,117,108,101,99,1,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,79, - 0,0,0,115,28,0,0,0,100,1,100,2,108,0,109,1, - 125,3,1,0,124,3,106,2,124,1,105,0,124,2,164,1, - 142,1,83,0,41,3,97,32,1,0,0,10,32,32,32,32, - 32,32,32,32,70,105,110,100,32,100,105,115,116,114,105,98, - 117,116,105,111,110,115,46,10,10,32,32,32,32,32,32,32, - 32,82,101,116,117,114,110,32,97,110,32,105,116,101,114,97, - 98,108,101,32,111,102,32,97,108,108,32,68,105,115,116,114, - 105,98,117,116,105,111,110,32,105,110,115,116,97,110,99,101, - 115,32,99,97,112,97,98,108,101,32,111,102,10,32,32,32, - 32,32,32,32,32,108,111,97,100,105,110,103,32,116,104,101, - 32,109,101,116,97,100,97,116,97,32,102,111,114,32,112,97, - 99,107,97,103,101,115,32,109,97,116,99,104,105,110,103,32, - 96,96,99,111,110,116,101,120,116,46,110,97,109,101,96,96, - 10,32,32,32,32,32,32,32,32,40,111,114,32,97,108,108, - 32,110,97,109,101,115,32,105,102,32,96,96,78,111,110,101, - 96,96,32,105,110,100,105,99,97,116,101,100,41,32,97,108, - 111,110,103,32,116,104,101,32,112,97,116,104,115,32,105,110, - 32,116,104,101,32,108,105,115,116,10,32,32,32,32,32,32, - 32,32,111,102,32,100,105,114,101,99,116,111,114,105,101,115, - 32,96,96,99,111,110,116,101,120,116,46,112,97,116,104,96, - 96,46,10,32,32,32,32,32,32,32,32,114,74,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,60,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,194,0,0,0,114,120,0,0, - 0,114,121,0,0,0,114,60,1,0,0,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,61,1,0,0,98, - 5,0,0,115,4,0,0,0,0,10,12,1,122,29,80,97, - 116,104,70,105,110,100,101,114,46,102,105,110,100,95,100,105, - 115,116,114,105,98,117,116,105,111,110,115,41,1,78,41,2, - 78,78,41,1,78,41,13,114,126,0,0,0,114,125,0,0, - 0,114,127,0,0,0,114,128,0,0,0,114,208,0,0,0, - 114,47,1,0,0,114,53,1,0,0,114,55,1,0,0,114, - 56,1,0,0,114,59,1,0,0,114,204,0,0,0,114,207, - 0,0,0,114,61,1,0,0,114,6,0,0,0,114,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,46,1,0, - 0,221,4,0,0,115,34,0,0,0,8,2,4,2,2,1, - 10,9,2,1,10,12,2,1,10,21,2,1,10,14,2,1, - 12,31,2,1,12,23,2,1,12,12,2,1,114,46,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,110,0,0,0,114,6, - 0,0,0,114,17,1,0,0,169,1,114,141,0,0,0,114, - 6,0,0,0,114,9,0,0,0,114,20,1,0,0,127,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,72,0,0,0,114,105,0,0,0,78,41,7, - 114,168,0,0,0,218,8,95,108,111,97,100,101,114,115,114, - 45,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,119,0,0,0,114, - 45,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,190,0, - 0,0,114,6,0,0,0,114,63,1,0,0,114,9,0,0, - 0,114,210,0,0,0,121,5,0,0,115,16,0,0,0,0, - 4,4,1,12,1,26,1,6,2,10,1,6,1,8,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,2,0,0,0,67,0,0,0,115,10,0, - 0,0,100,1,124,0,95,0,100,2,83,0,41,3,122,31, - 73,110,118,97,108,105,100,97,116,101,32,116,104,101,32,100, - 105,114,101,99,116,111,114,121,32,109,116,105,109,101,46,114, - 105,0,0,0,78,41,1,114,65,1,0,0,114,247,0,0, - 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, - 114,47,1,0,0,135,5,0,0,115,2,0,0,0,0,2, - 122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,118, - 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, - 0,0,0,67,0,0,0,115,42,0,0,0,124,0,160,0, - 124,1,161,1,125,2,124,2,100,1,117,0,114,26,100,1, - 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, - 103,0,102,2,83,0,41,2,122,197,84,114,121,32,116,111, - 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,32, - 110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,32, - 32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,111, - 110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,97, - 100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,114, - 116,105,111,110,115,41,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, - 41,3,114,204,0,0,0,114,141,0,0,0,114,179,0,0, - 0,41,3,114,119,0,0,0,114,140,0,0,0,114,188,0, - 0,0,114,6,0,0,0,114,6,0,0,0,114,9,0,0, - 0,114,138,0,0,0,141,5,0,0,115,8,0,0,0,0, - 7,10,1,8,1,8,1,122,22,70,105,108,101,70,105,110, - 100,101,114,46,102,105,110,100,95,108,111,97,100,101,114,99, - 6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, - 6,0,0,0,67,0,0,0,115,26,0,0,0,124,1,124, - 2,124,3,131,2,125,6,116,0,124,2,124,3,124,6,124, - 4,100,1,141,4,83,0,41,2,78,114,178,0,0,0,41, - 1,114,191,0,0,0,41,7,114,119,0,0,0,114,189,0, - 0,0,114,140,0,0,0,114,45,0,0,0,90,4,115,109, - 115,108,114,203,0,0,0,114,141,0,0,0,114,6,0,0, - 0,114,6,0,0,0,114,9,0,0,0,114,59,1,0,0, - 153,5,0,0,115,8,0,0,0,0,1,10,1,8,1,2, - 255,122,20,70,105,108,101,70,105,110,100,101,114,46,95,103, - 101,116,95,115,112,101,99,78,99,3,0,0,0,0,0,0, - 0,0,0,0,0,14,0,0,0,8,0,0,0,67,0,0, - 0,115,96,1,0,0,100,1,125,3,124,1,160,0,100,2, - 161,1,100,3,25,0,125,4,122,24,116,1,124,0,106,2, - 112,34,116,3,160,4,161,0,131,1,106,5,125,5,87,0, - 110,22,4,0,116,6,121,64,1,0,1,0,1,0,100,4, - 125,5,89,0,110,2,48,0,124,5,124,0,106,7,107,3, - 114,90,124,0,160,8,161,0,1,0,124,5,124,0,95,7, - 116,9,131,0,114,112,124,0,106,10,125,6,124,4,160,11, - 161,0,125,7,110,10,124,0,106,12,125,6,124,4,125,7, - 124,7,124,6,118,0,114,216,116,13,124,0,106,2,124,4, - 131,2,125,8,124,0,106,14,68,0,93,58,92,2,125,9, - 125,10,100,5,124,9,23,0,125,11,116,13,124,8,124,11, - 131,2,125,12,116,15,124,12,131,1,114,148,124,0,160,16, - 124,10,124,1,124,12,124,8,103,1,124,2,161,5,2,0, - 1,0,83,0,113,148,116,17,124,8,131,1,125,3,124,0, - 106,14,68,0,93,82,92,2,125,9,125,10,116,13,124,0, - 106,2,124,4,124,9,23,0,131,2,125,12,116,18,106,19, - 100,6,124,12,100,3,100,7,141,3,1,0,124,7,124,9, - 23,0,124,6,118,0,114,222,116,15,124,12,131,1,114,222, - 124,0,160,16,124,10,124,1,124,12,100,8,124,2,161,5, - 2,0,1,0,83,0,113,222,124,3,144,1,114,92,116,18, - 160,19,100,9,124,8,161,2,1,0,116,18,160,20,124,1, - 100,8,161,2,125,13,124,8,103,1,124,13,95,21,124,13, - 83,0,100,8,83,0,41,10,122,111,84,114,121,32,116,111, - 32,102,105,110,100,32,97,32,115,112,101,99,32,102,111,114, - 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,109, + 0,115,80,0,0,0,116,0,124,0,160,1,161,0,131,1, + 125,1,124,1,124,0,106,2,107,3,114,74,124,0,160,3, + 124,0,106,4,124,1,161,2,125,2,124,2,100,0,117,1, + 114,68,124,2,106,5,100,0,117,0,114,68,124,2,106,6, + 114,68,124,2,106,6,124,0,95,7,124,1,124,0,95,2, + 124,0,106,7,83,0,114,109,0,0,0,41,8,114,111,0, + 0,0,114,25,1,0,0,114,26,1,0,0,114,27,1,0, + 0,114,23,1,0,0,114,140,0,0,0,114,178,0,0,0, + 114,24,1,0,0,41,3,114,118,0,0,0,90,11,112,97, + 114,101,110,116,95,112,97,116,104,114,187,0,0,0,114,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,143,4,0,0,115, + 16,0,0,0,0,2,12,1,10,1,14,3,18,1,6,1, + 8,1,6,1,122,27,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,114,101,99,97,108,99,117,108,97,116, + 101,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,116, + 0,124,0,160,1,161,0,131,1,83,0,114,109,0,0,0, + 41,2,114,6,1,0,0,114,32,1,0,0,114,246,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,8,95,95,105,116,101,114,95,95,156,4,0,0,115,2, + 0,0,0,0,1,122,23,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,95,105,116,101,114,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, + 0,0,0,67,0,0,0,115,12,0,0,0,124,0,160,0, + 161,0,124,1,25,0,83,0,114,109,0,0,0,169,1,114, + 32,1,0,0,41,2,114,118,0,0,0,218,5,105,110,100, + 101,120,114,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,159,4, + 0,0,115,2,0,0,0,0,1,122,26,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,95,103,101,116,105, + 116,101,109,95,95,99,3,0,0,0,0,0,0,0,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,162,4,0,0,115,2, + 0,0,0,0,1,122,26,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,95,115,101,116,105,116,101,109,95, + 95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,116, + 0,124,0,160,1,161,0,131,1,83,0,114,109,0,0,0, + 41,2,114,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,165,4,0,0,115,2,0, + 0,0,0,1,122,22,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,108,101,110,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,67,0,0,0,115,12,0,0,0,100,1,160,0,124,0, + 106,1,161,1,83,0,41,2,78,122,20,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,40,123,33,114,125,41,41, + 2,114,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,168,4,0,0,115,2,0, + 0,0,0,1,122,23,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,114,101,112,114,95,95,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,67,0,0,0,115,12,0,0,0,124,1,124,0,160, + 0,161,0,118,0,83,0,114,109,0,0,0,114,34,1,0, + 0,169,2,114,118,0,0,0,218,4,105,116,101,109,114,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,171,4,0,0,115, + 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,95,99,111,110,116,97,105,110, + 115,95,95,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,67,0,0,0,115,16,0,0, + 0,124,0,106,0,160,1,124,1,161,1,1,0,100,0,83, + 0,114,109,0,0,0,41,2,114,24,1,0,0,114,186,0, + 0,0,114,40,1,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,186,0,0,0,174,4,0,0,115, + 2,0,0,0,0,1,122,21,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,97,112,112,101,110,100,78,41,15, + 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, + 127,0,0,0,114,209,0,0,0,114,30,1,0,0,114,25, + 1,0,0,114,32,1,0,0,114,33,1,0,0,114,36,1, + 0,0,114,37,1,0,0,114,38,1,0,0,114,39,1,0, + 0,114,42,1,0,0,114,186,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 22,1,0,0,116,4,0,0,115,24,0,0,0,8,1,4, + 6,8,6,8,10,8,4,8,13,8,3,8,3,8,3,8, + 3,8,3,8,3,114,22,1,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, + 0,0,0,115,80,0,0,0,101,0,90,1,100,0,90,2, + 100,1,100,2,132,0,90,3,101,4,100,3,100,4,132,0, + 131,1,90,5,100,5,100,6,132,0,90,6,100,7,100,8, + 132,0,90,7,100,9,100,10,132,0,90,8,100,11,100,12, + 132,0,90,9,100,13,100,14,132,0,90,10,100,15,100,16, + 132,0,90,11,100,17,83,0,41,18,218,16,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,99,4,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, + 0,67,0,0,0,115,18,0,0,0,116,0,124,1,124,2, + 124,3,131,3,124,0,95,1,100,0,83,0,114,109,0,0, + 0,41,2,114,22,1,0,0,114,24,1,0,0,114,28,1, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,209,0,0,0,180,4,0,0,115,2,0,0,0,0, + 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, + 100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, + 0,67,0,0,0,115,12,0,0,0,100,1,160,0,124,1, + 106,1,161,1,83,0,41,2,122,115,82,101,116,117,114,110, + 32,114,101,112,114,32,102,111,114,32,116,104,101,32,109,111, + 100,117,108,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,101,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,32,84,104,101,32,105,109, + 112,111,114,116,32,109,97,99,104,105,110,101,114,121,32,100, + 111,101,115,32,116,104,101,32,106,111,98,32,105,116,115,101, + 108,102,46,10,10,32,32,32,32,32,32,32,32,122,25,60, + 109,111,100,117,108,101,32,123,33,114,125,32,40,110,97,109, + 101,115,112,97,99,101,41,62,41,2,114,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,183,4,0,0, + 115,2,0,0,0,0,7,122,28,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,46,109,111,100,117,108,101, + 95,114,101,112,114,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,78,84,114,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,192,4,0,0,115,2,0, + 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,83,0,41,2,78,114,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,195,4,0,0,115,2,0, + 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,6,0,0,0,67,0,0,0,115,16,0,0,0,116, + 0,100,1,100,2,100,3,100,4,100,5,141,4,83,0,41, + 6,78,114,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,198,4, + 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, + 115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95, + 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,114,210,0,0,0,114,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,201,4,0,0,115,2,0, + 0,0,0,1,122,30,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,99,114,101,97,116,101,95,109,111, + 100,117,108,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,0,83,0,114,109,0,0,0,114,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,204,4,0,0,115,2,0, + 0,0,0,1,122,28,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,67,0,0,0,115,26,0,0,0, + 116,0,160,1,100,1,124,0,106,2,161,2,1,0,116,0, + 160,3,124,0,124,1,161,2,83,0,41,2,122,98,76,111, + 97,100,32,97,32,110,97,109,101,115,112,97,99,101,32,109, 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, - 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,72,0,0,0,114, - 29,0,0,0,114,105,0,0,0,114,210,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,42,0,0,0,114,50,0,0,0,114,45, - 0,0,0,114,5,0,0,0,114,56,0,0,0,114,11,1, - 0,0,114,51,0,0,0,114,65,1,0,0,218,11,95,102, - 105,108,108,95,99,97,99,104,101,114,10,0,0,0,114,68, - 1,0,0,114,106,0,0,0,114,67,1,0,0,114,39,0, - 0,0,114,64,1,0,0,114,55,0,0,0,114,59,1,0, - 0,114,57,0,0,0,114,135,0,0,0,114,150,0,0,0, - 114,184,0,0,0,114,179,0,0,0,41,14,114,119,0,0, - 0,114,140,0,0,0,114,203,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,170,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,18,1,0,0, - 114,189,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, - 188,0,0,0,114,6,0,0,0,114,6,0,0,0,114,9, - 0,0,0,114,204,0,0,0,158,5,0,0,115,74,0,0, - 0,0,5,4,1,14,1,2,1,24,1,12,1,10,1,10, - 1,8,1,6,2,6,1,6,1,10,2,6,1,4,2,8, - 1,12,1,14,1,8,1,10,1,8,1,26,4,8,2,14, - 1,16,1,16,1,12,1,8,1,10,1,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,188,0,0,0,124, - 0,106,0,125,1,122,22,116,1,160,2,124,1,112,22,116, - 1,160,3,161,0,161,1,125,2,87,0,110,28,4,0,116, - 4,116,5,116,6,102,3,121,56,1,0,1,0,1,0,103, - 0,125,2,89,0,110,2,48,0,116,7,106,8,160,9,100, - 1,161,1,115,82,116,10,124,2,131,1,124,0,95,11,110, - 74,116,10,131,0,125,3,124,2,68,0,93,56,125,4,124, - 4,160,12,100,2,161,1,92,3,125,5,125,6,125,7,124, - 6,114,134,100,3,160,13,124,5,124,7,160,14,161,0,161, - 2,125,8,110,4,124,5,125,8,124,3,160,15,124,8,161, - 1,1,0,113,92,124,3,124,0,95,11,116,7,106,8,160, - 9,116,16,161,1,114,184,100,4,100,5,132,0,124,2,68, - 0,131,1,124,0,95,17,100,6,83,0,41,7,122,68,70, - 105,108,108,32,116,104,101,32,99,97,99,104,101,32,111,102, - 32,112,111,116,101,110,116,105,97,108,32,109,111,100,117,108, - 101,115,32,97,110,100,32,112,97,99,107,97,103,101,115,32, - 102,111,114,32,116,104,105,115,32,100,105,114,101,99,116,111, - 114,121,46,114,0,0,0,0,114,72,0,0,0,114,62,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,6,0,0,0,41,1,114,106,0,0,0, - 41,2,114,33,0,0,0,90,2,102,110,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,218,9,60,115,101,116, - 99,111,109,112,62,235,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,45,0,0,0,114,5,0,0,0,114,8,1,0,0,114, - 56,0,0,0,114,4,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,2, - 0,0,0,114,11,0,0,0,114,12,0,0,0,114,66,1, - 0,0,114,67,1,0,0,114,101,0,0,0,114,63,0,0, - 0,114,106,0,0,0,218,3,97,100,100,114,13,0,0,0, - 114,68,1,0,0,41,9,114,119,0,0,0,114,45,0,0, - 0,114,9,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,42,1, - 0,0,114,117,0,0,0,114,30,1,0,0,114,18,1,0, - 0,90,8,110,101,119,95,110,97,109,101,114,6,0,0,0, - 114,6,0,0,0,114,9,0,0,0,114,70,1,0,0,206, - 5,0,0,115,34,0,0,0,0,2,6,1,2,1,22,1, - 18,3,10,3,12,1,12,7,6,1,8,1,16,1,4,1, - 18,2,4,1,12,1,6,1,12,1,122,22,70,105,108,101, + 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,207,4,0,0,115,8,0,0,0, + 0,7,6,1,4,255,4,2,122,28,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,46,108,111,97,100,95, + 109,111,100,117,108,101,78,41,12,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,209,0,0,0,114,207,0, + 0,0,114,44,1,0,0,114,182,0,0,0,114,229,0,0, + 0,114,213,0,0,0,114,212,0,0,0,114,217,0,0,0, + 114,220,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,43,1,0,0,179,4, + 0,0,115,18,0,0,0,8,1,8,3,2,1,10,8,8, + 3,8,3,8,3,8,3,8,3,114,43,1,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,64,0,0,0,115,118,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,101,4,100,2,100,3,132,0, + 131,1,90,5,101,4,100,4,100,5,132,0,131,1,90,6, + 101,4,100,6,100,7,132,0,131,1,90,7,101,4,100,8, + 100,9,132,0,131,1,90,8,101,4,100,19,100,11,100,12, + 132,1,131,1,90,9,101,4,100,20,100,13,100,14,132,1, + 131,1,90,10,101,4,100,21,100,15,100,16,132,1,131,1, + 90,11,101,4,100,17,100,18,132,0,131,1,90,12,100,10, + 83,0,41,22,218,10,80,97,116,104,70,105,110,100,101,114, + 122,62,77,101,116,97,32,112,97,116,104,32,102,105,110,100, + 101,114,32,102,111,114,32,115,121,115,46,112,97,116,104,32, + 97,110,100,32,112,97,99,107,97,103,101,32,95,95,112,97, + 116,104,95,95,32,97,116,116,114,105,98,117,116,101,115,46, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,4,0,0,0,67,0,0,0,115,64,0,0,0,116,0, + 116,1,106,2,160,3,161,0,131,1,68,0,93,44,92,2, + 125,1,125,2,124,2,100,1,117,0,114,40,116,1,106,2, + 124,1,61,0,113,14,116,4,124,2,100,2,131,2,114,14, + 124,2,160,5,161,0,1,0,113,14,100,1,83,0,41,3, + 122,125,67,97,108,108,32,116,104,101,32,105,110,118,97,108, + 105,100,97,116,101,95,99,97,99,104,101,115,40,41,32,109, + 101,116,104,111,100,32,111,110,32,97,108,108,32,112,97,116, + 104,32,101,110,116,114,121,32,102,105,110,100,101,114,115,10, + 32,32,32,32,32,32,32,32,115,116,111,114,101,100,32,105, + 110,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,115,32,40,119,104,101,114, + 101,32,105,109,112,108,101,109,101,110,116,101,100,41,46,78, + 218,17,105,110,118,97,108,105,100,97,116,101,95,99,97,99, + 104,101,115,41,6,218,4,108,105,115,116,114,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,225,4, + 0,0,115,10,0,0,0,0,4,22,1,8,1,10,1,10, + 1,122,28,80,97,116,104,70,105,110,100,101,114,46,105,110, + 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 9,0,0,0,67,0,0,0,115,82,0,0,0,116,0,106, + 1,100,1,117,1,114,28,116,0,106,1,115,28,116,2,160, + 3,100,2,116,4,161,2,1,0,116,0,106,1,68,0,93, + 42,125,2,122,14,124,2,124,1,131,1,87,0,2,0,1, + 0,83,0,4,0,116,5,121,74,1,0,1,0,1,0,89, + 0,113,34,89,0,113,34,48,0,113,34,100,1,83,0,41, + 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, + 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, + 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, + 107,115,32,105,115,32,101,109,112,116,121,41,6,114,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, + 235,4,0,0,115,16,0,0,0,0,3,16,1,12,1,10, + 1,2,1,14,1,12,1,12,2,122,22,80,97,116,104,70, + 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, + 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,67,0,0,0,115,100,0,0,0,124, + 1,100,1,107,2,114,42,122,12,116,0,160,1,161,0,125, + 1,87,0,110,20,4,0,116,2,121,40,1,0,1,0,1, + 0,89,0,100,2,83,0,48,0,122,14,116,3,106,4,124, + 1,25,0,125,2,87,0,110,38,4,0,116,5,121,94,1, + 0,1,0,1,0,124,0,160,6,124,1,161,1,125,2,124, + 2,116,3,106,4,124,1,60,0,89,0,110,2,48,0,124, + 2,83,0,41,3,122,210,71,101,116,32,116,104,101,32,102, + 105,110,100,101,114,32,102,111,114,32,116,104,101,32,112,97, + 116,104,32,101,110,116,114,121,32,102,114,111,109,32,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,248, + 4,0,0,115,22,0,0,0,0,8,8,1,2,1,12,1, + 12,3,8,1,2,1,14,1,12,1,10,1,16,1,122,31, + 80,97,116,104,70,105,110,100,101,114,46,95,112,97,116,104, + 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,99, + 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, + 4,0,0,0,67,0,0,0,115,82,0,0,0,116,0,124, + 2,100,1,131,2,114,26,124,2,160,1,124,1,161,1,92, + 2,125,3,125,4,110,14,124,2,160,2,124,1,161,1,125, + 3,103,0,125,4,124,3,100,0,117,1,114,60,116,3,160, + 4,124,1,124,3,161,2,83,0,116,3,160,5,124,1,100, + 0,161,2,125,5,124,4,124,5,95,6,124,5,83,0,41, + 2,78,114,137,0,0,0,41,7,114,128,0,0,0,114,137, + 0,0,0,114,206,0,0,0,114,134,0,0,0,114,201,0, + 0,0,114,183,0,0,0,114,178,0,0,0,41,6,114,193, + 0,0,0,114,139,0,0,0,114,50,1,0,0,114,140,0, + 0,0,114,141,0,0,0,114,187,0,0,0,114,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,14,5,0, + 0,115,18,0,0,0,0,4,10,1,16,2,10,1,4,1, + 8,1,12,1,12,1,6,1,122,27,80,97,116,104,70,105, + 110,100,101,114,46,95,108,101,103,97,99,121,95,103,101,116, + 95,115,112,101,99,78,99,4,0,0,0,0,0,0,0,0, + 0,0,0,9,0,0,0,5,0,0,0,67,0,0,0,115, + 166,0,0,0,103,0,125,4,124,2,68,0,93,134,125,5, + 116,0,124,5,116,1,116,2,102,2,131,2,115,28,113,8, + 124,0,160,3,124,5,161,1,125,6,124,6,100,1,117,1, + 114,8,116,4,124,6,100,2,131,2,114,70,124,6,160,5, + 124,1,124,3,161,2,125,7,110,12,124,0,160,6,124,1, + 124,6,161,2,125,7,124,7,100,1,117,0,114,92,113,8, + 124,7,106,7,100,1,117,1,114,110,124,7,2,0,1,0, + 83,0,124,7,106,8,125,8,124,8,100,1,117,0,114,132, + 116,9,100,3,131,1,130,1,124,4,160,10,124,8,161,1, + 1,0,113,8,116,11,160,12,124,1,100,1,161,2,125,7, + 124,4,124,7,95,8,124,7,83,0,41,4,122,63,70,105, + 110,100,32,116,104,101,32,108,111,97,100,101,114,32,111,114, + 32,110,97,109,101,115,112,97,99,101,95,112,97,116,104,32, + 102,111,114,32,116,104,105,115,32,109,111,100,117,108,101,47, + 112,97,99,107,97,103,101,32,110,97,109,101,46,78,114,203, + 0,0,0,122,19,115,112,101,99,32,109,105,115,115,105,110, + 103,32,108,111,97,100,101,114,41,13,114,161,0,0,0,114, + 84,0,0,0,218,5,98,121,116,101,115,114,54,1,0,0, + 114,128,0,0,0,114,203,0,0,0,114,55,1,0,0,114, + 140,0,0,0,114,178,0,0,0,114,117,0,0,0,114,167, + 0,0,0,114,134,0,0,0,114,183,0,0,0,41,9,114, + 193,0,0,0,114,139,0,0,0,114,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,29,5,0,0,115,40,0,0,0,0,5,4,1, + 8,1,14,1,2,1,10,1,8,1,10,1,14,2,12,1, + 8,1,2,1,10,1,8,1,6,1,8,1,8,5,12,2, + 12,1,6,1,122,20,80,97,116,104,70,105,110,100,101,114, + 46,95,103,101,116,95,115,112,101,99,99,4,0,0,0,0, + 0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,67, + 0,0,0,115,100,0,0,0,124,2,100,1,117,0,114,14, + 116,0,106,1,125,2,124,0,160,2,124,1,124,2,124,3, + 161,3,125,4,124,4,100,1,117,0,114,40,100,1,83,0, + 124,4,106,3,100,1,117,0,114,92,124,4,106,4,125,5, + 124,5,114,86,100,1,124,4,95,5,116,6,124,1,124,5, + 124,0,106,2,131,3,124,4,95,4,124,4,83,0,100,1, + 83,0,110,4,124,4,83,0,100,1,83,0,41,2,122,141, + 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, + 101,99,32,102,111,114,32,39,102,117,108,108,110,97,109,101, + 39,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, + 32,39,112,97,116,104,39,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,115,101,97,114,99,104,32,105,115,32, + 98,97,115,101,100,32,111,110,32,115,121,115,46,112,97,116, + 104,95,104,111,111,107,115,32,97,110,100,32,115,121,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,61,5,0,0,115,26,0,0,0, + 0,6,8,1,6,1,14,1,8,1,4,1,10,1,6,1, + 4,3,6,1,16,1,4,2,6,2,122,20,80,97,116,104, + 70,105,110,100,101,114,46,102,105,110,100,95,115,112,101,99, + 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,4,0,0,0,67,0,0,0,115,30,0,0,0,124,0, + 160,0,124,1,124,2,161,2,125,3,124,3,100,1,117,0, + 114,24,100,1,83,0,124,3,106,1,83,0,41,2,122,170, + 102,105,110,100,32,116,104,101,32,109,111,100,117,108,101,32, + 111,110,32,115,121,115,46,112,97,116,104,32,111,114,32,39, + 112,97,116,104,39,32,98,97,115,101,100,32,111,110,32,115, + 121,115,46,112,97,116,104,95,104,111,111,107,115,32,97,110, + 100,10,32,32,32,32,32,32,32,32,115,121,115,46,112,97, + 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, + 101,46,10,10,32,32,32,32,32,32,32,32,84,104,105,115, + 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, + 99,97,116,101,100,46,32,32,85,115,101,32,102,105,110,100, + 95,115,112,101,99,40,41,32,105,110,115,116,101,97,100,46, + 10,10,32,32,32,32,32,32,32,32,78,114,204,0,0,0, + 114,205,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,206,0,0,0,85,5,0,0,115,8,0, + 0,0,0,8,12,1,8,1,4,1,122,22,80,97,116,104, + 70,105,110,100,101,114,46,102,105,110,100,95,109,111,100,117, + 108,101,99,1,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,4,0,0,0,79,0,0,0,115,28,0,0,0, + 100,1,100,2,108,0,109,1,125,3,1,0,124,3,106,2, + 124,1,105,0,124,2,164,1,142,1,83,0,41,3,97,32, + 1,0,0,10,32,32,32,32,32,32,32,32,70,105,110,100, + 32,100,105,115,116,114,105,98,117,116,105,111,110,115,46,10, + 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,32, + 97,110,32,105,116,101,114,97,98,108,101,32,111,102,32,97, + 108,108,32,68,105,115,116,114,105,98,117,116,105,111,110,32, + 105,110,115,116,97,110,99,101,115,32,99,97,112,97,98,108, + 101,32,111,102,10,32,32,32,32,32,32,32,32,108,111,97, + 100,105,110,103,32,116,104,101,32,109,101,116,97,100,97,116, + 97,32,102,111,114,32,112,97,99,107,97,103,101,115,32,109, + 97,116,99,104,105,110,103,32,96,96,99,111,110,116,101,120, + 116,46,110,97,109,101,96,96,10,32,32,32,32,32,32,32, + 32,40,111,114,32,97,108,108,32,110,97,109,101,115,32,105, + 102,32,96,96,78,111,110,101,96,96,32,105,110,100,105,99, + 97,116,101,100,41,32,97,108,111,110,103,32,116,104,101,32, + 112,97,116,104,115,32,105,110,32,116,104,101,32,108,105,115, + 116,10,32,32,32,32,32,32,32,32,111,102,32,100,105,114, + 101,99,116,111,114,105,101,115,32,96,96,99,111,110,116,101, + 120,116,46,112,97,116,104,96,96,46,10,32,32,32,32,32, + 32,32,32,114,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,98,5,0,0,115,4,0,0,0, + 0,10,12,1,122,29,80,97,116,104,70,105,110,100,101,114, + 46,102,105,110,100,95,100,105,115,116,114,105,98,117,116,105, + 111,110,115,41,1,78,41,2,78,78,41,1,78,41,13,114, + 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, + 0,0,0,114,207,0,0,0,114,46,1,0,0,114,52,1, + 0,0,114,54,1,0,0,114,55,1,0,0,114,58,1,0, + 0,114,203,0,0,0,114,206,0,0,0,114,60,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,45,1,0,0,221,4,0,0,115,34,0, + 0,0,8,2,4,2,2,1,10,9,2,1,10,12,2,1, + 10,21,2,1,10,14,2,1,12,31,2,1,12,23,2,1, + 12,12,2,1,114,45,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, + 0,0,115,90,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,101,6,90,7,100,6,100,7,132,0,90,8,100, + 8,100,9,132,0,90,9,100,19,100,11,100,12,132,1,90, + 10,100,13,100,14,132,0,90,11,101,12,100,15,100,16,132, + 0,131,1,90,13,100,17,100,18,132,0,90,14,100,10,83, + 0,41,20,218,10,70,105,108,101,70,105,110,100,101,114,122, + 172,70,105,108,101,45,98,97,115,101,100,32,102,105,110,100, + 101,114,46,10,10,32,32,32,32,73,110,116,101,114,97,99, + 116,105,111,110,115,32,119,105,116,104,32,116,104,101,32,102, + 105,108,101,32,115,121,115,116,101,109,32,97,114,101,32,99, + 97,99,104,101,100,32,102,111,114,32,112,101,114,102,111,114, + 109,97,110,99,101,44,32,98,101,105,110,103,10,32,32,32, + 32,114,101,102,114,101,115,104,101,100,32,119,104,101,110,32, + 116,104,101,32,100,105,114,101,99,116,111,114,121,32,116,104, + 101,32,102,105,110,100,101,114,32,105,115,32,104,97,110,100, + 108,105,110,103,32,104,97,115,32,98,101,101,110,32,109,111, + 100,105,102,105,101,100,46,10,10,32,32,32,32,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0, + 0,0,7,0,0,0,115,84,0,0,0,103,0,125,3,124, + 2,68,0,93,32,92,2,137,0,125,4,124,3,160,0,135, + 0,102,1,100,1,100,2,132,8,124,4,68,0,131,1,161, + 1,1,0,113,8,124,3,124,0,95,1,124,1,112,54,100, + 3,124,0,95,2,100,4,124,0,95,3,116,4,131,0,124, + 0,95,5,116,4,131,0,124,0,95,6,100,5,83,0,41, + 6,122,154,73,110,105,116,105,97,108,105,122,101,32,119,105, + 116,104,32,116,104,101,32,112,97,116,104,32,116,111,32,115, + 101,97,114,99,104,32,111,110,32,97,110,100,32,97,32,118, + 97,114,105,97,98,108,101,32,110,117,109,98,101,114,32,111, + 102,10,32,32,32,32,32,32,32,32,50,45,116,117,112,108, + 101,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104, + 101,32,108,111,97,100,101,114,32,97,110,100,32,116,104,101, + 32,102,105,108,101,32,115,117,102,102,105,120,101,115,32,116, + 104,101,32,108,111,97,100,101,114,10,32,32,32,32,32,32, + 32,32,114,101,99,111,103,110,105,122,101,115,46,99,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,127,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,121,5, + 0,0,115,16,0,0,0,0,4,4,1,12,1,26,1,6, + 2,10,1,6,1,8,1,122,19,70,105,108,101,70,105,110, + 100,101,114,46,95,95,105,110,105,116,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0, + 0,67,0,0,0,115,10,0,0,0,100,1,124,0,95,0, + 100,2,83,0,41,3,122,31,73,110,118,97,108,105,100,97, + 116,101,32,116,104,101,32,100,105,114,101,99,116,111,114,121, + 32,109,116,105,109,101,46,114,104,0,0,0,78,41,1,114, + 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,135,5,0, + 0,115,2,0,0,0,0,2,122,28,70,105,108,101,70,105, + 110,100,101,114,46,105,110,118,97,108,105,100,97,116,101,95, + 99,97,99,104,101,115,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, + 42,0,0,0,124,0,160,0,124,1,161,1,125,2,124,2, + 100,1,117,0,114,26,100,1,103,0,102,2,83,0,124,2, + 106,1,124,2,106,2,112,38,103,0,102,2,83,0,41,2, + 122,197,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,44, + 32,111,114,32,116,104,101,32,110,97,109,101,115,112,97,99, + 101,10,32,32,32,32,32,32,32,32,112,97,99,107,97,103, + 101,32,112,111,114,116,105,111,110,115,46,32,82,101,116,117, + 114,110,115,32,40,108,111,97,100,101,114,44,32,108,105,115, + 116,45,111,102,45,112,111,114,116,105,111,110,115,41,46,10, + 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,85,115,101,32,102,105,110,100,95,115,112, + 101,99,40,41,32,105,110,115,116,101,97,100,46,10,10,32, + 32,32,32,32,32,32,32,78,41,3,114,203,0,0,0,114, + 140,0,0,0,114,178,0,0,0,41,3,114,118,0,0,0, + 114,139,0,0,0,114,187,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,137,0,0,0,141,5, + 0,0,115,8,0,0,0,0,7,10,1,8,1,8,1,122, + 22,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100, + 95,108,111,97,100,101,114,99,6,0,0,0,0,0,0,0, + 0,0,0,0,7,0,0,0,6,0,0,0,67,0,0,0, + 115,26,0,0,0,124,1,124,2,124,3,131,2,125,6,116, + 0,124,2,124,3,124,6,124,4,100,1,141,4,83,0,41, + 2,78,114,177,0,0,0,41,1,114,190,0,0,0,41,7, + 114,118,0,0,0,114,188,0,0,0,114,139,0,0,0,114, + 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,153,5,0,0,115,8,0,0, + 0,0,1,10,1,8,1,2,255,122,20,70,105,108,101,70, + 105,110,100,101,114,46,95,103,101,116,95,115,112,101,99,78, + 99,3,0,0,0,0,0,0,0,0,0,0,0,14,0,0, + 0,8,0,0,0,67,0,0,0,115,96,1,0,0,100,1, + 125,3,124,1,160,0,100,2,161,1,100,3,25,0,125,4, + 122,24,116,1,124,0,106,2,112,34,116,3,160,4,161,0, + 131,1,106,5,125,5,87,0,110,22,4,0,116,6,121,64, + 1,0,1,0,1,0,100,4,125,5,89,0,110,2,48,0, + 124,5,124,0,106,7,107,3,114,90,124,0,160,8,161,0, + 1,0,124,5,124,0,95,7,116,9,131,0,114,112,124,0, + 106,10,125,6,124,4,160,11,161,0,125,7,110,10,124,0, + 106,12,125,6,124,4,125,7,124,7,124,6,118,0,114,216, + 116,13,124,0,106,2,124,4,131,2,125,8,124,0,106,14, + 68,0,93,58,92,2,125,9,125,10,100,5,124,9,23,0, + 125,11,116,13,124,8,124,11,131,2,125,12,116,15,124,12, + 131,1,114,148,124,0,160,16,124,10,124,1,124,12,124,8, + 103,1,124,2,161,5,2,0,1,0,83,0,113,148,116,17, + 124,8,131,1,125,3,124,0,106,14,68,0,93,82,92,2, + 125,9,125,10,116,13,124,0,106,2,124,4,124,9,23,0, + 131,2,125,12,116,18,106,19,100,6,124,12,100,3,100,7, + 141,3,1,0,124,7,124,9,23,0,124,6,118,0,114,222, + 116,15,124,12,131,1,114,222,124,0,160,16,124,10,124,1, + 124,12,100,8,124,2,161,5,2,0,1,0,83,0,113,222, + 124,3,144,1,114,92,116,18,160,19,100,9,124,8,161,2, + 1,0,116,18,160,20,124,1,100,8,161,2,125,13,124,8, + 103,1,124,13,95,21,124,13,83,0,100,8,83,0,41,10, + 122,111,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 115,112,101,99,32,102,111,114,32,116,104,101,32,115,112,101, + 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,82,101,116,117,114,110,115,32, + 116,104,101,32,109,97,116,99,104,105,110,103,32,115,112,101, + 99,44,32,111,114,32,78,111,110,101,32,105,102,32,110,111, + 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, + 32,70,114,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, + 158,5,0,0,115,74,0,0,0,0,5,4,1,14,1,2, + 1,24,1,12,1,10,1,10,1,8,1,6,2,6,1,6, + 1,10,2,6,1,4,2,8,1,12,1,14,1,8,1,10, + 1,8,1,26,4,8,2,14,1,16,1,16,1,12,1,8, + 1,10,1,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,188,0,0,0,124,0,106,0,125,1,122,22,116, + 1,160,2,124,1,112,22,116,1,160,3,161,0,161,1,125, + 2,87,0,110,28,4,0,116,4,116,5,116,6,102,3,121, + 56,1,0,1,0,1,0,103,0,125,2,89,0,110,2,48, + 0,116,7,106,8,160,9,100,1,161,1,115,82,116,10,124, + 2,131,1,124,0,95,11,110,74,116,10,131,0,125,3,124, + 2,68,0,93,56,125,4,124,4,160,12,100,2,161,1,92, + 3,125,5,125,6,125,7,124,6,114,134,100,3,160,13,124, + 5,124,7,160,14,161,0,161,2,125,8,110,4,124,5,125, + 8,124,3,160,15,124,8,161,1,1,0,113,92,124,3,124, + 0,95,11,116,7,106,8,160,9,116,16,161,1,114,184,100, + 4,100,5,132,0,124,2,68,0,131,1,124,0,95,17,100, + 6,83,0,41,7,122,68,70,105,108,108,32,116,104,101,32, + 99,97,99,104,101,32,111,102,32,112,111,116,101,110,116,105, + 97,108,32,109,111,100,117,108,101,115,32,97,110,100,32,112, + 97,99,107,97,103,101,115,32,102,111,114,32,116,104,105,115, + 32,100,105,114,101,99,116,111,114,121,46,114,0,0,0,0, + 114,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,235,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,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,7,0,0,0,115,18,0,0,0, - 135,0,135,1,102,2,100,1,100,2,132,8,125,2,124,2, - 83,0,41,3,97,20,1,0,0,65,32,99,108,97,115,115, - 32,109,101,116,104,111,100,32,119,104,105,99,104,32,114,101, - 116,117,114,110,115,32,97,32,99,108,111,115,117,114,101,32, - 116,111,32,117,115,101,32,111,110,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,10,32,32,32,32,32,32,32,32, - 119,104,105,99,104,32,119,105,108,108,32,114,101,116,117,114, - 110,32,97,110,32,105,110,115,116,97,110,99,101,32,117,115, - 105,110,103,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,108,111,97,100,101,114,115,32,97,110,100,32,116,104, - 101,32,112,97,116,104,10,32,32,32,32,32,32,32,32,99, - 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, - 115,117,114,101,46,10,10,32,32,32,32,32,32,32,32,73, - 102,32,116,104,101,32,112,97,116,104,32,99,97,108,108,101, - 100,32,111,110,32,116,104,101,32,99,108,111,115,117,114,101, - 32,105,115,32,110,111,116,32,97,32,100,105,114,101,99,116, - 111,114,121,44,32,73,109,112,111,114,116,69,114,114,111,114, - 32,105,115,10,32,32,32,32,32,32,32,32,114,97,105,115, - 101,100,46,10,10,32,32,32,32,32,32,32,32,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,19,0,0,0,115,36,0,0,0,116,0,124,0,131, - 1,115,20,116,1,100,1,124,0,100,2,141,2,130,1,136, - 0,124,0,103,1,136,1,162,1,82,0,142,0,83,0,41, - 3,122,45,80,97,116,104,32,104,111,111,107,32,102,111,114, - 32,105,109,112,111,114,116,108,105,98,46,109,97,99,104,105, - 110,101,114,121,46,70,105,108,101,70,105,110,100,101,114,46, - 122,30,111,110,108,121,32,100,105,114,101,99,116,111,114,105, - 101,115,32,97,114,101,32,115,117,112,112,111,114,116,101,100, - 114,49,0,0,0,41,2,114,57,0,0,0,114,118,0,0, - 0,114,49,0,0,0,169,2,114,194,0,0,0,114,69,1, - 0,0,114,6,0,0,0,114,9,0,0,0,218,24,112,97, - 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, - 70,105,110,100,101,114,247,5,0,0,115,6,0,0,0,0, - 2,8,1,12,1,122,54,70,105,108,101,70,105,110,100,101, - 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, - 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,114,6,0, - 0,0,41,3,114,194,0,0,0,114,69,1,0,0,114,76, - 1,0,0,114,6,0,0,0,114,75,1,0,0,114,9,0, - 0,0,218,9,112,97,116,104,95,104,111,111,107,237,5,0, - 0,115,4,0,0,0,0,10,14,6,122,20,70,105,108,101, - 70,105,110,100,101,114,46,112,97,116,104,95,104,111,111,107, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, - 160,0,124,0,106,1,161,1,83,0,41,2,78,122,16,70, - 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, - 2,114,63,0,0,0,114,45,0,0,0,114,247,0,0,0, - 114,6,0,0,0,114,6,0,0,0,114,9,0,0,0,114, - 40,1,0,0,255,5,0,0,115,2,0,0,0,0,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,114,101, - 112,114,95,95,41,1,78,41,15,114,126,0,0,0,114,125, - 0,0,0,114,127,0,0,0,114,128,0,0,0,114,210,0, - 0,0,114,47,1,0,0,114,144,0,0,0,114,207,0,0, - 0,114,138,0,0,0,114,59,1,0,0,114,204,0,0,0, - 114,70,1,0,0,114,208,0,0,0,114,77,1,0,0,114, - 40,1,0,0,114,6,0,0,0,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,114,62,1,0,0,112,5,0, - 0,115,22,0,0,0,8,2,4,7,8,14,8,4,4,2, - 8,12,8,5,10,48,8,31,2,1,10,17,114,62,1,0, - 0,99,4,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,8,0,0,0,67,0,0,0,115,144,0,0,0,124, - 0,160,0,100,1,161,1,125,4,124,0,160,0,100,2,161, - 1,125,5,124,4,115,66,124,5,114,36,124,5,106,1,125, - 4,110,30,124,2,124,3,107,2,114,56,116,2,124,1,124, - 2,131,2,125,4,110,10,116,3,124,1,124,2,131,2,125, - 4,124,5,115,84,116,4,124,1,124,2,124,4,100,3,141, - 3,125,5,122,36,124,5,124,0,100,2,60,0,124,4,124, - 0,100,1,60,0,124,2,124,0,100,4,60,0,124,3,124, - 0,100,5,60,0,87,0,110,18,4,0,116,5,121,138,1, - 0,1,0,1,0,89,0,110,2,48,0,100,0,83,0,41, - 6,78,218,10,95,95,108,111,97,100,101,114,95,95,218,8, - 95,95,115,112,101,99,95,95,114,63,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,141,0,0,0,114, - 16,1,0,0,114,10,1,0,0,114,191,0,0,0,218,9, - 69,120,99,101,112,116,105,111,110,41,6,90,2,110,115,114, - 117,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,141,0,0,0,114,188, - 0,0,0,114,6,0,0,0,114,6,0,0,0,114,9,0, - 0,0,218,14,95,102,105,120,95,117,112,95,109,111,100,117, - 108,101,5,6,0,0,115,34,0,0,0,0,2,10,1,10, - 1,4,1,4,1,8,1,8,1,12,2,10,1,4,1,14, - 1,2,1,8,1,8,1,8,1,12,1,12,2,114,82,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 116,0,116,1,160,2,161,0,102,2,125,0,116,3,116,4, - 102,2,125,1,116,5,116,6,102,2,125,2,124,0,124,1, - 124,2,103,3,83,0,41,1,122,95,82,101,116,117,114,110, - 115,32,97,32,108,105,115,116,32,111,102,32,102,105,108,101, - 45,98,97,115,101,100,32,109,111,100,117,108,101,32,108,111, - 97,100,101,114,115,46,10,10,32,32,32,32,69,97,99,104, - 32,105,116,101,109,32,105,115,32,97,32,116,117,112,108,101, - 32,40,108,111,97,100,101,114,44,32,115,117,102,102,105,120, - 101,115,41,46,10,32,32,32,32,41,7,114,253,0,0,0, - 114,164,0,0,0,218,18,101,120,116,101,110,115,105,111,110, - 95,115,117,102,102,105,120,101,115,114,10,1,0,0,114,102, - 0,0,0,114,16,1,0,0,114,89,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,6,0, - 0,0,114,6,0,0,0,114,9,0,0,0,114,185,0,0, - 0,28,6,0,0,115,8,0,0,0,0,5,12,1,8,1, - 8,1,114,185,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,176,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,118,1,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, - 108,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,118,0,114,170,116, - 1,106,3,124,5,25,0,125,8,1,0,113,224,113,106,122, - 20,116,0,160,5,124,5,161,1,125,8,87,0,1,0,113, - 224,87,0,113,106,4,0,116,8,121,212,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,108,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,172,116,14,160,15,100,22,161,1,1, - 0,100,23,116,11,118,0,144,1,114,172,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,65,0,0,0,114,76,0, - 0,0,218,8,98,117,105,108,116,105,110,115,114,161,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,40,0,0, - 0,78,41,1,114,24,0,0,0,41,2,114,33,0,0,0, - 114,95,0,0,0,114,6,0,0,0,114,6,0,0,0,114, - 9,0,0,0,114,20,1,0,0,64,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,74,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,5,0,0,0,114,36,0,0,0, - 114,32,0,0,0,114,41,0,0,0,114,59,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,75,0,0,0,114,6,0,0,0,41, - 2,114,33,0,0,0,218,1,115,114,6,0,0,0,114,6, - 0,0,0,114,9,0,0,0,114,71,1,0,0,80,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,193,0,0,0,114,10,0,0,0,122,4,46,112,121,119, - 122,6,95,100,46,112,121,100,84,78,41,18,114,135,0,0, - 0,114,2,0,0,0,114,164,0,0,0,114,32,1,0,0, - 114,126,0,0,0,90,18,95,98,117,105,108,116,105,110,95, - 102,114,111,109,95,110,97,109,101,114,130,0,0,0,218,3, - 97,108,108,114,118,0,0,0,114,37,0,0,0,114,15,0, - 0,0,114,22,1,0,0,114,168,0,0,0,114,83,1,0, - 0,114,102,0,0,0,114,187,0,0,0,114,192,0,0,0, - 114,196,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,32,0, - 0,0,114,36,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,6,0,0,0,114,6,0,0,0,114,9,0,0,0,218, - 6,95,115,101,116,117,112,39,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,12,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,90, - 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,90,1,0,0,114,185,0,0,0,114,2,0, - 0,0,114,52,1,0,0,114,168,0,0,0,114,62,1,0, - 0,114,77,1,0,0,218,9,109,101,116,97,95,112,97,116, - 104,114,187,0,0,0,114,46,1,0,0,41,2,114,89,1, - 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, - 97,100,101,114,115,114,6,0,0,0,114,6,0,0,0,114, - 9,0,0,0,218,8,95,105,110,115,116,97,108,108,104,6, - 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, - 92,1,0,0,41,1,114,61,0,0,0,41,1,78,41,3, - 78,78,78,41,2,114,74,0,0,0,114,74,0,0,0,41, - 1,84,41,1,78,41,1,78,41,63,114,128,0,0,0,114, - 14,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,13,0,0,0, - 114,15,0,0,0,114,22,0,0,0,114,28,0,0,0,114, - 30,0,0,0,114,39,0,0,0,114,48,0,0,0,114,50, - 0,0,0,114,54,0,0,0,114,55,0,0,0,114,57,0, - 0,0,114,60,0,0,0,114,70,0,0,0,218,4,116,121, - 112,101,218,8,95,95,99,111,100,101,95,95,114,163,0,0, - 0,114,20,0,0,0,114,149,0,0,0,114,19,0,0,0, - 114,25,0,0,0,114,237,0,0,0,114,92,0,0,0,114, - 88,0,0,0,114,102,0,0,0,114,89,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,98,0,0,0,114,103,0,0,0,114,109, - 0,0,0,114,113,0,0,0,114,115,0,0,0,114,137,0, - 0,0,114,144,0,0,0,114,153,0,0,0,114,157,0,0, - 0,114,159,0,0,0,114,166,0,0,0,114,171,0,0,0, - 114,172,0,0,0,114,177,0,0,0,218,6,111,98,106,101, - 99,116,114,186,0,0,0,114,191,0,0,0,114,192,0,0, - 0,114,209,0,0,0,114,222,0,0,0,114,240,0,0,0, - 114,10,1,0,0,114,16,1,0,0,114,22,1,0,0,114, - 253,0,0,0,114,23,1,0,0,114,44,1,0,0,114,46, - 1,0,0,114,62,1,0,0,114,82,1,0,0,114,185,0, - 0,0,114,90,1,0,0,114,92,1,0,0,114,6,0,0, - 0,114,6,0,0,0,114,6,0,0,0,114,9,0,0,0, - 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,126, - 0,0,0,4,22,4,1,4,1,2,1,2,255,4,4,8, - 17,8,5,8,5,8,6,8,6,8,12,8,10,8,9,8, - 5,8,7,8,9,10,22,10,127,0,20,16,1,12,2,4, - 1,4,2,6,2,6,2,8,2,16,71,8,40,8,19,8, - 12,8,12,8,28,8,17,8,33,8,28,8,24,10,13,10, - 10,10,11,8,14,6,3,4,1,2,255,12,68,14,64,14, - 29,16,127,0,17,14,72,18,45,18,26,4,3,18,53,14, - 63,14,42,14,127,0,20,14,127,0,22,10,23,8,11,8, - 65, + 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,206,5,0,0,115,34,0,0,0, + 0,2,6,1,2,1,22,1,18,3,10,3,12,1,12,7, + 6,1,8,1,16,1,4,1,18,2,4,1,12,1,6,1, + 12,1,122,22,70,105,108,101,70,105,110,100,101,114,46,95, + 102,105,108,108,95,99,97,99,104,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,7, + 0,0,0,115,18,0,0,0,135,0,135,1,102,2,100,1, + 100,2,132,8,125,2,124,2,83,0,41,3,97,20,1,0, + 0,65,32,99,108,97,115,115,32,109,101,116,104,111,100,32, + 119,104,105,99,104,32,114,101,116,117,114,110,115,32,97,32, + 99,108,111,115,117,114,101,32,116,111,32,117,115,101,32,111, + 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,10, + 32,32,32,32,32,32,32,32,119,104,105,99,104,32,119,105, + 108,108,32,114,101,116,117,114,110,32,97,110,32,105,110,115, + 116,97,110,99,101,32,117,115,105,110,103,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,108,111,97,100,101,114, + 115,32,97,110,100,32,116,104,101,32,112,97,116,104,10,32, + 32,32,32,32,32,32,32,99,97,108,108,101,100,32,111,110, + 32,116,104,101,32,99,108,111,115,117,114,101,46,10,10,32, + 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, + 116,104,32,99,97,108,108,101,100,32,111,110,32,116,104,101, + 32,99,108,111,115,117,114,101,32,105,115,32,110,111,116,32, + 97,32,100,105,114,101,99,116,111,114,121,44,32,73,109,112, + 111,114,116,69,114,114,111,114,32,105,115,10,32,32,32,32, + 32,32,32,32,114,97,105,115,101,100,46,10,10,32,32,32, + 32,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,4,0,0,0,19,0,0,0,115,36, + 0,0,0,116,0,124,0,131,1,115,20,116,1,100,1,124, + 0,100,2,141,2,130,1,136,0,124,0,103,1,136,1,162, + 1,82,0,142,0,83,0,41,3,122,45,80,97,116,104,32, + 104,111,111,107,32,102,111,114,32,105,109,112,111,114,116,108, + 105,98,46,109,97,99,104,105,110,101,114,121,46,70,105,108, + 101,70,105,110,100,101,114,46,122,30,111,110,108,121,32,100, + 105,114,101,99,116,111,114,105,101,115,32,97,114,101,32,115, + 117,112,112,111,114,116,101,100,114,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,247,5, + 0,0,115,6,0,0,0,0,2,8,1,12,1,122,54,70, + 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, + 111,111,107,46,60,108,111,99,97,108,115,62,46,112,97,116, + 104,95,104,111,111,107,95,102,111,114,95,70,105,108,101,70, + 105,110,100,101,114,114,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,237,5,0,0,115,4,0,0,0,0,10, + 14,6,122,20,70,105,108,101,70,105,110,100,101,114,46,112, + 97,116,104,95,104,111,111,107,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, + 0,115,12,0,0,0,100,1,160,0,124,0,106,1,161,1, + 83,0,41,2,78,122,16,70,105,108,101,70,105,110,100,101, + 114,40,123,33,114,125,41,41,2,114,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,255,5,0,0, + 115,2,0,0,0,0,1,122,19,70,105,108,101,70,105,110, + 100,101,114,46,95,95,114,101,112,114,95,95,41,1,78,41, + 15,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, + 114,127,0,0,0,114,209,0,0,0,114,46,1,0,0,114, + 143,0,0,0,114,206,0,0,0,114,137,0,0,0,114,58, + 1,0,0,114,203,0,0,0,114,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,112,5,0,0,115,22,0,0,0,8,2, + 4,7,8,14,8,4,4,2,8,12,8,5,10,48,8,31, + 2,1,10,17,114,61,1,0,0,99,4,0,0,0,0,0, + 0,0,0,0,0,0,6,0,0,0,8,0,0,0,67,0, + 0,0,115,144,0,0,0,124,0,160,0,100,1,161,1,125, + 4,124,0,160,0,100,2,161,1,125,5,124,4,115,66,124, + 5,114,36,124,5,106,1,125,4,110,30,124,2,124,3,107, + 2,114,56,116,2,124,1,124,2,131,2,125,4,110,10,116, + 3,124,1,124,2,131,2,125,4,124,5,115,84,116,4,124, + 1,124,2,124,4,100,3,141,3,125,5,122,36,124,5,124, + 0,100,2,60,0,124,4,124,0,100,1,60,0,124,2,124, + 0,100,4,60,0,124,3,124,0,100,5,60,0,87,0,110, + 18,4,0,116,5,121,138,1,0,1,0,1,0,89,0,110, + 2,48,0,100,0,83,0,41,6,78,218,10,95,95,108,111, + 97,100,101,114,95,95,218,8,95,95,115,112,101,99,95,95, + 114,62,1,0,0,90,8,95,95,102,105,108,101,95,95,90, + 10,95,95,99,97,99,104,101,100,95,95,41,6,218,3,103, + 101,116,114,140,0,0,0,114,15,1,0,0,114,9,1,0, + 0,114,190,0,0,0,218,9,69,120,99,101,112,116,105,111, + 110,41,6,90,2,110,115,114,116,0,0,0,90,8,112,97, + 116,104,110,97,109,101,90,9,99,112,97,116,104,110,97,109, + 101,114,140,0,0,0,114,187,0,0,0,114,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,5,6,0,0,115,34, + 0,0,0,0,2,10,1,10,1,4,1,4,1,8,1,8, + 1,12,2,10,1,4,1,14,1,2,1,8,1,8,1,8, + 1,12,1,12,2,114,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,28,6,0,0,115,8,0, + 0,0,0,5,12,1,8,1,8,1,114,184,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, + 9,0,0,0,67,0,0,0,115,176,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,118,1,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,108,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,118,0,114,170,116,1,106,3,124,5,25,0,125, + 8,1,0,113,224,113,106,122,20,116,0,160,5,124,5,161, + 1,125,8,87,0,1,0,113,224,87,0,113,106,4,0,116, + 8,121,212,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,108,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,172,116, + 14,160,15,100,22,161,1,1,0,100,23,116,11,118,0,144, + 1,114,172,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,64,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,80,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,39, + 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, + 12,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,104,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,20,16,1,12,2,4,1,4,2,6,2,6,2,8, + 2,16,71,8,40,8,19,8,12,8,12,8,28,8,17,8, + 33,8,28,8,24,10,13,10,10,10,11,8,14,6,3,4, + 1,2,255,12,68,14,64,14,29,16,127,0,17,14,72,18, + 45,18,26,4,3,18,53,14,63,14,42,14,127,0,20,14, + 127,0,22,10,23,8,11,8,65, }; From webhook-mailer at python.org Wed Feb 19 13:21:52 2020 From: webhook-mailer at python.org (ananthan-123) Date: Wed, 19 Feb 2020 18:21:52 -0000 Subject: [Python-checkins] bpo-39479:Add math.lcm() function: Least Common Multiple (#18547) Message-ID: https://github.com/python/cpython/commit/f2ee21d858bc03dd801b97afe60ee2ea289e2fe9 commit: f2ee21d858bc03dd801b97afe60ee2ea289e2fe9 branch: master author: ananthan-123 committer: GitHub date: 2020-02-19T18:21:37Z summary: bpo-39479:Add math.lcm() function: Least Common Multiple (#18547) * Update math.rst * Update math.rst * updated whats new * Update test_math.py * Update mathmodule.c * Update mathmodule.c.h * Update ACKS * ?? Added by blurb_it. * Update 3.9.rst * Update 2020-02-18-12-37-16.bpo-39479.j3UcCq.rst * Update math.rst * Update 2020-02-18-12-37-16.bpo-39479.j3UcCq.rst * Update test_math.py * Update ACKS * Update mathmodule.c.h * Update mathmodule.c * Update mathmodule.c.h * Update mathmodule.c.h Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst M Doc/library/math.rst M Doc/whatsnew/3.9.rst M Lib/test/test_math.py M Misc/ACKS M Modules/clinic/mathmodule.c.h M Modules/mathmodule.c diff --git a/Doc/library/math.rst b/Doc/library/math.rst index c4c180037f878..d8ac35256d1b4 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -136,6 +136,15 @@ Number-theoretic and representation functions .. versionadded:: 3.5 +.. function:: lcm(a, b) + + Return the least common multiple of integers *a* and *b*. The value of + ``lcm(a, b)`` is the smallest nonnegative integer that is a multiple of + both *a* and *b*. If either *a* or *b* is zero then ``lcm(a, b)`` is zero. + + .. versionadded:: 3.9 + + .. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) Return ``True`` if the values *a* and *b* are close to each other and diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 66eb9e77a7912..161675d32f670 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -216,6 +216,9 @@ import attempts. math ---- +Add :func:`math.lcm`: return the least common multiple of *a* and *b*. +(Contributed by Ananthakrishnan in :issue:`39479`.) + Add :func:`math.nextafter`: return the next floating-point value after *x* towards *y*. (Contributed by Victor Stinner in :issue:`39288`.) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index b3301f6a5cf74..ad8273d50cc39 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -974,6 +974,41 @@ def __index__(self): with self.assertRaises(TypeError): math.isqrt(value) + def test_lcm(self): + lcm = math.lcm + self.assertEqual(lcm(0, 0), 0) + self.assertEqual(lcm(1, 0), 0) + self.assertEqual(lcm(-1, 0), 0) + self.assertEqual(lcm(0, 1), 0) + self.assertEqual(lcm(0, -1), 0) + self.assertEqual(lcm(7, 1), 7) + self.assertEqual(lcm(7, -1), 7) + self.assertEqual(lcm(-23, 15), 345) + self.assertEqual(lcm(120, 84), 840) + self.assertEqual(lcm(84, -120), 840) + self.assertEqual(lcm(1216342683557601535506311712, + 436522681849110124616458784), + 16592536571065866494401400422922201534178938447014944) + x = 43461045657039990237 + y = 10645022458251153277 + + for c in (652560, + 57655923087165495981): + a = x * c + b = y * c + d = x * y * c + self.assertEqual(lcm(a, b), d) + self.assertEqual(lcm(b, a), d) + self.assertEqual(lcm(-a, b), d) + self.assertEqual(lcm(b, -a), d) + self.assertEqual(lcm(a, -b), d) + self.assertEqual(lcm(-b, a), d) + self.assertEqual(lcm(-a, -b), d) + self.assertEqual(lcm(-b, -a), d) + self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) + self.assertRaises(TypeError, lcm, 120.0, 84) + self.assertRaises(TypeError, lcm, 120, 84.0) + def testLdexp(self): self.assertRaises(TypeError, math.ldexp) self.ftest('ldexp(0,1)', math.ldexp(0,1), 0) diff --git a/Misc/ACKS b/Misc/ACKS index e8ce30310bfd8..b11ee9cdea67d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -45,6 +45,7 @@ Rose Ames A. Amoroso Mark Anacker Shashwat Anand +Ananthakrishnan Anders Andersen Tycho Andersen John Anderson diff --git a/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst b/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst new file mode 100644 index 0000000000000..6f16623a8f5cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst @@ -0,0 +1 @@ +Add :func:`math.lcm` function: least common multiple. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index f95d291d41f80..df45a1a0c5e85 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -85,6 +85,36 @@ PyDoc_STRVAR(math_factorial__doc__, #define MATH_FACTORIAL_METHODDEF \ {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__}, +PyDoc_STRVAR(math_lcm__doc__, +"lcm($module, x, y, /)\n" +"--\n" +"\n" +"least common multiple of x and y"); + +#define MATH_LCM_METHODDEF \ + {"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm__doc__}, + +static PyObject * +math_lcm_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +math_lcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + + if (!_PyArg_CheckPositional("lcm", nargs, 2, 2)) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = math_lcm_impl(module, a, b); + +exit: + return return_value; +} + PyDoc_STRVAR(math_trunc__doc__, "trunc($module, x, /)\n" "--\n" @@ -895,4 +925,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9b51d215dbcac060 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f8daa185c043a7b7 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 309f229159540..f74b7e1a34203 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2017,6 +2017,59 @@ math_factorial(PyObject *module, PyObject *arg) } +/*[clinic input] +math.lcm + x as a: object + y as b: object + / +least common multiple of x and y +[clinic start generated code]*/ + +static PyObject * +math_lcm_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=6f83fb6d671074ba input=efb3d7b7334b7118]*/ +{ + PyObject *g, *m, *f, *ab; + + a = PyNumber_Index(a); + if (a == NULL) { + return NULL; + } + b = PyNumber_Index(b); + if (b == NULL) { + Py_DECREF(a); + return NULL; + } + if (_PyLong_Sign(a) == 0 || _PyLong_Sign(b) == 0) { + Py_DECREF(a); + Py_DECREF(b); + return PyLong_FromLong(0); + } + g = _PyLong_GCD(a, b); + if (g == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + f = PyNumber_FloorDivide(a, g); + Py_DECREF(g); + Py_DECREF(a); + if (f == NULL) { + Py_DECREF(b); + return NULL; + } + m = PyNumber_Multiply(f, b); + Py_DECREF(f); + Py_DECREF(b); + if (m == NULL) { + return NULL; + } + ab = PyNumber_Absolute(m); + Py_DECREF(m); + return ab; +} + + /*[clinic input] math.trunc @@ -3362,6 +3415,7 @@ static PyMethodDef math_methods[] = { MATH_ISINF_METHODDEF MATH_ISNAN_METHODDEF MATH_ISQRT_METHODDEF + MATH_LCM_METHODDEF MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, MATH_LOG_METHODDEF From webhook-mailer at python.org Thu Feb 20 08:39:29 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Thu, 20 Feb 2020 13:39:29 -0000 Subject: [Python-checkins] Valgrind no longer supports --db-attach=yes. (#18568) Message-ID: https://github.com/python/cpython/commit/c0cb8beb389da3ba67ad31b1ecc95e100b6292ab commit: c0cb8beb389da3ba67ad31b1ecc95e100b6292ab branch: master author: Stefan Krah committer: GitHub date: 2020-02-20T14:39:14+01:00 summary: Valgrind no longer supports --db-attach=yes. (#18568) files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 77c0c9cd82c13..1f1dc776c11e7 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -18,7 +18,7 @@ CONFIGS_64="x64 uint128 ansi64 universal" CONFIGS_32="ppro ansi32 ansi-legacy universal" VALGRIND="valgrind --tool=memcheck --leak-resolution=high \ - --db-attach=yes --suppressions=Misc/valgrind-python.supp" + --suppressions=Misc/valgrind-python.supp" # Get args case $@ in From webhook-mailer at python.org Thu Feb 20 13:07:40 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Thu, 20 Feb 2020 18:07:40 -0000 Subject: [Python-checkins] Update runall.bat to the latest Windows build system. (#18571) Message-ID: https://github.com/python/cpython/commit/9b833e00e447a3b8b6966686bff701f549c66263 commit: 9b833e00e447a3b8b6966686bff701f549c66263 branch: master author: Stefan Krah committer: GitHub date: 2020-02-20T19:07:31+01:00 summary: Update runall.bat to the latest Windows build system. (#18571) files: M Modules/_decimal/tests/runall.bat diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index 5bc872a63f83a..a9d6c6f19c8bb 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -7,105 +7,123 @@ cd ..\..\..\ echo. echo # ====================================================================== -echo # Building Python +echo # Building Python (Debug^|x64) echo # ====================================================================== echo. -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 -echo. -echo. +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Debug -p x64 echo. echo # ====================================================================== -echo # test_decimal: platform=x64 +echo # platform=Debug^|x64 echo # ====================================================================== echo. -cd PCbuild\amd64 - echo # ==================== refleak tests ======================= echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call python.bat -m test -uall -R 3:3 test_decimal echo. echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # test_decimal: platform=x86 +echo # Building Python (Release^|x64) echo # ====================================================================== echo. -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p x64 + echo. +echo # ====================================================================== +echo # platform=Release^|x64 +echo # ====================================================================== echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + echo. +echo # ====================================================================== +echo # Building Python (Debug^|Win32) +echo # ====================================================================== echo. -cd amd64 +call .\Tools\buildbot\clean.bat +call Tools\buildbot\build.bat -c Debug -p Win32 echo. echo # ====================================================================== -echo # deccheck: platform=x64 +echo # platform=Debug^|Win32 echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= echo. -python_d.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # deccheck: platform=x86 +echo # Building Python (Release^|Win32) echo # ====================================================================== echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Release^|Win32 +echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== regular tests ======================= echo. -python_d.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. - - -cd ..\Modules\_decimal\tests - - - From webhook-mailer at python.org Thu Feb 20 13:08:57 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Thu, 20 Feb 2020 18:08:57 -0000 Subject: [Python-checkins] Use the new recommended number of repetitions in the refleak tests. (#18569) Message-ID: https://github.com/python/cpython/commit/1246d892038a693304549f8574e6c2784b91589a commit: 1246d892038a693304549f8574e6c2784b91589a branch: master author: Stefan Krah committer: GitHub date: 2020-02-20T19:08:53+01:00 summary: Use the new recommended number of repetitions in the refleak tests. (#18569) files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 1f1dc776c11e7..29b7723dd50c0 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -78,7 +78,7 @@ for config in $CONFIGS; do $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" - ./python -m test -uall -R 2:2 test_decimal + ./python -m test -uall -R 3:3 test_decimal ############ regular tests ########### From webhook-mailer at python.org Thu Feb 20 13:30:16 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:30:16 -0000 Subject: [Python-checkins] Update runall.bat to the latest Windows build system. (GH-18571) (#18572) Message-ID: https://github.com/python/cpython/commit/25749101ad98b4f7c4b808c21b72a365181a78a1 commit: 25749101ad98b4f7c4b808c21b72a365181a78a1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:30:00+01:00 summary: Update runall.bat to the latest Windows build system. (GH-18571) (#18572) (cherry picked from commit 9b833e00e447a3b8b6966686bff701f549c66263) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall.bat diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index 5bc872a63f83a..a9d6c6f19c8bb 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -7,105 +7,123 @@ cd ..\..\..\ echo. echo # ====================================================================== -echo # Building Python +echo # Building Python (Debug^|x64) echo # ====================================================================== echo. -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 -echo. -echo. +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Debug -p x64 echo. echo # ====================================================================== -echo # test_decimal: platform=x64 +echo # platform=Debug^|x64 echo # ====================================================================== echo. -cd PCbuild\amd64 - echo # ==================== refleak tests ======================= echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call python.bat -m test -uall -R 3:3 test_decimal echo. echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # test_decimal: platform=x86 +echo # Building Python (Release^|x64) echo # ====================================================================== echo. -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p x64 + echo. +echo # ====================================================================== +echo # platform=Release^|x64 +echo # ====================================================================== echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + echo. +echo # ====================================================================== +echo # Building Python (Debug^|Win32) +echo # ====================================================================== echo. -cd amd64 +call .\Tools\buildbot\clean.bat +call Tools\buildbot\build.bat -c Debug -p Win32 echo. echo # ====================================================================== -echo # deccheck: platform=x64 +echo # platform=Debug^|Win32 echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= echo. -python_d.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # deccheck: platform=x86 +echo # Building Python (Release^|Win32) echo # ====================================================================== echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Release^|Win32 +echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== regular tests ======================= echo. -python_d.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. - - -cd ..\Modules\_decimal\tests - - - From webhook-mailer at python.org Thu Feb 20 13:31:16 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:31:16 -0000 Subject: [Python-checkins] Update runall.bat to the latest Windows build system. (GH-18571) (#18573) Message-ID: https://github.com/python/cpython/commit/471d2b9ce071947ea1d6b61618518cbeb9227348 commit: 471d2b9ce071947ea1d6b61618518cbeb9227348 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:31:11+01:00 summary: Update runall.bat to the latest Windows build system. (GH-18571) (#18573) (cherry picked from commit 9b833e00e447a3b8b6966686bff701f549c66263) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall.bat diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index 5bc872a63f83a..a9d6c6f19c8bb 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -7,105 +7,123 @@ cd ..\..\..\ echo. echo # ====================================================================== -echo # Building Python +echo # Building Python (Debug^|x64) echo # ====================================================================== echo. -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 -echo. -echo. +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Debug -p x64 echo. echo # ====================================================================== -echo # test_decimal: platform=x64 +echo # platform=Debug^|x64 echo # ====================================================================== echo. -cd PCbuild\amd64 - echo # ==================== refleak tests ======================= echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call python.bat -m test -uall -R 3:3 test_decimal echo. echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # test_decimal: platform=x86 +echo # Building Python (Release^|x64) echo # ====================================================================== echo. -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p x64 + echo. +echo # ====================================================================== +echo # platform=Release^|x64 +echo # ====================================================================== echo. echo # ==================== regular tests ======================= echo. -python.exe -m test -uall test_decimal +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + echo. +echo # ====================================================================== +echo # Building Python (Debug^|Win32) +echo # ====================================================================== echo. -cd amd64 +call .\Tools\buildbot\clean.bat +call Tools\buildbot\build.bat -c Debug -p Win32 echo. echo # ====================================================================== -echo # deccheck: platform=x64 +echo # platform=Debug^|Win32 echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= echo. -python_d.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. -cd .. echo. echo # ====================================================================== -echo # deccheck: platform=x86 +echo # Building Python (Release^|Win32) echo # ====================================================================== echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Release^|Win32 +echo # ====================================================================== echo. -echo # ==================== debug build ======================= +echo # ==================== regular tests ======================= echo. -python_d.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat -m test -uall test_decimal echo. echo. -echo # =================== release build ====================== +echo # ==================== deccheck ======================= echo. -python.exe ..\Modules\_decimal\tests\deccheck.py +call python.bat .\Modules\_decimal\tests\deccheck.py echo. echo. - - -cd ..\Modules\_decimal\tests - - - From webhook-mailer at python.org Thu Feb 20 13:31:44 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:31:44 -0000 Subject: [Python-checkins] Use the new recommended number of repetitions in the refleak tests. (GH-18569) (#18574) Message-ID: https://github.com/python/cpython/commit/0721f7afb0a9c0500d2a912a55f2a290ec94ff53 commit: 0721f7afb0a9c0500d2a912a55f2a290ec94ff53 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:31:39+01:00 summary: Use the new recommended number of repetitions in the refleak tests. (GH-18569) (#18574) (cherry picked from commit 1246d892038a693304549f8574e6c2784b91589a) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 77c0c9cd82c13..18328841afcc1 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -78,7 +78,7 @@ for config in $CONFIGS; do $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" - ./python -m test -uall -R 2:2 test_decimal + ./python -m test -uall -R 3:3 test_decimal ############ regular tests ########### From webhook-mailer at python.org Thu Feb 20 13:37:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:37:28 -0000 Subject: [Python-checkins] Use the new recommended number of repetitions in the refleak tests. (GH-18569) (#18575) Message-ID: https://github.com/python/cpython/commit/a3c2c5f15ba5b4ad6fb86b3320d0464f1c502fd2 commit: a3c2c5f15ba5b4ad6fb86b3320d0464f1c502fd2 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:37:23+01:00 summary: Use the new recommended number of repetitions in the refleak tests. (GH-18569) (#18575) (cherry picked from commit 1246d892038a693304549f8574e6c2784b91589a) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 77c0c9cd82c13..18328841afcc1 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -78,7 +78,7 @@ for config in $CONFIGS; do $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" - ./python -m test -uall -R 2:2 test_decimal + ./python -m test -uall -R 3:3 test_decimal ############ regular tests ########### From webhook-mailer at python.org Thu Feb 20 13:38:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:38:24 -0000 Subject: [Python-checkins] Valgrind no longer supports --db-attach=yes. (GH-18568) (#18576) Message-ID: https://github.com/python/cpython/commit/9c87fbe54e1c797e3c690c6426bdf5e79c457cf1 commit: 9c87fbe54e1c797e3c690c6426bdf5e79c457cf1 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:38:19+01:00 summary: Valgrind no longer supports --db-attach=yes. (GH-18568) (#18576) (cherry picked from commit c0cb8beb389da3ba67ad31b1ecc95e100b6292ab) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 18328841afcc1..29b7723dd50c0 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -18,7 +18,7 @@ CONFIGS_64="x64 uint128 ansi64 universal" CONFIGS_32="ppro ansi32 ansi-legacy universal" VALGRIND="valgrind --tool=memcheck --leak-resolution=high \ - --db-attach=yes --suppressions=Misc/valgrind-python.supp" + --suppressions=Misc/valgrind-python.supp" # Get args case $@ in From webhook-mailer at python.org Thu Feb 20 13:54:44 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 18:54:44 -0000 Subject: [Python-checkins] Valgrind no longer supports --db-attach=yes. (GH-18568) (#18578) Message-ID: https://github.com/python/cpython/commit/736e0eaf5b3b0865f5dc4a105816861c7c29d3dc commit: 736e0eaf5b3b0865f5dc4a105816861c7c29d3dc branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T19:54:37+01:00 summary: Valgrind no longer supports --db-attach=yes. (GH-18568) (#18578) (cherry picked from commit c0cb8beb389da3ba67ad31b1ecc95e100b6292ab) Co-authored-by: Stefan Krah Co-authored-by: Stefan Krah files: M Modules/_decimal/tests/runall-memorydebugger.sh diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 18328841afcc1..29b7723dd50c0 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -18,7 +18,7 @@ CONFIGS_64="x64 uint128 ansi64 universal" CONFIGS_32="ppro ansi32 ansi-legacy universal" VALGRIND="valgrind --tool=memcheck --leak-resolution=high \ - --db-attach=yes --suppressions=Misc/valgrind-python.supp" + --suppressions=Misc/valgrind-python.supp" # Get args case $@ in From webhook-mailer at python.org Thu Feb 20 17:24:51 2020 From: webhook-mailer at python.org (Steve Dower) Date: Thu, 20 Feb 2020 22:24:51 -0000 Subject: [Python-checkins] bpo-39184: Fix incorrect return value (GH-18580) Message-ID: https://github.com/python/cpython/commit/6c444d0dab8f06cf304263b34beb299101cef3de commit: 6c444d0dab8f06cf304263b34beb299101cef3de branch: master author: Steve Dower committer: GitHub date: 2020-02-20T14:24:43-08:00 summary: bpo-39184: Fix incorrect return value (GH-18580) https://bugs.python.org/issue39184 Automerge-Triggered-By: @zooba files: M PC/msvcrtmodule.c diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index 5c06ec2621ea6..faceb03fba39d 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -180,7 +180,7 @@ msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags) int fd; if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) { - return NULL; + return -1; } _Py_BEGIN_SUPPRESS_IPH From webhook-mailer at python.org Thu Feb 20 17:44:54 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 20 Feb 2020 22:44:54 -0000 Subject: [Python-checkins] bpo-39184: Fix incorrect return value (GH-18580) Message-ID: https://github.com/python/cpython/commit/d0a464e31ac67685ef8ad35ecd993f17dfd6ab35 commit: d0a464e31ac67685ef8ad35ecd993f17dfd6ab35 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T14:44:47-08:00 summary: bpo-39184: Fix incorrect return value (GH-18580) https://bugs.python.org/issue39184 Automerge-Triggered-By: @zooba (cherry picked from commit 6c444d0dab8f06cf304263b34beb299101cef3de) Co-authored-by: Steve Dower files: M PC/msvcrtmodule.c diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index 5c06ec2621ea6..faceb03fba39d 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -180,7 +180,7 @@ msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags) int fd; if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) { - return NULL; + return -1; } _Py_BEGIN_SUPPRESS_IPH From webhook-mailer at python.org Thu Feb 20 19:52:52 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Fri, 21 Feb 2020 00:52:52 -0000 Subject: [Python-checkins] bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) Message-ID: https://github.com/python/cpython/commit/90930e65455f60216f09d175586139242dbba260 commit: 90930e65455f60216f09d175586139242dbba260 branch: master author: Stefan Krah committer: GitHub date: 2020-02-21T01:52:47+01:00 summary: bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) files: M Lib/test/test_decimal.py M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/tests/deccheck.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index fe0cfc7b66d7e..f1abd2aecb122 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,6 +5476,41 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) + def test_maxcontext_exact_arith(self): + + # Make sure that exact operations do not raise MemoryError due + # to huge intermediate values when the context precision is very + # large. + + # The following functions fill the available precision and are + # therefore not suitable for large precisions (by design of the + # specification). + MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', + 'logical_and', 'logical_or', 'logical_xor', + 'next_toward', 'rotate', 'shift'] + + Decimal = C.Decimal + Context = C.Context + localcontext = C.localcontext + + # Here only some functions that are likely candidates for triggering a + # MemoryError are tested. deccheck.py has an exhaustive test. + maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) + with localcontext(maxcontext): + self.assertEqual(Decimal(0).exp(), 1) + self.assertEqual(Decimal(1).ln(), 0) + self.assertEqual(Decimal(1).log10(), 0) + self.assertEqual(Decimal(10**2).log10(), 2) + self.assertEqual(Decimal(10**223).log10(), 223) + self.assertEqual(Decimal(10**19).logb(), 19) + self.assertEqual(Decimal(4).sqrt(), 2) + self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) + self.assertEqual(divmod(Decimal(10), 3), (3, 1)) + self.assertEqual(Decimal(10) // 3, 3) + self.assertEqual(Decimal(4) / 2, 2) + self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) + + @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index bfa8bb343e60c..0986edb576a10 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -3781,6 +3781,43 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); + + if (*status & MPD_Malloc_error) { + /* Inexact quotients (the usual case) fill the entire context precision, + * which can lead to malloc() failures for very high precisions. Retry + * the operation with a lower precision in case the result is exact. + * + * We need an upper bound for the number of digits of a_coeff / b_coeff + * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest + * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable + * bound. + * + * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. + * The largest amount of digits is generated if b_coeff' is a power of 2 or + * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). + * + * We arrive at a total upper bound: + * + * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= + * a->digits + log2(b_coeff) = + * a->digits + log10(b_coeff) / log10(2) <= + * a->digits + b->digits * 4; + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits + b->digits * 4; + if (workctx.prec >= ctx->prec) { + return; /* No point in retrying, keep the original error. */ + } + + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); + if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ + *status = 0; + return; + } + + mpd_seterror(q, *status, status); + } } /* Internal function. */ @@ -7702,9 +7739,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, /* END LIBMPDEC_ONLY */ /* Algorithm from decimal.py */ -void -mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) +static void +_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) { mpd_context_t maxcontext; MPD_NEW_STATIC(c,0,0,0,0); @@ -7836,6 +7873,40 @@ mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, goto out; } +void +mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + _mpd_qsqrt(result, a, ctx, status); + + if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { + /* The above conditions can occur at very high context precisions + * if intermediate values get too large. Retry the operation with + * a lower context precision in case the result is exact. + * + * If the result is exact, an upper bound for the number of digits + * is the number of digits in the input. + * + * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits; + + if (workctx.prec >= ctx->prec) { + return; /* No point in repeating this, keep the original error. */ + } + + _mpd_qsqrt(result, a, &workctx, &workstatus); + if (workstatus == 0) { + *status = 0; + return; + } + + mpd_seterror(result, *status, status); + } +} + /******************************************************************************/ /* Base conversions */ diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index f907531e1ffa5..5cd5db5711426 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -125,6 +125,12 @@ 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') } +# Functions that set no context flags but whose result can differ depending +# on prec, Emin and Emax. +MaxContextSkip = ['is_normal', 'is_subnormal', 'logical_invert', 'next_minus', + 'next_plus', 'number_class', 'logical_and', 'logical_or', + 'logical_xor', 'next_toward', 'rotate', 'shift'] + # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', @@ -344,6 +350,20 @@ def __init__(self, funcname, operands): self.pex = RestrictedList() # Python exceptions for P.Decimal self.presults = RestrictedList() # P.Decimal results + # If the above results are exact, unrounded and not clamped, repeat + # the operation with a maxcontext to ensure that huge intermediate + # values do not cause a MemoryError. + self.with_maxcontext = False + self.maxcontext = context.c.copy() + self.maxcontext.prec = C.MAX_PREC + self.maxcontext.Emax = C.MAX_EMAX + self.maxcontext.Emin = C.MIN_EMIN + self.maxcontext.clear_flags() + + self.maxop = RestrictedList() # converted C.Decimal operands + self.maxex = RestrictedList() # Python exceptions for C.Decimal + self.maxresults = RestrictedList() # C.Decimal results + # ====================================================================== # SkipHandler: skip known discrepancies @@ -545,13 +565,17 @@ def function_as_string(t): if t.contextfunc: cargs = t.cop pargs = t.pop + maxargs = t.maxop cfunc = "c_func: %s(" % t.funcname pfunc = "p_func: %s(" % t.funcname + maxfunc = "max_func: %s(" % t.funcname else: cself, cargs = t.cop[0], t.cop[1:] pself, pargs = t.pop[0], t.pop[1:] + maxself, maxargs = t.maxop[0], t.maxop[1:] cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) + maxfunc = "max_func: %s.%s(" % (repr(maxself), t.funcname) err = cfunc for arg in cargs: @@ -565,6 +589,14 @@ def function_as_string(t): err = err.rstrip(", ") err += ")" + if t.with_maxcontext: + err += "\n" + err += maxfunc + for arg in maxargs: + err += "%s, " % repr(arg) + err = err.rstrip(", ") + err += ")" + return err def raise_error(t): @@ -577,9 +609,24 @@ def raise_error(t): err = "Error in %s:\n\n" % t.funcname err += "input operands: %s\n\n" % (t.op,) err += function_as_string(t) - err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) - err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) - err += "%s\n\n" % str(t.context) + + err += "\n\nc_result: %s\np_result: %s\n" % (t.cresults, t.presults) + if t.with_maxcontext: + err += "max_result: %s\n\n" % (t.maxresults) + else: + err += "\n" + + err += "c_exceptions: %s\np_exceptions: %s\n" % (t.cex, t.pex) + if t.with_maxcontext: + err += "max_exceptions: %s\n\n" % t.maxex + else: + err += "\n" + + err += "%s\n" % str(t.context) + if t.with_maxcontext: + err += "%s\n" % str(t.maxcontext) + else: + err += "\n" raise VerifyError(err) @@ -603,6 +650,13 @@ def raise_error(t): # are printed to stdout. # ====================================================================== +def all_nan(a): + if isinstance(a, C.Decimal): + return a.is_nan() + elif isinstance(a, tuple): + return all(all_nan(v) for v in a) + return False + def convert(t, convstr=True): """ t is the testset. At this stage the testset contains a tuple of operands t.op of various types. For decimal methods the first @@ -617,10 +671,12 @@ def convert(t, convstr=True): for i, op in enumerate(t.op): context.clear_status() + t.maxcontext.clear_flags() if op in RoundModes: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) elif not t.contextfunc and i == 0 or \ convstr and isinstance(op, str): @@ -638,11 +694,25 @@ def convert(t, convstr=True): p = None pex = e.__class__ + try: + C.setcontext(t.maxcontext) + maxop = C.Decimal(op) + maxex = None + except (TypeError, ValueError, OverflowError) as e: + maxop = None + maxex = e.__class__ + finally: + C.setcontext(context.c) + t.cop.append(c) t.cex.append(cex) + t.pop.append(p) t.pex.append(pex) + t.maxop.append(maxop) + t.maxex.append(maxex) + if cex is pex: if str(c) != str(p) or not context.assert_eq_status(): raise_error(t) @@ -652,14 +722,21 @@ def convert(t, convstr=True): else: raise_error(t) + # The exceptions in the maxcontext operation can legitimately + # differ, only test that maxex implies cex: + if maxex is not None and cex is not maxex: + raise_error(t) + elif isinstance(op, Context): t.context = op t.cop.append(op.c) t.pop.append(op.p) + t.maxop.append(t.maxcontext) else: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) return 1 @@ -673,6 +750,7 @@ def callfuncs(t): t.rc and t.rp are the results of the operation. """ context.clear_status() + t.maxcontext.clear_flags() try: if t.contextfunc: @@ -700,6 +778,35 @@ def callfuncs(t): t.rp = None t.pex.append(e.__class__) + # If the above results are exact, unrounded, normal etc., repeat the + # operation with a maxcontext to ensure that huge intermediate values + # do not cause a MemoryError. + if (t.funcname not in MaxContextSkip and + not context.c.flags[C.InvalidOperation] and + not context.c.flags[C.Inexact] and + not context.c.flags[C.Rounded] and + not context.c.flags[C.Subnormal] and + not context.c.flags[C.Clamped] and + not context.clamp and # results are padded to context.prec if context.clamp==1. + not any(isinstance(v, C.Context) for v in t.cop)): # another context is used. + t.with_maxcontext = True + try: + if t.contextfunc: + maxargs = t.maxop + t.rmax = getattr(t.maxcontext, t.funcname)(*maxargs) + else: + maxself = t.maxop[0] + maxargs = t.maxop[1:] + try: + C.setcontext(t.maxcontext) + t.rmax = getattr(maxself, t.funcname)(*maxargs) + finally: + C.setcontext(context.c) + t.maxex.append(None) + except (TypeError, ValueError, OverflowError, MemoryError) as e: + t.rmax = None + t.maxex.append(e.__class__) + def verify(t, stat): """ t is the testset. At this stage the testset contains the following tuples: @@ -714,6 +821,9 @@ def verify(t, stat): """ t.cresults.append(str(t.rc)) t.presults.append(str(t.rp)) + if t.with_maxcontext: + t.maxresults.append(str(t.rmax)) + if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): # General case: both results are Decimals. t.cresults.append(t.rc.to_eng_string()) @@ -725,6 +835,12 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) + if t.with_maxcontext and isinstance(t.rmax, C.Decimal): + t.maxresults.append(t.rmax.to_eng_string()) + t.maxresults.append(t.rmax.as_tuple()) + t.maxresults.append(str(t.rmax.imag)) + t.maxresults.append(str(t.rmax.real)) + nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: @@ -732,6 +848,9 @@ def verify(t, stat): if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): if t.rc != t.rp: raise_error(t) + if t.with_maxcontext and not isinstance(t.rmax, tuple): + if t.rmax != t.rc: + raise_error(t) stat[type(t.rc).__name__] += 1 # The return value lists must be equal. @@ -744,6 +863,20 @@ def verify(t, stat): if not t.context.assert_eq_status(): raise_error(t) + if t.with_maxcontext: + # NaN payloads etc. depend on precision and clamp. + if all_nan(t.rc) and all_nan(t.rmax): + return + # The return value lists must be equal. + if t.maxresults != t.cresults: + raise_error(t) + # The Python exception lists (TypeError, etc.) must be equal. + if t.maxex != t.cex: + raise_error(t) + # The context flags must be equal. + if t.maxcontext.flags != t.context.c.flags: + raise_error(t) + # ====================================================================== # Main test loops From webhook-mailer at python.org Thu Feb 20 20:15:49 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 01:15:49 -0000 Subject: [Python-checkins] bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) (#18585) Message-ID: https://github.com/python/cpython/commit/c6f95543b4832c3f0170179da39bcf99b40a7aa8 commit: c6f95543b4832c3f0170179da39bcf99b40a7aa8 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T02:15:41+01:00 summary: bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) (#18585) (cherry picked from commit 90930e65455f60216f09d175586139242dbba260) Authored-by: Stefan Krah files: M Lib/test/test_decimal.py M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/tests/deccheck.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 1f37b5372a3e7..0e9cd3095c85e 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,6 +5476,41 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) + def test_maxcontext_exact_arith(self): + + # Make sure that exact operations do not raise MemoryError due + # to huge intermediate values when the context precision is very + # large. + + # The following functions fill the available precision and are + # therefore not suitable for large precisions (by design of the + # specification). + MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', + 'logical_and', 'logical_or', 'logical_xor', + 'next_toward', 'rotate', 'shift'] + + Decimal = C.Decimal + Context = C.Context + localcontext = C.localcontext + + # Here only some functions that are likely candidates for triggering a + # MemoryError are tested. deccheck.py has an exhaustive test. + maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) + with localcontext(maxcontext): + self.assertEqual(Decimal(0).exp(), 1) + self.assertEqual(Decimal(1).ln(), 0) + self.assertEqual(Decimal(1).log10(), 0) + self.assertEqual(Decimal(10**2).log10(), 2) + self.assertEqual(Decimal(10**223).log10(), 223) + self.assertEqual(Decimal(10**19).logb(), 19) + self.assertEqual(Decimal(4).sqrt(), 2) + self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) + self.assertEqual(divmod(Decimal(10), 3), (3, 1)) + self.assertEqual(Decimal(10) // 3, 3) + self.assertEqual(Decimal(4) / 2, 2) + self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) + + @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index bfa8bb343e60c..0986edb576a10 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -3781,6 +3781,43 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); + + if (*status & MPD_Malloc_error) { + /* Inexact quotients (the usual case) fill the entire context precision, + * which can lead to malloc() failures for very high precisions. Retry + * the operation with a lower precision in case the result is exact. + * + * We need an upper bound for the number of digits of a_coeff / b_coeff + * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest + * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable + * bound. + * + * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. + * The largest amount of digits is generated if b_coeff' is a power of 2 or + * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). + * + * We arrive at a total upper bound: + * + * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= + * a->digits + log2(b_coeff) = + * a->digits + log10(b_coeff) / log10(2) <= + * a->digits + b->digits * 4; + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits + b->digits * 4; + if (workctx.prec >= ctx->prec) { + return; /* No point in retrying, keep the original error. */ + } + + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); + if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ + *status = 0; + return; + } + + mpd_seterror(q, *status, status); + } } /* Internal function. */ @@ -7702,9 +7739,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, /* END LIBMPDEC_ONLY */ /* Algorithm from decimal.py */ -void -mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) +static void +_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) { mpd_context_t maxcontext; MPD_NEW_STATIC(c,0,0,0,0); @@ -7836,6 +7873,40 @@ mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, goto out; } +void +mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + _mpd_qsqrt(result, a, ctx, status); + + if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { + /* The above conditions can occur at very high context precisions + * if intermediate values get too large. Retry the operation with + * a lower context precision in case the result is exact. + * + * If the result is exact, an upper bound for the number of digits + * is the number of digits in the input. + * + * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits; + + if (workctx.prec >= ctx->prec) { + return; /* No point in repeating this, keep the original error. */ + } + + _mpd_qsqrt(result, a, &workctx, &workstatus); + if (workstatus == 0) { + *status = 0; + return; + } + + mpd_seterror(result, *status, status); + } +} + /******************************************************************************/ /* Base conversions */ diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index f907531e1ffa5..5cd5db5711426 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -125,6 +125,12 @@ 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') } +# Functions that set no context flags but whose result can differ depending +# on prec, Emin and Emax. +MaxContextSkip = ['is_normal', 'is_subnormal', 'logical_invert', 'next_minus', + 'next_plus', 'number_class', 'logical_and', 'logical_or', + 'logical_xor', 'next_toward', 'rotate', 'shift'] + # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', @@ -344,6 +350,20 @@ def __init__(self, funcname, operands): self.pex = RestrictedList() # Python exceptions for P.Decimal self.presults = RestrictedList() # P.Decimal results + # If the above results are exact, unrounded and not clamped, repeat + # the operation with a maxcontext to ensure that huge intermediate + # values do not cause a MemoryError. + self.with_maxcontext = False + self.maxcontext = context.c.copy() + self.maxcontext.prec = C.MAX_PREC + self.maxcontext.Emax = C.MAX_EMAX + self.maxcontext.Emin = C.MIN_EMIN + self.maxcontext.clear_flags() + + self.maxop = RestrictedList() # converted C.Decimal operands + self.maxex = RestrictedList() # Python exceptions for C.Decimal + self.maxresults = RestrictedList() # C.Decimal results + # ====================================================================== # SkipHandler: skip known discrepancies @@ -545,13 +565,17 @@ def function_as_string(t): if t.contextfunc: cargs = t.cop pargs = t.pop + maxargs = t.maxop cfunc = "c_func: %s(" % t.funcname pfunc = "p_func: %s(" % t.funcname + maxfunc = "max_func: %s(" % t.funcname else: cself, cargs = t.cop[0], t.cop[1:] pself, pargs = t.pop[0], t.pop[1:] + maxself, maxargs = t.maxop[0], t.maxop[1:] cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) + maxfunc = "max_func: %s.%s(" % (repr(maxself), t.funcname) err = cfunc for arg in cargs: @@ -565,6 +589,14 @@ def function_as_string(t): err = err.rstrip(", ") err += ")" + if t.with_maxcontext: + err += "\n" + err += maxfunc + for arg in maxargs: + err += "%s, " % repr(arg) + err = err.rstrip(", ") + err += ")" + return err def raise_error(t): @@ -577,9 +609,24 @@ def raise_error(t): err = "Error in %s:\n\n" % t.funcname err += "input operands: %s\n\n" % (t.op,) err += function_as_string(t) - err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) - err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) - err += "%s\n\n" % str(t.context) + + err += "\n\nc_result: %s\np_result: %s\n" % (t.cresults, t.presults) + if t.with_maxcontext: + err += "max_result: %s\n\n" % (t.maxresults) + else: + err += "\n" + + err += "c_exceptions: %s\np_exceptions: %s\n" % (t.cex, t.pex) + if t.with_maxcontext: + err += "max_exceptions: %s\n\n" % t.maxex + else: + err += "\n" + + err += "%s\n" % str(t.context) + if t.with_maxcontext: + err += "%s\n" % str(t.maxcontext) + else: + err += "\n" raise VerifyError(err) @@ -603,6 +650,13 @@ def raise_error(t): # are printed to stdout. # ====================================================================== +def all_nan(a): + if isinstance(a, C.Decimal): + return a.is_nan() + elif isinstance(a, tuple): + return all(all_nan(v) for v in a) + return False + def convert(t, convstr=True): """ t is the testset. At this stage the testset contains a tuple of operands t.op of various types. For decimal methods the first @@ -617,10 +671,12 @@ def convert(t, convstr=True): for i, op in enumerate(t.op): context.clear_status() + t.maxcontext.clear_flags() if op in RoundModes: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) elif not t.contextfunc and i == 0 or \ convstr and isinstance(op, str): @@ -638,11 +694,25 @@ def convert(t, convstr=True): p = None pex = e.__class__ + try: + C.setcontext(t.maxcontext) + maxop = C.Decimal(op) + maxex = None + except (TypeError, ValueError, OverflowError) as e: + maxop = None + maxex = e.__class__ + finally: + C.setcontext(context.c) + t.cop.append(c) t.cex.append(cex) + t.pop.append(p) t.pex.append(pex) + t.maxop.append(maxop) + t.maxex.append(maxex) + if cex is pex: if str(c) != str(p) or not context.assert_eq_status(): raise_error(t) @@ -652,14 +722,21 @@ def convert(t, convstr=True): else: raise_error(t) + # The exceptions in the maxcontext operation can legitimately + # differ, only test that maxex implies cex: + if maxex is not None and cex is not maxex: + raise_error(t) + elif isinstance(op, Context): t.context = op t.cop.append(op.c) t.pop.append(op.p) + t.maxop.append(t.maxcontext) else: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) return 1 @@ -673,6 +750,7 @@ def callfuncs(t): t.rc and t.rp are the results of the operation. """ context.clear_status() + t.maxcontext.clear_flags() try: if t.contextfunc: @@ -700,6 +778,35 @@ def callfuncs(t): t.rp = None t.pex.append(e.__class__) + # If the above results are exact, unrounded, normal etc., repeat the + # operation with a maxcontext to ensure that huge intermediate values + # do not cause a MemoryError. + if (t.funcname not in MaxContextSkip and + not context.c.flags[C.InvalidOperation] and + not context.c.flags[C.Inexact] and + not context.c.flags[C.Rounded] and + not context.c.flags[C.Subnormal] and + not context.c.flags[C.Clamped] and + not context.clamp and # results are padded to context.prec if context.clamp==1. + not any(isinstance(v, C.Context) for v in t.cop)): # another context is used. + t.with_maxcontext = True + try: + if t.contextfunc: + maxargs = t.maxop + t.rmax = getattr(t.maxcontext, t.funcname)(*maxargs) + else: + maxself = t.maxop[0] + maxargs = t.maxop[1:] + try: + C.setcontext(t.maxcontext) + t.rmax = getattr(maxself, t.funcname)(*maxargs) + finally: + C.setcontext(context.c) + t.maxex.append(None) + except (TypeError, ValueError, OverflowError, MemoryError) as e: + t.rmax = None + t.maxex.append(e.__class__) + def verify(t, stat): """ t is the testset. At this stage the testset contains the following tuples: @@ -714,6 +821,9 @@ def verify(t, stat): """ t.cresults.append(str(t.rc)) t.presults.append(str(t.rp)) + if t.with_maxcontext: + t.maxresults.append(str(t.rmax)) + if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): # General case: both results are Decimals. t.cresults.append(t.rc.to_eng_string()) @@ -725,6 +835,12 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) + if t.with_maxcontext and isinstance(t.rmax, C.Decimal): + t.maxresults.append(t.rmax.to_eng_string()) + t.maxresults.append(t.rmax.as_tuple()) + t.maxresults.append(str(t.rmax.imag)) + t.maxresults.append(str(t.rmax.real)) + nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: @@ -732,6 +848,9 @@ def verify(t, stat): if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): if t.rc != t.rp: raise_error(t) + if t.with_maxcontext and not isinstance(t.rmax, tuple): + if t.rmax != t.rc: + raise_error(t) stat[type(t.rc).__name__] += 1 # The return value lists must be equal. @@ -744,6 +863,20 @@ def verify(t, stat): if not t.context.assert_eq_status(): raise_error(t) + if t.with_maxcontext: + # NaN payloads etc. depend on precision and clamp. + if all_nan(t.rc) and all_nan(t.rmax): + return + # The return value lists must be equal. + if t.maxresults != t.cresults: + raise_error(t) + # The Python exception lists (TypeError, etc.) must be equal. + if t.maxex != t.cex: + raise_error(t) + # The context flags must be equal. + if t.maxcontext.flags != t.context.c.flags: + raise_error(t) + # ====================================================================== # Main test loops From webhook-mailer at python.org Thu Feb 20 20:16:50 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 01:16:50 -0000 Subject: [Python-checkins] bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) (#18584) Message-ID: https://github.com/python/cpython/commit/b6271025c640c228505dc9f194362a0c2ab81c61 commit: b6271025c640c228505dc9f194362a0c2ab81c61 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T02:16:42+01:00 summary: bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581) (#18584) (cherry picked from commit 90930e65455f60216f09d175586139242dbba260) Authored-by: Stefan Krah files: M Lib/test/test_decimal.py M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/tests/deccheck.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 1f37b5372a3e7..0e9cd3095c85e 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,6 +5476,41 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) + def test_maxcontext_exact_arith(self): + + # Make sure that exact operations do not raise MemoryError due + # to huge intermediate values when the context precision is very + # large. + + # The following functions fill the available precision and are + # therefore not suitable for large precisions (by design of the + # specification). + MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', + 'logical_and', 'logical_or', 'logical_xor', + 'next_toward', 'rotate', 'shift'] + + Decimal = C.Decimal + Context = C.Context + localcontext = C.localcontext + + # Here only some functions that are likely candidates for triggering a + # MemoryError are tested. deccheck.py has an exhaustive test. + maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) + with localcontext(maxcontext): + self.assertEqual(Decimal(0).exp(), 1) + self.assertEqual(Decimal(1).ln(), 0) + self.assertEqual(Decimal(1).log10(), 0) + self.assertEqual(Decimal(10**2).log10(), 2) + self.assertEqual(Decimal(10**223).log10(), 223) + self.assertEqual(Decimal(10**19).logb(), 19) + self.assertEqual(Decimal(4).sqrt(), 2) + self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) + self.assertEqual(divmod(Decimal(10), 3), (3, 1)) + self.assertEqual(Decimal(10) // 3, 3) + self.assertEqual(Decimal(4) / 2, 2) + self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) + + @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index bfa8bb343e60c..0986edb576a10 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -3781,6 +3781,43 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); + + if (*status & MPD_Malloc_error) { + /* Inexact quotients (the usual case) fill the entire context precision, + * which can lead to malloc() failures for very high precisions. Retry + * the operation with a lower precision in case the result is exact. + * + * We need an upper bound for the number of digits of a_coeff / b_coeff + * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest + * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable + * bound. + * + * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. + * The largest amount of digits is generated if b_coeff' is a power of 2 or + * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). + * + * We arrive at a total upper bound: + * + * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= + * a->digits + log2(b_coeff) = + * a->digits + log10(b_coeff) / log10(2) <= + * a->digits + b->digits * 4; + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits + b->digits * 4; + if (workctx.prec >= ctx->prec) { + return; /* No point in retrying, keep the original error. */ + } + + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); + if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ + *status = 0; + return; + } + + mpd_seterror(q, *status, status); + } } /* Internal function. */ @@ -7702,9 +7739,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, /* END LIBMPDEC_ONLY */ /* Algorithm from decimal.py */ -void -mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) +static void +_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) { mpd_context_t maxcontext; MPD_NEW_STATIC(c,0,0,0,0); @@ -7836,6 +7873,40 @@ mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, goto out; } +void +mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + _mpd_qsqrt(result, a, ctx, status); + + if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { + /* The above conditions can occur at very high context precisions + * if intermediate values get too large. Retry the operation with + * a lower context precision in case the result is exact. + * + * If the result is exact, an upper bound for the number of digits + * is the number of digits in the input. + * + * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 + */ + uint32_t workstatus = 0; + mpd_context_t workctx = *ctx; + workctx.prec = a->digits; + + if (workctx.prec >= ctx->prec) { + return; /* No point in repeating this, keep the original error. */ + } + + _mpd_qsqrt(result, a, &workctx, &workstatus); + if (workstatus == 0) { + *status = 0; + return; + } + + mpd_seterror(result, *status, status); + } +} + /******************************************************************************/ /* Base conversions */ diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index f907531e1ffa5..5cd5db5711426 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -125,6 +125,12 @@ 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') } +# Functions that set no context flags but whose result can differ depending +# on prec, Emin and Emax. +MaxContextSkip = ['is_normal', 'is_subnormal', 'logical_invert', 'next_minus', + 'next_plus', 'number_class', 'logical_and', 'logical_or', + 'logical_xor', 'next_toward', 'rotate', 'shift'] + # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', @@ -344,6 +350,20 @@ def __init__(self, funcname, operands): self.pex = RestrictedList() # Python exceptions for P.Decimal self.presults = RestrictedList() # P.Decimal results + # If the above results are exact, unrounded and not clamped, repeat + # the operation with a maxcontext to ensure that huge intermediate + # values do not cause a MemoryError. + self.with_maxcontext = False + self.maxcontext = context.c.copy() + self.maxcontext.prec = C.MAX_PREC + self.maxcontext.Emax = C.MAX_EMAX + self.maxcontext.Emin = C.MIN_EMIN + self.maxcontext.clear_flags() + + self.maxop = RestrictedList() # converted C.Decimal operands + self.maxex = RestrictedList() # Python exceptions for C.Decimal + self.maxresults = RestrictedList() # C.Decimal results + # ====================================================================== # SkipHandler: skip known discrepancies @@ -545,13 +565,17 @@ def function_as_string(t): if t.contextfunc: cargs = t.cop pargs = t.pop + maxargs = t.maxop cfunc = "c_func: %s(" % t.funcname pfunc = "p_func: %s(" % t.funcname + maxfunc = "max_func: %s(" % t.funcname else: cself, cargs = t.cop[0], t.cop[1:] pself, pargs = t.pop[0], t.pop[1:] + maxself, maxargs = t.maxop[0], t.maxop[1:] cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) + maxfunc = "max_func: %s.%s(" % (repr(maxself), t.funcname) err = cfunc for arg in cargs: @@ -565,6 +589,14 @@ def function_as_string(t): err = err.rstrip(", ") err += ")" + if t.with_maxcontext: + err += "\n" + err += maxfunc + for arg in maxargs: + err += "%s, " % repr(arg) + err = err.rstrip(", ") + err += ")" + return err def raise_error(t): @@ -577,9 +609,24 @@ def raise_error(t): err = "Error in %s:\n\n" % t.funcname err += "input operands: %s\n\n" % (t.op,) err += function_as_string(t) - err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) - err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) - err += "%s\n\n" % str(t.context) + + err += "\n\nc_result: %s\np_result: %s\n" % (t.cresults, t.presults) + if t.with_maxcontext: + err += "max_result: %s\n\n" % (t.maxresults) + else: + err += "\n" + + err += "c_exceptions: %s\np_exceptions: %s\n" % (t.cex, t.pex) + if t.with_maxcontext: + err += "max_exceptions: %s\n\n" % t.maxex + else: + err += "\n" + + err += "%s\n" % str(t.context) + if t.with_maxcontext: + err += "%s\n" % str(t.maxcontext) + else: + err += "\n" raise VerifyError(err) @@ -603,6 +650,13 @@ def raise_error(t): # are printed to stdout. # ====================================================================== +def all_nan(a): + if isinstance(a, C.Decimal): + return a.is_nan() + elif isinstance(a, tuple): + return all(all_nan(v) for v in a) + return False + def convert(t, convstr=True): """ t is the testset. At this stage the testset contains a tuple of operands t.op of various types. For decimal methods the first @@ -617,10 +671,12 @@ def convert(t, convstr=True): for i, op in enumerate(t.op): context.clear_status() + t.maxcontext.clear_flags() if op in RoundModes: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) elif not t.contextfunc and i == 0 or \ convstr and isinstance(op, str): @@ -638,11 +694,25 @@ def convert(t, convstr=True): p = None pex = e.__class__ + try: + C.setcontext(t.maxcontext) + maxop = C.Decimal(op) + maxex = None + except (TypeError, ValueError, OverflowError) as e: + maxop = None + maxex = e.__class__ + finally: + C.setcontext(context.c) + t.cop.append(c) t.cex.append(cex) + t.pop.append(p) t.pex.append(pex) + t.maxop.append(maxop) + t.maxex.append(maxex) + if cex is pex: if str(c) != str(p) or not context.assert_eq_status(): raise_error(t) @@ -652,14 +722,21 @@ def convert(t, convstr=True): else: raise_error(t) + # The exceptions in the maxcontext operation can legitimately + # differ, only test that maxex implies cex: + if maxex is not None and cex is not maxex: + raise_error(t) + elif isinstance(op, Context): t.context = op t.cop.append(op.c) t.pop.append(op.p) + t.maxop.append(t.maxcontext) else: t.cop.append(op) t.pop.append(op) + t.maxop.append(op) return 1 @@ -673,6 +750,7 @@ def callfuncs(t): t.rc and t.rp are the results of the operation. """ context.clear_status() + t.maxcontext.clear_flags() try: if t.contextfunc: @@ -700,6 +778,35 @@ def callfuncs(t): t.rp = None t.pex.append(e.__class__) + # If the above results are exact, unrounded, normal etc., repeat the + # operation with a maxcontext to ensure that huge intermediate values + # do not cause a MemoryError. + if (t.funcname not in MaxContextSkip and + not context.c.flags[C.InvalidOperation] and + not context.c.flags[C.Inexact] and + not context.c.flags[C.Rounded] and + not context.c.flags[C.Subnormal] and + not context.c.flags[C.Clamped] and + not context.clamp and # results are padded to context.prec if context.clamp==1. + not any(isinstance(v, C.Context) for v in t.cop)): # another context is used. + t.with_maxcontext = True + try: + if t.contextfunc: + maxargs = t.maxop + t.rmax = getattr(t.maxcontext, t.funcname)(*maxargs) + else: + maxself = t.maxop[0] + maxargs = t.maxop[1:] + try: + C.setcontext(t.maxcontext) + t.rmax = getattr(maxself, t.funcname)(*maxargs) + finally: + C.setcontext(context.c) + t.maxex.append(None) + except (TypeError, ValueError, OverflowError, MemoryError) as e: + t.rmax = None + t.maxex.append(e.__class__) + def verify(t, stat): """ t is the testset. At this stage the testset contains the following tuples: @@ -714,6 +821,9 @@ def verify(t, stat): """ t.cresults.append(str(t.rc)) t.presults.append(str(t.rp)) + if t.with_maxcontext: + t.maxresults.append(str(t.rmax)) + if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): # General case: both results are Decimals. t.cresults.append(t.rc.to_eng_string()) @@ -725,6 +835,12 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) + if t.with_maxcontext and isinstance(t.rmax, C.Decimal): + t.maxresults.append(t.rmax.to_eng_string()) + t.maxresults.append(t.rmax.as_tuple()) + t.maxresults.append(str(t.rmax.imag)) + t.maxresults.append(str(t.rmax.real)) + nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: @@ -732,6 +848,9 @@ def verify(t, stat): if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): if t.rc != t.rp: raise_error(t) + if t.with_maxcontext and not isinstance(t.rmax, tuple): + if t.rmax != t.rc: + raise_error(t) stat[type(t.rc).__name__] += 1 # The return value lists must be equal. @@ -744,6 +863,20 @@ def verify(t, stat): if not t.context.assert_eq_status(): raise_error(t) + if t.with_maxcontext: + # NaN payloads etc. depend on precision and clamp. + if all_nan(t.rc) and all_nan(t.rmax): + return + # The return value lists must be equal. + if t.maxresults != t.cresults: + raise_error(t) + # The Python exception lists (TypeError, etc.) must be equal. + if t.maxex != t.cex: + raise_error(t) + # The context flags must be equal. + if t.maxcontext.flags != t.context.c.flags: + raise_error(t) + # ====================================================================== # Main test loops From webhook-mailer at python.org Thu Feb 20 23:52:01 2020 From: webhook-mailer at python.org (Andy Lester) Date: Fri, 21 Feb 2020 04:52:01 -0000 Subject: [Python-checkins] closes bpo-39684: Combine two if/thens and squash uninit var warning. (GH-18565) Message-ID: https://github.com/python/cpython/commit/933fc53f3f9c64ffa703b1f23a93bec560faea57 commit: 933fc53f3f9c64ffa703b1f23a93bec560faea57 branch: master author: Andy Lester committer: GitHub date: 2020-02-20T20:51:47-08:00 summary: closes bpo-39684: Combine two if/thens and squash uninit var warning. (GH-18565) files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4475eca9432db..ee6d3dfd3945b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -12209,20 +12209,15 @@ PyUnicode_IsIdentifier(PyObject *self) int kind = 0; void *data = NULL; - wchar_t *wstr; + const wchar_t *wstr = NULL; + Py_UCS4 ch; if (ready) { kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); - } - else { - wstr = _PyUnicode_WSTR(self); - } - - Py_UCS4 ch; - if (ready) { ch = PyUnicode_READ(kind, data, 0); } else { + wstr = _PyUnicode_WSTR(self); ch = wstr[0]; } /* PEP 3131 says that the first character must be in From webhook-mailer at python.org Fri Feb 21 00:53:20 2020 From: webhook-mailer at python.org (Pete Wicken) Date: Fri, 21 Feb 2020 05:53:20 -0000 Subject: [Python-checkins] bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Message-ID: https://github.com/python/cpython/commit/424e5686d82235e08f8108b8bbe034bc91421689 commit: 424e5686d82235e08f8108b8bbe034bc91421689 branch: master author: Pete Wicken <2273100+JamoBox at users.noreply.github.com> committer: GitHub date: 2020-02-20T21:53:12-08:00 summary: bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Make the definition of the width more explicit that it includes any extra signs added by other options. https://bugs.python.org/issue38657 Automerge-Triggered-By: @Mariatta files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e2983db1ac832..89c169a512b52 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -415,8 +415,9 @@ error. .. versionchanged:: 3.6 Added the ``'_'`` option (see also :pep:`515`). -*width* is a decimal integer defining the minimum field width. If not -specified, then the field width will be determined by the content. +*width* is a decimal integer defining the minimum total field width, +including any prefixes, separators, and other formatting characters. +If not specified, then the field width will be determined by the content. When no explicit alignment is given, preceding the *width* field by a zero (``'0'``) character enables From webhook-mailer at python.org Fri Feb 21 01:06:05 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 06:06:05 -0000 Subject: [Python-checkins] bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Message-ID: https://github.com/python/cpython/commit/09db1da63f866afff8a64ae3c60acdcd6bc80501 commit: 09db1da63f866afff8a64ae3c60acdcd6bc80501 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T22:05:58-08:00 summary: bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Make the definition of the width more explicit that it includes any extra signs added by other options. https://bugs.python.org/issue38657 Automerge-Triggered-By: @Mariatta (cherry picked from commit 424e5686d82235e08f8108b8bbe034bc91421689) Co-authored-by: Pete Wicken <2273100+JamoBox at users.noreply.github.com> files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index bbbfed273ee45..6cbe54963196a 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -416,8 +416,9 @@ error. .. versionchanged:: 3.6 Added the ``'_'`` option (see also :pep:`515`). -*width* is a decimal integer defining the minimum field width. If not -specified, then the field width will be determined by the content. +*width* is a decimal integer defining the minimum total field width, +including any prefixes, separators, and other formatting characters. +If not specified, then the field width will be determined by the content. When no explicit alignment is given, preceding the *width* field by a zero (``'0'``) character enables From webhook-mailer at python.org Fri Feb 21 01:06:22 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 06:06:22 -0000 Subject: [Python-checkins] bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Message-ID: https://github.com/python/cpython/commit/a2075121217e809c9a5511f6ca225c12f340de0c commit: a2075121217e809c9a5511f6ca225c12f340de0c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-20T22:06:18-08:00 summary: bpo-38657: Clarify numeric padding behaviour in string formatting (GH-17036) Make the definition of the width more explicit that it includes any extra signs added by other options. https://bugs.python.org/issue38657 Automerge-Triggered-By: @Mariatta (cherry picked from commit 424e5686d82235e08f8108b8bbe034bc91421689) Co-authored-by: Pete Wicken <2273100+JamoBox at users.noreply.github.com> files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e2983db1ac832..89c169a512b52 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -415,8 +415,9 @@ error. .. versionchanged:: 3.6 Added the ``'_'`` option (see also :pep:`515`). -*width* is a decimal integer defining the minimum field width. If not -specified, then the field width will be determined by the content. +*width* is a decimal integer defining the minimum total field width, +including any prefixes, separators, and other formatting characters. +If not specified, then the field width will be determined by the content. When no explicit alignment is given, preceding the *width* field by a zero (``'0'``) character enables From webhook-mailer at python.org Fri Feb 21 03:48:44 2020 From: webhook-mailer at python.org (alclarks) Date: Fri, 21 Feb 2020 08:48:44 -0000 Subject: [Python-checkins] bpo-9495: avoid confusing chained exception in argparse test (GH-17120) Message-ID: https://github.com/python/cpython/commit/d4331c56b4f6fe6f18caf19fc1ecf9fec14f7066 commit: d4331c56b4f6fe6f18caf19fc1ecf9fec14f7066 branch: master author: alclarks <57201106+alclarks at users.noreply.github.com> committer: GitHub date: 2020-02-21T10:48:36+02:00 summary: bpo-9495: avoid confusing chained exception in argparse test (GH-17120) files: M Lib/test/test_argparse.py M Misc/ACKS diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index b095783a02e1e..9899a53d6d197 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -105,7 +105,8 @@ def stderr_to_parser_error(parse_args, *args, **kwargs): code = sys.exc_info()[1].code stdout = sys.stdout.getvalue() stderr = sys.stderr.getvalue() - raise ArgumentParserError("SystemExit", stdout, stderr, code) + raise ArgumentParserError( + "SystemExit", stdout, stderr, code) from None finally: sys.stdout = old_stdout sys.stderr = old_stderr diff --git a/Misc/ACKS b/Misc/ACKS index b11ee9cdea67d..976c26eb9117b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -312,6 +312,7 @@ Gilles Civario Chris Clark Diana Clarke Laurie Clark-Michalek +Alexander Clarkson Mike Clarkson Andrew Clegg Brad Clements From webhook-mailer at python.org Fri Feb 21 04:18:03 2020 From: webhook-mailer at python.org (Denis Chernikov) Date: Fri, 21 Feb 2020 09:18:03 -0000 Subject: [Python-checkins] Reuse identifier of PREDICT macros as PREDICT_ID (GH-17155) Message-ID: https://github.com/python/cpython/commit/baf29b221682be0f4fde53a05ea3f57c3c79f431 commit: baf29b221682be0f4fde53a05ea3f57c3c79f431 branch: master author: Denis Chernikov committer: GitHub date: 2020-02-21T10:17:50+01:00 summary: Reuse identifier of PREDICT macros as PREDICT_ID (GH-17155) In function `_PyEval_EvalFrameDefault`, macros PREDICT and PREDICTED use the same identifier creation scheme, which may be shared between them, reducing code repetition, and do ensure that the same identifier is generated. files: M Python/ceval.c diff --git a/Python/ceval.c b/Python/ceval.c index 426d0bbee8901..3f65820c25da9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -921,21 +921,23 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) */ +#define PREDICT_ID(op) PRED_##op + #if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS -#define PREDICT(op) if (0) goto PRED_##op +#define PREDICT(op) if (0) goto PREDICT_ID(op) #else #define PREDICT(op) \ - do{ \ + do { \ _Py_CODEUNIT word = *next_instr; \ opcode = _Py_OPCODE(word); \ - if (opcode == op){ \ + if (opcode == op) { \ oparg = _Py_OPARG(word); \ next_instr++; \ - goto PRED_##op; \ + goto PREDICT_ID(op); \ } \ } while(0) #endif -#define PREDICTED(op) PRED_##op: +#define PREDICTED(op) PREDICT_ID(op): /* Stack manipulation macros */ From webhook-mailer at python.org Fri Feb 21 04:33:09 2020 From: webhook-mailer at python.org (Christopher Hunt) Date: Fri, 21 Feb 2020 09:33:09 -0000 Subject: [Python-checkins] bpo-35727: Use exit code 0 on sys.exit() in multiprocessing.Process. (GH-11538) Message-ID: https://github.com/python/cpython/commit/c2ac4cf040ea950bf552d1e77bea613a1a5474fe commit: c2ac4cf040ea950bf552d1e77bea613a1a5474fe branch: master author: Christopher Hunt committer: GitHub date: 2020-02-21T10:33:04+01:00 summary: bpo-35727: Use exit code 0 on sys.exit() in multiprocessing.Process. (GH-11538) files: A Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst M Lib/multiprocessing/process.py M Lib/test/_test_multiprocessing.py M Misc/ACKS diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index be13c079bb89b..0b2e0b45b2397 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -317,12 +317,12 @@ def _bootstrap(self, parent_sentinel=None): finally: util._exit_function() except SystemExit as e: - if not e.args: - exitcode = 1 - elif isinstance(e.args[0], int): - exitcode = e.args[0] + if e.code is None: + exitcode = 0 + elif isinstance(e.code, int): + exitcode = e.code else: - sys.stderr.write(str(e.args[0]) + '\n') + sys.stderr.write(str(e.code) + '\n') exitcode = 1 except: exitcode = 1 diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 4e48cd45e14ca..73dc75d34a6f0 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -864,12 +864,21 @@ def test_sys_exit(self): os.unlink(testfn) - for reason in (True, False, 8): - p = self.Process(target=sys.exit, args=(reason,)) - p.daemon = True - p.start() - join_process(p) - self.assertEqual(p.exitcode, reason) + cases = [ + ((True,), 1), + ((False,), 0), + ((8,), 8), + ((None,), 0), + ((), 0), + ] + + for args, expected in cases: + with self.subTest(args=args): + p = self.Process(target=sys.exit, args=args) + p.daemon = True + p.start() + join_process(p) + self.assertEqual(p.exitcode, expected) # # diff --git a/Misc/ACKS b/Misc/ACKS index 976c26eb9117b..f329a2d4a7d33 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -746,6 +746,7 @@ Lawrence Hudson Michael Hudson Jim Hugunin Greg Humphreys +Chris Hunt Eric Huss Nehal Hussain Taihyun Hwang diff --git a/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst b/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst new file mode 100644 index 0000000000000..9f3fa40e51bf3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst @@ -0,0 +1 @@ +Fix sys.exit() and sys.exit(None) exit code propagation when used in multiprocessing.Process. \ No newline at end of file From webhook-mailer at python.org Fri Feb 21 05:47:50 2020 From: webhook-mailer at python.org (Julien Danjou) Date: Fri, 21 Feb 2020 10:47:50 -0000 Subject: [Python-checkins] fix(doc): set correct RST syntax for c:function (GH-18589) Message-ID: https://github.com/python/cpython/commit/d4d17fd2cf69e7c8f4cd03fbf2d575370945b952 commit: d4d17fd2cf69e7c8f4cd03fbf2d575370945b952 branch: master author: Julien Danjou committer: GitHub date: 2020-02-21T11:47:41+01:00 summary: fix(doc): set correct RST syntax for c:function (GH-18589) The current content is not rendered since the syntax is not correct. files: M Doc/c-api/memory.rst diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index ba7bd3b9a5387..8a8542f0479ec 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -533,7 +533,7 @@ tracemalloc C API .. versionadded:: 3.7 -.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) +.. c:function:: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) Track an allocated memory block in the :mod:`tracemalloc` module. @@ -542,7 +542,7 @@ tracemalloc C API If memory block is already tracked, update the existing trace. -.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +.. c:function:: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) Untrack an allocated memory block in the :mod:`tracemalloc` module. Do nothing if the block was not tracked. From webhook-mailer at python.org Fri Feb 21 05:54:04 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 10:54:04 -0000 Subject: [Python-checkins] fix(doc): set correct RST syntax for c:function (GH-18589) Message-ID: https://github.com/python/cpython/commit/9ce361d3bb15cf49b82fa03e3e593d7cbd8ee1ff commit: 9ce361d3bb15cf49b82fa03e3e593d7cbd8ee1ff branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T02:54:00-08:00 summary: fix(doc): set correct RST syntax for c:function (GH-18589) The current content is not rendered since the syntax is not correct. (cherry picked from commit d4d17fd2cf69e7c8f4cd03fbf2d575370945b952) Co-authored-by: Julien Danjou files: M Doc/c-api/memory.rst diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index ba7bd3b9a5387..8a8542f0479ec 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -533,7 +533,7 @@ tracemalloc C API .. versionadded:: 3.7 -.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) +.. c:function:: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) Track an allocated memory block in the :mod:`tracemalloc` module. @@ -542,7 +542,7 @@ tracemalloc C API If memory block is already tracked, update the existing trace. -.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +.. c:function:: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) Untrack an allocated memory block in the :mod:`tracemalloc` module. Do nothing if the block was not tracked. From webhook-mailer at python.org Fri Feb 21 09:09:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 14:09:28 -0000 Subject: [Python-checkins] fix(doc): set correct RST syntax for c:function (GH-18589) Message-ID: https://github.com/python/cpython/commit/50ce89071d212e659818825522be48acda4d2979 commit: 50ce89071d212e659818825522be48acda4d2979 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T06:09:24-08:00 summary: fix(doc): set correct RST syntax for c:function (GH-18589) The current content is not rendered since the syntax is not correct. (cherry picked from commit d4d17fd2cf69e7c8f4cd03fbf2d575370945b952) Co-authored-by: Julien Danjou files: M Doc/c-api/memory.rst diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index f14e1e123a0df..f4c94c4f3ce8d 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -533,7 +533,7 @@ tracemalloc C API .. versionadded:: 3.7 -.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) +.. c:function:: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) Track an allocated memory block in the :mod:`tracemalloc` module. @@ -542,7 +542,7 @@ tracemalloc C API If memory block is already tracked, update the existing trace. -.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +.. c:function:: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) Untrack an allocated memory block in the :mod:`tracemalloc` module. Do nothing if the block was not tracked. From webhook-mailer at python.org Fri Feb 21 12:57:34 2020 From: webhook-mailer at python.org (Berker Peksag) Date: Fri, 21 Feb 2020 17:57:34 -0000 Subject: [Python-checkins] bpo-35950: Raise UnsupportedOperation in BufferedReader.truncate() (GH-18586) Message-ID: https://github.com/python/cpython/commit/fd5116c0e77aec05f67fb24f10562ac920648035 commit: fd5116c0e77aec05f67fb24f10562ac920648035 branch: master author: Berker Peksag committer: GitHub date: 2020-02-21T09:57:26-08:00 summary: bpo-35950: Raise UnsupportedOperation in BufferedReader.truncate() (GH-18586) The truncate() method of io.BufferedReader() should raise UnsupportedOperation when it is called on a read-only io.BufferedReader() instance. https://bugs.python.org/issue35950 Automerge-Triggered-By: @methane files: A Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst M Lib/_pyio.py M Lib/test/test_io.py M Modules/_io/bufferedio.c diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 4c2414672ed56..8eaa114c07c91 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -792,6 +792,9 @@ def tell(self): return pos def truncate(self, pos=None): + self._checkClosed() + self._checkWritable() + # Flush the stream. We're mixing buffered I/O with lower-level I/O, # and a flush may be necessary to synch both views of the current # file state. diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 0bfa4d249e9a6..c27dfd96bc00d 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1528,6 +1528,13 @@ def test_read_on_closed(self): self.assertRaises(ValueError, b.peek) self.assertRaises(ValueError, b.read1, 1) + def test_truncate_on_read_only(self): + rawio = self.MockFileIO(b"abc") + bufio = self.tp(rawio) + self.assertFalse(bufio.writable()) + self.assertRaises(self.UnsupportedOperation, bufio.truncate) + self.assertRaises(self.UnsupportedOperation, bufio.truncate, 0) + class CBufferedReaderTest(BufferedReaderTest, SizeofTest): tp = io.BufferedReader @@ -2372,6 +2379,10 @@ def test_interleaved_readline_write(self): # You can't construct a BufferedRandom over a non-seekable stream. test_unseekable = None + # writable() returns True, so there's no point to test it over + # a writable stream. + test_truncate_on_read_only = None + class CBufferedRandomTest(BufferedRandomTest, SizeofTest): tp = io.BufferedRandom diff --git a/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst b/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst new file mode 100644 index 0000000000000..92e3b2399238e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst @@ -0,0 +1,2 @@ +Raise :exc:`io.UnsupportedOperation` in :meth:`io.BufferedReader.truncate` +when it is called on a read-only :class:`io.BufferedReader` instance. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 6f55577813c9f..a09082c84f8a2 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1315,15 +1315,19 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos) PyObject *res = NULL; CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "truncate of closed file") + if (!self->writable) { + return bufferediobase_unsupported("truncate"); + } if (!ENTER_BUFFERED(self)) return NULL; - if (self->writable) { - res = buffered_flush_and_rewind_unlocked(self); - if (res == NULL) - goto end; - Py_CLEAR(res); + res = buffered_flush_and_rewind_unlocked(self); + if (res == NULL) { + goto end; } + Py_CLEAR(res); + res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); if (res == NULL) goto end; From webhook-mailer at python.org Fri Feb 21 15:27:45 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Fri, 21 Feb 2020 20:27:45 -0000 Subject: [Python-checkins] bpo-39576: docs: set context for decimal arbitrary precision arithmetic (#18594) Message-ID: https://github.com/python/cpython/commit/a025d4ca99fb4c652465368e0b4eb03cf4b316b9 commit: a025d4ca99fb4c652465368e0b4eb03cf4b316b9 branch: master author: Stefan Krah committer: GitHub date: 2020-02-21T21:27:37+01:00 summary: bpo-39576: docs: set context for decimal arbitrary precision arithmetic (#18594) files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index bcae55eb82178..2a51429bdff5c 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2121,17 +2121,67 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic. +arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. However, to realize this performance gain, the -context needs to be set for unrounded calculations. +for very large numbers. - >>> c = getcontext() - >>> c.prec = MAX_PREC - >>> c.Emax = MAX_EMAX - >>> c.Emin = MIN_EMIN +The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` +and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` +should always be 0 (the default). Setting :attr:`prec` requires some care. -.. versionadded:: 3.3 \ No newline at end of file +The easiest approach for trying out bignum arithmetic is to use the maximum +value for :attr:`prec` as well [#]_:: + + >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) + >>> x = Decimal(2) ** 256 + >>> x / 128 + Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') + + +For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and +the available memory will be insufficient:: + + >>> Decimal(1) / 3 + Traceback (most recent call last): + File "", line 1, in + MemoryError + +On systems with overallocation (e.g. Linux), a more sophisticated approach is to +adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of +RAM and expect 10 simultaneous operands using a maximum of 500MB each:: + + >>> import sys + >>> + >>> # Maximum number of digits for a single operand using 500MB in 8 byte words + >>> # with 19 (9 for the 32-bit version) digits per word: + >>> maxdigits = 19 * ((500 * 1024**2) // 8) + >>> + >>> # Check that this works: + >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) + >>> c.traps[Inexact] = True + >>> setcontext(c) + >>> + >>> # Fill the available precision with nines: + >>> x = Decimal(0).logical_invert() * 9 + >>> sys.getsizeof(x) + 524288112 + >>> x + 2 + Traceback (most recent call last): + File "", line 1, in + decimal.Inexact: [] + +In general (and especially on systems without overallocation), it is recommended +to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations +are expected to be exact. + + +.. [#] + .. versionadded:: 3.3 + +.. [#] + .. versionchanged:: 3.9 + This approach now works for all exact results except for non-integer powers. + Also backported to 3.7 and 3.8. From webhook-mailer at python.org Fri Feb 21 15:36:06 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 20:36:06 -0000 Subject: [Python-checkins] bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-18594) (#18596) Message-ID: https://github.com/python/cpython/commit/00e45877e33d32bb61aa13a2033e3bba370bda4d commit: 00e45877e33d32bb61aa13a2033e3bba370bda4d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T21:36:02+01:00 summary: bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-18594) (#18596) (cherry picked from commit a025d4ca99fb4c652465368e0b4eb03cf4b316b9) Authored-by: Stefan Krah files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index bcae55eb82178..2a51429bdff5c 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2121,17 +2121,67 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic. +arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. However, to realize this performance gain, the -context needs to be set for unrounded calculations. +for very large numbers. - >>> c = getcontext() - >>> c.prec = MAX_PREC - >>> c.Emax = MAX_EMAX - >>> c.Emin = MIN_EMIN +The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` +and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` +should always be 0 (the default). Setting :attr:`prec` requires some care. -.. versionadded:: 3.3 \ No newline at end of file +The easiest approach for trying out bignum arithmetic is to use the maximum +value for :attr:`prec` as well [#]_:: + + >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) + >>> x = Decimal(2) ** 256 + >>> x / 128 + Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') + + +For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and +the available memory will be insufficient:: + + >>> Decimal(1) / 3 + Traceback (most recent call last): + File "", line 1, in + MemoryError + +On systems with overallocation (e.g. Linux), a more sophisticated approach is to +adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of +RAM and expect 10 simultaneous operands using a maximum of 500MB each:: + + >>> import sys + >>> + >>> # Maximum number of digits for a single operand using 500MB in 8 byte words + >>> # with 19 (9 for the 32-bit version) digits per word: + >>> maxdigits = 19 * ((500 * 1024**2) // 8) + >>> + >>> # Check that this works: + >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) + >>> c.traps[Inexact] = True + >>> setcontext(c) + >>> + >>> # Fill the available precision with nines: + >>> x = Decimal(0).logical_invert() * 9 + >>> sys.getsizeof(x) + 524288112 + >>> x + 2 + Traceback (most recent call last): + File "", line 1, in + decimal.Inexact: [] + +In general (and especially on systems without overallocation), it is recommended +to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations +are expected to be exact. + + +.. [#] + .. versionadded:: 3.3 + +.. [#] + .. versionchanged:: 3.9 + This approach now works for all exact results except for non-integer powers. + Also backported to 3.7 and 3.8. From webhook-mailer at python.org Fri Feb 21 15:36:47 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 21 Feb 2020 20:36:47 -0000 Subject: [Python-checkins] bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-18594) (#18597) Message-ID: https://github.com/python/cpython/commit/d6965ff026f35498e554bc964ef2be8f4d80eb7f commit: d6965ff026f35498e554bc964ef2be8f4d80eb7f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-21T21:36:42+01:00 summary: bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-18594) (#18597) (cherry picked from commit a025d4ca99fb4c652465368e0b4eb03cf4b316b9) Authored-by: Stefan Krah files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index bcae55eb82178..2a51429bdff5c 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2121,17 +2121,67 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic. +arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. However, to realize this performance gain, the -context needs to be set for unrounded calculations. +for very large numbers. - >>> c = getcontext() - >>> c.prec = MAX_PREC - >>> c.Emax = MAX_EMAX - >>> c.Emin = MIN_EMIN +The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` +and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` +should always be 0 (the default). Setting :attr:`prec` requires some care. -.. versionadded:: 3.3 \ No newline at end of file +The easiest approach for trying out bignum arithmetic is to use the maximum +value for :attr:`prec` as well [#]_:: + + >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) + >>> x = Decimal(2) ** 256 + >>> x / 128 + Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') + + +For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and +the available memory will be insufficient:: + + >>> Decimal(1) / 3 + Traceback (most recent call last): + File "", line 1, in + MemoryError + +On systems with overallocation (e.g. Linux), a more sophisticated approach is to +adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of +RAM and expect 10 simultaneous operands using a maximum of 500MB each:: + + >>> import sys + >>> + >>> # Maximum number of digits for a single operand using 500MB in 8 byte words + >>> # with 19 (9 for the 32-bit version) digits per word: + >>> maxdigits = 19 * ((500 * 1024**2) // 8) + >>> + >>> # Check that this works: + >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) + >>> c.traps[Inexact] = True + >>> setcontext(c) + >>> + >>> # Fill the available precision with nines: + >>> x = Decimal(0).logical_invert() * 9 + >>> sys.getsizeof(x) + 524288112 + >>> x + 2 + Traceback (most recent call last): + File "", line 1, in + decimal.Inexact: [] + +In general (and especially on systems without overallocation), it is recommended +to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations +are expected to be exact. + + +.. [#] + .. versionadded:: 3.3 + +.. [#] + .. versionchanged:: 3.9 + This approach now works for all exact results except for non-integer powers. + Also backported to 3.7 and 3.8. From webhook-mailer at python.org Sat Feb 22 08:11:56 2020 From: webhook-mailer at python.org (Yonatan Goldschmidt) Date: Sat, 22 Feb 2020 13:11:56 -0000 Subject: [Python-checkins] bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Message-ID: https://github.com/python/cpython/commit/1c56f8ffad44478b4214a2bf8eb7cf51c28a347a commit: 1c56f8ffad44478b4214a2bf8eb7cf51c28a347a branch: master author: Yonatan Goldschmidt committer: GitHub date: 2020-02-22T15:11:48+02:00 summary: bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Hold reference of __bases__ tuple until tuple item is done with, because by dropping the reference the item may be destroyed. files: A Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst M Lib/test/test_isinstance.py M Misc/ACKS M Objects/abstract.c diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 65751ab916855..53639e984e48a 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -251,6 +251,27 @@ def test_isinstance_recursion_limit(self): # blown self.assertRaises(RecursionError, blowstack, isinstance, '', str) + def test_issubclass_refcount_handling(self): + # bpo-39382: abstract_issubclass() didn't hold item reference while + # peeking in the bases tuple, in the single inheritance case. + class A: + @property + def __bases__(self): + return (int, ) + + class B: + def __init__(self): + # setting this here increases the chances of exhibiting the bug, + # probably due to memory layout changes. + self.x = 1 + + @property + def __bases__(self): + return (A(), ) + + self.assertEqual(True, issubclass(B(), int)) + + def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. diff --git a/Misc/ACKS b/Misc/ACKS index f329a2d4a7d33..fe24a5636ccc2 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -594,6 +594,7 @@ Karan Goel Jeroen Van Goey Christoph Gohlke Tim Golden +Yonatan Goldschmidt Mark Gollahon Guilherme Gon?alves Tiago Gon?alves diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst new file mode 100644 index 0000000000000..605f4c8e5dfd1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst @@ -0,0 +1,3 @@ +Fix a use-after-free in the single inheritance path of ``issubclass()``, when +the ``__bases__`` of an object has a single reference, and so does its first item. +Patch by Yonatan Goldschmidt. diff --git a/Objects/abstract.c b/Objects/abstract.c index f0e01f7691bb3..de5652f3e685f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2379,9 +2379,16 @@ abstract_issubclass(PyObject *derived, PyObject *cls) int r = 0; while (1) { - if (derived == cls) + if (derived == cls) { + Py_XDECREF(bases); /* See below comment */ return 1; - bases = abstract_get_bases(derived); + } + /* Use XSETREF to drop bases reference *after* finishing with + derived; bases might be the only reference to it. + XSETREF is used instead of SETREF, because bases is NULL on the + first iteration of the loop. + */ + Py_XSETREF(bases, abstract_get_bases(derived)); if (bases == NULL) { if (PyErr_Occurred()) return -1; @@ -2395,7 +2402,6 @@ abstract_issubclass(PyObject *derived, PyObject *cls) /* Avoid recursivity in the single inheritance case */ if (n == 1) { derived = PyTuple_GET_ITEM(bases, 0); - Py_DECREF(bases); continue; } for (i = 0; i < n; i++) { From webhook-mailer at python.org Sat Feb 22 08:32:40 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 22 Feb 2020 13:32:40 -0000 Subject: [Python-checkins] bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Message-ID: https://github.com/python/cpython/commit/43a0137c87b997c6ba8b23cc3281ce2de18f008a commit: 43a0137c87b997c6ba8b23cc3281ce2de18f008a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-22T05:32:36-08:00 summary: bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Hold reference of __bases__ tuple until tuple item is done with, because by dropping the reference the item may be destroyed. (cherry picked from commit 1c56f8ffad44478b4214a2bf8eb7cf51c28a347a) Co-authored-by: Yonatan Goldschmidt files: A Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst M Lib/test/test_isinstance.py M Misc/ACKS M Objects/abstract.c diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 65751ab916855..53639e984e48a 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -251,6 +251,27 @@ def test_isinstance_recursion_limit(self): # blown self.assertRaises(RecursionError, blowstack, isinstance, '', str) + def test_issubclass_refcount_handling(self): + # bpo-39382: abstract_issubclass() didn't hold item reference while + # peeking in the bases tuple, in the single inheritance case. + class A: + @property + def __bases__(self): + return (int, ) + + class B: + def __init__(self): + # setting this here increases the chances of exhibiting the bug, + # probably due to memory layout changes. + self.x = 1 + + @property + def __bases__(self): + return (A(), ) + + self.assertEqual(True, issubclass(B(), int)) + + def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. diff --git a/Misc/ACKS b/Misc/ACKS index 613763195b687..2107435cf093b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -568,6 +568,7 @@ Karan Goel Jeroen Van Goey Christoph Gohlke Tim Golden +Yonatan Goldschmidt Mark Gollahon Guilherme Gon?alves Tiago Gon?alves diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst new file mode 100644 index 0000000000000..605f4c8e5dfd1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst @@ -0,0 +1,3 @@ +Fix a use-after-free in the single inheritance path of ``issubclass()``, when +the ``__bases__`` of an object has a single reference, and so does its first item. +Patch by Yonatan Goldschmidt. diff --git a/Objects/abstract.c b/Objects/abstract.c index 9416df4321f3f..e6831feb82433 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2287,9 +2287,16 @@ abstract_issubclass(PyObject *derived, PyObject *cls) int r = 0; while (1) { - if (derived == cls) + if (derived == cls) { + Py_XDECREF(bases); /* See below comment */ return 1; - bases = abstract_get_bases(derived); + } + /* Use XSETREF to drop bases reference *after* finishing with + derived; bases might be the only reference to it. + XSETREF is used instead of SETREF, because bases is NULL on the + first iteration of the loop. + */ + Py_XSETREF(bases, abstract_get_bases(derived)); if (bases == NULL) { if (PyErr_Occurred()) return -1; @@ -2303,7 +2310,6 @@ abstract_issubclass(PyObject *derived, PyObject *cls) /* Avoid recursivity in the single inheritance case */ if (n == 1) { derived = PyTuple_GET_ITEM(bases, 0); - Py_DECREF(bases); continue; } for (i = 0; i < n; i++) { From webhook-mailer at python.org Sat Feb 22 08:34:10 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 22 Feb 2020 13:34:10 -0000 Subject: [Python-checkins] bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Message-ID: https://github.com/python/cpython/commit/0c1827e70c1c05ce1982a34380cea7d391904293 commit: 0c1827e70c1c05ce1982a34380cea7d391904293 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-22T05:34:06-08:00 summary: bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530) Hold reference of __bases__ tuple until tuple item is done with, because by dropping the reference the item may be destroyed. (cherry picked from commit 1c56f8ffad44478b4214a2bf8eb7cf51c28a347a) Co-authored-by: Yonatan Goldschmidt files: A Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst M Lib/test/test_isinstance.py M Misc/ACKS M Objects/abstract.c diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 65751ab916855..53639e984e48a 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -251,6 +251,27 @@ def test_isinstance_recursion_limit(self): # blown self.assertRaises(RecursionError, blowstack, isinstance, '', str) + def test_issubclass_refcount_handling(self): + # bpo-39382: abstract_issubclass() didn't hold item reference while + # peeking in the bases tuple, in the single inheritance case. + class A: + @property + def __bases__(self): + return (int, ) + + class B: + def __init__(self): + # setting this here increases the chances of exhibiting the bug, + # probably due to memory layout changes. + self.x = 1 + + @property + def __bases__(self): + return (A(), ) + + self.assertEqual(True, issubclass(B(), int)) + + def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. diff --git a/Misc/ACKS b/Misc/ACKS index 69ed251b988db..8fd4df5bf3f19 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -584,6 +584,7 @@ Karan Goel Jeroen Van Goey Christoph Gohlke Tim Golden +Yonatan Goldschmidt Mark Gollahon Guilherme Gon?alves Tiago Gon?alves diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst new file mode 100644 index 0000000000000..605f4c8e5dfd1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst @@ -0,0 +1,3 @@ +Fix a use-after-free in the single inheritance path of ``issubclass()``, when +the ``__bases__`` of an object has a single reference, and so does its first item. +Patch by Yonatan Goldschmidt. diff --git a/Objects/abstract.c b/Objects/abstract.c index 77d09143aa076..bc1ebd930c016 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2336,9 +2336,16 @@ abstract_issubclass(PyObject *derived, PyObject *cls) int r = 0; while (1) { - if (derived == cls) + if (derived == cls) { + Py_XDECREF(bases); /* See below comment */ return 1; - bases = abstract_get_bases(derived); + } + /* Use XSETREF to drop bases reference *after* finishing with + derived; bases might be the only reference to it. + XSETREF is used instead of SETREF, because bases is NULL on the + first iteration of the loop. + */ + Py_XSETREF(bases, abstract_get_bases(derived)); if (bases == NULL) { if (PyErr_Occurred()) return -1; @@ -2352,7 +2359,6 @@ abstract_issubclass(PyObject *derived, PyObject *cls) /* Avoid recursivity in the single inheritance case */ if (n == 1) { derived = PyTuple_GET_ITEM(bases, 0); - Py_DECREF(bases); continue; } for (i = 0; i < n; i++) { From webhook-mailer at python.org Sat Feb 22 12:56:06 2020 From: webhook-mailer at python.org (ananthan-123) Date: Sat, 22 Feb 2020 17:56:06 -0000 Subject: [Python-checkins] bpo-17422: Language reference should specify restrictions on class namespace (#18559) Message-ID: https://github.com/python/cpython/commit/fbe2e0bb8a7ee75d0f9d57682436dac7d69e202e commit: fbe2e0bb8a7ee75d0f9d57682436dac7d69e202e branch: master author: ananthan-123 committer: GitHub date: 2020-02-22T09:56:01-08:00 summary: bpo-17422: Language reference should specify restrictions on class namespace (#18559) The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. files: A Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 9520f824287f6..5b3b669c5eb91 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1946,10 +1946,12 @@ Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). The -``__prepare__`` method should be implemented as a :func:`classmethod`. +``__prepare__`` method should be implemented as a :func:`classmethod`. The +namespace returned by ``__prepare__`` is passed in to ``__new__``, but when +the final class object is created the namespace is copied into a new ``dict``. If the metaclass has no ``__prepare__`` attribute, then the class namespace -is initialised as an empty ordered mapping. +is initialised as an empty :func:`dict`. .. seealso:: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst new file mode 100644 index 0000000000000..f071d286176ae --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst @@ -0,0 +1 @@ +The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. From webhook-mailer at python.org Sat Feb 22 16:16:29 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 22 Feb 2020 21:16:29 -0000 Subject: [Python-checkins] bpo-17422: Language reference should specify restrictions on class namespace (GH-18559) Message-ID: https://github.com/python/cpython/commit/91ba44623e5cb8f4a7b0d3fc1fab8ff8d8a849c2 commit: 91ba44623e5cb8f4a7b0d3fc1fab8ff8d8a849c2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-22T13:16:17-08:00 summary: bpo-17422: Language reference should specify restrictions on class namespace (GH-18559) The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. (cherry picked from commit fbe2e0bb8a7ee75d0f9d57682436dac7d69e202e) Co-authored-by: ananthan-123 files: A Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 7b3bf0d2f5f36..06f4992cf544a 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1946,10 +1946,12 @@ Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). The -``__prepare__`` method should be implemented as a :func:`classmethod`. +``__prepare__`` method should be implemented as a :func:`classmethod`. The +namespace returned by ``__prepare__`` is passed in to ``__new__``, but when +the final class object is created the namespace is copied into a new ``dict``. If the metaclass has no ``__prepare__`` attribute, then the class namespace -is initialised as an empty ordered mapping. +is initialised as an empty :func:`dict`. .. seealso:: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst new file mode 100644 index 0000000000000..f071d286176ae --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst @@ -0,0 +1 @@ +The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. From webhook-mailer at python.org Sat Feb 22 16:16:47 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 22 Feb 2020 21:16:47 -0000 Subject: [Python-checkins] bpo-17422: Language reference should specify restrictions on class namespace (GH-18559) Message-ID: https://github.com/python/cpython/commit/36a120d343c1cb69b8d02913569c153e8bb969c8 commit: 36a120d343c1cb69b8d02913569c153e8bb969c8 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-22T13:16:43-08:00 summary: bpo-17422: Language reference should specify restrictions on class namespace (GH-18559) The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. (cherry picked from commit fbe2e0bb8a7ee75d0f9d57682436dac7d69e202e) Co-authored-by: ananthan-123 files: A Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index d25357db43468..b682465d3ddc8 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1932,10 +1932,12 @@ Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). The -``__prepare__`` method should be implemented as a :func:`classmethod`. +``__prepare__`` method should be implemented as a :func:`classmethod`. The +namespace returned by ``__prepare__`` is passed in to ``__new__``, but when +the final class object is created the namespace is copied into a new ``dict``. If the metaclass has no ``__prepare__`` attribute, then the class namespace -is initialised as an empty ordered mapping. +is initialised as an empty :func:`dict`. .. seealso:: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst new file mode 100644 index 0000000000000..f071d286176ae --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst @@ -0,0 +1 @@ +The language reference now specifies restrictions on class namespaces. Adapted from a patch by Ethan Furman. From webhook-mailer at python.org Sun Feb 23 06:21:43 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 23 Feb 2020 11:21:43 -0000 Subject: [Python-checkins] bpo-39648: Expand math.gcd() and math.lcm() to handle multiple arguments. (GH-18604) Message-ID: https://github.com/python/cpython/commit/559e7f165ad03731e6bc2211c0e6d8d9c02fb549 commit: 559e7f165ad03731e6bc2211c0e6d8d9c02fb549 branch: master author: Serhiy Storchaka committer: GitHub date: 2020-02-23T11:21:29Z summary: bpo-39648: Expand math.gcd() and math.lcm() to handle multiple arguments. (GH-18604) * bpo-39648: Expand math.gcd() and math.lcm() to handle multiple arguments. * Simplify fast path. * Difine lcm() without arguments returning 1. * Apply suggestions from code review Co-Authored-By: Mark Dickinson Co-authored-by: Mark Dickinson files: A Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst M Doc/library/math.rst M Doc/whatsnew/3.9.rst M Lib/test/test_math.py M Modules/clinic/mathmodule.c.h M Modules/mathmodule.c diff --git a/Doc/library/math.rst b/Doc/library/math.rst index d8ac35256d1b4..6ec1feee35a6d 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -126,23 +126,19 @@ Number-theoretic and representation functions `_\. -.. function:: gcd(a, b) +.. function:: gcd(*integers) - Return the greatest common divisor of the integers *a* and *b*. If either - *a* or *b* is nonzero, then the value of ``gcd(a, b)`` is the largest - positive integer that divides both *a* and *b*. ``gcd(0, 0)`` returns - ``0``. + Return the greatest common divisor of the specified integer arguments. + If any of the arguments is nonzero, then the returned value is the largest + positive integer that is a divisor af all arguments. If all arguments + are zero, then the returned value is ``0``. ``gcd()`` without arguments + returns ``0``. .. versionadded:: 3.5 - -.. function:: lcm(a, b) - - Return the least common multiple of integers *a* and *b*. The value of - ``lcm(a, b)`` is the smallest nonnegative integer that is a multiple of - both *a* and *b*. If either *a* or *b* is zero then ``lcm(a, b)`` is zero. - - .. versionadded:: 3.9 + .. versionchanged:: 3.9 + Added support for an arbitrary number of arguments. Formerly, only two + arguments were supported. .. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) @@ -210,6 +206,17 @@ Number-theoretic and representation functions .. versionadded:: 3.8 +.. function:: lcm(*integers) + + Return the least common multiple of the specified integer arguments. + If all arguments are nonzero, then the returned value is the smallest + positive integer that is a multiple of all arguments. If any of the arguments + is zero, then the returned value is ``0``. ``lcm()`` without arguments + returns ``1``. + + .. versionadded:: 3.9 + + .. function:: ldexp(x, i) Return ``x * (2**i)``. This is essentially the inverse of function diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 161675d32f670..a0ae4eb9b825a 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -216,8 +216,13 @@ import attempts. math ---- -Add :func:`math.lcm`: return the least common multiple of *a* and *b*. -(Contributed by Ananthakrishnan in :issue:`39479`.) +Expanded the :func:`math.gcd` function to handle multiple arguments. +Formerly, it only supported two arguments. +(Contributed by Serhiy Storchaka in :issue:`39648`.) + +Add :func:`math.lcm`: return the least common multiple of specified arguments. +(Contributed by Mark Dickinson, Ananthakrishnan and Serhiy Storchaka in +:issue:`39479` and :issue:`39648`.) Add :func:`math.nextafter`: return the next floating-point value after *x* towards *y*. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index ad8273d50cc39..cc39402b3c60b 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -705,33 +705,32 @@ def testGcd(self): self.assertEqual(gcd(84, -120), 12) self.assertEqual(gcd(1216342683557601535506311712, 436522681849110124616458784), 32) - c = 652560 + x = 434610456570399902378880679233098819019853229470286994367836600566 y = 1064502245825115327754847244914921553977 - a = x * c - b = y * c - self.assertEqual(gcd(a, b), c) - self.assertEqual(gcd(b, a), c) - self.assertEqual(gcd(-a, b), c) - self.assertEqual(gcd(b, -a), c) - self.assertEqual(gcd(a, -b), c) - self.assertEqual(gcd(-b, a), c) - self.assertEqual(gcd(-a, -b), c) - self.assertEqual(gcd(-b, -a), c) - c = 576559230871654959816130551884856912003141446781646602790216406874 - a = x * c - b = y * c - self.assertEqual(gcd(a, b), c) - self.assertEqual(gcd(b, a), c) - self.assertEqual(gcd(-a, b), c) - self.assertEqual(gcd(b, -a), c) - self.assertEqual(gcd(a, -b), c) - self.assertEqual(gcd(-b, a), c) - self.assertEqual(gcd(-a, -b), c) - self.assertEqual(gcd(-b, -a), c) - + for c in (652560, + 576559230871654959816130551884856912003141446781646602790216406874): + a = x * c + b = y * c + self.assertEqual(gcd(a, b), c) + self.assertEqual(gcd(b, a), c) + self.assertEqual(gcd(-a, b), c) + self.assertEqual(gcd(b, -a), c) + self.assertEqual(gcd(a, -b), c) + self.assertEqual(gcd(-b, a), c) + self.assertEqual(gcd(-a, -b), c) + self.assertEqual(gcd(-b, -a), c) + + self.assertEqual(gcd(), 0) + self.assertEqual(gcd(120), 120) + self.assertEqual(gcd(-120), 120) + self.assertEqual(gcd(120, 84, 102), 6) + self.assertEqual(gcd(120, 1, 84), 1) + + self.assertRaises(TypeError, gcd, 120.0) self.assertRaises(TypeError, gcd, 120.0, 84) self.assertRaises(TypeError, gcd, 120, 84.0) + self.assertRaises(TypeError, gcd, 120, 1, 84.0) self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12) def testHypot(self): @@ -989,9 +988,9 @@ def test_lcm(self): self.assertEqual(lcm(1216342683557601535506311712, 436522681849110124616458784), 16592536571065866494401400422922201534178938447014944) + x = 43461045657039990237 y = 10645022458251153277 - for c in (652560, 57655923087165495981): a = x * c @@ -1005,9 +1004,18 @@ def test_lcm(self): self.assertEqual(lcm(-b, a), d) self.assertEqual(lcm(-a, -b), d) self.assertEqual(lcm(-b, -a), d) - self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) + + self.assertEqual(lcm(), 1) + self.assertEqual(lcm(120), 120) + self.assertEqual(lcm(-120), 120) + self.assertEqual(lcm(120, 84, 102), 14280) + self.assertEqual(lcm(120, 0, 84), 0) + + self.assertRaises(TypeError, lcm, 120.0) self.assertRaises(TypeError, lcm, 120.0, 84) self.assertRaises(TypeError, lcm, 120, 84.0) + self.assertRaises(TypeError, lcm, 120, 0, 84.0) + self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) def testLdexp(self): self.assertRaises(TypeError, math.ldexp) diff --git a/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst b/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst new file mode 100644 index 0000000000000..f205911ad9bfd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst @@ -0,0 +1 @@ +Expanded :func:`math.gcd` and :func:`math.lcm` to handle multiple arguments. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index df45a1a0c5e85..65f3dd4f520ae 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -2,36 +2,6 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(math_gcd__doc__, -"gcd($module, x, y, /)\n" -"--\n" -"\n" -"greatest common divisor of x and y"); - -#define MATH_GCD_METHODDEF \ - {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd__doc__}, - -static PyObject * -math_gcd_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -math_gcd(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - - if (!_PyArg_CheckPositional("gcd", nargs, 2, 2)) { - goto exit; - } - a = args[0]; - b = args[1]; - return_value = math_gcd_impl(module, a, b); - -exit: - return return_value; -} - PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" "--\n" @@ -85,36 +55,6 @@ PyDoc_STRVAR(math_factorial__doc__, #define MATH_FACTORIAL_METHODDEF \ {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__}, -PyDoc_STRVAR(math_lcm__doc__, -"lcm($module, x, y, /)\n" -"--\n" -"\n" -"least common multiple of x and y"); - -#define MATH_LCM_METHODDEF \ - {"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm__doc__}, - -static PyObject * -math_lcm_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -math_lcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - - if (!_PyArg_CheckPositional("lcm", nargs, 2, 2)) { - goto exit; - } - a = args[0]; - b = args[1]; - return_value = math_lcm_impl(module, a, b); - -exit: - return return_value; -} - PyDoc_STRVAR(math_trunc__doc__, "trunc($module, x, /)\n" "--\n" @@ -925,4 +865,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=f8daa185c043a7b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1eae2b3ef19568fa input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index f74b7e1a34203..77e325cf0c63d 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -826,37 +826,125 @@ m_log10(double x) } -/*[clinic input] -math.gcd +static PyObject * +math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs) +{ + PyObject *res, *x; + Py_ssize_t i; - x as a: object - y as b: object - / + if (nargs == 0) { + return PyLong_FromLong(0); + } + res = PyNumber_Index(args[0]); + if (res == NULL) { + return NULL; + } + if (nargs == 1) { + Py_SETREF(res, PyNumber_Absolute(res)); + return res; + } + for (i = 1; i < nargs; i++) { + x = PyNumber_Index(args[i]); + if (x == NULL) { + Py_DECREF(res); + return NULL; + } + if (res == _PyLong_One) { + /* Fast path: just check arguments. + It is okay to use identity comparison here. */ + Py_DECREF(x); + continue; + } + Py_SETREF(res, _PyLong_GCD(res, x)); + Py_DECREF(x); + if (res == NULL) { + return NULL; + } + } + return res; +} + +PyDoc_STRVAR(math_gcd_doc, +"gcd($module, *integers)\n" +"--\n" +"\n" +"Greatest Common Divisor."); -greatest common divisor of x and y -[clinic start generated code]*/ static PyObject * -math_gcd_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=7b2e0c151bd7a5d8 input=c2691e57fb2a98fa]*/ +long_lcm(PyObject *a, PyObject *b) { - PyObject *g; + PyObject *g, *m, *f, *ab; - a = PyNumber_Index(a); - if (a == NULL) + if (Py_SIZE(a) == 0 || Py_SIZE(b) == 0) { + return PyLong_FromLong(0); + } + g = _PyLong_GCD(a, b); + if (g == NULL) { return NULL; - b = PyNumber_Index(b); - if (b == NULL) { - Py_DECREF(a); + } + f = PyNumber_FloorDivide(a, g); + Py_DECREF(g); + if (f == NULL) { return NULL; } - g = _PyLong_GCD(a, b); - Py_DECREF(a); - Py_DECREF(b); - return g; + m = PyNumber_Multiply(f, b); + Py_DECREF(f); + if (m == NULL) { + return NULL; + } + ab = PyNumber_Absolute(m); + Py_DECREF(m); + return ab; } +static PyObject * +math_lcm(PyObject *module, PyObject * const *args, Py_ssize_t nargs) +{ + PyObject *res, *x; + Py_ssize_t i; + + if (nargs == 0) { + return PyLong_FromLong(1); + } + res = PyNumber_Index(args[0]); + if (res == NULL) { + return NULL; + } + if (nargs == 1) { + Py_SETREF(res, PyNumber_Absolute(res)); + return res; + } + for (i = 1; i < nargs; i++) { + x = PyNumber_Index(args[i]); + if (x == NULL) { + Py_DECREF(res); + return NULL; + } + if (res == _PyLong_Zero) { + /* Fast path: just check arguments. + It is okay to use identity comparison here. */ + Py_DECREF(x); + continue; + } + Py_SETREF(res, long_lcm(res, x)); + Py_DECREF(x); + if (res == NULL) { + return NULL; + } + } + return res; +} + + +PyDoc_STRVAR(math_lcm_doc, +"lcm($module, *integers)\n" +"--\n" +"\n" +"Least Common Multiple."); + + /* Call is_error when errno != 0, and where x is the result libm * returned. is_error will usually set up an exception and return * true (1), but may return false (0) without setting up an exception. @@ -2017,59 +2105,6 @@ math_factorial(PyObject *module, PyObject *arg) } -/*[clinic input] -math.lcm - x as a: object - y as b: object - / -least common multiple of x and y -[clinic start generated code]*/ - -static PyObject * -math_lcm_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=6f83fb6d671074ba input=efb3d7b7334b7118]*/ -{ - PyObject *g, *m, *f, *ab; - - a = PyNumber_Index(a); - if (a == NULL) { - return NULL; - } - b = PyNumber_Index(b); - if (b == NULL) { - Py_DECREF(a); - return NULL; - } - if (_PyLong_Sign(a) == 0 || _PyLong_Sign(b) == 0) { - Py_DECREF(a); - Py_DECREF(b); - return PyLong_FromLong(0); - } - g = _PyLong_GCD(a, b); - if (g == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - f = PyNumber_FloorDivide(a, g); - Py_DECREF(g); - Py_DECREF(a); - if (f == NULL) { - Py_DECREF(b); - return NULL; - } - m = PyNumber_Multiply(f, b); - Py_DECREF(f); - Py_DECREF(b); - if (m == NULL) { - return NULL; - } - ab = PyNumber_Absolute(m); - Py_DECREF(m); - return ab; -} - - /*[clinic input] math.trunc @@ -3408,14 +3443,14 @@ static PyMethodDef math_methods[] = { MATH_FREXP_METHODDEF MATH_FSUM_METHODDEF {"gamma", math_gamma, METH_O, math_gamma_doc}, - MATH_GCD_METHODDEF + {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd_doc}, {"hypot", (PyCFunction)(void(*)(void))math_hypot, METH_FASTCALL, math_hypot_doc}, MATH_ISCLOSE_METHODDEF MATH_ISFINITE_METHODDEF MATH_ISINF_METHODDEF MATH_ISNAN_METHODDEF MATH_ISQRT_METHODDEF - MATH_LCM_METHODDEF + {"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm_doc}, MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, MATH_LOG_METHODDEF From webhook-mailer at python.org Sun Feb 23 08:36:58 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sun, 23 Feb 2020 13:36:58 -0000 Subject: [Python-checkins] bpo-39576: Clarify the word size for the 32-bit build. (#18616) Message-ID: https://github.com/python/cpython/commit/b76518d43fb82ed9e5d27025d18c90a23d525c90 commit: b76518d43fb82ed9e5d27025d18c90a23d525c90 branch: master author: Stefan Krah committer: GitHub date: 2020-02-23T14:36:54+01:00 summary: bpo-39576: Clarify the word size for the 32-bit build. (#18616) files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 2a51429bdff5c..4e640cc695990 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2155,8 +2155,8 @@ RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys >>> - >>> # Maximum number of digits for a single operand using 500MB in 8 byte words - >>> # with 19 (9 for the 32-bit version) digits per word: + >>> # Maximum number of digits for a single operand using 500MB in 8-byte words + >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): >>> maxdigits = 19 * ((500 * 1024**2) // 8) >>> >>> # Check that this works: From webhook-mailer at python.org Sun Feb 23 08:43:05 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 23 Feb 2020 13:43:05 -0000 Subject: [Python-checkins] bpo-39576: Clarify the word size for the 32-bit build. (GH-18616) (#18617) Message-ID: https://github.com/python/cpython/commit/24c570bbb82a7cb70576c253a73390accfa7ed78 commit: 24c570bbb82a7cb70576c253a73390accfa7ed78 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T14:42:57+01:00 summary: bpo-39576: Clarify the word size for the 32-bit build. (GH-18616) (#18617) (cherry picked from commit b76518d43fb82ed9e5d27025d18c90a23d525c90) Authored-by: Stefan Krah files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 2a51429bdff5c..4e640cc695990 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2155,8 +2155,8 @@ RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys >>> - >>> # Maximum number of digits for a single operand using 500MB in 8 byte words - >>> # with 19 (9 for the 32-bit version) digits per word: + >>> # Maximum number of digits for a single operand using 500MB in 8-byte words + >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): >>> maxdigits = 19 * ((500 * 1024**2) // 8) >>> >>> # Check that this works: From webhook-mailer at python.org Sun Feb 23 08:44:33 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 23 Feb 2020 13:44:33 -0000 Subject: [Python-checkins] bpo-39576: Clarify the word size for the 32-bit build. (GH-18616) (#18618) Message-ID: https://github.com/python/cpython/commit/c6ecd9c14081a787959e13df33e250102a658154 commit: c6ecd9c14081a787959e13df33e250102a658154 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T14:44:28+01:00 summary: bpo-39576: Clarify the word size for the 32-bit build. (GH-18616) (#18618) (cherry picked from commit b76518d43fb82ed9e5d27025d18c90a23d525c90) Authored-by: Stefan Krah files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 2a51429bdff5c..4e640cc695990 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2155,8 +2155,8 @@ RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys >>> - >>> # Maximum number of digits for a single operand using 500MB in 8 byte words - >>> # with 19 (9 for the 32-bit version) digits per word: + >>> # Maximum number of digits for a single operand using 500MB in 8-byte words + >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): >>> maxdigits = 19 * ((500 * 1024**2) // 8) >>> >>> # Check that this works: From webhook-mailer at python.org Sun Feb 23 15:48:41 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Sun, 23 Feb 2020 20:48:41 -0000 Subject: [Python-checkins] [3.8] bpo-39427: Document -X opt options in the CLI --help and the man page (GH-18131) (GH-18133) Message-ID: https://github.com/python/cpython/commit/13951c7f25c628ea2dc0a869ebe18e7bf593fa6d commit: 13951c7f25c628ea2dc0a869ebe18e7bf593fa6d branch: 3.8 author: Pablo Galindo committer: GitHub date: 2020-02-23T20:48:27Z summary: [3.8] bpo-39427: Document -X opt options in the CLI --help and the man page (GH-18131) (GH-18133) https://bugs.python.org/issue39427 Automerge-Triggered-By: @pablogsal (cherry picked from commit 41f0ef6abbd304409c55612a08788cdd59fbc8a3) Co-authored-by: Pablo Galindo files: A Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst M Misc/python.man M Python/initconfig.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst new file mode 100644 index 0000000000000..a3915a4d81c79 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst @@ -0,0 +1,2 @@ +Document all possibilities for the ``-X`` options in the command line help +section. Patch by Pablo Galindo. diff --git a/Misc/python.man b/Misc/python.man index 3aa9f1f9c7eac..3645b0206eb2b 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -273,7 +273,45 @@ field matches the line number, where zero matches all line numbers and is thus equivalent to an omitted line number. .TP .BI "\-X " option -Set implementation specific option. +Set implementation specific option. The following options are available: + + -X faulthandler: enable faulthandler + + -X showrefcount: output the total reference count and number of used + memory blocks when the program finishes or after each statement in the + interactive interpreter. This only works on debug builds + + -X tracemalloc: start tracing Python memory allocations using the + tracemalloc module. By default, only the most recent frame is stored in a + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a + traceback limit of NFRAME frames + + -X showalloccount: output the total count of allocated objects for each + type when the program finishes. This only works when Python was built with + COUNT_ALLOCS defined + + -X importtime: show how long each import takes. It shows module name, + cumulative time (including nested imports) and self time (excluding + nested imports). Note that its output may be broken in multi-threaded + application. Typical usage is python3 -X importtime -c 'import asyncio' + + -X dev: enable CPython?s ?development mode?, introducing additional runtime + checks which are too expensive to be enabled by default. It will not be + more verbose than the default if the code is correct: new warnings are + only emitted when an issue is detected. Effect of the developer mode: + * Add default warning filter, as -W default + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function + * Enable the faulthandler module to dump the Python traceback on a crash + * Enable asyncio debug mode + * Set the dev_mode attribute of sys.flags to True + * io.IOBase destructor logs close() exceptions + + -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would + otherwise activate automatically). See PYTHONUTF8 for more details + + -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the + given directory instead of to the code tree. .TP .B \-x Skip the first line of the source. This is intended for a DOS diff --git a/Python/initconfig.c b/Python/initconfig.c index a30fdd1bab954..a0b2691bcd75c 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -63,7 +63,38 @@ static const char usage_3[] = "\ -W arg : warning control; arg is action:message:category:module:lineno\n\ also PYTHONWARNINGS=arg\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ --X opt : set implementation-specific option\n\ +-X opt : set implementation-specific option. The following options are available:\n\ +\n\ + -X faulthandler: enable faulthandler\n\ + -X showrefcount: output the total reference count and number of used\n\ + memory blocks when the program finishes or after each statement in the\n\ + interactive interpreter. This only works on debug builds\n\ + -X tracemalloc: start tracing Python memory allocations using the\n\ + tracemalloc module. By default, only the most recent frame is stored in a\n\ + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ + traceback limit of NFRAME frames\n\ + -X showalloccount: output the total count of allocated objects for each\n\ + type when the program finishes. This only works when Python was built with\n\ + COUNT_ALLOCS defined\n\ + -X importtime: show how long each import takes. It shows module name,\n\ + cumulative time (including nested imports) and self time (excluding\n\ + nested imports). Note that its output may be broken in multi-threaded\n\ + application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ + -X dev: enable CPython?s ?development mode?, introducing additional runtime\n\ + checks which are too expensive to be enabled by default. Effect of the\n\ + developer mode:\n\ + * Add default warning filter, as -W default\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ + * Enable the faulthandler module to dump the Python traceback on a crash\n\ + * Enable asyncio debug mode\n\ + * Set the dev_mode attribute of sys.flags to True\n\ + * io.IOBase destructor logs close() exceptions\n\ + -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ + otherwise activate automatically)\n\ + -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ + given directory instead of to the code tree\n\ +\n\ --check-hash-based-pycs always|default|never:\n\ control how Python invalidates hash-based .pyc files\n\ "; From webhook-mailer at python.org Sun Feb 23 15:48:41 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Sun, 23 Feb 2020 20:48:41 -0000 Subject: [Python-checkins] [3.7] bpo-39427: Document -X opt options in the CLI --help and the man page (GH-18131) (#18134) Message-ID: https://github.com/python/cpython/commit/333b9899fc7807575d1742b77b4633ac53bd528f commit: 333b9899fc7807575d1742b77b4633ac53bd528f branch: 3.7 author: Pablo Galindo committer: GitHub date: 2020-02-23T20:48:30Z summary: [3.7] bpo-39427: Document -X opt options in the CLI --help and the man page (GH-18131) (#18134) https://bugs.python.org/issue39427 Automerge-Triggered-By: @pablogsal. (cherry picked from commit 41f0ef6abbd304409c55612a08788cdd59fbc8a3) Co-authored-by: Pablo Galindo files: A Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst M Misc/python.man M Modules/main.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst new file mode 100644 index 0000000000000..a3915a4d81c79 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst @@ -0,0 +1,2 @@ +Document all possibilities for the ``-X`` options in the command line help +section. Patch by Pablo Galindo. diff --git a/Misc/python.man b/Misc/python.man index 8d5ad8cd6ca87..67a5bb4cf849d 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -273,7 +273,42 @@ field matches the line number, where zero matches all line numbers and is thus equivalent to an omitted line number. .TP .BI "\-X " option -Set implementation specific option. +Set implementation specific option. The following options are available: + + -X faulthandler: enable faulthandler + + -X showrefcount: output the total reference count and number of used + memory blocks when the program finishes or after each statement in the + interactive interpreter. This only works on debug builds + + -X tracemalloc: start tracing Python memory allocations using the + tracemalloc module. By default, only the most recent frame is stored in a + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a + traceback limit of NFRAME frames + + -X showalloccount: output the total count of allocated objects for each + type when the program finishes. This only works when Python was built with + COUNT_ALLOCS defined + + -X importtime: show how long each import takes. It shows module name, + cumulative time (including nested imports) and self time (excluding + nested imports). Note that its output may be broken in multi-threaded + application. Typical usage is python3 -X importtime -c 'import asyncio' + + -X dev: enable CPython?s ?development mode?, introducing additional runtime + checks which are too expensive to be enabled by default. It will not be + more verbose than the default if the code is correct: new warnings are + only emitted when an issue is detected. Effect of the developer mode: + * Add default warning filter, as -W default + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function + * Enable the faulthandler module to dump the Python traceback on a crash + * Enable asyncio debug mode + * Set the dev_mode attribute of sys.flags to True + + -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would + otherwise activate automatically). See PYTHONUTF8 for more details + .TP .B \-x Skip the first line of the source. This is intended for a DOS diff --git a/Modules/main.c b/Modules/main.c index 4d13184f2d184..33aa36d196f17 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -114,7 +114,35 @@ static const char usage_3[] = "\ -W arg : warning control; arg is action:message:category:module:lineno\n\ also PYTHONWARNINGS=arg\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ --X opt : set implementation-specific option\n\ +-X opt : set implementation-specific option. The following options are available:\n\ +\n\ + -X faulthandler: enable faulthandler\n\ + -X showrefcount: output the total reference count and number of used\n\ + memory blocks when the program finishes or after each statement in the\n\ + interactive interpreter. This only works on debug builds\n\ + -X tracemalloc: start tracing Python memory allocations using the\n\ + tracemalloc module. By default, only the most recent frame is stored in a\n\ + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ + traceback limit of NFRAME frames\n\ + -X showalloccount: output the total count of allocated objects for each\n\ + type when the program finishes. This only works when Python was built with\n\ + COUNT_ALLOCS defined\n\ + -X importtime: show how long each import takes. It shows module name,\n\ + cumulative time (including nested imports) and self time (excluding\n\ + nested imports). Note that its output may be broken in multi-threaded\n\ + application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ + -X dev: enable CPython?s ?development mode?, introducing additional runtime\n\ + checks which are too expensive to be enabled by default. Effect of the\n\ + developer mode:\n\ + * Add default warning filter, as -W default\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ + * Enable the faulthandler module to dump the Python traceback on a crash\n\ + * Enable asyncio debug mode\n\ + * Set the dev_mode attribute of sys.flags to True\n\ + -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ + otherwise activate automatically)\n\ +\n\ --check-hash-based-pycs always|default|never:\n\ control how Python invalidates hash-based .pyc files\n\ "; From webhook-mailer at python.org Sun Feb 23 17:34:01 2020 From: webhook-mailer at python.org (Antoine Pitrou) Date: Sun, 23 Feb 2020 22:34:01 -0000 Subject: [Python-checkins] bpo-39681: Fix C pickle regression with minimal file-like objects (#18592) Message-ID: https://github.com/python/cpython/commit/9f37872e307734666a7169f7be6e3370d3068282 commit: 9f37872e307734666a7169f7be6e3370d3068282 branch: master author: Antoine Pitrou committer: GitHub date: 2020-02-23T23:33:53+01:00 summary: bpo-39681: Fix C pickle regression with minimal file-like objects (#18592) Fix a regression where the C pickle module wouldn't allow unpickling from a file-like object that doesn't expose a readinto() method. files: A Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst M Lib/test/pickletester.py M Modules/_pickle.c diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index ba893f39c2f34..6ef4c8989f55b 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -73,6 +73,18 @@ def tell(self): raise io.UnsupportedOperation +class MinimalIO(object): + """ + A file-like object that doesn't support readinto(). + """ + def __init__(self, *args): + self._bio = io.BytesIO(*args) + self.getvalue = self._bio.getvalue + self.read = self._bio.read + self.readline = self._bio.readline + self.write = self._bio.write + + # We can't very well test the extension registry without putting known stuff # in it, but we have to be careful to restore its original state. Code # should do this: @@ -3363,7 +3375,7 @@ def test_reusing_unpickler_objects(self): f.seek(0) self.assertEqual(unpickler.load(), data2) - def _check_multiple_unpicklings(self, ioclass): + def _check_multiple_unpicklings(self, ioclass, *, seekable=True): for proto in protocols: with self.subTest(proto=proto): data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len] @@ -3376,10 +3388,10 @@ def _check_multiple_unpicklings(self, ioclass): f = ioclass(pickled * N) unpickler = self.unpickler_class(f) for i in range(N): - if f.seekable(): + if seekable: pos = f.tell() self.assertEqual(unpickler.load(), data1) - if f.seekable(): + if seekable: self.assertEqual(f.tell(), pos + len(pickled)) self.assertRaises(EOFError, unpickler.load) @@ -3387,7 +3399,12 @@ def test_multiple_unpicklings_seekable(self): self._check_multiple_unpicklings(io.BytesIO) def test_multiple_unpicklings_unseekable(self): - self._check_multiple_unpicklings(UnseekableIO) + self._check_multiple_unpicklings(UnseekableIO, seekable=False) + + def test_multiple_unpicklings_minimal(self): + # File-like object that doesn't support peek() and readinto() + # (bpo-39681) + self._check_multiple_unpicklings(MinimalIO, seekable=False) def test_unpickling_buffering_readline(self): # Issue #12687: the unpickler's buffering logic could fail with diff --git a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst new file mode 100644 index 0000000000000..c10e2fd7a4b6d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst @@ -0,0 +1,2 @@ +Fix a regression where the C pickle module wouldn't allow unpickling from a +file-like object that doesn't expose a readinto() method. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 2ba7a168d0ee9..a75035107a28e 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1373,13 +1373,42 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) } /* Read from file */ - if (!self->readinto) { + if (!self->read) { + /* We're unpickling memory, this means the input is truncated */ return bad_readline(); } if (_Unpickler_SkipConsumed(self) < 0) { return -1; } + if (!self->readinto) { + /* readinto() not supported on file-like object, fall back to read() + * and copy into destination buffer (bpo-39681) */ + PyObject* len = PyLong_FromSsize_t(n); + if (len == NULL) { + return -1; + } + PyObject* data = _Pickle_FastCall(self->read, len); + if (data == NULL) { + return -1; + } + if (!PyBytes_Check(data)) { + PyErr_Format(PyExc_ValueError, + "read() returned non-bytes object (%R)", + Py_TYPE(data)); + Py_DECREF(data); + return -1; + } + Py_ssize_t read_size = PyBytes_GET_SIZE(data); + if (read_size < n) { + Py_DECREF(data); + return bad_readline(); + } + memcpy(buf, PyBytes_AS_STRING(data), n); + Py_DECREF(data); + return n; + } + /* Call readinto() into user buffer */ PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); if (buf_obj == NULL) { @@ -1608,17 +1637,19 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) _Py_IDENTIFIER(readinto); _Py_IDENTIFIER(readline); + /* Optional file methods */ if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { return -1; } + if (_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto) < 0) { + return -1; + } (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); - (void)_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto); (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); - if (!self->readline || !self->readinto || !self->read) { + if (!self->readline || !self->read) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, - "file must have 'read', 'readinto' and " - "'readline' attributes"); + "file must have 'read' and 'readline' attributes"); } Py_CLEAR(self->read); Py_CLEAR(self->readinto); From webhook-mailer at python.org Sun Feb 23 17:53:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 23 Feb 2020 22:53:28 -0000 Subject: [Python-checkins] bpo-39681: Fix C pickle regression with minimal file-like objects (GH-18592) (#18630) Message-ID: https://github.com/python/cpython/commit/b19f7ecfa3adc6ba1544225317b9473649815b38 commit: b19f7ecfa3adc6ba1544225317b9473649815b38 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T23:53:24+01:00 summary: bpo-39681: Fix C pickle regression with minimal file-like objects (GH-18592) (#18630) Fix a regression where the C pickle module wouldn't allow unpickling from a file-like object that doesn't expose a readinto() method. (cherry picked from commit 9f37872e307734666a7169f7be6e3370d3068282) Co-authored-by: Antoine Pitrou Co-authored-by: Antoine Pitrou files: A Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst M Lib/test/pickletester.py M Modules/_pickle.c diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 3a8aee4320c65..7c8383f3eaac9 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -73,6 +73,18 @@ def tell(self): raise io.UnsupportedOperation +class MinimalIO(object): + """ + A file-like object that doesn't support readinto(). + """ + def __init__(self, *args): + self._bio = io.BytesIO(*args) + self.getvalue = self._bio.getvalue + self.read = self._bio.read + self.readline = self._bio.readline + self.write = self._bio.write + + # We can't very well test the extension registry without putting known stuff # in it, but we have to be careful to restore its original state. Code # should do this: @@ -3361,7 +3373,7 @@ def test_reusing_unpickler_objects(self): f.seek(0) self.assertEqual(unpickler.load(), data2) - def _check_multiple_unpicklings(self, ioclass): + def _check_multiple_unpicklings(self, ioclass, *, seekable=True): for proto in protocols: with self.subTest(proto=proto): data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len] @@ -3374,10 +3386,10 @@ def _check_multiple_unpicklings(self, ioclass): f = ioclass(pickled * N) unpickler = self.unpickler_class(f) for i in range(N): - if f.seekable(): + if seekable: pos = f.tell() self.assertEqual(unpickler.load(), data1) - if f.seekable(): + if seekable: self.assertEqual(f.tell(), pos + len(pickled)) self.assertRaises(EOFError, unpickler.load) @@ -3385,7 +3397,12 @@ def test_multiple_unpicklings_seekable(self): self._check_multiple_unpicklings(io.BytesIO) def test_multiple_unpicklings_unseekable(self): - self._check_multiple_unpicklings(UnseekableIO) + self._check_multiple_unpicklings(UnseekableIO, seekable=False) + + def test_multiple_unpicklings_minimal(self): + # File-like object that doesn't support peek() and readinto() + # (bpo-39681) + self._check_multiple_unpicklings(MinimalIO, seekable=False) def test_unpickling_buffering_readline(self): # Issue #12687: the unpickler's buffering logic could fail with diff --git a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst new file mode 100644 index 0000000000000..c10e2fd7a4b6d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst @@ -0,0 +1,2 @@ +Fix a regression where the C pickle module wouldn't allow unpickling from a +file-like object that doesn't expose a readinto() method. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 9f6e66f70a546..55e2734ca2f31 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1371,13 +1371,42 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) } /* Read from file */ - if (!self->readinto) { + if (!self->read) { + /* We're unpickling memory, this means the input is truncated */ return bad_readline(); } if (_Unpickler_SkipConsumed(self) < 0) { return -1; } + if (!self->readinto) { + /* readinto() not supported on file-like object, fall back to read() + * and copy into destination buffer (bpo-39681) */ + PyObject* len = PyLong_FromSsize_t(n); + if (len == NULL) { + return -1; + } + PyObject* data = _Pickle_FastCall(self->read, len); + if (data == NULL) { + return -1; + } + if (!PyBytes_Check(data)) { + PyErr_Format(PyExc_ValueError, + "read() returned non-bytes object (%R)", + Py_TYPE(data)); + Py_DECREF(data); + return -1; + } + Py_ssize_t read_size = PyBytes_GET_SIZE(data); + if (read_size < n) { + Py_DECREF(data); + return bad_readline(); + } + memcpy(buf, PyBytes_AS_STRING(data), n); + Py_DECREF(data); + return n; + } + /* Call readinto() into user buffer */ PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); if (buf_obj == NULL) { @@ -1606,17 +1635,19 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) _Py_IDENTIFIER(readinto); _Py_IDENTIFIER(readline); + /* Optional file methods */ if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { return -1; } + if (_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto) < 0) { + return -1; + } (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); - (void)_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto); (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); - if (!self->readline || !self->readinto || !self->read) { + if (!self->readline || !self->read) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, - "file must have 'read', 'readinto' and " - "'readline' attributes"); + "file must have 'read' and 'readline' attributes"); } Py_CLEAR(self->read); Py_CLEAR(self->readinto); From webhook-mailer at python.org Sun Feb 23 21:07:40 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 02:07:40 -0000 Subject: [Python-checkins] bpo-39654: Update pyclbr doc to reflect additional information returned (GH-18528) Message-ID: https://github.com/python/cpython/commit/973348427e3e987f42ea8a871e18c8d17b5abf52 commit: 973348427e3e987f42ea8a871e18c8d17b5abf52 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T18:07:33-08:00 summary: bpo-39654: Update pyclbr doc to reflect additional information returned (GH-18528) Full nested function and class info makes it a module browser. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Terry Jan Reedy (cherry picked from commit aea045adb8c90394264908670cbc495c5a41b65e) Co-authored-by: Hakan ?elik files: A Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst M Doc/library/pyclbr.rst diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index b80a2faed9b42..36e83e85c2314 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -1,8 +1,8 @@ -:mod:`pyclbr` --- Python class browser support -============================================== +:mod:`pyclbr` --- Python module browser support +=============================================== .. module:: pyclbr - :synopsis: Supports information extraction for a Python class browser. + :synopsis: Supports information extraction for a Python module browser. .. sectionauthor:: Fred L. Drake, Jr. @@ -29,6 +29,9 @@ modules. *path* is a sequence of directory paths prepended to ``sys.path``, which is used to locate the module source code. + This function is the original interface and is only kept for back + compatibility. It returns a filtered version of the following. + .. function:: readmodule_ex(module, path=None) diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst new file mode 100644 index 0000000000000..cff201d812476 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst @@ -0,0 +1,2 @@ +In pyclbr doc, update 'class' to 'module' where appropriate and add readmodule comment. +Patch by Hakan ?elik. From webhook-mailer at python.org Sun Feb 23 21:07:55 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 02:07:55 -0000 Subject: [Python-checkins] bpo-39654: Update pyclbr doc to reflect additional information returned (GH-18528) Message-ID: https://github.com/python/cpython/commit/d57f99929a4013741f14233ed6e517ad6c9b24d0 commit: d57f99929a4013741f14233ed6e517ad6c9b24d0 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T18:07:50-08:00 summary: bpo-39654: Update pyclbr doc to reflect additional information returned (GH-18528) Full nested function and class info makes it a module browser. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Terry Jan Reedy (cherry picked from commit aea045adb8c90394264908670cbc495c5a41b65e) Co-authored-by: Hakan ?elik files: A Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst M Doc/library/pyclbr.rst diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index b80a2faed9b42..36e83e85c2314 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -1,8 +1,8 @@ -:mod:`pyclbr` --- Python class browser support -============================================== +:mod:`pyclbr` --- Python module browser support +=============================================== .. module:: pyclbr - :synopsis: Supports information extraction for a Python class browser. + :synopsis: Supports information extraction for a Python module browser. .. sectionauthor:: Fred L. Drake, Jr. @@ -29,6 +29,9 @@ modules. *path* is a sequence of directory paths prepended to ``sys.path``, which is used to locate the module source code. + This function is the original interface and is only kept for back + compatibility. It returns a filtered version of the following. + .. function:: readmodule_ex(module, path=None) diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst new file mode 100644 index 0000000000000..cff201d812476 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst @@ -0,0 +1,2 @@ +In pyclbr doc, update 'class' to 'module' where appropriate and add readmodule comment. +Patch by Hakan ?elik. From webhook-mailer at python.org Sun Feb 23 22:14:58 2020 From: webhook-mailer at python.org (Daniel Hahler) Date: Mon, 24 Feb 2020 03:14:58 -0000 Subject: [Python-checkins] bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Message-ID: https://github.com/python/cpython/commit/4015d1cda3cdba869103779eb6ff32ad798ff885 commit: 4015d1cda3cdba869103779eb6ff32ad798ff885 branch: master author: Daniel Hahler committer: GitHub date: 2020-02-23T22:14:53-05:00 summary: bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Appears to be obsolete since 75bb54c3d8. Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst M Lib/bdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index 7b19ba3690362..b18a0612d8c78 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -548,14 +548,7 @@ def format_stack_entry(self, frame_lineno, lprefix=': '): s += frame.f_code.co_name else: s += "" - if '__args__' in frame.f_locals: - args = frame.f_locals['__args__'] - else: - args = None - if args: - s += reprlib.repr(args) - else: - s += '()' + s += '()' if '__return__' in frame.f_locals: rv = frame.f_locals['__return__'] s += '->' diff --git a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst new file mode 100644 index 0000000000000..5a88f79f05f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst @@ -0,0 +1 @@ +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. From webhook-mailer at python.org Sun Feb 23 22:32:55 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 03:32:55 -0000 Subject: [Python-checkins] bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Message-ID: https://github.com/python/cpython/commit/097612a3f711f5a6a3aec207cad78a35eb3a756d commit: 097612a3f711f5a6a3aec207cad78a35eb3a756d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T19:32:50-08:00 summary: bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Appears to be obsolete since 75bb54c3d8. Co-authored-by: Terry Jan Reedy (cherry picked from commit 4015d1cda3cdba869103779eb6ff32ad798ff885) Co-authored-by: Daniel Hahler files: A Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst M Lib/bdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index caf207733b73e..fcdc5731f8787 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -546,14 +546,7 @@ def format_stack_entry(self, frame_lineno, lprefix=': '): s += frame.f_code.co_name else: s += "" - if '__args__' in frame.f_locals: - args = frame.f_locals['__args__'] - else: - args = None - if args: - s += reprlib.repr(args) - else: - s += '()' + s += '()' if '__return__' in frame.f_locals: rv = frame.f_locals['__return__'] s += '->' diff --git a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst new file mode 100644 index 0000000000000..5a88f79f05f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst @@ -0,0 +1 @@ +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. From webhook-mailer at python.org Sun Feb 23 22:33:12 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 03:33:12 -0000 Subject: [Python-checkins] bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Message-ID: https://github.com/python/cpython/commit/c97fc564a6c76ba5287f1b16bc841a1765820b0c commit: c97fc564a6c76ba5287f1b16bc841a1765820b0c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-23T19:33:07-08:00 summary: bpo-39649: Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry (GH-18531) Appears to be obsolete since 75bb54c3d8. Co-authored-by: Terry Jan Reedy (cherry picked from commit 4015d1cda3cdba869103779eb6ff32ad798ff885) Co-authored-by: Daniel Hahler files: A Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst M Lib/bdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index 50d9eece89ad7..18491da897357 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -548,14 +548,7 @@ def format_stack_entry(self, frame_lineno, lprefix=': '): s += frame.f_code.co_name else: s += "" - if '__args__' in frame.f_locals: - args = frame.f_locals['__args__'] - else: - args = None - if args: - s += reprlib.repr(args) - else: - s += '()' + s += '()' if '__return__' in frame.f_locals: rv = frame.f_locals['__return__'] s += '->' diff --git a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst new file mode 100644 index 0000000000000..5a88f79f05f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst @@ -0,0 +1 @@ +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. From webhook-mailer at python.org Mon Feb 24 01:40:56 2020 From: webhook-mailer at python.org (Andy Lester) Date: Mon, 24 Feb 2020 06:40:56 -0000 Subject: [Python-checkins] closes bpo-39736: const strings in Modules/_datetimemodule.c and Modules/_testbuffer.c (GH-18637) Message-ID: https://github.com/python/cpython/commit/c3fa634096eedbaf477698adab666f03085a7928 commit: c3fa634096eedbaf477698adab666f03085a7928 branch: master author: Andy Lester committer: GitHub date: 2020-02-23T22:40:43-08:00 summary: closes bpo-39736: const strings in Modules/_datetimemodule.c and Modules/_testbuffer.c (GH-18637) files: M Modules/_datetimemodule.c M Modules/_testbuffer.c diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 4cafd14012558..4c985b37385e8 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -4179,11 +4179,11 @@ static PyObject * time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) { char buf[100]; - char *timespec = NULL; + const char *timespec = NULL; static char *keywords[] = {"timespec", NULL}; PyObject *result; int us = TIME_GET_MICROSECOND(self); - static char *specs[][2] = { + static const char *specs[][2] = { {"hours", "%02d"}, {"minutes", "%02d:%02d"}, {"seconds", "%02d:%02d:%02d"}, @@ -5415,7 +5415,7 @@ datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) char buffer[100]; PyObject *result = NULL; int us = DATE_GET_MICROSECOND(self); - static char *specs[][2] = { + static const char *specs[][2] = { {"hours", "%04d-%02d-%02d%c%02d"}, {"minutes", "%04d-%02d-%02d%c%02d:%02d"}, {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"}, diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index f4c2b590ac9c3..d8321768bc972 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -2050,7 +2050,7 @@ static PyObject * ndarray_get_format(NDArrayObject *self, void *closure) { Py_buffer *base = &self->head->base; - char *fmt = base->format ? base->format : ""; + const char *fmt = base->format ? base->format : ""; return PyUnicode_FromString(fmt); } From webhook-mailer at python.org Mon Feb 24 05:15:50 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 24 Feb 2020 10:15:50 -0000 Subject: [Python-checkins] Give proper credits for the memoryview implementation. (#18626) Message-ID: https://github.com/python/cpython/commit/ee3bac4cba56b51ce924f13d77b97131eec1a865 commit: ee3bac4cba56b51ce924f13d77b97131eec1a865 branch: master author: Stefan Krah committer: GitHub date: 2020-02-24T11:15:26+01:00 summary: Give proper credits for the memoryview implementation. (#18626) files: M Objects/memoryobject.c diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 6887c4335f1f1..7f9c90035f574 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1,4 +1,14 @@ -/* Memoryview object implementation */ +/* + * Memoryview object implementation + * -------------------------------- + * + * This implementation is a complete rewrite contributed by Stefan Krah in + * Python 3.3. Substantial credit goes to Antoine Pitrou (who had already + * fortified and rewritten the previous implementation) and Nick Coghlan + * (who came up with the idea of the ManagedBuffer) for analyzing the complex + * ownership rules. + * + */ #include "Python.h" #include "pycore_object.h" From webhook-mailer at python.org Mon Feb 24 05:51:45 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 10:51:45 -0000 Subject: [Python-checkins] Give proper credits for the memoryview implementation. (GH-18626) (#18643) Message-ID: https://github.com/python/cpython/commit/3dc6961681df000e113383fddaff2f932ef6abaa commit: 3dc6961681df000e113383fddaff2f932ef6abaa branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-24T11:51:40+01:00 summary: Give proper credits for the memoryview implementation. (GH-18626) (#18643) (cherry picked from commit ee3bac4cba56b51ce924f13d77b97131eec1a865) Authored-by: Stefan Krah files: M Objects/memoryobject.c diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index ce8fa3f270051..61669aedc7342 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1,4 +1,14 @@ -/* Memoryview object implementation */ +/* + * Memoryview object implementation + * -------------------------------- + * + * This implementation is a complete rewrite contributed by Stefan Krah in + * Python 3.3. Substantial credit goes to Antoine Pitrou (who had already + * fortified and rewritten the previous implementation) and Nick Coghlan + * (who came up with the idea of the ManagedBuffer) for analyzing the complex + * ownership rules. + * + */ #include "Python.h" #include "internal/mem.h" From webhook-mailer at python.org Mon Feb 24 05:52:14 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 10:52:14 -0000 Subject: [Python-checkins] Give proper credits for the memoryview implementation. (GH-18626) (#18642) Message-ID: https://github.com/python/cpython/commit/aa8213486f69c15bb9e07d2232d19bf2e9875070 commit: aa8213486f69c15bb9e07d2232d19bf2e9875070 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-24T11:52:10+01:00 summary: Give proper credits for the memoryview implementation. (GH-18626) (#18642) (cherry picked from commit ee3bac4cba56b51ce924f13d77b97131eec1a865) Authored-by: Stefan Krah files: M Objects/memoryobject.c diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 92050791b5d16..0bbcbb2e7eefa 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1,4 +1,14 @@ -/* Memoryview object implementation */ +/* + * Memoryview object implementation + * -------------------------------- + * + * This implementation is a complete rewrite contributed by Stefan Krah in + * Python 3.3. Substantial credit goes to Antoine Pitrou (who had already + * fortified and rewritten the previous implementation) and Nick Coghlan + * (who came up with the idea of the ManagedBuffer) for analyzing the complex + * ownership rules. + * + */ #include "Python.h" #include "pycore_object.h" From webhook-mailer at python.org Mon Feb 24 06:24:51 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 24 Feb 2020 11:24:51 -0000 Subject: [Python-checkins] Give proper credit for figuring out and writing PEP-3118 tests. (#18644) Message-ID: https://github.com/python/cpython/commit/b942ba03b8530f26240d4e36567d2ff42d701420 commit: b942ba03b8530f26240d4e36567d2ff42d701420 branch: master author: Stefan Krah committer: GitHub date: 2020-02-24T12:24:43+01:00 summary: Give proper credit for figuring out and writing PEP-3118 tests. (#18644) files: M Lib/test/test_buffer.py diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 0aa78016f5d1a..6178ffde7a566 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -10,6 +10,8 @@ # the same way as the original. Thus, a substantial part of the # memoryview tests is now in this module. # +# Written and designed by Stefan Krah for Python 3.3. +# import contextlib import unittest From webhook-mailer at python.org Mon Feb 24 06:44:11 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 11:44:11 -0000 Subject: [Python-checkins] Give proper credit for figuring out and writing PEP-3118 tests. (GH-18644) (#18646) Message-ID: https://github.com/python/cpython/commit/45cc9ce4de0a333a3beb0111741de0e8ea6b5a26 commit: 45cc9ce4de0a333a3beb0111741de0e8ea6b5a26 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-24T12:44:06+01:00 summary: Give proper credit for figuring out and writing PEP-3118 tests. (GH-18644) (#18646) (cherry picked from commit b942ba03b8530f26240d4e36567d2ff42d701420) Authored-by: Stefan Krah files: M Lib/test/test_buffer.py diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 47413c03d6630..dd84faf371e7d 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -10,6 +10,8 @@ # the same way as the original. Thus, a substantial part of the # memoryview tests is now in this module. # +# Written and designed by Stefan Krah for Python 3.3. +# import contextlib import unittest From webhook-mailer at python.org Mon Feb 24 06:44:44 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 11:44:44 -0000 Subject: [Python-checkins] Give proper credit for figuring out and writing PEP-3118 tests. (GH-18644) (#18645) Message-ID: https://github.com/python/cpython/commit/e349e83826e0dd9fd7b0262d33700f1f92b97c73 commit: e349e83826e0dd9fd7b0262d33700f1f92b97c73 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-24T12:44:40+01:00 summary: Give proper credit for figuring out and writing PEP-3118 tests. (GH-18644) (#18645) (cherry picked from commit b942ba03b8530f26240d4e36567d2ff42d701420) Authored-by: Stefan Krah files: M Lib/test/test_buffer.py diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index f302da415d33f..08727d87d4b36 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -10,6 +10,8 @@ # the same way as the original. Thus, a substantial part of the # memoryview tests is now in this module. # +# Written and designed by Stefan Krah for Python 3.3. +# import contextlib import unittest From webhook-mailer at python.org Mon Feb 24 07:59:18 2020 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 24 Feb 2020 12:59:18 -0000 Subject: [Python-checkins] Add note to Mac installer ReadMe about macOS 10.15 Gatekeeper changes. (GH-18647) Message-ID: https://github.com/python/cpython/commit/a199f48ea7ec22e7753baf52bffa3a89b8784d96 commit: a199f48ea7ec22e7753baf52bffa3a89b8784d96 branch: 3.8 author: Ned Deily committer: GitHub date: 2020-02-24T07:59:13-05:00 summary: Add note to Mac installer ReadMe about macOS 10.15 Gatekeeper changes. (GH-18647) files: M Mac/BuildScript/resources/ReadMe.rtf diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index d321fcd80c2eb..4cb0111d83a53 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,5 +1,5 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; +{\rtf1\ansi\ansicpg1252\cocoartf2511 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} @@ -36,8 +36,7 @@ The bundled \f0\b0 \ulnone \ \ This package includes its own private version of Tcl/Tk 8.6. It does not use any system-supplied or third-party supplied versions of Tcl/Tk.\ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\cf0 \ +\ Due to new security checks on macOS 10.15 Catalina, when launching IDLE macOS may open a window with a message \f1\b "Python" would like to access files in your Documents folder \f0\b0 . This is normal as IDLE uses your @@ -49,9 +48,14 @@ Due to new security checks on macOS 10.15 Catalina, when launching IDLE macOS ma \f0\b0 file dialog windows. Click on the \f1\b OK \f0\b0 button to proceed.\ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\f1\b \cf0 \ul \ulc0 \ +\f1\b \ul \ +macOS 10.15 (Catalina) Gatekeeper Requirements [changed in 3.8.2]\ + +\f0\b0 \ulnone \ +As of 2020-02-03, Apple has changed how third-party installer packages, like those provided by python.org, are notarized for verification by Gatekeeper and begun enforcing additional requirements such as code signing and use of the hardened runtime. As of 3.8.2, python.org installer packages now meet those additional notarization requirements. The necessary changes in packaging should be transparent to your use of Python but, in the unlikely event that you encounter changes in behavior between 3.8.1 and 3.8.2 in areas like ctypes, importlib, or mmap, please check bugs.python.org for existing reports and, if necessary, open a new issue.\ + +\f1\b \ul \ Other changes\ \f0\b0 \ulnone \ From webhook-mailer at python.org Mon Feb 24 08:01:02 2020 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 24 Feb 2020 13:01:02 -0000 Subject: [Python-checkins] Add note to Mac installer ReadMe about macOS 10.15 Gatekeeper changes. (GH-18648) Message-ID: https://github.com/python/cpython/commit/514328480a11164100bdb16f2e61c0623dce1fc8 commit: 514328480a11164100bdb16f2e61c0623dce1fc8 branch: master author: Ned Deily committer: GitHub date: 2020-02-24T08:00:58-05:00 summary: Add note to Mac installer ReadMe about macOS 10.15 Gatekeeper changes. (GH-18648) files: M Mac/BuildScript/resources/ReadMe.rtf diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index fc5739aee540a..086ab42b38936 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,5 +1,5 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; +{\rtf1\ansi\ansicpg1252\cocoartf2511 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} @@ -56,6 +56,12 @@ Due to new security checks on macOS 10.15 Catalina, when launching IDLE macOS ma \f0\b0 button to proceed.\ \ +\f1\b \ul macOS 10.15 (Catalina) Gatekeeper Requirements [changed in 3.9.0a4]\ + +\f0\b0 \ulnone \ +As of 2020-02-03, Apple has changed how third-party installer packages, like those provided by python.org, are notarized for verification by Gatekeeper and begun enforcing additional requirements such as code signing and use of the hardened runtime. As of 3.9.0a4, python.org installer packages now meet those additional notarization requirements. The necessary changes in packaging should be transparent to your use of Python but, in the unlikely event that you encounter changes in behavior between 3.9.0a4 and earlier 3.9.0 alphas in areas like ctypes, importlib, or mmap, please check bugs.python.org for existing reports and, if necessary, open a new issue.\ +\ + \f1\b \ul Other changes\ \f0\b0 \ulnone \ From webhook-mailer at python.org Mon Feb 24 09:59:45 2020 From: webhook-mailer at python.org (idomic) Date: Mon, 24 Feb 2020 14:59:45 -0000 Subject: [Python-checkins] bpo-39128: Added algorithm description (GH-18624) Message-ID: https://github.com/python/cpython/commit/8af4712a16e4b7d1b60f1faec13cd7a88da95f6a commit: 8af4712a16e4b7d1b60f1faec13cd7a88da95f6a branch: master author: idomic committer: GitHub date: 2020-02-24T06:59:40-08:00 summary: bpo-39128: Added algorithm description (GH-18624) # [bpo-39128](https://bugs.python.org/issue39128): happy eyeballs description # [3.9] 39128 - happy eyeballs description (GH-18624) # [3.8] 39128 - happy eyeballs description (GH-18624) https://bugs.python.org/issue39128 files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 3acd79d283580..d60a6ce95cdd8 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -451,6 +451,17 @@ Opening network connections Added the *happy_eyeballs_delay* and *interleave* parameters. + Happy Eyeballs Algorithm: Success with Dual-Stack Hosts. + When a server's IPv4 path and protocol are working, but the server's + IPv6 path and protocol are not working, a dual-stack client + application experiences significant connection delay compared to an + IPv4-only client. This is undesirable because it causes the dual- + stack client to have a worse user experience. This document + specifies requirements for algorithms that reduce this user-visible + delay and provides an algorithm. + + For more information: https://tools.ietf.org/html/rfc6555 + .. versionadded:: 3.7 The *ssl_handshake_timeout* parameter. From webhook-mailer at python.org Mon Feb 24 10:06:07 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 24 Feb 2020 15:06:07 -0000 Subject: [Python-checkins] bpo-39128: Added algorithm description (GH-18624) Message-ID: https://github.com/python/cpython/commit/1f4cf0c22b00fefb17611546755b65d3cb488330 commit: 1f4cf0c22b00fefb17611546755b65d3cb488330 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-24T07:06:00-08:00 summary: bpo-39128: Added algorithm description (GH-18624) GH- [bpo-39128](https://bugs.python.org/issue39128): happy eyeballs description GH- [3.9] 39128 - happy eyeballs description (GH-18624) GH- [3.8] 39128 - happy eyeballs description (GH-18624) https://bugs.python.org/issue39128 (cherry picked from commit 8af4712a16e4b7d1b60f1faec13cd7a88da95f6a) Co-authored-by: idomic files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 4ea8521eb0bf3..9022993e619a5 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -439,6 +439,17 @@ Opening network connections Added the *happy_eyeballs_delay* and *interleave* parameters. + Happy Eyeballs Algorithm: Success with Dual-Stack Hosts. + When a server's IPv4 path and protocol are working, but the server's + IPv6 path and protocol are not working, a dual-stack client + application experiences significant connection delay compared to an + IPv4-only client. This is undesirable because it causes the dual- + stack client to have a worse user experience. This document + specifies requirements for algorithms that reduce this user-visible + delay and provides an algorithm. + + For more information: https://tools.ietf.org/html/rfc6555 + .. versionadded:: 3.7 The *ssl_handshake_timeout* parameter. From webhook-mailer at python.org Mon Feb 24 22:19:08 2020 From: webhook-mailer at python.org (Berker Peksag) Date: Tue, 25 Feb 2020 03:19:08 -0000 Subject: [Python-checkins] bpo-30566: Fix IndexError when using punycode codec (GH-18632) Message-ID: https://github.com/python/cpython/commit/ba22e8f174309979d90047c5dc64fcb63bc2c32e commit: ba22e8f174309979d90047c5dc64fcb63bc2c32e branch: master author: Berker Peksag committer: GitHub date: 2020-02-25T06:19:03+03:00 summary: bpo-30566: Fix IndexError when using punycode codec (GH-18632) Trying to decode an invalid string with the punycode codec shoud raise UnicodeError. files: A Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst M Lib/encodings/punycode.py M Lib/test/test_codecs.py diff --git a/Lib/encodings/punycode.py b/Lib/encodings/punycode.py index 66c51013ea431..1c5726447077b 100644 --- a/Lib/encodings/punycode.py +++ b/Lib/encodings/punycode.py @@ -143,7 +143,7 @@ def decode_generalized_number(extended, extpos, bias, errors): digit = char - 22 # 0x30-26 elif errors == "strict": raise UnicodeError("Invalid extended code point '%s'" - % extended[extpos]) + % extended[extpos-1]) else: return extpos, None t = T(j, bias) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 3aec34c7f167d..8d9cb9089039c 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1343,6 +1343,18 @@ def test_decode(self): puny = puny.decode("ascii").encode("ascii") self.assertEqual(uni, puny.decode("punycode")) + def test_decode_invalid(self): + testcases = [ + (b"xn--w&", "strict", UnicodeError()), + (b"xn--w&", "ignore", "xn-"), + ] + for puny, errors, expected in testcases: + with self.subTest(puny=puny, errors=errors): + if isinstance(expected, Exception): + self.assertRaises(UnicodeError, puny.decode, "punycode", errors) + else: + self.assertEqual(puny.decode("punycode", errors), expected) + # From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html nameprep_tests = [ diff --git a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst new file mode 100644 index 0000000000000..c780633030090 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst @@ -0,0 +1,2 @@ +Fix :exc:`IndexError` when trying to decode an invalid string with punycode +codec. From webhook-mailer at python.org Mon Feb 24 22:42:46 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 25 Feb 2020 03:42:46 -0000 Subject: [Python-checkins] bpo-30566: Fix IndexError when using punycode codec (GH-18632) Message-ID: https://github.com/python/cpython/commit/daef21ce7dfd3735101d85d6ebf7554187c33ab8 commit: daef21ce7dfd3735101d85d6ebf7554187c33ab8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-25T06:42:39+03:00 summary: bpo-30566: Fix IndexError when using punycode codec (GH-18632) Trying to decode an invalid string with the punycode codec shoud raise UnicodeError. (cherry picked from commit ba22e8f174309979d90047c5dc64fcb63bc2c32e) Co-authored-by: Berker Peksag files: A Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst M Lib/encodings/punycode.py M Lib/test/test_codecs.py diff --git a/Lib/encodings/punycode.py b/Lib/encodings/punycode.py index 66c51013ea431..1c5726447077b 100644 --- a/Lib/encodings/punycode.py +++ b/Lib/encodings/punycode.py @@ -143,7 +143,7 @@ def decode_generalized_number(extended, extpos, bias, errors): digit = char - 22 # 0x30-26 elif errors == "strict": raise UnicodeError("Invalid extended code point '%s'" - % extended[extpos]) + % extended[extpos-1]) else: return extpos, None t = T(j, bias) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index b37525bf66043..8c10e948e8041 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1331,6 +1331,18 @@ def test_decode(self): puny = puny.decode("ascii").encode("ascii") self.assertEqual(uni, puny.decode("punycode")) + def test_decode_invalid(self): + testcases = [ + (b"xn--w&", "strict", UnicodeError()), + (b"xn--w&", "ignore", "xn-"), + ] + for puny, errors, expected in testcases: + with self.subTest(puny=puny, errors=errors): + if isinstance(expected, Exception): + self.assertRaises(UnicodeError, puny.decode, "punycode", errors) + else: + self.assertEqual(puny.decode("punycode", errors), expected) + # From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html nameprep_tests = [ diff --git a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst new file mode 100644 index 0000000000000..c780633030090 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst @@ -0,0 +1,2 @@ +Fix :exc:`IndexError` when trying to decode an invalid string with punycode +codec. From webhook-mailer at python.org Mon Feb 24 22:43:50 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 25 Feb 2020 03:43:50 -0000 Subject: [Python-checkins] bpo-30566: Fix IndexError when using punycode codec (GH-18632) Message-ID: https://github.com/python/cpython/commit/55be9a6c09d4415f50b14212ce22eccefa83ca64 commit: 55be9a6c09d4415f50b14212ce22eccefa83ca64 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-25T06:43:46+03:00 summary: bpo-30566: Fix IndexError when using punycode codec (GH-18632) Trying to decode an invalid string with the punycode codec shoud raise UnicodeError. (cherry picked from commit ba22e8f174309979d90047c5dc64fcb63bc2c32e) Co-authored-by: Berker Peksag files: A Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst M Lib/encodings/punycode.py M Lib/test/test_codecs.py diff --git a/Lib/encodings/punycode.py b/Lib/encodings/punycode.py index 66c51013ea431..1c5726447077b 100644 --- a/Lib/encodings/punycode.py +++ b/Lib/encodings/punycode.py @@ -143,7 +143,7 @@ def decode_generalized_number(extended, extpos, bias, errors): digit = char - 22 # 0x30-26 elif errors == "strict": raise UnicodeError("Invalid extended code point '%s'" - % extended[extpos]) + % extended[extpos-1]) else: return extpos, None t = T(j, bias) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index cd2761353490a..5a450ebd9dc2b 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1406,6 +1406,18 @@ def test_decode(self): puny = puny.decode("ascii").encode("ascii") self.assertEqual(uni, puny.decode("punycode")) + def test_decode_invalid(self): + testcases = [ + (b"xn--w&", "strict", UnicodeError()), + (b"xn--w&", "ignore", "xn-"), + ] + for puny, errors, expected in testcases: + with self.subTest(puny=puny, errors=errors): + if isinstance(expected, Exception): + self.assertRaises(UnicodeError, puny.decode, "punycode", errors) + else: + self.assertEqual(puny.decode("punycode", errors), expected) + class UnicodeInternalTest(unittest.TestCase): @unittest.skipUnless(SIZEOF_WCHAR_T == 4, 'specific to 32-bit wchar_t') diff --git a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst new file mode 100644 index 0000000000000..c780633030090 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst @@ -0,0 +1,2 @@ +Fix :exc:`IndexError` when trying to decode an invalid string with punycode +codec. From webhook-mailer at python.org Mon Feb 24 22:47:38 2020 From: webhook-mailer at python.org (Brandt Bucher) Date: Tue, 25 Feb 2020 03:47:38 -0000 Subject: [Python-checkins] bpo-36144: Dictionary Union (PEP 584) (#12088) Message-ID: https://github.com/python/cpython/commit/eb8ac57af26c4eb96a8230eba7492ce5ceef7886 commit: eb8ac57af26c4eb96a8230eba7492ce5ceef7886 branch: master author: Brandt Bucher committer: GitHub date: 2020-02-24T19:47:34-08:00 summary: bpo-36144: Dictionary Union (PEP 584) (#12088) files: A Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS.rst M Lib/collections/__init__.py M Lib/test/test_dict.py M Objects/dictobject.c diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 178cdb1fa5ba0..1aa7d10ad22e4 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -994,6 +994,26 @@ def __contains__(self, key): # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) + + def __or__(self, other): + if isinstance(other, UserDict): + return self.__class__(self.data | other.data) + if isinstance(other, dict): + return self.__class__(self.data | other) + return NotImplemented + def __ror__(self, other): + if isinstance(other, UserDict): + return self.__class__(other.data | self.data) + if isinstance(other, dict): + return self.__class__(other | self.data) + return NotImplemented + def __ior__(self, other): + if isinstance(other, UserDict): + self.data |= other.data + else: + self.data |= other + return self + def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index de483ab552155..d5a3d9e894574 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -37,6 +37,38 @@ def test_literal_constructor(self): dictliteral = '{' + ', '.join(formatted_items) + '}' self.assertEqual(eval(dictliteral), dict(items)) + def test_merge_operator(self): + + a = {0: 0, 1: 1, 2: 1} + b = {1: 1, 2: 2, 3: 3} + + c = a.copy() + c |= b + + self.assertEqual(a | b, {0: 0, 1: 1, 2: 2, 3: 3}) + self.assertEqual(c, {0: 0, 1: 1, 2: 2, 3: 3}) + + c = b.copy() + c |= a + + self.assertEqual(b | a, {1: 1, 2: 1, 3: 3, 0: 0}) + self.assertEqual(c, {1: 1, 2: 1, 3: 3, 0: 0}) + + c = a.copy() + c |= [(1, 1), (2, 2), (3, 3)] + + self.assertEqual(c, {0: 0, 1: 1, 2: 2, 3: 3}) + + self.assertIs(a.__or__(None), NotImplemented) + self.assertIs(a.__or__(()), NotImplemented) + self.assertIs(a.__or__("BAD"), NotImplemented) + self.assertIs(a.__or__(""), NotImplemented) + + self.assertRaises(TypeError, a.__ior__, None) + self.assertEqual(a.__ior__(()), {0: 0, 1: 1, 2: 1}) + self.assertRaises(ValueError, a.__ior__, "BAD") + self.assertEqual(a.__ior__(""), {0: 0, 1: 1, 2: 1}) + def test_bool(self): self.assertIs(not {}, True) self.assertTrue({1: 2}) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS.rst new file mode 100644 index 0000000000000..7d6d076ea7d4d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS.rst @@ -0,0 +1,2 @@ +:class:`dict` (and :class:`collections.UserDict`) objects now support PEP 584's merge (``|``) and update (``|=``) operators. +Patch by Brandt Bucher. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 86ac4ef4816d8..4aa927afd9c7a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2320,6 +2320,25 @@ dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) return _PyDict_FromKeys((PyObject *)type, iterable, value); } +/* Single-arg dict update; used by dict_update_common and operators. */ +static int +dict_update_arg(PyObject *self, PyObject *arg) +{ + if (PyDict_CheckExact(arg)) { + return PyDict_Merge(self, arg, 1); + } + _Py_IDENTIFIER(keys); + PyObject *func; + if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { + return -1; + } + if (func != NULL) { + Py_DECREF(func); + return PyDict_Merge(self, arg, 1); + } + return PyDict_MergeFromSeq2(self, arg, 1); +} + static int dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, const char *methname) @@ -2331,23 +2350,7 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, result = -1; } else if (arg != NULL) { - if (PyDict_CheckExact(arg)) { - result = PyDict_Merge(self, arg, 1); - } - else { - _Py_IDENTIFIER(keys); - PyObject *func; - if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { - result = -1; - } - else if (func != NULL) { - Py_DECREF(func); - result = PyDict_Merge(self, arg, 1); - } - else { - result = PyDict_MergeFromSeq2(self, arg, 1); - } - } + result = dict_update_arg(self, arg); } if (result == 0 && kwds != NULL) { @@ -3169,6 +3172,33 @@ dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) return PyLong_FromSsize_t(_PyDict_SizeOf(mp)); } +static PyObject * +dict_or(PyObject *self, PyObject *other) +{ + if (!PyDict_Check(self) || !PyDict_Check(other)) { + Py_RETURN_NOTIMPLEMENTED; + } + PyObject *new = PyDict_Copy(self); + if (new == NULL) { + return NULL; + } + if (dict_update_arg(new, other)) { + Py_DECREF(new); + return NULL; + } + return new; +} + +static PyObject * +dict_ior(PyObject *self, PyObject *other) +{ + if (dict_update_arg(self, other)) { + return NULL; + } + Py_INCREF(self); + return self; +} + PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); PyDoc_STRVAR(sizeof__doc__, @@ -3274,6 +3304,11 @@ static PySequenceMethods dict_as_sequence = { 0, /* sq_inplace_repeat */ }; +static PyNumberMethods dict_as_number = { + .nb_or = dict_or, + .nb_inplace_or = dict_ior, +}; + static PyObject * dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3335,7 +3370,7 @@ PyTypeObject PyDict_Type = { 0, /* tp_setattr */ 0, /* tp_as_async */ (reprfunc)dict_repr, /* tp_repr */ - 0, /* tp_as_number */ + &dict_as_number, /* tp_as_number */ &dict_as_sequence, /* tp_as_sequence */ &dict_as_mapping, /* tp_as_mapping */ PyObject_HashNotImplemented, /* tp_hash */ From webhook-mailer at python.org Tue Feb 25 15:07:19 2020 From: webhook-mailer at python.org (Steve Dower) Date: Tue, 25 Feb 2020 20:07:19 -0000 Subject: [Python-checkins] bpo-38403: Update nuspec file for deprecated field and git repository (GH-18657) Message-ID: https://github.com/python/cpython/commit/d6448919702142123d937a54f20a81aeaf8d2acc commit: d6448919702142123d937a54f20a81aeaf8d2acc branch: master author: Steve Dower committer: GitHub date: 2020-02-25T20:07:00Z summary: bpo-38403: Update nuspec file for deprecated field and git repository (GH-18657) files: A Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst A PC/icons/logo.svg A PC/icons/logox128.png M PC/layout/support/nuspec.py diff --git a/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst b/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst new file mode 100644 index 0000000000000..144ffd50af0e9 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst @@ -0,0 +1,2 @@ +Package for nuget.org now includes repository reference and bundled icon +image. diff --git a/PC/icons/logo.svg b/PC/icons/logo.svg new file mode 100644 index 0000000000000..6f521503a3832 --- /dev/null +++ b/PC/icons/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PC/icons/logox128.png b/PC/icons/logox128.png new file mode 100644 index 0000000000000..d2655c72e7df4 Binary files /dev/null and b/PC/icons/logox128.png differ diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py index b85095c555fe0..9c6a9a9159509 100644 --- a/PC/layout/support/nuspec.py +++ b/PC/layout/support/nuspec.py @@ -3,6 +3,7 @@ """ import os +import sys from .constants import * @@ -14,6 +15,7 @@ "PYTHON_TAG": VER_DOT, "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), "FILELIST": r' ', + "GIT": sys._git, } NUSPEC_PLATFORM_DATA = dict( @@ -42,10 +44,13 @@ tools\LICENSE.txt https://www.python.org/ Installs {PYTHON_BITNESS} Python for use in build scenarios. + images\logox128.png https://www.python.org/static/favicon.ico python + + {FILELIST} @@ -68,5 +73,6 @@ def get_nuspec_layout(ns): data[k] = v if ns.include_all or ns.include_props: data["FILELIST"] = FILELIST_WITH_PROPS + data["LOGO"] = ns.source / "PC" / "icons" / "logox128.png" nuspec = NUSPEC_TEMPLATE.format_map(data) yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) From webhook-mailer at python.org Tue Feb 25 15:24:56 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 25 Feb 2020 20:24:56 -0000 Subject: [Python-checkins] bpo-38403: Update nuspec file for deprecated field and git repository (GH-18657) Message-ID: https://github.com/python/cpython/commit/1bbb81b251bcc8b05e0cd33cd36aef55481b13db commit: 1bbb81b251bcc8b05e0cd33cd36aef55481b13db branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-25T12:24:48-08:00 summary: bpo-38403: Update nuspec file for deprecated field and git repository (GH-18657) (cherry picked from commit d6448919702142123d937a54f20a81aeaf8d2acc) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst A PC/icons/logo.svg A PC/icons/logox128.png M PC/layout/support/nuspec.py diff --git a/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst b/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst new file mode 100644 index 0000000000000..144ffd50af0e9 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-02-25-18-43-34.bpo-34803.S3VcS0.rst @@ -0,0 +1,2 @@ +Package for nuget.org now includes repository reference and bundled icon +image. diff --git a/PC/icons/logo.svg b/PC/icons/logo.svg new file mode 100644 index 0000000000000..6f521503a3832 --- /dev/null +++ b/PC/icons/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PC/icons/logox128.png b/PC/icons/logox128.png new file mode 100644 index 0000000000000..d2655c72e7df4 Binary files /dev/null and b/PC/icons/logox128.png differ diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py index b85095c555fe0..9c6a9a9159509 100644 --- a/PC/layout/support/nuspec.py +++ b/PC/layout/support/nuspec.py @@ -3,6 +3,7 @@ """ import os +import sys from .constants import * @@ -14,6 +15,7 @@ "PYTHON_TAG": VER_DOT, "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), "FILELIST": r' ', + "GIT": sys._git, } NUSPEC_PLATFORM_DATA = dict( @@ -42,10 +44,13 @@ tools\LICENSE.txt https://www.python.org/ Installs {PYTHON_BITNESS} Python for use in build scenarios. + images\logox128.png https://www.python.org/static/favicon.ico python + + {FILELIST} @@ -68,5 +73,6 @@ def get_nuspec_layout(ns): data[k] = v if ns.include_all or ns.include_props: data["FILELIST"] = FILELIST_WITH_PROPS + data["LOGO"] = ns.source / "PC" / "icons" / "logox128.png" nuspec = NUSPEC_TEMPLATE.format_map(data) yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) From webhook-mailer at python.org Wed Feb 26 01:04:47 2020 From: webhook-mailer at python.org (Inada Naoki) Date: Wed, 26 Feb 2020 06:04:47 -0000 Subject: [Python-checkins] Doc: int -> int or Py_ssize_t (GH-18663) Message-ID: https://github.com/python/cpython/commit/57c7a0bdf4f7da8cf47f797f075950f6b8c98b99 commit: 57c7a0bdf4f7da8cf47f797f075950f6b8c98b99 branch: master author: Inada Naoki committer: GitHub date: 2020-02-26T15:04:39+09:00 summary: Doc: int -> int or Py_ssize_t (GH-18663) files: M Doc/c-api/arg.rst diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index f17c63d0b9dc9..b7baad589a72c 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -105,7 +105,7 @@ which disallows mutable objects such as :class:`bytearray`. Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``. -``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to ``NULL``. @@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`. bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (read-only :term:`bytes-like object`) [const char \*, int] +``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. @@ -155,7 +155,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``u#`` (:class:`str`) [const Py_UNICODE \*, int] +``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. This variant allows null code points. @@ -172,7 +172,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] Like ``u#``, but the Python object may also be ``None``, in which case the :c:type:`Py_UNICODE` pointer is set to ``NULL``. @@ -213,7 +213,7 @@ which disallows mutable objects such as :class:`bytearray`. recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] This variant on ``s#`` is used for encoding Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -244,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] Same as ``es#`` except that byte string objects are passed through without recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. @@ -549,7 +549,7 @@ Building values Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, ``None`` is used. - ``s#`` (:class:`str` or ``None``) [const char \*, int] + ``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -558,14 +558,14 @@ Building values This converts a C string to a Python :class:`bytes` object. If the C string pointer is ``NULL``, ``None`` is returned. - ``y#`` (:class:`bytes`) [const char \*, int] + ``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`] This converts a C string and its lengths to a Python object. If the C string pointer is ``NULL``, ``None`` is returned. ``z`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``z#`` (:class:`str` or ``None``) [const char \*, int] + ``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] @@ -573,7 +573,7 @@ Building values data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. - ``u#`` (:class:`str`) [const wchar_t \*, int] + ``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`] Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -581,7 +581,7 @@ Building values ``U`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``U#`` (:class:`str` or ``None``) [const char \*, int] + ``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``i`` (:class:`int`) [int] From webhook-mailer at python.org Wed Feb 26 01:10:26 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 26 Feb 2020 06:10:26 -0000 Subject: [Python-checkins] Doc: int -> int or Py_ssize_t (GH-18663) Message-ID: https://github.com/python/cpython/commit/0ef328abe329724b4a00a553e39c9ad310b746e1 commit: 0ef328abe329724b4a00a553e39c9ad310b746e1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-25T22:10:17-08:00 summary: Doc: int -> int or Py_ssize_t (GH-18663) (cherry picked from commit 57c7a0bdf4f7da8cf47f797f075950f6b8c98b99) Co-authored-by: Inada Naoki files: M Doc/c-api/arg.rst diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index a5d1edc5f5b15..caa93d63db05b 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -105,7 +105,7 @@ which disallows mutable objects such as :class:`bytearray`. Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``. -``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to ``NULL``. @@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`. bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (read-only :term:`bytes-like object`) [const char \*, int] +``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. @@ -155,7 +155,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``u#`` (:class:`str`) [const Py_UNICODE \*, int] +``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. This variant allows null code points. @@ -172,7 +172,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] Like ``u#``, but the Python object may also be ``None``, in which case the :c:type:`Py_UNICODE` pointer is set to ``NULL``. @@ -213,7 +213,7 @@ which disallows mutable objects such as :class:`bytearray`. recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] This variant on ``s#`` is used for encoding Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -244,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] Same as ``es#`` except that byte string objects are passed through without recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. @@ -549,7 +549,7 @@ Building values Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, ``None`` is used. - ``s#`` (:class:`str` or ``None``) [const char \*, int] + ``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -558,14 +558,14 @@ Building values This converts a C string to a Python :class:`bytes` object. If the C string pointer is ``NULL``, ``None`` is returned. - ``y#`` (:class:`bytes`) [const char \*, int] + ``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`] This converts a C string and its lengths to a Python object. If the C string pointer is ``NULL``, ``None`` is returned. ``z`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``z#`` (:class:`str` or ``None``) [const char \*, int] + ``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] @@ -573,7 +573,7 @@ Building values data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. - ``u#`` (:class:`str`) [const wchar_t \*, int] + ``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`] Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -581,7 +581,7 @@ Building values ``U`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``U#`` (:class:`str` or ``None``) [const char \*, int] + ``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``i`` (:class:`int`) [int] From webhook-mailer at python.org Wed Feb 26 01:11:22 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 26 Feb 2020 06:11:22 -0000 Subject: [Python-checkins] Doc: int -> int or Py_ssize_t (GH-18663) Message-ID: https://github.com/python/cpython/commit/c3536b79425edc623860073eed4cf8945b2281dc commit: c3536b79425edc623860073eed4cf8945b2281dc branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-25T22:11:16-08:00 summary: Doc: int -> int or Py_ssize_t (GH-18663) (cherry picked from commit 57c7a0bdf4f7da8cf47f797f075950f6b8c98b99) Co-authored-by: Inada Naoki files: M Doc/c-api/arg.rst diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index f17c63d0b9dc9..b7baad589a72c 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -105,7 +105,7 @@ which disallows mutable objects such as :class:`bytearray`. Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``. -``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to ``NULL``. @@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`. bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (read-only :term:`bytes-like object`) [const char \*, int] +``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. @@ -155,7 +155,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``u#`` (:class:`str`) [const Py_UNICODE \*, int] +``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. This variant allows null code points. @@ -172,7 +172,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] Like ``u#``, but the Python object may also be ``None``, in which case the :c:type:`Py_UNICODE` pointer is set to ``NULL``. @@ -213,7 +213,7 @@ which disallows mutable objects such as :class:`bytearray`. recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] This variant on ``s#`` is used for encoding Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -244,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] Same as ``es#`` except that byte string objects are passed through without recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. @@ -549,7 +549,7 @@ Building values Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, ``None`` is used. - ``s#`` (:class:`str` or ``None``) [const char \*, int] + ``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -558,14 +558,14 @@ Building values This converts a C string to a Python :class:`bytes` object. If the C string pointer is ``NULL``, ``None`` is returned. - ``y#`` (:class:`bytes`) [const char \*, int] + ``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`] This converts a C string and its lengths to a Python object. If the C string pointer is ``NULL``, ``None`` is returned. ``z`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``z#`` (:class:`str` or ``None``) [const char \*, int] + ``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] @@ -573,7 +573,7 @@ Building values data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. - ``u#`` (:class:`str`) [const wchar_t \*, int] + ``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`] Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -581,7 +581,7 @@ Building values ``U`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``U#`` (:class:`str` or ``None``) [const char \*, int] + ``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``i`` (:class:`int`) [int] From webhook-mailer at python.org Wed Feb 26 02:00:40 2020 From: webhook-mailer at python.org (sweeneyde) Date: Wed, 26 Feb 2020 07:00:40 -0000 Subject: [Python-checkins] bpo-39737: Remove code repitition in list_richcompare (GH-18638) Message-ID: https://github.com/python/cpython/commit/be7ead62db9a1db3e2cd997b0beffd4480e51f5c commit: be7ead62db9a1db3e2cd997b0beffd4480e51f5c branch: master author: sweeneyde <36520290+sweeneyde at users.noreply.github.com> committer: GitHub date: 2020-02-26T09:00:35+02:00 summary: bpo-39737: Remove code repitition in list_richcompare (GH-18638) I may speed up list comparison on some platforms. files: M Objects/listobject.c diff --git a/Objects/listobject.c b/Objects/listobject.c index 3c39c6444bfd6..3ac03b71d03ac 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2643,8 +2643,7 @@ list_richcompare(PyObject *v, PyObject *w, int op) Py_INCREF(vitem); Py_INCREF(witem); - int k = PyObject_RichCompareBool(vl->ob_item[i], - wl->ob_item[i], Py_EQ); + int k = PyObject_RichCompareBool(vitem, witem, Py_EQ); Py_DECREF(vitem); Py_DECREF(witem); if (k < 0) From webhook-mailer at python.org Wed Feb 26 09:34:02 2020 From: webhook-mailer at python.org (opavlyuk) Date: Wed, 26 Feb 2020 14:34:02 -0000 Subject: [Python-checkins] bpo-34788: Add support for scoped IPv6 addresses (GH-13772) Message-ID: https://github.com/python/cpython/commit/21da76d1f1b527d62b2e9ef79dd9aa514d996341 commit: 21da76d1f1b527d62b2e9ef79dd9aa514d996341 branch: master author: opavlyuk <40970635+opavlyuk at users.noreply.github.com> committer: GitHub date: 2020-02-26T06:33:57-08:00 summary: bpo-34788: Add support for scoped IPv6 addresses (GH-13772) Automerge-Triggered-By: @asvetlov files: A Misc/NEWS.d/next/Library/2019-07-17-08-26-14.bpo-34788.pwV1OK.rst M Doc/library/ipaddress.rst M Doc/library/socket.rst M Doc/tools/susp-ignored.csv M Doc/whatsnew/3.9.rst M Lib/ipaddress.py M Lib/test/test_ipaddress.py diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index 140401d2f3673..5938439941792 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -217,11 +217,20 @@ write code that handles both IP versions correctly. Address objects are :RFC:`4291` for details. For example, ``"0000:0000:0000:0000:0000:0abc:0007:0def"`` can be compressed to ``"::abc:7:def"``. + + Optionally, the string may also have a scope zone ID, expressed + with a suffix ``%scope_id``. If present, the scope ID must be non-empty, + and may not contain ``%``. + See :RFC:`4007` for details. + For example, ``fe80::1234%1`` might identify address ``fe80::1234`` on the first link of the node. 2. An integer that fits into 128 bits. 3. An integer packed into a :class:`bytes` object of length 16, big-endian. + >>> ipaddress.IPv6Address('2001:db8::1000') IPv6Address('2001:db8::1000') + >>> ipaddress.IPv6Address('ff02::5678%1') + IPv6Address('ff02::5678%1') .. attribute:: compressed @@ -268,6 +277,12 @@ write code that handles both IP versions correctly. Address objects are ``::FFFF/96``), this property will report the embedded IPv4 address. For any other address, this property will be ``None``. + .. attribute:: scope_id + + For scoped addresses as defined by :RFC:`4007`, this property identifies + the particular zone of the address's scope that the address belongs to, + as a string. When no scope zone is specified, this property will be ``None``. + .. attribute:: sixtofour For addresses that appear to be 6to4 addresses (starting with @@ -299,6 +314,8 @@ the :func:`str` and :func:`int` builtin functions:: >>> int(ipaddress.IPv6Address('::1')) 1 +Note that IPv6 scoped addresses are converted to integers without scope zone ID. + Operators ^^^^^^^^^ @@ -311,8 +328,9 @@ IPv6). Comparison operators """""""""""""""""""" -Address objects can be compared with the usual set of comparison operators. Some -examples:: +Address objects can be compared with the usual set of comparison operators. +Same IPv6 addresses with different scope zone IDs are not equal. +Some examples:: >>> IPv4Address('127.0.0.2') > IPv4Address('127.0.0.1') True @@ -320,6 +338,10 @@ examples:: False >>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1') True + >>> IPv6Address('fe80::1234') == IPv6Address('fe80::1234%1') + False + >>> IPv6Address('fe80::1234%1') != IPv6Address('fe80::1234%2') + True Arithmetic operators diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 2cc946c519d40..5426b5abe4f0f 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -78,15 +78,15 @@ created. Socket addresses are represented as follows: Python programs. - For :const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo, - scopeid)`` is used, where *flowinfo* and *scopeid* represent the ``sin6_flowinfo`` + scope_id)`` is used, where *flowinfo* and *scope_id* represent the ``sin6_flowinfo`` and ``sin6_scope_id`` members in :const:`struct sockaddr_in6` in C. For - :mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for - backward compatibility. Note, however, omission of *scopeid* can cause problems + :mod:`socket` module methods, *flowinfo* and *scope_id* can be omitted just for + backward compatibility. Note, however, omission of *scope_id* can cause problems in manipulating scoped IPv6 addresses. .. versionchanged:: 3.7 - For multicast addresses (with *scopeid* meaningful) *address* may not contain - ``%scope`` (or ``zone id``) part. This information is superfluous and may + For multicast addresses (with *scope_id* meaningful) *address* may not contain + ``%scope_id`` (or ``zone id``) part. This information is superfluous and may be safely omitted (recommended). - :const:`AF_NETLINK` sockets are represented as pairs ``(pid, groups)``. @@ -738,7 +738,7 @@ The :mod:`socket` module also offers various network-related services: :const:`AI_CANONNAME` is part of the *flags* argument; else *canonname* will be empty. *sockaddr* is a tuple describing a socket address, whose format depends on the returned *family* (a ``(address, port)`` 2-tuple for - :const:`AF_INET`, a ``(address, port, flow info, scope id)`` 4-tuple for + :const:`AF_INET`, a ``(address, port, flowinfo, scope_id)`` 4-tuple for :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect` method. @@ -759,7 +759,7 @@ The :mod:`socket` module also offers various network-related services: .. versionchanged:: 3.7 for IPv6 multicast addresses, string representing an address will not - contain ``%scope`` part. + contain ``%scope_id`` part. .. function:: getfqdn([name]) @@ -827,8 +827,8 @@ The :mod:`socket` module also offers various network-related services: or numeric address representation in *host*. Similarly, *port* can contain a string port name or a numeric port number. - For IPv6 addresses, ``%scope`` is appended to the host part if *sockaddr* - contains meaningful *scopeid*. Usually this happens for multicast addresses. + For IPv6 addresses, ``%scope_id`` is appended to the host part if *sockaddr* + contains meaningful *scope_id*. Usually this happens for multicast addresses. For more information about *flags* you can consult :manpage:`getnameinfo(3)`. @@ -1354,7 +1354,7 @@ to sockets. .. versionchanged:: 3.7 For multicast IPv6 address, first item of *address* does not contain - ``%scope`` part anymore. In order to get full IPv6 address use + ``%scope_id`` part anymore. In order to get full IPv6 address use :func:`getnameinfo`. .. method:: socket.recvmsg(bufsize[, ancbufsize[, flags]]) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 5cdfd40f5b027..d3901be2f56c9 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -147,6 +147,8 @@ library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,:db8,IPv6Address('2001:db8::1000') library/ipaddress,,::,IPv6Address('2001:db8::1000') +library/ipaddress,,::,IPv6Address('ff02::5678%1') +library/ipaddress,,::,fe80::1234 library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" library/ipaddress,,::,"""::abc:7:def""" diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index a0ae4eb9b825a..d3b35fcff5c43 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -213,6 +213,15 @@ now raises :exc:`ImportError` instead of :exc:`ValueError` for invalid relative import attempts. (Contributed by Ngalim Siregar in :issue:`37444`.) +ipaddress +--------- + +:mod:`ipaddress` now supports IPv6 Scoped Addresses (IPv6 address with suffix ``%``). + +Scoped IPv6 addresses can be parsed using :class:`ipaddress.IPv6Address`. +If present, scope zone ID is available through the :attr:`~ipaddress.IPv6Address.scope_id` attribute. +(Contributed by Oleksandr Pavliuk in :issue:`34788`.) + math ---- diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 7d80a52c158a9..9c47405ce8d8c 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1836,6 +1836,26 @@ def _reverse_pointer(self): reverse_chars = self.exploded[::-1].replace(':', '') return '.'.join(reverse_chars) + '.ip6.arpa' + @staticmethod + def _split_scope_id(ip_str): + """Helper function to parse IPv6 string address with scope id. + + See RFC 4007 for details. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + (addr, scope_id) tuple. + + """ + addr, sep, scope_id = ip_str.partition('%') + if not sep: + scope_id = None + elif not scope_id or '%' in scope_id: + raise AddressValueError('Invalid IPv6 address: "%r"' % ip_str) + return addr, scope_id + @property def max_prefixlen(self): return self._max_prefixlen @@ -1849,7 +1869,7 @@ class IPv6Address(_BaseV6, _BaseAddress): """Represent and manipulate single IPv6 Addresses.""" - __slots__ = ('_ip', '__weakref__') + __slots__ = ('_ip', '_scope_id', '__weakref__') def __init__(self, address): """Instantiate a new IPv6 address object. @@ -1872,12 +1892,14 @@ def __init__(self, address): if isinstance(address, int): self._check_int_address(address) self._ip = address + self._scope_id = None return # Constructing from a packed address if isinstance(address, bytes): self._check_packed_address(address, 16) self._ip = int.from_bytes(address, 'big') + self._scope_id = None return # Assume input argument to be string or any object representation @@ -1885,8 +1907,37 @@ def __init__(self, address): addr_str = str(address) if '/' in addr_str: raise AddressValueError("Unexpected '/' in %r" % address) + addr_str, self._scope_id = self._split_scope_id(addr_str) + self._ip = self._ip_int_from_string(addr_str) + def __str__(self): + ip_str = super().__str__() + return ip_str + '%' + self._scope_id if self._scope_id else ip_str + + def __hash__(self): + return hash((self._ip, self._scope_id)) + + def __eq__(self, other): + address_equal = super().__eq__(other) + if address_equal is NotImplemented: + return NotImplemented + if not address_equal: + return False + return self._scope_id == getattr(other, '_scope_id', None) + + @property + def scope_id(self): + """Identifier of a particular zone of the address's scope. + + See RFC 4007 for details. + + Returns: + A string identifying the zone of the address if specified, else None. + + """ + return self._scope_id + @property def packed(self): """The binary representation of this address.""" @@ -2040,7 +2091,7 @@ def hostmask(self): return self.network.hostmask def __str__(self): - return '%s/%d' % (self._string_from_ip_int(self._ip), + return '%s/%d' % (super().__str__(), self._prefixlen) def __eq__(self, other): diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 3a59a6102f4c5..f4a4afba76a99 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -170,6 +170,15 @@ def assertBadLength(length): assertBadLength(15) assertBadLength(17) + def test_blank_scope_id(self): + address = ('::1%') + with self.assertAddressError('Invalid IPv6 address: "%r"', address): + self.factory(address) + + def test_invalid_scope_id_with_percent(self): + address = ('::1%scope%') + with self.assertAddressError('Invalid IPv6 address: "%r"', address): + self.factory(address) class AddressTestCase_v4(BaseTestCase, CommonTestMixin_v4): factory = ipaddress.IPv4Address @@ -328,24 +337,30 @@ def test_format(self): self.assertEqual(txt, format(v6, fmt)) def test_network_passed_as_address(self): - addr = "::1/24" - with self.assertAddressError("Unexpected '/' in %r", addr): - ipaddress.IPv6Address(addr) + def assertBadSplit(addr): + msg = "Unexpected '/' in %r" + with self.assertAddressError(msg, addr): + ipaddress.IPv6Address(addr) + assertBadSplit("::1/24") + assertBadSplit("::1%scope_id/24") def test_bad_address_split_v6_not_enough_parts(self): def assertBadSplit(addr): msg = "At least 3 parts expected in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit(":") assertBadSplit(":1") assertBadSplit("FEDC:9878") + assertBadSplit(":%scope") + assertBadSplit(":1%scope") + assertBadSplit("FEDC:9878%scope") def test_bad_address_split_v6_too_many_colons(self): def assertBadSplit(addr): msg = "At most 8 colons permitted in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit("9:8:7:6:5:4:3::2:1") @@ -355,10 +370,17 @@ def assertBadSplit(addr): # A trailing IPv4 address is two parts assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42") + assertBadSplit("9:8:7:6:5:4:3::2:1%scope") + assertBadSplit("10:9:8:7:6:5:4:3:2:1%scope") + assertBadSplit("::8:7:6:5:4:3:2:1%scope") + assertBadSplit("8:7:6:5:4:3:2:1::%scope") + # A trailing IPv4 address is two parts + assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42%scope") + def test_bad_address_split_v6_too_many_parts(self): def assertBadSplit(addr): msg = "Exactly 8 parts expected without '::' in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit("3ffe:0:0:0:0:0:0:0:1") @@ -368,18 +390,26 @@ def assertBadSplit(addr): assertBadSplit("9:8:7:6:5:4:3:42.42.42.42") assertBadSplit("7:6:5:4:3:42.42.42.42") + assertBadSplit("3ffe:0:0:0:0:0:0:0:1%scope") + assertBadSplit("9:8:7:6:5:4:3:2:1%scope") + assertBadSplit("7:6:5:4:3:2:1%scope") + # A trailing IPv4 address is two parts + assertBadSplit("9:8:7:6:5:4:3:42.42.42.42%scope") + assertBadSplit("7:6:5:4:3:42.42.42.42%scope") + def test_bad_address_split_v6_too_many_parts_with_double_colon(self): def assertBadSplit(addr): msg = "Expected at most 7 other parts with '::' in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit("1:2:3:4::5:6:7:8") + assertBadSplit("1:2:3:4::5:6:7:8%scope") def test_bad_address_split_v6_repeated_double_colon(self): def assertBadSplit(addr): msg = "At most one '::' permitted in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit("3ffe::1::1") @@ -393,10 +423,21 @@ def assertBadSplit(addr): assertBadSplit(":::") assertBadSplit('2001:db8:::1') + assertBadSplit("3ffe::1::1%scope") + assertBadSplit("1::2::3::4:5%scope") + assertBadSplit("2001::db:::1%scope") + assertBadSplit("3ffe::1::%scope") + assertBadSplit("::3ffe::1%scope") + assertBadSplit(":3ffe::1::1%scope") + assertBadSplit("3ffe::1::1:%scope") + assertBadSplit(":3ffe::1::1:%scope") + assertBadSplit(":::%scope") + assertBadSplit('2001:db8:::1%scope') + def test_bad_address_split_v6_leading_colon(self): def assertBadSplit(addr): msg = "Leading ':' only permitted as part of '::' in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit(":2001:db8::1") @@ -404,10 +445,15 @@ def assertBadSplit(addr): assertBadSplit(":1:2:3:4:5:6:") assertBadSplit(":6:5:4:3:2:1::") + assertBadSplit(":2001:db8::1%scope") + assertBadSplit(":1:2:3:4:5:6:7%scope") + assertBadSplit(":1:2:3:4:5:6:%scope") + assertBadSplit(":6:5:4:3:2:1::%scope") + def test_bad_address_split_v6_trailing_colon(self): def assertBadSplit(addr): msg = "Trailing ':' only permitted as part of '::' in %r" - with self.assertAddressError(msg, addr): + with self.assertAddressError(msg, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadSplit("2001:db8::1:") @@ -415,9 +461,14 @@ def assertBadSplit(addr): assertBadSplit("::1.2.3.4:") assertBadSplit("::7:6:5:4:3:2:") + assertBadSplit("2001:db8::1:%scope") + assertBadSplit("1:2:3:4:5:6:7:%scope") + assertBadSplit("::1.2.3.4:%scope") + assertBadSplit("::7:6:5:4:3:2:%scope") + def test_bad_v4_part_in(self): def assertBadAddressPart(addr, v4_error): - with self.assertAddressError("%s in %r", v4_error, addr): + with self.assertAddressError("%s in %r", v4_error, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadAddressPart("3ffe::1.net", "Expected 4 octets in '1.net'") @@ -431,9 +482,20 @@ def assertBadAddressPart(addr, v4_error): "Only decimal digits permitted in 'net' " "in '1.1.1.net'") + assertBadAddressPart("3ffe::1.net%scope", "Expected 4 octets in '1.net'") + assertBadAddressPart("3ffe::127.0.1%scope", + "Expected 4 octets in '127.0.1'") + assertBadAddressPart("::1.2.3%scope", + "Expected 4 octets in '1.2.3'") + assertBadAddressPart("::1.2.3.4.5%scope", + "Expected 4 octets in '1.2.3.4.5'") + assertBadAddressPart("3ffe::1.1.1.net%scope", + "Only decimal digits permitted in 'net' " + "in '1.1.1.net'") + def test_invalid_characters(self): def assertBadPart(addr, part): - msg = "Only hex digits permitted in %r in %r" % (part, addr) + msg = "Only hex digits permitted in %r in %r" % (part, addr.split('%')[0]) with self.assertAddressError(re.escape(msg)): ipaddress.IPv6Address(addr) @@ -444,10 +506,17 @@ def assertBadPart(addr, part): assertBadPart("1.2.3.4::", "1.2.3.4") assertBadPart('1234:axy::b', "axy") + assertBadPart("3ffe::goog%scope", "goog") + assertBadPart("3ffe::-0%scope", "-0") + assertBadPart("3ffe::+0%scope", "+0") + assertBadPart("3ffe::-1%scope", "-1") + assertBadPart("1.2.3.4::%scope", "1.2.3.4") + assertBadPart('1234:axy::b%scope', "axy") + def test_part_length(self): def assertBadPart(addr, part): msg = "At most 4 characters permitted in %r in %r" - with self.assertAddressError(msg, part, addr): + with self.assertAddressError(msg, part, addr.split('%')[0]): ipaddress.IPv6Address(addr) assertBadPart("::00000", "00000") @@ -455,11 +524,17 @@ def assertBadPart(addr, part): assertBadPart("02001:db8::", "02001") assertBadPart('2001:888888::1', "888888") + assertBadPart("::00000%scope", "00000") + assertBadPart("3ffe::10000%scope", "10000") + assertBadPart("02001:db8::%scope", "02001") + assertBadPart('2001:888888::1%scope', "888888") + def test_pickle(self): self.pickle_test('2001:db8::') def test_weakref(self): weakref.ref(self.factory('2001:db8::')) + weakref.ref(self.factory('2001:db8::%scope')) class NetmaskTestMixin_v4(CommonTestMixin_v4): @@ -617,11 +692,20 @@ def test_no_mask(self): # IPv6Network has prefixlen, but IPv6Interface doesn't. # Should we add it to IPv4Interface too? (bpo-36392) + scoped_net = self.factory('::1%scope') + self.assertEqual(str(scoped_net), '::1%scope/128') + self.assertEqual(str(scoped_net.netmask), 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff') + self.assertEqual(str(scoped_net.hostmask), '::') + def test_split_netmask(self): addr = "cafe:cafe::/128/190" with self.assertAddressError("Only one '/' permitted in %r" % addr): self.factory(addr) + scoped_addr = "cafe:cafe::%scope/128/190" + with self.assertAddressError("Only one '/' permitted in %r" % scoped_addr): + self.factory(scoped_addr) + def test_address_errors(self): def assertBadAddress(addr, details): with self.assertAddressError(details): @@ -634,6 +718,13 @@ def assertBadAddress(addr, details): assertBadAddress("10/8", "At least 3 parts") assertBadAddress("1234:axy::b", "Only hex digits") + assertBadAddress("/%scope", "Address cannot be empty") + assertBadAddress("/%scope8", "Address cannot be empty") + assertBadAddress("google.com%scope", "At least 3 parts") + assertBadAddress("1.2.3.4%scope", "At least 3 parts") + assertBadAddress("10%scope/8", "At least 3 parts") + assertBadAddress("1234:axy::b%scope", "Only hex digits") + def test_valid_netmask(self): # We only support CIDR for IPv6, because expanded netmasks are not # standard notation. @@ -645,6 +736,14 @@ def test_valid_netmask(self): # Zero prefix is treated as decimal. self.assertEqual(str(self.factory('::/0%d' % i)), net_str) + self.assertEqual(str(self.factory('2001:db8::%scope/32')), '2001:db8::%scope/32') + for i in range(0, 129): + # Generate and re-parse the CIDR format (trivial). + net_str = '::/%d' % i + self.assertEqual(str(self.factory(net_str)), net_str) + # Zero prefix is treated as decimal. + self.assertEqual(str(self.factory('::/0%d' % i)), net_str) + def test_netmask_errors(self): def assertBadNetmask(addr, netmask): msg = "%r is not a valid netmask" % netmask @@ -663,6 +762,8 @@ def assertBadNetmask(addr, netmask): assertBadNetmask("::1", "pudding") assertBadNetmask("::", "::") + assertBadNetmask("::1%scope", "pudding") + def test_netmask_in_tuple_errors(self): def assertBadNetmask(addr, netmask): msg = "%r is not a valid netmask" % netmask @@ -670,12 +771,15 @@ def assertBadNetmask(addr, netmask): self.factory((addr, netmask)) assertBadNetmask("::1", -1) assertBadNetmask("::1", 129) + assertBadNetmask("::1%scope", 129) def test_pickle(self): self.pickle_test('2001:db8::1000/124') self.pickle_test('2001:db8::1000/127') # IPV6LENGTH - 1 self.pickle_test('2001:db8::1000') # IPV6LENGTH + self.pickle_test('2001:db8::1000%scope') # IPV6LENGTH + class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6): factory = ipaddress.IPv6Interface @@ -702,6 +806,13 @@ def test_subnet_of(self): self.factory('2000:aaa::/48').subnet_of( self.factory('2000:aaa::/56'))) + self.assertFalse( + self.factory('2000:999::%scope/56').subnet_of( + self.factory('2000:aaa::%scope/48'))) + self.assertTrue( + self.factory('2000:aaa::%scope/56').subnet_of( + self.factory('2000:aaa::%scope/48'))) + def test_supernet_of(self): # containee left of container self.assertFalse( @@ -748,13 +859,19 @@ class ComparisonTests(unittest.TestCase): v6addr = ipaddress.IPv6Address(1) v6net = ipaddress.IPv6Network(1) v6intf = ipaddress.IPv6Interface(1) + v6addr_scoped = ipaddress.IPv6Address('::1%scope') + v6net_scoped= ipaddress.IPv6Network('::1%scope') + v6intf_scoped= ipaddress.IPv6Interface('::1%scope') v4_addresses = [v4addr, v4intf] v4_objects = v4_addresses + [v4net] v6_addresses = [v6addr, v6intf] v6_objects = v6_addresses + [v6net] + v6_scoped_addresses = [v6addr_scoped, v6intf_scoped] + v6_scoped_objects = v6_scoped_addresses + [v6net_scoped] objects = v4_objects + v6_objects + objects_with_scoped = objects + v6_scoped_objects v4addr2 = ipaddress.IPv4Address(2) v4net2 = ipaddress.IPv4Network(2) @@ -762,11 +879,14 @@ class ComparisonTests(unittest.TestCase): v6addr2 = ipaddress.IPv6Address(2) v6net2 = ipaddress.IPv6Network(2) v6intf2 = ipaddress.IPv6Interface(2) + v6addr2_scoped = ipaddress.IPv6Address('::2%scope') + v6net2_scoped = ipaddress.IPv6Network('::2%scope') + v6intf2_scoped = ipaddress.IPv6Interface('::2%scope') def test_foreign_type_equality(self): # __eq__ should never raise TypeError directly other = object() - for obj in self.objects: + for obj in self.objects_with_scoped: self.assertNotEqual(obj, other) self.assertFalse(obj == other) self.assertEqual(obj.__eq__(other), NotImplemented) @@ -781,8 +901,17 @@ def test_mixed_type_equality(self): continue self.assertNotEqual(lhs, rhs) + def test_scoped_ipv6_equality(self): + for lhs, rhs in zip(self.v6_objects, self.v6_scoped_objects): + self.assertNotEqual(lhs, rhs) + + def test_v4_with_v6_scoped_equality(self): + for lhs in self.v4_objects: + for rhs in self.v6_scoped_objects: + self.assertNotEqual(lhs, rhs) + def test_same_type_equality(self): - for obj in self.objects: + for obj in self.objects_with_scoped: self.assertEqual(obj, obj) self.assertLessEqual(obj, obj) self.assertGreaterEqual(obj, obj) @@ -795,6 +924,9 @@ def test_same_type_ordering(self): (self.v6addr, self.v6addr2), (self.v6net, self.v6net2), (self.v6intf, self.v6intf2), + (self.v6addr_scoped, self.v6addr2_scoped), + (self.v6net_scoped, self.v6net2_scoped), + (self.v6intf_scoped, self.v6intf2_scoped), ): self.assertNotEqual(lhs, rhs) self.assertLess(lhs, rhs) @@ -809,16 +941,21 @@ def test_same_type_ordering(self): def test_containment(self): for obj in self.v4_addresses: self.assertIn(obj, self.v4net) - for obj in self.v6_addresses: + for obj in self.v6_addresses + self.v6_scoped_addresses: self.assertIn(obj, self.v6net) - for obj in self.v4_objects + [self.v6net]: + for obj in self.v6_addresses + self.v6_scoped_addresses: + self.assertIn(obj, self.v6net_scoped) + + for obj in self.v4_objects + [self.v6net, self.v6net_scoped]: self.assertNotIn(obj, self.v6net) - for obj in self.v6_objects + [self.v4net]: + for obj in self.v4_objects + [self.v6net, self.v6net_scoped]: + self.assertNotIn(obj, self.v6net_scoped) + for obj in self.v6_objects + self.v6_scoped_objects + [self.v4net]: self.assertNotIn(obj, self.v4net) def test_mixed_type_ordering(self): - for lhs in self.objects: - for rhs in self.objects: + for lhs in self.objects_with_scoped: + for rhs in self.objects_with_scoped: if isinstance(lhs, type(rhs)) or isinstance(rhs, type(lhs)): continue self.assertRaises(TypeError, lambda: lhs < rhs) @@ -828,7 +965,7 @@ def test_mixed_type_ordering(self): def test_foreign_type_ordering(self): other = object() - for obj in self.objects: + for obj in self.objects_with_scoped: with self.assertRaises(TypeError): obj < other with self.assertRaises(TypeError): @@ -850,14 +987,18 @@ def test_mixed_type_key(self): # with get_mixed_type_key, you can sort addresses and network. v4_ordered = [self.v4addr, self.v4net, self.v4intf] v6_ordered = [self.v6addr, self.v6net, self.v6intf] + v6_scoped_ordered = [self.v6addr_scoped, self.v6net_scoped, self.v6intf_scoped] self.assertEqual(v4_ordered, sorted(self.v4_objects, key=ipaddress.get_mixed_type_key)) self.assertEqual(v6_ordered, sorted(self.v6_objects, key=ipaddress.get_mixed_type_key)) - self.assertEqual(v4_ordered + v6_ordered, - sorted(self.objects, + self.assertEqual(v6_scoped_ordered, + sorted(self.v6_scoped_objects, + key=ipaddress.get_mixed_type_key)) + self.assertEqual(v4_ordered + v6_scoped_ordered, + sorted(self.v4_objects + self.v6_scoped_objects, key=ipaddress.get_mixed_type_key)) self.assertEqual(NotImplemented, ipaddress.get_mixed_type_key(object)) @@ -867,6 +1008,8 @@ def test_incompatible_versions(self): v4net = ipaddress.ip_network('1.1.1.1') v6addr = ipaddress.ip_address('::1') v6net = ipaddress.ip_network('::1') + v6addr_scoped = ipaddress.ip_address('::1%scope') + v6net_scoped = ipaddress.ip_network('::1%scope') self.assertRaises(TypeError, v4addr.__lt__, v6addr) self.assertRaises(TypeError, v4addr.__gt__, v6addr) @@ -878,6 +1021,16 @@ def test_incompatible_versions(self): self.assertRaises(TypeError, v6net.__lt__, v4net) self.assertRaises(TypeError, v6net.__gt__, v4net) + self.assertRaises(TypeError, v4addr.__lt__, v6addr_scoped) + self.assertRaises(TypeError, v4addr.__gt__, v6addr_scoped) + self.assertRaises(TypeError, v4net.__lt__, v6net_scoped) + self.assertRaises(TypeError, v4net.__gt__, v6net_scoped) + + self.assertRaises(TypeError, v6addr_scoped.__lt__, v4addr) + self.assertRaises(TypeError, v6addr_scoped.__gt__, v4addr) + self.assertRaises(TypeError, v6net_scoped.__lt__, v4net) + self.assertRaises(TypeError, v6net_scoped.__gt__, v4net) + class IpaddrUnitTest(unittest.TestCase): @@ -891,12 +1044,19 @@ def setUp(self): self.ipv6_interface = ipaddress.IPv6Interface( '2001:658:22a:cafe:200:0:0:1/64') self.ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/64') + self.ipv6_scoped_address = ipaddress.IPv6Interface( + '2001:658:22a:cafe:200:0:0:1%scope') + self.ipv6_scoped_interface = ipaddress.IPv6Interface( + '2001:658:22a:cafe:200:0:0:1%scope/64') + self.ipv6_scoped_network = ipaddress.IPv6Network('2001:658:22a:cafe::%scope/64') def testRepr(self): self.assertEqual("IPv4Interface('1.2.3.4/32')", repr(ipaddress.IPv4Interface('1.2.3.4'))) self.assertEqual("IPv6Interface('::1/128')", repr(ipaddress.IPv6Interface('::1'))) + self.assertEqual("IPv6Interface('::1%scope/128')", + repr(ipaddress.IPv6Interface('::1%scope'))) # issue #16531: constructing IPv4Network from an (address, mask) tuple def testIPv4Tuple(self): @@ -983,6 +1143,8 @@ def testIPv6Tuple(self): self.assertEqual(ipaddress.IPv6Network((ip, '96')), net) + ip_scoped = ipaddress.IPv6Address('2001:db8::%scope') + # strict=True and host bits set ip = ipaddress.IPv6Address('2001:db8::1') with self.assertRaises(ValueError): @@ -1011,6 +1173,13 @@ def testIPv6Tuple(self): (42540766411282592856903984951653826561, '96')), ipaddress.IPv6Interface('2001:db8::1/96')) + ip_scoped = ipaddress.IPv6Address('2001:db8::1%scope') + with self.assertRaises(ValueError): + ipaddress.IPv6Network(('2001:db8::1%scope', 96)) + with self.assertRaises(ValueError): + ipaddress.IPv6Network((ip_scoped, 96)) + # strict=False and host bits set + # issue57 def testAddressIntMath(self): self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255, @@ -1021,6 +1190,10 @@ def testAddressIntMath(self): ipaddress.IPv6Address('::ffff')) self.assertEqual(ipaddress.IPv6Address('::ffff') - (2**16 - 2), ipaddress.IPv6Address('::1')) + self.assertNotEqual(ipaddress.IPv6Address('::1%scope') + (2**16 - 2), + ipaddress.IPv6Address('::ffff%scope')) + self.assertNotEqual(ipaddress.IPv6Address('::ffff%scope') - (2**16 - 2), + ipaddress.IPv6Address('::1%scope')) def testInvalidIntToBytes(self): self.assertRaises(ValueError, ipaddress.v4_int_to_packed, -1) @@ -1053,6 +1226,12 @@ def testGetNetwork(self): '2001:658:22a:cafe::') self.assertEqual(str(self.ipv6_network.hostmask), '::ffff:ffff:ffff:ffff') + self.assertEqual(int(self.ipv6_scoped_network.network_address), + 42540616829182469433403647294022090752) + self.assertEqual(str(self.ipv6_scoped_network.network_address), + '2001:658:22a:cafe::%scope') + self.assertEqual(str(self.ipv6_scoped_network.hostmask), + '::ffff:ffff:ffff:ffff') def testIpFromInt(self): self.assertEqual(self.ipv4_interface._ip, @@ -1060,17 +1239,23 @@ def testIpFromInt(self): ipv4 = ipaddress.ip_network('1.2.3.4') ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1') + ipv6_scoped = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1%scope') self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address))) self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address))) + self.assertNotEqual(ipv6_scoped, ipaddress.ip_network(int(ipv6_scoped.network_address))) v6_int = 42540616829182469433547762482097946625 self.assertEqual(self.ipv6_interface._ip, ipaddress.IPv6Interface(v6_int)._ip) + self.assertEqual(self.ipv6_scoped_interface._ip, + ipaddress.IPv6Interface(v6_int)._ip) self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version, 4) self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version, 6) + self.assertEqual(ipaddress.ip_network(self.ipv6_scoped_address._ip).version, + 6) def testIpFromPacked(self): address = ipaddress.ip_address @@ -1096,6 +1281,24 @@ def testGetIp(self): 42540616829182469433547762482097946625) self.assertEqual(str(self.ipv6_interface.ip), '2001:658:22a:cafe:200::1') + self.assertEqual(int(self.ipv6_scoped_interface.ip), + 42540616829182469433547762482097946625) + self.assertEqual(str(self.ipv6_scoped_interface.ip), + '2001:658:22a:cafe:200::1') + + def testGetScopeId(self): + self.assertEqual(self.ipv6_address.scope_id, + None) + self.assertEqual(str(self.ipv6_scoped_address.scope_id), + 'scope') + self.assertEqual(self.ipv6_interface.scope_id, + None) + self.assertEqual(str(self.ipv6_scoped_interface.scope_id), + 'scope') + self.assertEqual(self.ipv6_network.network_address.scope_id, + None) + self.assertEqual(str(self.ipv6_scoped_network.network_address.scope_id), + 'scope') def testGetNetmask(self): self.assertEqual(int(self.ipv4_network.netmask), 4294967040) @@ -1103,6 +1306,9 @@ def testGetNetmask(self): self.assertEqual(int(self.ipv6_network.netmask), 340282366920938463444927863358058659840) self.assertEqual(self.ipv6_network.prefixlen, 64) + self.assertEqual(int(self.ipv6_scoped_network.netmask), + 340282366920938463444927863358058659840) + self.assertEqual(self.ipv6_scoped_network.prefixlen, 64) def testZeroNetmask(self): ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0') @@ -1113,6 +1319,10 @@ def testZeroNetmask(self): self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0) self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0) + ipv6_scoped_zero_netmask = ipaddress.IPv6Interface('::1%scope/0') + self.assertEqual(int(ipv6_scoped_zero_netmask.network.netmask), 0) + self.assertEqual(ipv6_scoped_zero_netmask._prefix_from_prefix_string('0'), 0) + def testIPv4Net(self): net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255') self.assertEqual(net.prefixlen, 24) @@ -1126,9 +1336,15 @@ def testGetBroadcast(self): self.assertEqual(str(self.ipv6_network.broadcast_address), '2001:658:22a:cafe:ffff:ffff:ffff:ffff') + self.assertEqual(int(self.ipv6_scoped_network.broadcast_address), + 42540616829182469451850391367731642367) + self.assertEqual(str(self.ipv6_scoped_network.broadcast_address), + '2001:658:22a:cafe:ffff:ffff:ffff:ffff') + def testGetPrefixlen(self): self.assertEqual(self.ipv4_interface.network.prefixlen, 24) self.assertEqual(self.ipv6_interface.network.prefixlen, 64) + self.assertEqual(self.ipv6_scoped_interface.network.prefixlen, 64) def testGetSupernet(self): self.assertEqual(self.ipv4_network.supernet().prefixlen, 23) @@ -1143,6 +1359,9 @@ def testGetSupernet(self): '2001:658:22a:cafe::') self.assertEqual(ipaddress.IPv6Interface('::0/0').network.supernet(), ipaddress.IPv6Network('::0/0')) + self.assertEqual(self.ipv6_scoped_network.supernet().prefixlen, 63) + self.assertEqual(str(self.ipv6_scoped_network.supernet().network_address), + '2001:658:22a:cafe::') def testGetSupernet3(self): self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21) @@ -1152,6 +1371,9 @@ def testGetSupernet3(self): self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61) self.assertEqual(str(self.ipv6_network.supernet(3).network_address), '2001:658:22a:caf8::') + self.assertEqual(self.ipv6_scoped_network.supernet(3).prefixlen, 61) + self.assertEqual(str(self.ipv6_scoped_network.supernet(3).network_address), + '2001:658:22a:caf8::') def testGetSupernet4(self): self.assertRaises(ValueError, self.ipv4_network.supernet, @@ -1167,6 +1389,12 @@ def testGetSupernet4(self): new_prefix=65) self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2), self.ipv6_network.supernet(new_prefix=62)) + self.assertRaises(ValueError, self.ipv6_scoped_network.supernet, + prefixlen_diff=2, new_prefix=1) + self.assertRaises(ValueError, self.ipv6_scoped_network.supernet, + new_prefix=65) + self.assertEqual(self.ipv6_scoped_network.supernet(prefixlen_diff=2), + self.ipv6_scoped_network.supernet(new_prefix=62)) def testHosts(self): hosts = list(self.ipv4_network.hosts()) @@ -1180,6 +1408,12 @@ def testHosts(self): self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), hosts[0]) self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::ff'), hosts[-1]) + ipv6_scoped_network = ipaddress.IPv6Network('2001:658:22a:cafe::%scope/120') + hosts = list(ipv6_scoped_network.hosts()) + self.assertEqual(255, len(hosts)) + self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), hosts[0]) + self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::ff'), hosts[-1]) + # special case where only 1 bit is left for address addrs = [ipaddress.IPv4Address('2.0.0.0'), ipaddress.IPv4Address('2.0.0.1')] @@ -1198,6 +1432,14 @@ def testHosts(self): self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), list(ipaddress.ip_network(tpl_args).hosts())) + addrs = [ipaddress.IPv6Address('2001:658:22a:cafe::'), + ipaddress.IPv6Address('2001:658:22a:cafe::1')] + str_args = '2001:658:22a:cafe::/127' + tpl_args = ('2001:658:22a:cafe::', 127) + self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts())) + self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) + self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), + list(ipaddress.ip_network(tpl_args).hosts())) def testFancySubnetting(self): self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)), @@ -1214,6 +1456,13 @@ def testFancySubnetting(self): self.assertRaises(ValueError, list, self.ipv6_network.subnets(prefixlen_diff=4, new_prefix=68)) + self.assertEqual(sorted(self.ipv6_scoped_network.subnets(prefixlen_diff=4)), + sorted(self.ipv6_scoped_network.subnets(new_prefix=68))) + self.assertRaises(ValueError, list, + self.ipv6_scoped_network.subnets(new_prefix=63)) + self.assertRaises(ValueError, list, + self.ipv6_scoped_network.subnets(prefixlen_diff=4, + new_prefix=68)) def testGetSubnets(self): self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25) @@ -1225,6 +1474,7 @@ def testGetSubnets(self): '1.2.3.128') self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65) + self.assertEqual(list(self.ipv6_scoped_network.subnets())[0].prefixlen, 65) def testGetSubnetForSingle32(self): ip = ipaddress.IPv4Network('1.2.3.4/32') @@ -1240,6 +1490,12 @@ def testGetSubnetForSingle128(self): self.assertEqual(subnets1, ['::1/128']) self.assertEqual(subnets1, subnets2) + ip_scoped = ipaddress.IPv6Network('::1%scope/128') + subnets1 = [str(x) for x in ip_scoped.subnets()] + subnets2 = [str(x) for x in ip_scoped.subnets(2)] + self.assertEqual(subnets1, ['::1%scope/128']) + self.assertEqual(subnets1, subnets2) + def testSubnet2(self): ips = [str(x) for x in self.ipv4_network.subnets(2)] self.assertEqual( @@ -1283,12 +1539,18 @@ def testSubnetFailsForLargeCidrDiff(self): self.ipv6_interface.network.subnets(65)) self.assertRaises(ValueError, list, self.ipv6_network.subnets(65)) + self.assertRaises(ValueError, list, + self.ipv6_scoped_interface.network.subnets(65)) + self.assertRaises(ValueError, list, + self.ipv6_scoped_network.subnets(65)) def testSupernetFailsForLargeCidrDiff(self): self.assertRaises(ValueError, self.ipv4_interface.network.supernet, 25) self.assertRaises(ValueError, self.ipv6_interface.network.supernet, 65) + self.assertRaises(ValueError, + self.ipv6_scoped_interface.network.supernet, 65) def testSubnetFailsForNegativeCidrDiff(self): self.assertRaises(ValueError, list, @@ -1299,6 +1561,10 @@ def testSubnetFailsForNegativeCidrDiff(self): self.ipv6_interface.network.subnets(-1)) self.assertRaises(ValueError, list, self.ipv6_network.subnets(-1)) + self.assertRaises(ValueError, list, + self.ipv6_scoped_interface.network.subnets(-1)) + self.assertRaises(ValueError, list, + self.ipv6_scoped_network.subnets(-1)) def testGetNum_Addresses(self): self.assertEqual(self.ipv4_network.num_addresses, 256) @@ -1311,6 +1577,11 @@ def testGetNum_Addresses(self): 9223372036854775808) self.assertEqual(self.ipv6_network.supernet().num_addresses, 36893488147419103232) + self.assertEqual(self.ipv6_scoped_network.num_addresses, 18446744073709551616) + self.assertEqual(list(self.ipv6_scoped_network.subnets())[0].num_addresses, + 9223372036854775808) + self.assertEqual(self.ipv6_scoped_network.supernet().num_addresses, + 36893488147419103232) def testContains(self): self.assertIn(ipaddress.IPv4Interface('1.2.3.128/25'), @@ -1332,6 +1603,9 @@ def testNth(self): self.assertEqual(str(self.ipv6_network[5]), '2001:658:22a:cafe::5') self.assertRaises(IndexError, self.ipv6_network.__getitem__, 1 << 64) + self.assertEqual(str(self.ipv6_scoped_network[5]), + '2001:658:22a:cafe::5') + self.assertRaises(IndexError, self.ipv6_scoped_network.__getitem__, 1 << 64) def testGetitem(self): # http://code.google.com/p/ipaddr-py/issues/detail?id=15 @@ -1351,6 +1625,8 @@ def testEqual(self): ipaddress.IPv4Interface('1.2.3.4/23')) self.assertFalse(self.ipv4_interface == ipaddress.IPv6Interface('::1.2.3.4/24')) + self.assertFalse(self.ipv4_interface == + ipaddress.IPv6Interface('::1.2.3.4%scope/24')) self.assertFalse(self.ipv4_interface == '') self.assertFalse(self.ipv4_interface == []) self.assertFalse(self.ipv4_interface == 2) @@ -1365,6 +1641,20 @@ def testEqual(self): self.assertFalse(self.ipv6_interface == []) self.assertFalse(self.ipv6_interface == 2) + self.assertTrue(self.ipv6_scoped_interface == + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1%scope/64')) + self.assertFalse(self.ipv6_scoped_interface == + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1%scope/63')) + self.assertFalse(self.ipv6_scoped_interface == + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64')) + self.assertFalse(self.ipv6_scoped_interface == + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63')) + self.assertFalse(self.ipv6_scoped_interface == + ipaddress.IPv4Interface('1.2.3.4/23')) + self.assertFalse(self.ipv6_scoped_interface == '') + self.assertFalse(self.ipv6_scoped_interface == []) + self.assertFalse(self.ipv6_scoped_interface == 2) + def testNotEqual(self): self.assertFalse(self.ipv4_interface != ipaddress.IPv4Interface('1.2.3.4/24')) @@ -1372,6 +1662,8 @@ def testNotEqual(self): ipaddress.IPv4Interface('1.2.3.4/23')) self.assertTrue(self.ipv4_interface != ipaddress.IPv6Interface('::1.2.3.4/24')) + self.assertTrue(self.ipv4_interface != + ipaddress.IPv6Interface('::1.2.3.4%scope/24')) self.assertTrue(self.ipv4_interface != '') self.assertTrue(self.ipv4_interface != []) self.assertTrue(self.ipv4_interface != 2) @@ -1398,6 +1690,26 @@ def testNotEqual(self): self.assertTrue(self.ipv6_address != []) self.assertTrue(self.ipv6_address != 2) + self.assertFalse(self.ipv6_scoped_interface != + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1%scope/64')) + self.assertTrue(self.ipv6_scoped_interface != + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1%scope/63')) + self.assertTrue(self.ipv6_scoped_interface != + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64')) + self.assertTrue(self.ipv6_scoped_interface != + ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63')) + self.assertTrue(self.ipv6_scoped_interface != + ipaddress.IPv4Interface('1.2.3.4/23')) + self.assertTrue(self.ipv6_scoped_interface != '') + self.assertTrue(self.ipv6_scoped_interface != []) + self.assertTrue(self.ipv6_scoped_interface != 2) + + self.assertTrue(self.ipv6_scoped_address != + ipaddress.IPv4Address('1.2.3.4')) + self.assertTrue(self.ipv6_scoped_address != '') + self.assertTrue(self.ipv6_scoped_address != []) + self.assertTrue(self.ipv6_scoped_address != 2) + def testSlash32Constructor(self): self.assertEqual(str(ipaddress.IPv4Interface( '1.2.3.4/255.255.255.255')), '1.2.3.4/32') @@ -1405,6 +1717,8 @@ def testSlash32Constructor(self): def testSlash128Constructor(self): self.assertEqual(str(ipaddress.IPv6Interface('::1/128')), '::1/128') + self.assertEqual(str(ipaddress.IPv6Interface('::1%scope/128')), + '::1%scope/128') def testSlash0Constructor(self): self.assertEqual(str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')), @@ -1476,6 +1790,13 @@ def testCollapsing(self): collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3]) self.assertEqual(list(collapsed), [ip3]) + ip1 = ipaddress.IPv6Network('2001::%scope/100') + ip2 = ipaddress.IPv6Network('2001::%scope/120') + ip3 = ipaddress.IPv6Network('2001::%scope/96') + # test that ipv6 addresses are subsumed properly. + collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3]) + self.assertEqual(list(collapsed), [ip3]) + # the toejam test addr_tuples = [ (ipaddress.ip_address('1.1.1.1'), @@ -1489,6 +1810,18 @@ def testCollapsing(self): self.assertRaises(TypeError, ipaddress.collapse_addresses, [ip1, ip2]) + addr_tuples = [ + (ipaddress.ip_address('1.1.1.1'), + ipaddress.ip_address('::1%scope')), + (ipaddress.IPv4Network('1.1.0.0/24'), + ipaddress.IPv6Network('2001::%scope/120')), + (ipaddress.IPv4Network('1.1.0.0/32'), + ipaddress.IPv6Network('2001::%scope/128')), + ] + for ip1, ip2 in addr_tuples: + self.assertRaises(TypeError, ipaddress.collapse_addresses, + [ip1, ip2]) + def testSummarizing(self): #ip = ipaddress.ip_address #ipnet = ipaddress.ip_network @@ -1508,6 +1841,8 @@ def version(self): # test that a summary over ip4 & ip6 fails self.assertRaises(TypeError, list, summarize(ip1, ipaddress.IPv6Address('::1'))) + self.assertRaises(TypeError, list, + summarize(ip1, ipaddress.IPv6Address('::1%scope'))) # test a /24 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1.1.1.0/24')) @@ -1533,6 +1868,17 @@ def version(self): [ipaddress.ip_network('1::/16'), ipaddress.ip_network('2::/128')]) + ip1 = ipaddress.ip_address('1::%scope') + ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff%scope') + # test an IPv6 is summarized properly + self.assertEqual(list(summarize(ip1, ip2))[0], + ipaddress.ip_network('1::/16')) + # test an IPv6 range that isn't on a network byte boundary + ip2 = ipaddress.ip_address('2::%scope') + self.assertEqual(list(summarize(ip1, ip2)), + [ipaddress.ip_network('1::/16'), + ipaddress.ip_network('2::/128')]) + # test exception raised when first is greater than last self.assertRaises(ValueError, list, summarize(ipaddress.ip_address('1.1.1.0'), @@ -1558,6 +1904,10 @@ def testAddressComparison(self): ipaddress.ip_address('::1')) self.assertTrue(ipaddress.ip_address('::1') <= ipaddress.ip_address('::2')) + self.assertTrue(ipaddress.ip_address('::1%scope') <= + ipaddress.ip_address('::1%scope')) + self.assertTrue(ipaddress.ip_address('::1%scope') <= + ipaddress.ip_address('::2%scope')) def testInterfaceComparison(self): self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') == @@ -1590,6 +1940,52 @@ def testInterfaceComparison(self): self.assertTrue(ipaddress.ip_interface('::1/64') > ipaddress.ip_interface('::2/48')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') == + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') < + ipaddress.ip_interface('::1%scope/80')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') < + ipaddress.ip_interface('::2%scope/64')) + self.assertTrue(ipaddress.ip_interface('::2%scope/48') < + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/80') > + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::2%scope/64') > + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') > + ipaddress.ip_interface('::2%scope/48')) + + + self.assertFalse(ipaddress.ip_interface('::1%scope/64') == + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') < + ipaddress.ip_interface('::1/80')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') < + ipaddress.ip_interface('::2/64')) + self.assertTrue(ipaddress.ip_interface('::2%scope/48') < + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/80') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::2%scope/64') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1%scope/64') > + ipaddress.ip_interface('::2/48')) + + self.assertFalse(ipaddress.ip_interface('::1/64') == + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::1%scope/80')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::2%scope/64')) + self.assertTrue(ipaddress.ip_interface('::2/48') < + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1/80') > + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::2/64') > + ipaddress.ip_interface('::1%scope/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') > + ipaddress.ip_interface('::2%scope/48')) + def testNetworkComparison(self): # ip1 and ip2 have the same network address ip1 = ipaddress.IPv4Network('1.1.1.0/24') @@ -1669,6 +2065,7 @@ def testNetworkComparison(self): ipaddress.ip_network('1.1.1.2')) self.assertFalse(ipaddress.ip_network('1.1.1.2') <= ipaddress.ip_network('1.1.1.1')) + self.assertTrue(ipaddress.ip_network('::1') <= ipaddress.ip_network('::1')) self.assertTrue(ipaddress.ip_network('::1') <= @@ -1679,6 +2076,7 @@ def testNetworkComparison(self): def testStrictNetworks(self): self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24') self.assertRaises(ValueError, ipaddress.ip_network, '::1/120') + self.assertRaises(ValueError, ipaddress.ip_network, '::1%scope/120') def testOverlaps(self): other = ipaddress.IPv4Network('1.2.3.0/30') @@ -1707,13 +2105,28 @@ def testIPv6AddressTooLarge(self): self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'), ipaddress.ip_address('FFFF::c000:201')) + self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1%scope'), + ipaddress.ip_address('::FFFF:c000:201%scope')) + self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1%scope'), + ipaddress.ip_address('FFFF::c000:201%scope')) + self.assertNotEqual(ipaddress.ip_address('::FFFF:192.0.2.1%scope'), + ipaddress.ip_address('::FFFF:c000:201')) + self.assertNotEqual(ipaddress.ip_address('FFFF::192.0.2.1%scope'), + ipaddress.ip_address('FFFF::c000:201')) + self.assertNotEqual(ipaddress.ip_address('::FFFF:192.0.2.1'), + ipaddress.ip_address('::FFFF:c000:201%scope')) + self.assertNotEqual(ipaddress.ip_address('FFFF::192.0.2.1'), + ipaddress.ip_address('FFFF::c000:201%scope')) + def testIPVersion(self): self.assertEqual(self.ipv4_address.version, 4) self.assertEqual(self.ipv6_address.version, 6) + self.assertEqual(self.ipv6_scoped_address.version, 6) def testMaxPrefixLength(self): self.assertEqual(self.ipv4_interface.max_prefixlen, 32) self.assertEqual(self.ipv6_interface.max_prefixlen, 128) + self.assertEqual(self.ipv6_scoped_interface.max_prefixlen, 128) def testPacked(self): self.assertEqual(self.ipv4_address.packed, @@ -1728,6 +2141,14 @@ def testPacked(self): + b'\x00' * 6) self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed, b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8) + self.assertEqual(self.ipv6_scoped_address.packed, + b'\x20\x01\x06\x58\x02\x2a\xca\xfe' + b'\x02\x00\x00\x00\x00\x00\x00\x01') + self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::%scope').packed, + b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff' + + b'\x00' * 6) + self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0%scope').packed, + b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8) def testIpType(self): ipv4net = ipaddress.ip_network('1.2.3.4') diff --git a/Misc/NEWS.d/next/Library/2019-07-17-08-26-14.bpo-34788.pwV1OK.rst b/Misc/NEWS.d/next/Library/2019-07-17-08-26-14.bpo-34788.pwV1OK.rst new file mode 100644 index 0000000000000..db6f6d54d9e8d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-17-08-26-14.bpo-34788.pwV1OK.rst @@ -0,0 +1,2 @@ +Add support for scoped IPv6 addresses to :mod:`ipaddress`. Patch by Oleksandr +Pavliuk. From webhook-mailer at python.org Wed Feb 26 14:21:48 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Wed, 26 Feb 2020 19:21:48 -0000 Subject: [Python-checkins] bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) Message-ID: https://github.com/python/cpython/commit/6aa1f1ecf7142a4117eedb8c570f30da1598616c commit: 6aa1f1ecf7142a4117eedb8c570f30da1598616c branch: master author: Ammar Askar committer: GitHub date: 2020-02-26T19:21:41Z summary: bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) files: M .azure-pipelines/macos-steps.yml M .azure-pipelines/posix-steps.yml M .github/workflows/build.yml M .github/workflows/coverage.yml M .github/workflows/doc.yml diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml index d2ca580a93d7d..fa38a0df8c87b 100644 --- a/.azure-pipelines/macos-steps.yml +++ b/.azure-pipelines/macos-steps.yml @@ -6,7 +6,7 @@ steps: - script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - script: make pythoninfo diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 3ed3abd02a714..a63659fa20491 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -20,7 +20,7 @@ steps: - script: ./configure --with-pydebug displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - ${{ if eq(parameters.coverage, 'true') }}: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f13cfbc1ff4e..6774ae46f7e0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests @@ -82,7 +82,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e8b47b390e5a7..8e1b764ca8df4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -40,7 +40,7 @@ jobs: - name: Configure CPython run: ./configure --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: 'Coverage Preparation' diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 5bba8e690655f..c8d395cea5156 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -28,7 +28,7 @@ jobs: - name: 'Configure CPython' run: ./configure --with-pydebug - name: 'Build CPython' - run: make -s -j4 + run: make -j4 - name: 'Install build dependencies' run: make -C Doc/ PYTHON=../python venv - name: 'Build documentation' From webhook-mailer at python.org Wed Feb 26 14:57:21 2020 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 26 Feb 2020 19:57:21 -0000 Subject: [Python-checkins] bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) Message-ID: https://github.com/python/cpython/commit/343bc06d8047e4a2e675394528dbb5155be1b3b5 commit: 343bc06d8047e4a2e675394528dbb5155be1b3b5 branch: 3.8 author: Steve Dower committer: GitHub date: 2020-02-26T19:57:14Z summary: bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) Co-authored-by: Ammar Askar files: M .azure-pipelines/macos-steps.yml M .azure-pipelines/posix-steps.yml M .github/workflows/build.yml M .github/workflows/coverage.yml M .github/workflows/doc.yml M Doc/whatsnew/3.0.rst diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml index d2ca580a93d7d..fa38a0df8c87b 100644 --- a/.azure-pipelines/macos-steps.yml +++ b/.azure-pipelines/macos-steps.yml @@ -6,7 +6,7 @@ steps: - script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - script: make pythoninfo diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 3ed3abd02a714..a63659fa20491 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -20,7 +20,7 @@ steps: - script: ./configure --with-pydebug displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - ${{ if eq(parameters.coverage, 'true') }}: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16d6f0db8c908..2b4aec6e30975 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests @@ -78,7 +78,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e8b47b390e5a7..8e1b764ca8df4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -40,7 +40,7 @@ jobs: - name: Configure CPython run: ./configure --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: 'Coverage Preparation' diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 405b12e3d29c9..c8d395cea5156 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -23,17 +23,17 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout at v1 - - uses: actions/setup-python at v1 - with: - python-version: '3.7' - architecture: 'x64' + - name: 'Install Dependencies' + run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican + - name: 'Configure CPython' + run: ./configure --with-pydebug + - name: 'Build CPython' + run: make -j4 - name: 'Install build dependencies' - run: python -m pip install sphinx==2.2.0 blurb python-docs-theme + run: make -C Doc/ PYTHON=../python venv - name: 'Build documentation' - run: | - cd Doc - make check suspicious html PYTHON=python - - name: Upload + run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" doctest suspicious html + - name: 'Upload' uses: actions/upload-artifact at v1 with: name: doc-html diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 880958d3edb90..6b8bd8861fe9b 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -2,6 +2,8 @@ What's New In Python 3.0 **************************** +TEST CHANGE TO BE UNDONE + .. XXX Add trademark info for Apple, Microsoft. :Author: Guido van Rossum From webhook-mailer at python.org Wed Feb 26 15:01:55 2020 From: webhook-mailer at python.org (Brandt Bucher) Date: Wed, 26 Feb 2020 20:01:55 -0000 Subject: [Python-checkins] bpo-36144: Document PEP 584 (GH-18659) Message-ID: https://github.com/python/cpython/commit/d0ca9bd93bb9d8d4aa9bbe939ca7fd54ac870c8f commit: d0ca9bd93bb9d8d4aa9bbe939ca7fd54ac870c8f branch: master author: Brandt Bucher committer: GitHub date: 2020-02-26T12:01:48-08:00 summary: bpo-36144: Document PEP 584 (GH-18659) files: M Doc/library/stdtypes.rst M Doc/whatsnew/3.9.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 47d64f1e8d65f..435ba5b74ff34 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4392,6 +4392,22 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: >>> d.values() == d.values() False + .. describe:: d | other + + Create a new dictionary with the merged keys and values of *d* and + *other*, which must both be dictionaries. The values of *other* take + priority when *d* and *other* share keys. + + .. versionadded:: 3.9 + + .. describe:: d |= other + + Update the dictionary *d* with keys and values from *other*, which may be + either a :term:`mapping` or an :term:`iterable` of key/value pairs. The + values of *other* take priority when *d* and *other* share keys. + + .. versionadded:: 3.9 + Dictionaries compare equal if and only if they have the same ``(key, value)`` pairs (regardless of ordering). Order comparisons ('<', '<=', '>=', '>') raise :exc:`TypeError`. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index d3b35fcff5c43..8ad26d6978605 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -70,6 +70,12 @@ Summary -- Release highlights New Features ============ +Dictionary Merge & Update Operators +----------------------------------- + +Merge (``|``) and update (``|=``) operators have been added to the built-in +:class:`dict` class. See :pep:`584` for a full description. +(Contributed by Brandt Bucher in :issue:`36144`.) Other Language Changes From webhook-mailer at python.org Wed Feb 26 17:08:15 2020 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 26 Feb 2020 22:08:15 -0000 Subject: [Python-checkins] bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) Message-ID: https://github.com/python/cpython/commit/3bf9de2fb954bd1131f4f41517d7d5c316fb95f8 commit: 3bf9de2fb954bd1131f4f41517d7d5c316fb95f8 branch: 3.7 author: Steve Dower committer: GitHub date: 2020-02-26T22:08:10Z summary: bpo-39699: Don't silence make on Azure and Github CIs (GH-18583) Doc tests remain disabled for 3.7 Co-authored-by: Ammar Askar files: M .azure-pipelines/macos-steps.yml M .azure-pipelines/posix-steps.yml M .github/workflows/build.yml M .github/workflows/coverage.yml M .github/workflows/doc.yml diff --git a/.azure-pipelines/macos-steps.yml b/.azure-pipelines/macos-steps.yml index d2ca580a93d7d..fa38a0df8c87b 100644 --- a/.azure-pipelines/macos-steps.yml +++ b/.azure-pipelines/macos-steps.yml @@ -6,7 +6,7 @@ steps: - script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - script: make pythoninfo diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 15e3f0b9ad1bb..95d3e98fe97c0 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -20,7 +20,7 @@ steps: - script: ./configure --with-pydebug displayName: 'Configure CPython (debug)' -- script: make -s -j4 +- script: make -j4 displayName: 'Build CPython' - ${{ if eq(parameters.coverage, 'true') }}: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16d6f0db8c908..2b4aec6e30975 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests @@ -78,7 +78,7 @@ jobs: - name: Configure CPython run: ./configure --with-pydebug --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: Tests diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e8b47b390e5a7..8e1b764ca8df4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -40,7 +40,7 @@ jobs: - name: Configure CPython run: ./configure --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER - name: Build CPython - run: make -s -j4 + run: make -j4 - name: Display build info run: make pythoninfo - name: 'Coverage Preparation' diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 405b12e3d29c9..e943d32c24038 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -23,17 +23,17 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout at v1 - - uses: actions/setup-python at v1 - with: - python-version: '3.7' - architecture: 'x64' + - name: 'Install Dependencies' + run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican + - name: 'Configure CPython' + run: ./configure --with-pydebug + - name: 'Build CPython' + run: make -j4 - name: 'Install build dependencies' - run: python -m pip install sphinx==2.2.0 blurb python-docs-theme + run: make -C Doc/ PYTHON=../python venv - name: 'Build documentation' - run: | - cd Doc - make check suspicious html PYTHON=python - - name: Upload + run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W -j4" suspicious html + - name: 'Upload' uses: actions/upload-artifact at v1 with: name: doc-html From webhook-mailer at python.org Wed Feb 26 17:15:17 2020 From: webhook-mailer at python.org (Andrew Svetlov) Date: Wed, 26 Feb 2020 22:15:17 -0000 Subject: [Python-checkins] Suppress the hang (#18457) Message-ID: https://github.com/python/cpython/commit/0c6e3aa67b84adb0fb7c272ae06b7ae77f832295 commit: 0c6e3aa67b84adb0fb7c272ae06b7ae77f832295 branch: master author: Andrew Svetlov committer: GitHub date: 2020-02-27T00:15:12+02:00 summary: Suppress the hang (#18457) files: M Lib/test/test_asyncio/test_subprocess.py diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index a6c3acc420ac7..6657a88e657c2 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -477,12 +477,19 @@ def kill(): proc.kill = kill returncode = transport.get_returncode() transport.close() - await transport._wait() + await asyncio.wait_for(transport._wait(), 5) return (returncode, kill_called) # Ignore "Close running child process: kill ..." log with test_utils.disable_logger(): - returncode, killed = self.loop.run_until_complete(kill_running()) + try: + returncode, killed = self.loop.run_until_complete( + kill_running() + ) + except asyncio.TimeoutError: + self.skipTest( + "Timeout failure on waiting for subprocess stopping" + ) self.assertIsNone(returncode) # transport.close() must kill the process if it is still running From webhook-mailer at python.org Wed Feb 26 23:49:04 2020 From: webhook-mailer at python.org (Inada Naoki) Date: Thu, 27 Feb 2020 04:49:04 -0000 Subject: [Python-checkins] bpo-39087: Optimize PyUnicode_AsUTF8AndSize() (GH-18327) Message-ID: https://github.com/python/cpython/commit/02a4d57263a9846de35b0db12763ff9e7326f62c commit: 02a4d57263a9846de35b0db12763ff9e7326f62c branch: master author: Inada Naoki committer: GitHub date: 2020-02-27T13:48:59+09:00 summary: bpo-39087: Optimize PyUnicode_AsUTF8AndSize() (GH-18327) Avoid using temporary bytes object. files: A Misc/NEWS.d/next/Core and Builtins/2020-02-03-21-12-39.bpo-39087.YnbUpL.rst M Objects/stringlib/codecs.h M Objects/unicodeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-03-21-12-39.bpo-39087.YnbUpL.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-03-21-12-39.bpo-39087.YnbUpL.rst new file mode 100644 index 0000000000000..847f78f5b182e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-03-21-12-39.bpo-39087.YnbUpL.rst @@ -0,0 +1,2 @@ +Optimize :c:func:`PyUnicode_AsUTF8` and :c:func:`PyUnicode_AsUTF8AndSize` +slightly when they need to create internal UTF-8 cache. diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 269a5581f7005..eb42e071751d7 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -256,8 +256,9 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* UTF-8 encoder specialized for a Unicode kind to avoid the slow PyUnicode_READ() macro. Delete some parts of the code depending on the kind: UCS-1 strings don't need to handle surrogates for example. */ -Py_LOCAL_INLINE(PyObject *) -STRINGLIB(utf8_encoder)(PyObject *unicode, +Py_LOCAL_INLINE(char *) +STRINGLIB(utf8_encoder)(_PyBytesWriter *writer, + PyObject *unicode, STRINGLIB_CHAR *data, Py_ssize_t size, _Py_error_handler error_handler, @@ -277,17 +278,16 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, #else /* STRINGLIB_SIZEOF_CHAR == 4 */ const Py_ssize_t max_char_size = 4; #endif - _PyBytesWriter writer; assert(size >= 0); - _PyBytesWriter_Init(&writer); - if (size > PY_SSIZE_T_MAX / max_char_size) { /* integer overflow */ - return PyErr_NoMemory(); + PyErr_NoMemory(); + return NULL; } - p = _PyBytesWriter_Alloc(&writer, size * max_char_size); + _PyBytesWriter_Init(writer); + p = _PyBytesWriter_Alloc(writer, size * max_char_size); if (p == NULL) return NULL; @@ -323,7 +323,7 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, endpos++; /* Only overallocate the buffer if it's not the last write */ - writer.overallocate = (endpos < size); + writer->overallocate = (endpos < size); switch (error_handler) { @@ -347,8 +347,8 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, case _Py_ERROR_BACKSLASHREPLACE: /* subtract preallocated bytes */ - writer.min_size -= max_char_size * (endpos - startpos); - p = backslashreplace(&writer, p, + writer->min_size -= max_char_size * (endpos - startpos); + p = backslashreplace(writer, p, unicode, startpos, endpos); if (p == NULL) goto error; @@ -357,8 +357,8 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, case _Py_ERROR_XMLCHARREFREPLACE: /* subtract preallocated bytes */ - writer.min_size -= max_char_size * (endpos - startpos); - p = xmlcharrefreplace(&writer, p, + writer->min_size -= max_char_size * (endpos - startpos); + p = xmlcharrefreplace(writer, p, unicode, startpos, endpos); if (p == NULL) goto error; @@ -387,10 +387,10 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, goto error; /* subtract preallocated bytes */ - writer.min_size -= max_char_size * (newpos - startpos); + writer->min_size -= max_char_size * (newpos - startpos); if (PyBytes_Check(rep)) { - p = _PyBytesWriter_WriteBytes(&writer, p, + p = _PyBytesWriter_WriteBytes(writer, p, PyBytes_AS_STRING(rep), PyBytes_GET_SIZE(rep)); } @@ -406,7 +406,7 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, goto error; } - p = _PyBytesWriter_WriteBytes(&writer, p, + p = _PyBytesWriter_WriteBytes(writer, p, PyUnicode_DATA(rep), PyUnicode_GET_LENGTH(rep)); } @@ -420,7 +420,7 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, /* If overallocation was disabled, ensure that it was the last write. Otherwise, we missed an optimization */ - assert(writer.overallocate || i == size); + assert(writer->overallocate || i == size); } else #if STRINGLIB_SIZEOF_CHAR > 2 @@ -449,14 +449,13 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, Py_XDECREF(error_handler_obj); Py_XDECREF(exc); #endif - return _PyBytesWriter_Finish(&writer, p); + return p; #if STRINGLIB_SIZEOF_CHAR > 1 error: Py_XDECREF(rep); Py_XDECREF(error_handler_obj); Py_XDECREF(exc); - _PyBytesWriter_Dealloc(&writer); return NULL; #endif } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ee6d3dfd3945b..e0a666f70da36 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3991,11 +3991,11 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) } +static int unicode_fill_utf8(PyObject *unicode); + const char * PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) { - PyObject *bytes; - if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; @@ -4004,21 +4004,9 @@ PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) return NULL; if (PyUnicode_UTF8(unicode) == NULL) { - assert(!PyUnicode_IS_COMPACT_ASCII(unicode)); - bytes = _PyUnicode_AsUTF8String(unicode, NULL); - if (bytes == NULL) - return NULL; - _PyUnicode_UTF8(unicode) = PyObject_MALLOC(PyBytes_GET_SIZE(bytes) + 1); - if (_PyUnicode_UTF8(unicode) == NULL) { - PyErr_NoMemory(); - Py_DECREF(bytes); + if (unicode_fill_utf8(unicode) == -1) { return NULL; } - _PyUnicode_UTF8_LENGTH(unicode) = PyBytes_GET_SIZE(bytes); - memcpy(_PyUnicode_UTF8(unicode), - PyBytes_AS_STRING(bytes), - _PyUnicode_UTF8_LENGTH(unicode) + 1); - Py_DECREF(bytes); } if (psize) @@ -5381,10 +5369,6 @@ static PyObject * unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, const char *errors) { - enum PyUnicode_Kind kind; - void *data; - Py_ssize_t size; - if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; @@ -5397,9 +5381,12 @@ unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode), PyUnicode_UTF8_LENGTH(unicode)); - kind = PyUnicode_KIND(unicode); - data = PyUnicode_DATA(unicode); - size = PyUnicode_GET_LENGTH(unicode); + enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + void *data = PyUnicode_DATA(unicode); + Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); + + _PyBytesWriter writer; + char *end; switch (kind) { default: @@ -5407,12 +5394,73 @@ unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, case PyUnicode_1BYTE_KIND: /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); - return ucs1lib_utf8_encoder(unicode, data, size, error_handler, errors); + end = ucs1lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors); + break; + case PyUnicode_2BYTE_KIND: + end = ucs2lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors); + break; + case PyUnicode_4BYTE_KIND: + end = ucs4lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors); + break; + } + + if (end == NULL) { + _PyBytesWriter_Dealloc(&writer); + return NULL; + } + return _PyBytesWriter_Finish(&writer, end); +} + +static int +unicode_fill_utf8(PyObject *unicode) +{ + /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ + assert(!PyUnicode_IS_ASCII(unicode)); + + enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + void *data = PyUnicode_DATA(unicode); + Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); + + _PyBytesWriter writer; + char *end; + + switch (kind) { + default: + Py_UNREACHABLE(); + case PyUnicode_1BYTE_KIND: + end = ucs1lib_utf8_encoder(&writer, unicode, data, size, + _Py_ERROR_STRICT, NULL); + break; case PyUnicode_2BYTE_KIND: - return ucs2lib_utf8_encoder(unicode, data, size, error_handler, errors); + end = ucs2lib_utf8_encoder(&writer, unicode, data, size, + _Py_ERROR_STRICT, NULL); + break; case PyUnicode_4BYTE_KIND: - return ucs4lib_utf8_encoder(unicode, data, size, error_handler, errors); + end = ucs4lib_utf8_encoder(&writer, unicode, data, size, + _Py_ERROR_STRICT, NULL); + break; + } + if (end == NULL) { + _PyBytesWriter_Dealloc(&writer); + return -1; + } + + char *start = writer.use_small_buffer ? writer.small_buffer : + PyBytes_AS_STRING(writer.buffer); + Py_ssize_t len = end - start; + + char *cache = PyObject_MALLOC(len + 1); + if (cache == NULL) { + _PyBytesWriter_Dealloc(&writer); + PyErr_NoMemory(); + return -1; } + _PyUnicode_UTF8(unicode) = cache; + _PyUnicode_UTF8_LENGTH(unicode) = len; + memcpy(cache, start, len); + cache[len] = '\0'; + _PyBytesWriter_Dealloc(&writer); + return 0; } PyObject * From webhook-mailer at python.org Thu Feb 27 15:01:59 2020 From: webhook-mailer at python.org (Markus Mohrhard) Date: Thu, 27 Feb 2020 20:01:59 -0000 Subject: [Python-checkins] bpo-39609: set the thread_name_prefix for the default asyncio executor (GH-18458) Message-ID: https://github.com/python/cpython/commit/374d998b507d34a6c0a3816a163926a8ba0c483f commit: 374d998b507d34a6c0a3816a163926a8ba0c483f branch: master author: Markus Mohrhard committer: GitHub date: 2020-02-27T12:01:47-08:00 summary: bpo-39609: set the thread_name_prefix for the default asyncio executor (GH-18458) Just a small debugging improvement to identify the asyncio executor threads. files: A Misc/NEWS.d/next/Library/2020-02-11-19-45-31.bpo-39609.dk40Uw.rst M Lib/asyncio/base_events.py diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index d78724b015370..b2d446a51fedb 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -806,7 +806,9 @@ def run_in_executor(self, executor, func, *args): # Only check when the default executor is being used self._check_default_executor() if executor is None: - executor = concurrent.futures.ThreadPoolExecutor() + executor = concurrent.futures.ThreadPoolExecutor( + thread_name_prefix='asyncio' + ) self._default_executor = executor return futures.wrap_future( executor.submit(func, *args), loop=self) diff --git a/Misc/NEWS.d/next/Library/2020-02-11-19-45-31.bpo-39609.dk40Uw.rst b/Misc/NEWS.d/next/Library/2020-02-11-19-45-31.bpo-39609.dk40Uw.rst new file mode 100644 index 0000000000000..233fad3e763d6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-11-19-45-31.bpo-39609.dk40Uw.rst @@ -0,0 +1 @@ +Add thread_name_prefix to default asyncio executor From webhook-mailer at python.org Thu Feb 27 18:08:38 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Thu, 27 Feb 2020 23:08:38 -0000 Subject: [Python-checkins] bpo-39704: Explicitly pass the path to codecov config (GH-18680) Message-ID: https://github.com/python/cpython/commit/766b7546a564c8e386a3c31eb06fc1b55e8f5a25 commit: 766b7546a564c8e386a3c31eb06fc1b55e8f5a25 branch: master author: Ammar Askar committer: GitHub date: 2020-02-27T15:08:30-08:00 summary: bpo-39704: Explicitly pass the path to codecov config (GH-18680) files: M .azure-pipelines/posix-steps.yml M .github/workflows/coverage.yml M .travis.yml diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index a63659fa20491..b6dde593019e6 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -49,7 +49,7 @@ steps: - script: ./venv/bin/python -m coverage xml displayName: 'Generate coverage.xml' - - script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash) + - script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml displayName: 'Publish code coverage results' diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 8e1b764ca8df4..bf166ab8f0867 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -65,7 +65,7 @@ jobs: - name: 'Publish code coverage results' run: | source ./.venv/bin/activate - bash <(curl -s https://codecov.io/bash) + bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -84,6 +84,6 @@ jobs: if: always() run: | make pythoninfo - bash <(curl -s https://codecov.io/bash) + bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.travis.yml b/.travis.yml index b1d50d49ca5cc..675e267fe2e82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -94,7 +94,7 @@ matrix: after_script: # Probably should be after_success once test suite updated to run under coverage.py. # Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files. - source ./venv/bin/activate - - bash <(curl -s https://codecov.io/bash) + - bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml - name: "Test code coverage (C)" os: linux language: c @@ -111,7 +111,7 @@ matrix: - xvfb-run make -j4 coverage-report after_script: # Probably should be after_success once test suite updated to run under coverage.py. - make pythoninfo - - bash <(curl -s https://codecov.io/bash) + - bash <(curl -s https://codecov.io/bash) -y .github/codecov.yml before_install: From webhook-mailer at python.org Thu Feb 27 21:45:16 2020 From: webhook-mailer at python.org (Andy Lester) Date: Fri, 28 Feb 2020 02:45:16 -0000 Subject: [Python-checkins] closes bpo-39721: Fix constness of members of tok_state struct. (GH-18600) Message-ID: https://github.com/python/cpython/commit/384f3c536dd15ba33ea7e8afb4087ae359d4c12e commit: 384f3c536dd15ba33ea7e8afb4087ae359d4c12e branch: master author: Andy Lester committer: GitHub date: 2020-02-27T18:44:52-08:00 summary: closes bpo-39721: Fix constness of members of tok_state struct. (GH-18600) The function PyTokenizer_FromUTF8 from Parser/tokenizer.c had a comment: /* XXX: constify members. */ This patch addresses that. In the tok_state struct: * end and start were non-const but could be made const * str and input were const but should have been non-const Changes to support this include: * decode_str() now returns a char * since it is allocated. * PyTokenizer_FromString() and PyTokenizer_FromUTF8() each creates a new char * for an allocate string instead of reusing the input const char *. * PyTokenizer_Get() and tok_get() now take const char ** arguments. * Various local vars are const or non-const accordingly. I was able to remove five casts that cast away constness. files: M Parser/parsetok.c M Parser/tokenizer.c M Parser/tokenizer.h diff --git a/Parser/parsetok.c b/Parser/parsetok.c index b0b1bd38a7bba..554455dbc2bad 100644 --- a/Parser/parsetok.c +++ b/Parser/parsetok.c @@ -240,7 +240,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, #endif for (;;) { - char *a, *b; + const char *a, *b; int type; size_t len; char *str; @@ -371,7 +371,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, buffer after parsing. Trailing whitespace and comments are OK. */ if (err_ret->error == E_DONE && start == single_input) { - char *cur = tok->cur; + const char *cur = tok->cur; char c = *tok->cur; for (;;) { diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 630b0aaab03f9..f82b102998171 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -59,7 +59,9 @@ tok_new(void) sizeof(struct tok_state)); if (tok == NULL) return NULL; - tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->buf = tok->cur = tok->inp = NULL; + tok->start = NULL; + tok->end = NULL; tok->done = E_OK; tok->fp = NULL; tok->input = NULL; @@ -111,7 +113,9 @@ error_ret(struct tok_state *tok) /* XXX */ tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ PyMem_FREE(tok->buf); - tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->buf = tok->cur = tok->inp = NULL; + tok->start = NULL; + tok->end = NULL; tok->done = E_DECODE; return NULL; /* as if it were EOF */ } @@ -664,11 +668,11 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { Look for encoding declarations inside STR, and record them inside TOK. */ -static const char * +static char * decode_str(const char *input, int single, struct tok_state *tok) { PyObject* utf8 = NULL; - const char *str; + char *str; const char *s; const char *newl[2] = {NULL, NULL}; int lineno = 0; @@ -726,16 +730,18 @@ struct tok_state * PyTokenizer_FromString(const char *str, int exec_input) { struct tok_state *tok = tok_new(); + char *decoded; + if (tok == NULL) return NULL; - str = decode_str(str, exec_input, tok); - if (str == NULL) { + decoded = decode_str(str, exec_input, tok); + if (decoded == NULL) { PyTokenizer_Free(tok); return NULL; } - /* XXX: constify members. */ - tok->buf = tok->cur = tok->end = tok->inp = (char*)str; + tok->buf = tok->cur = tok->inp = decoded; + tok->end = decoded; return tok; } @@ -743,17 +749,18 @@ struct tok_state * PyTokenizer_FromUTF8(const char *str, int exec_input) { struct tok_state *tok = tok_new(); + char *translated; if (tok == NULL) return NULL; - tok->input = str = translate_newlines(str, exec_input, tok); - if (str == NULL) { + tok->input = translated = translate_newlines(str, exec_input, tok); + if (translated == NULL) { PyTokenizer_Free(tok); return NULL; } tok->decoding_state = STATE_RAW; tok->read_coding_spec = 1; tok->enc = NULL; - tok->str = str; + tok->str = translated; tok->encoding = (char *)PyMem_MALLOC(6); if (!tok->encoding) { PyTokenizer_Free(tok); @@ -761,8 +768,8 @@ PyTokenizer_FromUTF8(const char *str, int exec_input) } strcpy(tok->encoding, "utf-8"); - /* XXX: constify members. */ - tok->buf = tok->cur = tok->end = tok->inp = (char*)str; + tok->buf = tok->cur = tok->inp = translated; + tok->end = translated; return tok; } @@ -812,7 +819,7 @@ PyTokenizer_Free(struct tok_state *tok) if (tok->fp != NULL && tok->buf != NULL) PyMem_FREE(tok->buf); if (tok->input) - PyMem_FREE((char *)tok->input); + PyMem_FREE(tok->input); PyMem_FREE(tok); } @@ -1138,7 +1145,7 @@ tok_decimal_tail(struct tok_state *tok) /* Get next token, after space stripping etc. */ static int -tok_get(struct tok_state *tok, char **p_start, char **p_end) +tok_get(struct tok_state *tok, const char **p_start, const char **p_end) { int c; int blankline, nonascii; @@ -1321,7 +1328,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); if (is_type_ignore) { - *p_start = (char *) ignore_end; + *p_start = ignore_end; *p_end = tok->cur; /* If this type ignore is the only thing on the line, consume the newline also. */ @@ -1331,7 +1338,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } return TYPE_IGNORE; } else { - *p_start = (char *) type_start; /* after type_comment_prefix */ + *p_start = type_start; /* after type_comment_prefix */ *p_end = tok->cur; return TYPE_COMMENT; } @@ -1410,7 +1417,8 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) Look ahead one token to see if that is 'def'. */ struct tok_state ahead_tok; - char *ahead_tok_start = NULL, *ahead_tok_end = NULL; + const char *ahead_tok_start = NULL; + const char *ahead_tok_end = NULL; int ahead_tok_kind; memcpy(&ahead_tok, tok, sizeof(ahead_tok)); @@ -1798,7 +1806,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } int -PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end) +PyTokenizer_Get(struct tok_state *tok, const char **p_start, const char **p_end) { int result = tok_get(tok, p_start, p_end); if (tok->decoding_erred) { @@ -1823,7 +1831,9 @@ PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) { struct tok_state *tok; FILE *fp; - char *p_start =NULL , *p_end =NULL , *encoding = NULL; + const char *p_start = NULL; + const char *p_end = NULL; + char *encoding = NULL; fd = _Py_dup(fd); if (fd < 0) { diff --git a/Parser/tokenizer.h b/Parser/tokenizer.h index 92669bfd8a160..5660ea38e9443 100644 --- a/Parser/tokenizer.h +++ b/Parser/tokenizer.h @@ -26,8 +26,8 @@ struct tok_state { char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL */ char *cur; /* Next character in buffer */ char *inp; /* End of data in buffer */ - char *end; /* End of input buffer if buf != NULL */ - char *start; /* Start of current token if not NULL */ + const char *end; /* End of input buffer if buf != NULL */ + const char *start; /* Start of current token if not NULL */ int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ /* NB If done != E_OK, cur must be == inp!!! */ FILE *fp; /* Rest of input; NULL if tokenizing a string */ @@ -60,8 +60,8 @@ struct tok_state { PyObject *decoding_readline; /* open(...).readline */ PyObject *decoding_buffer; const char* enc; /* Encoding for the current str. */ - const char* str; - const char* input; /* Tokenizer's newline translated copy of the string. */ + char* str; + char* input; /* Tokenizer's newline translated copy of the string. */ int type_comments; /* Whether to look for type comments */ @@ -78,7 +78,7 @@ extern struct tok_state *PyTokenizer_FromUTF8(const char *, int); extern struct tok_state *PyTokenizer_FromFile(FILE *, const char*, const char *, const char *); extern void PyTokenizer_Free(struct tok_state *); -extern int PyTokenizer_Get(struct tok_state *, char **, char **); +extern int PyTokenizer_Get(struct tok_state *, const char **, const char **); #define tok_dump _Py_tok_dump From webhook-mailer at python.org Fri Feb 28 02:05:09 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Fri, 28 Feb 2020 07:05:09 -0000 Subject: [Python-checkins] Fuzz struct.unpack and catch RecursionError in re.compile (GH-18679) Message-ID: https://github.com/python/cpython/commit/e263bb1e97ae8f84fb4f2ab5b0c4f529a2e5696d commit: e263bb1e97ae8f84fb4f2ab5b0c4f529a2e5696d branch: master author: Ammar Askar committer: GitHub date: 2020-02-27T23:05:02-08:00 summary: Fuzz struct.unpack and catch RecursionError in re.compile (GH-18679) files: A Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/hello_string A Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/long_zero A Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/varied_format_string M Modules/_xxtestfuzz/fuzz_tests.txt M Modules/_xxtestfuzz/fuzzer.c diff --git a/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/hello_string b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/hello_string new file mode 100644 index 0000000000000..92d47cd358eef Binary files /dev/null and b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/hello_string differ diff --git a/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/long_zero b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/long_zero new file mode 100644 index 0000000000000..d952225c3a6e0 Binary files /dev/null and b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/long_zero differ diff --git a/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/varied_format_string b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/varied_format_string new file mode 100644 index 0000000000000..a150dc087adfe Binary files /dev/null and b/Modules/_xxtestfuzz/fuzz_struct_unpack_corpus/varied_format_string differ diff --git a/Modules/_xxtestfuzz/fuzz_tests.txt b/Modules/_xxtestfuzz/fuzz_tests.txt index 9d330a668ee88..053b77b41b111 100644 --- a/Modules/_xxtestfuzz/fuzz_tests.txt +++ b/Modules/_xxtestfuzz/fuzz_tests.txt @@ -5,3 +5,4 @@ fuzz_json_loads fuzz_sre_compile fuzz_sre_match fuzz_csv_reader +fuzz_struct_unpack diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 74ba819b8b50b..6bd2c3aedccc9 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -79,6 +79,69 @@ static int fuzz_builtin_unicode(const char* data, size_t size) { return 0; } + +PyObject* struct_unpack_method = NULL; +PyObject* struct_error = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_struct_unpack() { + /* Import struct.unpack */ + PyObject* struct_module = PyImport_ImportModule("struct"); + if (struct_module == NULL) { + return 0; + } + struct_error = PyObject_GetAttrString(struct_module, "error"); + if (struct_error == NULL) { + return 0; + } + struct_unpack_method = PyObject_GetAttrString(struct_module, "unpack"); + return struct_unpack_method != NULL; +} +/* Fuzz struct.unpack(x, y) */ +static int fuzz_struct_unpack(const char* data, size_t size) { + /* Everything up to the first null byte is considered the + format. Everything after is the buffer */ + const char* first_null = memchr(data, '\0', size); + if (first_null == NULL) { + return 0; + } + + size_t format_length = first_null - data; + size_t buffer_length = size - format_length - 1; + + PyObject* pattern = PyBytes_FromStringAndSize(data, format_length); + if (pattern == NULL) { + return 0; + } + PyObject* buffer = PyBytes_FromStringAndSize(first_null + 1, buffer_length); + if (buffer == NULL) { + Py_DECREF(pattern); + return 0; + } + + PyObject* unpacked = PyObject_CallFunctionObjArgs( + struct_unpack_method, pattern, buffer, NULL); + /* Ignore any overflow errors, these are easily triggered accidentally */ + if (unpacked == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + } + /* The pascal format string will throw a negative size when passing 0 + like: struct.unpack('0p', b'') */ + if (unpacked == NULL && PyErr_ExceptionMatches(PyExc_SystemError)) { + PyErr_Clear(); + } + /* Ignore any struct.error exceptions, these can be caused by invalid + formats or incomplete buffers both of which are common. */ + if (unpacked == NULL && PyErr_ExceptionMatches(struct_error)) { + PyErr_Clear(); + } + + Py_XDECREF(unpacked); + Py_DECREF(pattern); + Py_DECREF(buffer); + return 0; +} + + #define MAX_JSON_TEST_SIZE 0x10000 PyObject* json_loads_method = NULL; @@ -190,9 +253,10 @@ static int fuzz_sre_compile(const char* data, size_t size) { PyErr_Clear(); } /* Ignore some common errors thrown by sre_parse: - Overflow, Assertion and Index */ + Overflow, Assertion, Recursion and Index */ if (compiled == NULL && (PyErr_ExceptionMatches(PyExc_OverflowError) || PyErr_ExceptionMatches(PyExc_AssertionError) || + PyErr_ExceptionMatches(PyExc_RecursionError) || PyErr_ExceptionMatches(PyExc_IndexError)) ) { PyErr_Clear(); @@ -378,6 +442,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_unicode) rv |= _run_fuzz(data, size, fuzz_builtin_unicode); #endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_struct_unpack) + static int STRUCT_UNPACK_INITIALIZED = 0; + if (!STRUCT_UNPACK_INITIALIZED && !init_struct_unpack()) { + PyErr_Print(); + abort(); + } else { + STRUCT_UNPACK_INITIALIZED = 1; + } + rv |= _run_fuzz(data, size, fuzz_struct_unpack); +#endif #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_json_loads) static int JSON_LOADS_INITIALIZED = 0; if (!JSON_LOADS_INITIALIZED && !init_json_loads()) { From webhook-mailer at python.org Fri Feb 28 09:26:49 2020 From: webhook-mailer at python.org (Vinay Sajip) Date: Fri, 28 Feb 2020 14:26:49 -0000 Subject: [Python-checkins] bpo-12915: Improve Unicode support for package names and attributes. (GH-18517) Message-ID: https://github.com/python/cpython/commit/4f17c5cd9a1ec50fe8de7ef68c39220a01a862cb commit: 4f17c5cd9a1ec50fe8de7ef68c39220a01a862cb branch: master author: Vinay Sajip committer: GitHub date: 2020-02-28T14:26:27Z summary: bpo-12915: Improve Unicode support for package names and attributes. (GH-18517) files: M Lib/pkgutil.py M Lib/test/test_pkgutil.py diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 4bc3083ac197e..4c184678a2912 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -638,8 +638,8 @@ def get_data(package, resource): return loader.get_data(resource_name) -_DOTTED_WORDS = r'[a-z_]\w*(\.[a-z_]\w*)*' -_NAME_PATTERN = re.compile(f'^({_DOTTED_WORDS})(:({_DOTTED_WORDS})?)?$', re.I) +_DOTTED_WORDS = r'(?!\d)(\w+)(\.(?!\d)(\w+))*' +_NAME_PATTERN = re.compile(f'^(?P{_DOTTED_WORDS})(?P:(?P{_DOTTED_WORDS})?)?$', re.U) del _DOTTED_WORDS def resolve_name(name): @@ -677,11 +677,12 @@ def resolve_name(name): m = _NAME_PATTERN.match(name) if not m: raise ValueError(f'invalid format: {name!r}') - groups = m.groups() - if groups[2]: + gd = m.groupdict() + if gd.get('cln'): # there is a colon - a one-step import is all that's needed - mod = importlib.import_module(groups[0]) - parts = groups[3].split('.') if groups[3] else [] + mod = importlib.import_module(gd['pkg']) + parts = gd.get('obj') + parts = parts.split('.') if parts else [] else: # no colon - have to iterate to find the package boundary parts = name.split('.') diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index 906150b10495b..53456c2f7659e 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -229,8 +229,40 @@ def test_name_resolution(self): ('logging.handlers:SysLogHandler.NO_SUCH_VALUE', AttributeError), ('logging.handlers.SysLogHandler.NO_SUCH_VALUE', AttributeError), ('ZeroDivisionError', ImportError), + ('os.path.9abc', ValueError), + ('9abc', ValueError), ) + # add some Unicode package names to the mix. + + unicode_words = ('\u0935\u092e\u0938', + '\xe9', '\xc8', + '\uc548\ub155\ud558\uc138\uc694', + '\u3055\u3088\u306a\u3089', + '\u3042\u308a\u304c\u3068\u3046', + '\u0425\u043e\u0440\u043e\u0448\u043e', + '\u0441\u043f\u0430\u0441\u0438\u0431\u043e', + '\u73b0\u4ee3\u6c49\u8bed\u5e38\u7528\u5b57\u8868') + + for uw in unicode_words: + d = os.path.join(self.dirname, uw) + os.makedirs(d, exist_ok=True) + # make an empty __init__.py file + f = os.path.join(d, '__init__.py') + with open(f, 'w') as f: + f.write('') + f.flush() + # now import the package we just created; clearing the caches is + # needed, otherwise the newly created package isn't found + importlib.invalidate_caches() + mod = importlib.import_module(uw) + success_cases += (uw, mod), + if len(uw) > 1: + failure_cases += (uw[:-1], ImportError), + + # add an example with a Unicode digit at the start + failure_cases += ('\u0966\u0935\u092e\u0938', ValueError), + for s, expected in success_cases: with self.subTest(s=s): o = pkgutil.resolve_name(s) From webhook-mailer at python.org Fri Feb 28 13:23:03 2020 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Fri, 28 Feb 2020 18:23:03 -0000 Subject: [Python-checkins] bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Message-ID: https://github.com/python/cpython/commit/c705fd1e89ccb8f6d414ec817b4616546147d877 commit: c705fd1e89ccb8f6d414ec817b4616546147d877 branch: master author: Terry Jan Reedy committer: GitHub date: 2020-02-28T13:22:55-05:00 summary: bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Previously, the button-up part of selecting with a mouse was treated as a click that meant 'jump' to this line, which modified the context and undid the selection files: A Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/codecontext.py M Lib/idlelib/idle_test/test_codecontext.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 021e1f7710e0f..0651b3d68dc8b 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2020-10-05? ====================================== +bpo-39781: Selecting code context lines no longer causes a jump. + bpo-39663: Add tests for pyparse find_good_parse_start(). bpo-39600: Remove duplicate font names from configuration list. diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 4ce98136fe417..989b30e599465 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -7,7 +7,6 @@ enclosing block. The number of hint lines is determined by the maxlines variable in the codecontext section of config-extensions.def. Lines which do not open blocks are not shown in the context hints pane. - """ import re from sys import maxsize as INFINITY @@ -17,8 +16,8 @@ from idlelib.config import idleConf -BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with", "async"} +BLOCKOPENERS = {'class', 'def', 'if', 'elif', 'else', 'while', 'for', + 'try', 'except', 'finally', 'with', 'async'} def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")): @@ -84,7 +83,7 @@ def __del__(self): if self.t1 is not None: try: self.text.after_cancel(self.t1) - except tkinter.TclError: + except tkinter.TclError: # pragma: no cover pass self.t1 = None @@ -112,7 +111,7 @@ def toggle_code_context_event(self, event=None): padx += widget.tk.getint(info['padx']) padx += widget.tk.getint(widget.cget('padx')) border += widget.tk.getint(widget.cget('border')) - self.context = tkinter.Text( + context = self.context = tkinter.Text( self.editwin.text_frame, height=1, width=1, # Don't request more than we get. @@ -120,11 +119,11 @@ def toggle_code_context_event(self, event=None): padx=padx, border=border, relief=SUNKEN, state='disabled') self.update_font() self.update_highlight_colors() - self.context.bind('', self.jumptoline) + context.bind('', self.jumptoline) # Get the current context and initiate the recurring update event. self.timer_event() # Grid the context widget above the text widget. - self.context.grid(row=0, column=1, sticky=NSEW) + context.grid(row=0, column=1, sticky=NSEW) line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'linenumber') @@ -215,18 +214,25 @@ def update_code_context(self): self.context['state'] = 'disabled' def jumptoline(self, event=None): - "Show clicked context line at top of editor." - lines = len(self.info) - if lines == 1: # No context lines are showing. - newtop = 1 - else: - # Line number clicked. - contextline = int(float(self.context.index('insert'))) - # Lines not displayed due to maxlines. - offset = max(1, lines - self.context_depth) - 1 - newtop = self.info[offset + contextline][0] - self.text.yview(f'{newtop}.0') - self.update_code_context() + """ Show clicked context line at top of editor. + + If a selection was made, don't jump; allow copying. + If no visible context, show the top line of the file. + """ + try: + self.context.index("sel.first") + except tkinter.TclError: + lines = len(self.info) + if lines == 1: # No context lines are showing. + newtop = 1 + else: + # Line number clicked. + contextline = int(float(self.context.index('insert'))) + # Lines not displayed due to maxlines. + offset = max(1, lines - self.context_depth) - 1 + newtop = self.info[offset + contextline][0] + self.text.yview(f'{newtop}.0') + self.update_code_context() def timer_event(self): "Event on editor text widget triggered every UPDATEINTERVAL ms." diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index 3ec49e97af6f9..9578cc731a6f9 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -332,6 +332,14 @@ def test_jumptoline(self): jump() eq(cc.topvisible, 8) + # Context selection stops jump. + cc.text.yview('5.0') + cc.update_code_context() + cc.context.tag_add('sel', '1.0', '2.0') + cc.context.mark_set('insert', '1.0') + jump() # Without selection, to line 2. + eq(cc.topvisible, 5) + @mock.patch.object(codecontext.CodeContext, 'update_code_context') def test_timer_event(self, mock_update): # Ensure code context is not active. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst new file mode 100644 index 0000000000000..4ae0defc2e217 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst @@ -0,0 +1 @@ +Selecting code context lines no longer causes a jump. From webhook-mailer at python.org Fri Feb 28 13:41:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 28 Feb 2020 18:41:24 -0000 Subject: [Python-checkins] bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Message-ID: https://github.com/python/cpython/commit/f4198aee4c288ce47c5803e87a461e31f81a0138 commit: f4198aee4c288ce47c5803e87a461e31f81a0138 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T10:41:17-08:00 summary: bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Previously, the button-up part of selecting with a mouse was treated as a click that meant 'jump' to this line, which modified the context and undid the selection (cherry picked from commit c705fd1e89ccb8f6d414ec817b4616546147d877) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/codecontext.py M Lib/idlelib/idle_test/test_codecontext.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 3c3367244852a..0fa08962b4107 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39781: Selecting code context lines no longer causes a jump. + bpo-39663: Add tests for pyparse find_good_parse_start(). bpo-39600: Remove duplicate font names from configuration list. diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 4ce98136fe417..989b30e599465 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -7,7 +7,6 @@ enclosing block. The number of hint lines is determined by the maxlines variable in the codecontext section of config-extensions.def. Lines which do not open blocks are not shown in the context hints pane. - """ import re from sys import maxsize as INFINITY @@ -17,8 +16,8 @@ from idlelib.config import idleConf -BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with", "async"} +BLOCKOPENERS = {'class', 'def', 'if', 'elif', 'else', 'while', 'for', + 'try', 'except', 'finally', 'with', 'async'} def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")): @@ -84,7 +83,7 @@ def __del__(self): if self.t1 is not None: try: self.text.after_cancel(self.t1) - except tkinter.TclError: + except tkinter.TclError: # pragma: no cover pass self.t1 = None @@ -112,7 +111,7 @@ def toggle_code_context_event(self, event=None): padx += widget.tk.getint(info['padx']) padx += widget.tk.getint(widget.cget('padx')) border += widget.tk.getint(widget.cget('border')) - self.context = tkinter.Text( + context = self.context = tkinter.Text( self.editwin.text_frame, height=1, width=1, # Don't request more than we get. @@ -120,11 +119,11 @@ def toggle_code_context_event(self, event=None): padx=padx, border=border, relief=SUNKEN, state='disabled') self.update_font() self.update_highlight_colors() - self.context.bind('', self.jumptoline) + context.bind('', self.jumptoline) # Get the current context and initiate the recurring update event. self.timer_event() # Grid the context widget above the text widget. - self.context.grid(row=0, column=1, sticky=NSEW) + context.grid(row=0, column=1, sticky=NSEW) line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'linenumber') @@ -215,18 +214,25 @@ def update_code_context(self): self.context['state'] = 'disabled' def jumptoline(self, event=None): - "Show clicked context line at top of editor." - lines = len(self.info) - if lines == 1: # No context lines are showing. - newtop = 1 - else: - # Line number clicked. - contextline = int(float(self.context.index('insert'))) - # Lines not displayed due to maxlines. - offset = max(1, lines - self.context_depth) - 1 - newtop = self.info[offset + contextline][0] - self.text.yview(f'{newtop}.0') - self.update_code_context() + """ Show clicked context line at top of editor. + + If a selection was made, don't jump; allow copying. + If no visible context, show the top line of the file. + """ + try: + self.context.index("sel.first") + except tkinter.TclError: + lines = len(self.info) + if lines == 1: # No context lines are showing. + newtop = 1 + else: + # Line number clicked. + contextline = int(float(self.context.index('insert'))) + # Lines not displayed due to maxlines. + offset = max(1, lines - self.context_depth) - 1 + newtop = self.info[offset + contextline][0] + self.text.yview(f'{newtop}.0') + self.update_code_context() def timer_event(self): "Event on editor text widget triggered every UPDATEINTERVAL ms." diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index 3ec49e97af6f9..9578cc731a6f9 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -332,6 +332,14 @@ def test_jumptoline(self): jump() eq(cc.topvisible, 8) + # Context selection stops jump. + cc.text.yview('5.0') + cc.update_code_context() + cc.context.tag_add('sel', '1.0', '2.0') + cc.context.mark_set('insert', '1.0') + jump() # Without selection, to line 2. + eq(cc.topvisible, 5) + @mock.patch.object(codecontext.CodeContext, 'update_code_context') def test_timer_event(self, mock_update): # Ensure code context is not active. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst new file mode 100644 index 0000000000000..4ae0defc2e217 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst @@ -0,0 +1 @@ +Selecting code context lines no longer causes a jump. From webhook-mailer at python.org Fri Feb 28 13:43:29 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 28 Feb 2020 18:43:29 -0000 Subject: [Python-checkins] bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Message-ID: https://github.com/python/cpython/commit/846ca4961da24669e6e0c901986e66ff485917b2 commit: 846ca4961da24669e6e0c901986e66ff485917b2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T10:43:25-08:00 summary: bpo-39781: Do not jump when select in IDLE codecontext (GH-18683) Previously, the button-up part of selecting with a mouse was treated as a click that meant 'jump' to this line, which modified the context and undid the selection (cherry picked from commit c705fd1e89ccb8f6d414ec817b4616546147d877) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/codecontext.py M Lib/idlelib/idle_test/test_codecontext.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index fe1706ed5a8be..134f843d85e8a 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bpo-39781: Selecting code context lines no longer causes a jump. + bpo-39663: Add tests for pyparse find_good_parse_start(). bpo-39600: Remove duplicate font names from configuration list. diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 4ce98136fe417..989b30e599465 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -7,7 +7,6 @@ enclosing block. The number of hint lines is determined by the maxlines variable in the codecontext section of config-extensions.def. Lines which do not open blocks are not shown in the context hints pane. - """ import re from sys import maxsize as INFINITY @@ -17,8 +16,8 @@ from idlelib.config import idleConf -BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with", "async"} +BLOCKOPENERS = {'class', 'def', 'if', 'elif', 'else', 'while', 'for', + 'try', 'except', 'finally', 'with', 'async'} def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")): @@ -84,7 +83,7 @@ def __del__(self): if self.t1 is not None: try: self.text.after_cancel(self.t1) - except tkinter.TclError: + except tkinter.TclError: # pragma: no cover pass self.t1 = None @@ -112,7 +111,7 @@ def toggle_code_context_event(self, event=None): padx += widget.tk.getint(info['padx']) padx += widget.tk.getint(widget.cget('padx')) border += widget.tk.getint(widget.cget('border')) - self.context = tkinter.Text( + context = self.context = tkinter.Text( self.editwin.text_frame, height=1, width=1, # Don't request more than we get. @@ -120,11 +119,11 @@ def toggle_code_context_event(self, event=None): padx=padx, border=border, relief=SUNKEN, state='disabled') self.update_font() self.update_highlight_colors() - self.context.bind('', self.jumptoline) + context.bind('', self.jumptoline) # Get the current context and initiate the recurring update event. self.timer_event() # Grid the context widget above the text widget. - self.context.grid(row=0, column=1, sticky=NSEW) + context.grid(row=0, column=1, sticky=NSEW) line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'linenumber') @@ -215,18 +214,25 @@ def update_code_context(self): self.context['state'] = 'disabled' def jumptoline(self, event=None): - "Show clicked context line at top of editor." - lines = len(self.info) - if lines == 1: # No context lines are showing. - newtop = 1 - else: - # Line number clicked. - contextline = int(float(self.context.index('insert'))) - # Lines not displayed due to maxlines. - offset = max(1, lines - self.context_depth) - 1 - newtop = self.info[offset + contextline][0] - self.text.yview(f'{newtop}.0') - self.update_code_context() + """ Show clicked context line at top of editor. + + If a selection was made, don't jump; allow copying. + If no visible context, show the top line of the file. + """ + try: + self.context.index("sel.first") + except tkinter.TclError: + lines = len(self.info) + if lines == 1: # No context lines are showing. + newtop = 1 + else: + # Line number clicked. + contextline = int(float(self.context.index('insert'))) + # Lines not displayed due to maxlines. + offset = max(1, lines - self.context_depth) - 1 + newtop = self.info[offset + contextline][0] + self.text.yview(f'{newtop}.0') + self.update_code_context() def timer_event(self): "Event on editor text widget triggered every UPDATEINTERVAL ms." diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index 3ec49e97af6f9..9578cc731a6f9 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -332,6 +332,14 @@ def test_jumptoline(self): jump() eq(cc.topvisible, 8) + # Context selection stops jump. + cc.text.yview('5.0') + cc.update_code_context() + cc.context.tag_add('sel', '1.0', '2.0') + cc.context.mark_set('insert', '1.0') + jump() # Without selection, to line 2. + eq(cc.topvisible, 5) + @mock.patch.object(codecontext.CodeContext, 'update_code_context') def test_timer_event(self, mock_update): # Ensure code context is not active. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst new file mode 100644 index 0000000000000..4ae0defc2e217 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-02-27-22-17-09.bpo-39781.bbYBeL.rst @@ -0,0 +1 @@ +Selecting code context lines no longer causes a jump. From webhook-mailer at python.org Fri Feb 28 14:59:24 2020 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Fri, 28 Feb 2020 19:59:24 -0000 Subject: [Python-checkins] bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) Message-ID: https://github.com/python/cpython/commit/916895f93905f8b8dad677cceff501833f5a633a commit: 916895f93905f8b8dad677cceff501833f5a633a branch: master author: Terry Jan Reedy committer: GitHub date: 2020-02-28T14:59:16-05:00 summary: bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) files: A Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 89c169a512b52..fa906f799c108 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -302,9 +302,9 @@ specification is to be interpreted. Most built-in types implement the following options for format specifications, although some of the formatting options are only supported by the numeric types. -A general convention is that an empty format string (``""``) produces +A general convention is that an empty format specification produces the same result as if you had called :func:`str` on the value. A -non-empty format string typically modifies the result. +non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst new file mode 100644 index 0000000000000..77db173168fc5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst @@ -0,0 +1 @@ +Change 'string' to 'specification' in format doc. From webhook-mailer at python.org Fri Feb 28 15:04:26 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 28 Feb 2020 20:04:26 -0000 Subject: [Python-checkins] bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) Message-ID: https://github.com/python/cpython/commit/5157506e043f75f49caecae1c6afee8517a7bbb0 commit: 5157506e043f75f49caecae1c6afee8517a7bbb0 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T12:04:19-08:00 summary: bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) (cherry picked from commit 916895f93905f8b8dad677cceff501833f5a633a) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 6cbe54963196a..ed8c912364c47 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -303,9 +303,9 @@ specification is to be interpreted. Most built-in types implement the following options for format specifications, although some of the formatting options are only supported by the numeric types. -A general convention is that an empty format string (``""``) produces +A general convention is that an empty format specification produces the same result as if you had called :func:`str` on the value. A -non-empty format string typically modifies the result. +non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst new file mode 100644 index 0000000000000..77db173168fc5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst @@ -0,0 +1 @@ +Change 'string' to 'specification' in format doc. From webhook-mailer at python.org Fri Feb 28 15:07:01 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 28 Feb 2020 20:07:01 -0000 Subject: [Python-checkins] bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) Message-ID: https://github.com/python/cpython/commit/445152e0d3ab6e4381aef8d1404c2c17a516070f commit: 445152e0d3ab6e4381aef8d1404c2c17a516070f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T12:06:53-08:00 summary: bpo-13790: Change 'string' to 'specification' in format doc (GH-18690) (cherry picked from commit 916895f93905f8b8dad677cceff501833f5a633a) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 89c169a512b52..fa906f799c108 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -302,9 +302,9 @@ specification is to be interpreted. Most built-in types implement the following options for format specifications, although some of the formatting options are only supported by the numeric types. -A general convention is that an empty format string (``""``) produces +A general convention is that an empty format specification produces the same result as if you had called :func:`str` on the value. A -non-empty format string typically modifies the result. +non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: diff --git a/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst new file mode 100644 index 0000000000000..77db173168fc5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-28-14-39-25.bpo-13790.hvLaRI.rst @@ -0,0 +1 @@ +Change 'string' to 'specification' in format doc. From webhook-mailer at python.org Fri Feb 28 18:25:41 2020 From: webhook-mailer at python.org (Shantanu) Date: Fri, 28 Feb 2020 23:25:41 -0000 Subject: [Python-checkins] bpo-39718: add TYPE_IGNORE, COLONEQUAL to py38 changes in token (GH-18598) Message-ID: https://github.com/python/cpython/commit/c2f7eb254bee036afc8a71437ec6aac82f06a1ce commit: c2f7eb254bee036afc8a71437ec6aac82f06a1ce branch: master author: Shantanu committer: GitHub date: 2020-02-28T18:25:36-05:00 summary: bpo-39718: add TYPE_IGNORE, COLONEQUAL to py38 changes in token (GH-18598) files: A Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst M Doc/library/token.rst diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 1777929be739d..dab8f0fa9b64f 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -87,7 +87,7 @@ the :mod:`tokenize` module. now tokenized as :data:`NAME` tokens. .. versionchanged:: 3.8 - Added :data:`TYPE_COMMENT`. + Added :data:`TYPE_COMMENT`, :data:`TYPE_IGNORE`, :data:`COLONEQUAL`. Added :data:`AWAIT` and :data:`ASYNC` tokens back (they're needed to support parsing older Python versions for :func:`ast.parse` with ``feature_version`` set to 6 or lower). diff --git a/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst b/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst new file mode 100644 index 0000000000000..8072f617192b4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst @@ -0,0 +1 @@ +Update :mod:`token` documentation to reflect additions in Python 3.8 \ No newline at end of file From webhook-mailer at python.org Fri Feb 28 18:31:24 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 28 Feb 2020 23:31:24 -0000 Subject: [Python-checkins] bpo-39718: add TYPE_IGNORE, COLONEQUAL to py38 changes in token (GH-18598) Message-ID: https://github.com/python/cpython/commit/7f53d87cb0324e391c969855ed8f4b3255f9f744 commit: 7f53d87cb0324e391c969855ed8f4b3255f9f744 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T15:31:20-08:00 summary: bpo-39718: add TYPE_IGNORE, COLONEQUAL to py38 changes in token (GH-18598) (cherry picked from commit c2f7eb254bee036afc8a71437ec6aac82f06a1ce) Co-authored-by: Shantanu files: A Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst M Doc/library/token.rst diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 1777929be739d..dab8f0fa9b64f 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -87,7 +87,7 @@ the :mod:`tokenize` module. now tokenized as :data:`NAME` tokens. .. versionchanged:: 3.8 - Added :data:`TYPE_COMMENT`. + Added :data:`TYPE_COMMENT`, :data:`TYPE_IGNORE`, :data:`COLONEQUAL`. Added :data:`AWAIT` and :data:`ASYNC` tokens back (they're needed to support parsing older Python versions for :func:`ast.parse` with ``feature_version`` set to 6 or lower). diff --git a/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst b/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst new file mode 100644 index 0000000000000..8072f617192b4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-21-22-05-20.bpo-39718.xtBoSi.rst @@ -0,0 +1 @@ +Update :mod:`token` documentation to reflect additions in Python 3.8 \ No newline at end of file From webhook-mailer at python.org Fri Feb 28 19:22:03 2020 From: webhook-mailer at python.org (Steve Dower) Date: Sat, 29 Feb 2020 00:22:03 -0000 Subject: [Python-checkins] bpo-39789: Update Windows release build machines to VS 2019 (GH-18695) Message-ID: https://github.com/python/cpython/commit/03153dd1459fab94f294a118ed1525e34d58601a commit: 03153dd1459fab94f294a118ed1525e34d58601a branch: master author: Steve Dower committer: GitHub date: 2020-02-29T00:21:46Z summary: bpo-39789: Update Windows release build machines to VS 2019 (GH-18695) Also fixes some potential Nuget build issues. files: A Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst 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-msi.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-publish-store.yml M .azure-pipelines/windows-release/stage-sign.yml M .azure-pipelines/windows-release/stage-test-embed.yml M .azure-pipelines/windows-release/stage-test-msi.yml M .azure-pipelines/windows-release/stage-test-nuget.yml M PC/layout/support/nuspec.py M Tools/nuget/make_pkg.proj diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index 9391a91e30b5e..69f3b1e16451e 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -3,7 +3,7 @@ jobs: displayName: Docs build pool: name: 'Windows Release' - #vmName: win2016-vs2017 + #vmImage: windows-2019 workspace: clean: all @@ -45,7 +45,7 @@ jobs: displayName: Python build pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all @@ -91,7 +91,7 @@ jobs: condition: and(succeeded(), ne(variables['DoPGO'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all @@ -141,7 +141,7 @@ jobs: displayName: Publish Tcl/Tk Library pool: - vmName: windows-latest + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml index 3306e1cbc49d9..dbccdead143b2 100644 --- a/.azure-pipelines/windows-release/stage-layout-embed.yml +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml index 78bc1b3975e93..8fc8da3e52fe0 100644 --- a/.azure-pipelines/windows-release/stage-layout-full.yml +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoLayout'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml index 60a5c9ea5435c..def4f7d3c6bee 100644 --- a/.azure-pipelines/windows-release/stage-layout-msix.yml +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -3,7 +3,7 @@ jobs: displayName: Make MSIX layout pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-nuget.yml b/.azure-pipelines/windows-release/stage-layout-nuget.yml index 7e20f89530349..41cdff850e83b 100644 --- a/.azure-pipelines/windows-release/stage-layout-nuget.yml +++ b/.azure-pipelines/windows-release/stage-layout-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-msi.yml b/.azure-pipelines/windows-release/stage-msi.yml index 7afc816a0c6e9..9b965b09c1474 100644 --- a/.azure-pipelines/windows-release/stage-msi.yml +++ b/.azure-pipelines/windows-release/stage-msi.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), not(variables['SigningCertificate'])) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 variables: ReleaseUri: http://www.python.org/{arch} diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml index f17ba9628e21b..07e343a0b4e0c 100644 --- a/.azure-pipelines/windows-release/stage-pack-msix.yml +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -3,7 +3,7 @@ jobs: displayName: Pack MSIX bundles pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml index 34619fc5fdc31..b100364820d95 100644 --- a/.azure-pipelines/windows-release/stage-pack-nuget.yml +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml index b78bd493a0fd1..d5edf44ef5c2e 100644 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index 0474d40e4bc02..4b88bdebf8cc4 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'))) pool: - #vmName: win2016-vs2017 + #vmImage: windows-2019 name: 'Windows Release' workspace: diff --git a/.azure-pipelines/windows-release/stage-publish-store.yml b/.azure-pipelines/windows-release/stage-publish-store.yml index b22147b1ab45e..e0512b95f27da 100644 --- a/.azure-pipelines/windows-release/stage-publish-store.yml +++ b/.azure-pipelines/windows-release/stage-publish-store.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml index a0adc0581229d..4d757ae8fca03 100644 --- a/.azure-pipelines/windows-release/stage-sign.yml +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -114,7 +114,7 @@ jobs: condition: and(succeeded(), not(variables['SigningCertificate'])) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 steps: - checkout: none diff --git a/.azure-pipelines/windows-release/stage-test-embed.yml b/.azure-pipelines/windows-release/stage-test-embed.yml index b33176266a20d..d99bd74722bac 100644 --- a/.azure-pipelines/windows-release/stage-test-embed.yml +++ b/.azure-pipelines/windows-release/stage-test-embed.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-test-msi.yml b/.azure-pipelines/windows-release/stage-test-msi.yml index 27b0c96987a7a..21e38c39590f7 100644 --- a/.azure-pipelines/windows-release/stage-test-msi.yml +++ b/.azure-pipelines/windows-release/stage-test-msi.yml @@ -3,7 +3,7 @@ jobs: displayName: Test MSI pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-test-nuget.yml b/.azure-pipelines/windows-release/stage-test-nuget.yml index 1f8b601d0d023..94d815e95226e 100644 --- a/.azure-pipelines/windows-release/stage-test-nuget.yml +++ b/.azure-pipelines/windows-release/stage-test-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst b/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst new file mode 100644 index 0000000000000..077b0afcba3c1 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst @@ -0,0 +1 @@ +Update Windows release build machines to Visual Studio 2019 (MSVC 14.2). diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py index 9c6a9a9159509..dbcb713ef9d0c 100644 --- a/PC/layout/support/nuspec.py +++ b/PC/layout/support/nuspec.py @@ -14,7 +14,7 @@ NUSPEC_DATA = { "PYTHON_TAG": VER_DOT, "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), - "FILELIST": r' ', + "FILELIST": r' ', "GIT": sys._git, } @@ -31,7 +31,7 @@ VER_DOT, VER_MICRO, "-" if VER_SUFFIX else "", VER_SUFFIX ) -FILELIST_WITH_PROPS = r""" +FILELIST_WITH_PROPS = r""" """ NUSPEC_TEMPLATE = r""" @@ -44,13 +44,13 @@ tools\LICENSE.txt https://www.python.org/ Installs {PYTHON_BITNESS} Python for use in build scenarios. - images\logox128.png + images\python.png https://www.python.org/static/favicon.ico python - + {FILELIST} @@ -73,6 +73,6 @@ def get_nuspec_layout(ns): data[k] = v if ns.include_all or ns.include_props: data["FILELIST"] = FILELIST_WITH_PROPS - data["LOGO"] = ns.source / "PC" / "icons" / "logox128.png" nuspec = NUSPEC_TEMPLATE.format_map(data) yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) + yield "python.png", ns.source / "PC" / "icons" / "logox128.png" diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index b387b8eef5423..710ef3dcb5c01 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -33,7 +33,7 @@ "$(IntermediateOutputPath)pkg\pip.exe" -B -m pip install -U $(Packages) - "$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).nuspec" -BasePath "$(IntermediateOutputPath)pkg" + "$(Nuget)" pack "$(IntermediateOutputPath)pkg\python.nuspec" -BasePath "$(IntermediateOutputPath)pkg" "$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec" -BasePath "$(BuildPath.TrimEnd(`\`))" $(NugetArguments) -OutputDirectory "$(OutputPath.Trim(`\`))" $(NugetArguments) -Version "$(NuspecVersion)" From webhook-mailer at python.org Fri Feb 28 19:41:07 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 29 Feb 2020 00:41:07 -0000 Subject: [Python-checkins] bpo-39789: Update Windows release build machines to VS 2019 (GH-18695) Message-ID: https://github.com/python/cpython/commit/45c4112b7250cb600aa2f3a42b4e6b5bfd2919c4 commit: 45c4112b7250cb600aa2f3a42b4e6b5bfd2919c4 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-28T16:41:03-08:00 summary: bpo-39789: Update Windows release build machines to VS 2019 (GH-18695) Also fixes some potential Nuget build issues. (cherry picked from commit 03153dd1459fab94f294a118ed1525e34d58601a) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst 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-msi.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-publish-store.yml M .azure-pipelines/windows-release/stage-sign.yml M .azure-pipelines/windows-release/stage-test-embed.yml M .azure-pipelines/windows-release/stage-test-msi.yml M .azure-pipelines/windows-release/stage-test-nuget.yml M PC/layout/support/nuspec.py M Tools/nuget/make_pkg.proj diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index 9391a91e30b5e..69f3b1e16451e 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -3,7 +3,7 @@ jobs: displayName: Docs build pool: name: 'Windows Release' - #vmName: win2016-vs2017 + #vmImage: windows-2019 workspace: clean: all @@ -45,7 +45,7 @@ jobs: displayName: Python build pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all @@ -91,7 +91,7 @@ jobs: condition: and(succeeded(), ne(variables['DoPGO'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all @@ -141,7 +141,7 @@ jobs: displayName: Publish Tcl/Tk Library pool: - vmName: windows-latest + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml index 3306e1cbc49d9..dbccdead143b2 100644 --- a/.azure-pipelines/windows-release/stage-layout-embed.yml +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml index 78bc1b3975e93..8fc8da3e52fe0 100644 --- a/.azure-pipelines/windows-release/stage-layout-full.yml +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoLayout'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml index 60a5c9ea5435c..def4f7d3c6bee 100644 --- a/.azure-pipelines/windows-release/stage-layout-msix.yml +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -3,7 +3,7 @@ jobs: displayName: Make MSIX layout pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-layout-nuget.yml b/.azure-pipelines/windows-release/stage-layout-nuget.yml index 7e20f89530349..41cdff850e83b 100644 --- a/.azure-pipelines/windows-release/stage-layout-nuget.yml +++ b/.azure-pipelines/windows-release/stage-layout-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-msi.yml b/.azure-pipelines/windows-release/stage-msi.yml index 7afc816a0c6e9..9b965b09c1474 100644 --- a/.azure-pipelines/windows-release/stage-msi.yml +++ b/.azure-pipelines/windows-release/stage-msi.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), not(variables['SigningCertificate'])) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 variables: ReleaseUri: http://www.python.org/{arch} diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml index f17ba9628e21b..07e343a0b4e0c 100644 --- a/.azure-pipelines/windows-release/stage-pack-msix.yml +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -3,7 +3,7 @@ jobs: displayName: Pack MSIX bundles pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml index 34619fc5fdc31..b100364820d95 100644 --- a/.azure-pipelines/windows-release/stage-pack-nuget.yml +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml index b78bd493a0fd1..d5edf44ef5c2e 100644 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index 8c95f1b950cd7..b4710d8c248e2 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'))) pool: - #vmName: win2016-vs2017 + #vmImage: windows-2019 name: 'Windows Release' workspace: diff --git a/.azure-pipelines/windows-release/stage-publish-store.yml b/.azure-pipelines/windows-release/stage-publish-store.yml index b22147b1ab45e..e0512b95f27da 100644 --- a/.azure-pipelines/windows-release/stage-publish-store.yml +++ b/.azure-pipelines/windows-release/stage-publish-store.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml index a0adc0581229d..4d757ae8fca03 100644 --- a/.azure-pipelines/windows-release/stage-sign.yml +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -114,7 +114,7 @@ jobs: condition: and(succeeded(), not(variables['SigningCertificate'])) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 steps: - checkout: none diff --git a/.azure-pipelines/windows-release/stage-test-embed.yml b/.azure-pipelines/windows-release/stage-test-embed.yml index b33176266a20d..d99bd74722bac 100644 --- a/.azure-pipelines/windows-release/stage-test-embed.yml +++ b/.azure-pipelines/windows-release/stage-test-embed.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-test-msi.yml b/.azure-pipelines/windows-release/stage-test-msi.yml index 27b0c96987a7a..21e38c39590f7 100644 --- a/.azure-pipelines/windows-release/stage-test-msi.yml +++ b/.azure-pipelines/windows-release/stage-test-msi.yml @@ -3,7 +3,7 @@ jobs: displayName: Test MSI pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/.azure-pipelines/windows-release/stage-test-nuget.yml b/.azure-pipelines/windows-release/stage-test-nuget.yml index 1f8b601d0d023..94d815e95226e 100644 --- a/.azure-pipelines/windows-release/stage-test-nuget.yml +++ b/.azure-pipelines/windows-release/stage-test-nuget.yml @@ -4,7 +4,7 @@ jobs: condition: and(succeeded(), eq(variables['DoNuget'], 'true')) pool: - vmName: win2016-vs2017 + vmImage: windows-2019 workspace: clean: all diff --git a/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst b/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst new file mode 100644 index 0000000000000..077b0afcba3c1 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-02-28-22-46-09.bpo-39789.67XRoP.rst @@ -0,0 +1 @@ +Update Windows release build machines to Visual Studio 2019 (MSVC 14.2). diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py index 9c6a9a9159509..dbcb713ef9d0c 100644 --- a/PC/layout/support/nuspec.py +++ b/PC/layout/support/nuspec.py @@ -14,7 +14,7 @@ NUSPEC_DATA = { "PYTHON_TAG": VER_DOT, "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), - "FILELIST": r' ', + "FILELIST": r' ', "GIT": sys._git, } @@ -31,7 +31,7 @@ VER_DOT, VER_MICRO, "-" if VER_SUFFIX else "", VER_SUFFIX ) -FILELIST_WITH_PROPS = r""" +FILELIST_WITH_PROPS = r""" """ NUSPEC_TEMPLATE = r""" @@ -44,13 +44,13 @@ tools\LICENSE.txt https://www.python.org/ Installs {PYTHON_BITNESS} Python for use in build scenarios. - images\logox128.png + images\python.png https://www.python.org/static/favicon.ico python - + {FILELIST} @@ -73,6 +73,6 @@ def get_nuspec_layout(ns): data[k] = v if ns.include_all or ns.include_props: data["FILELIST"] = FILELIST_WITH_PROPS - data["LOGO"] = ns.source / "PC" / "icons" / "logox128.png" nuspec = NUSPEC_TEMPLATE.format_map(data) yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) + yield "python.png", ns.source / "PC" / "icons" / "logox128.png" diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index b387b8eef5423..710ef3dcb5c01 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -33,7 +33,7 @@ "$(IntermediateOutputPath)pkg\pip.exe" -B -m pip install -U $(Packages) - "$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).nuspec" -BasePath "$(IntermediateOutputPath)pkg" + "$(Nuget)" pack "$(IntermediateOutputPath)pkg\python.nuspec" -BasePath "$(IntermediateOutputPath)pkg" "$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec" -BasePath "$(BuildPath.TrimEnd(`\`))" $(NugetArguments) -OutputDirectory "$(OutputPath.Trim(`\`))" $(NugetArguments) -Version "$(NuspecVersion)" From webhook-mailer at python.org Fri Feb 28 20:28:42 2020 From: webhook-mailer at python.org (Gregory P. Smith) Date: Sat, 29 Feb 2020 01:28:42 -0000 Subject: [Python-checkins] bpo-39769: Fix compileall ddir for subpkgs. (GH-18676) Message-ID: https://github.com/python/cpython/commit/02673352b5db6ca4d3dc804965facbedfe66425d commit: 02673352b5db6ca4d3dc804965facbedfe66425d branch: master author: Gregory P. Smith committer: GitHub date: 2020-02-28T17:28:37-08:00 summary: bpo-39769: Fix compileall ddir for subpkgs. (GH-18676) Fix compileall.compile_dir() ddir= behavior on sub-packages. Fixes compileall.compile_dir's ddir parameter and compileall command line flag `-d` to no longer write the wrong pathname to the generated pyc file for submodules beneath the root of the directory tree being compiled. This fixes a regression introduced with Python 3.5. Also marks the _new_ in 3.9 from PR #16012 parameters to compile_dir as keyword only (as that is the only way they will be used) and fixes an omission of them in one place from the docs. files: A Misc/NEWS.d/next/Library/2020-02-27-00-40-21.bpo-39769.hJmxu4.rst M Doc/library/compileall.rst M Lib/compileall.py M Lib/test/test_compileall.py M Lib/test/test_importlib/util.py diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index 394d60634f1e0..b1ae9d60e8ae1 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -143,7 +143,7 @@ runtime. Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, stripdir=None, prependdir=None, limit_sl_dest=None) +.. function:: compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. Return a true value if all the files compiled successfully, @@ -221,7 +221,7 @@ Public functions .. versionchanged:: 3.9 Added *stripdir*, *prependdir* and *limit_sl_dest* arguments. -.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None) +.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, \*, stripdir=None, prependdir=None, limit_sl_dest=None) Compile the file with path *fullname*. Return a true value if the file compiled successfully, and a false value otherwise. diff --git a/Lib/compileall.py b/Lib/compileall.py index 8cfde5b7b3e0a..1831ad749f2b1 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -46,7 +46,7 @@ def _walk_dir(dir, maxlevels, quiet=0): def compile_dir(dir, maxlevels=None, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, - invalidation_mode=None, stripdir=None, + invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None): """Byte-compile all modules in the given directory tree. @@ -72,6 +72,13 @@ def compile_dir(dir, maxlevels=None, ddir=None, force=False, the defined path """ ProcessPoolExecutor = None + if ddir is not None and (stripdir is not None or prependdir is not None): + raise ValueError(("Destination dir (ddir) cannot be used " + "in combination with stripdir or prependdir")) + if ddir is not None: + stripdir = dir + prependdir = ddir + ddir = None if workers < 0: raise ValueError('workers must be greater or equal to 0') if workers != 1: @@ -111,7 +118,7 @@ def compile_dir(dir, maxlevels=None, ddir=None, force=False, def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, - invalidation_mode=None, stripdir=None, prependdir=None, + invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None): """Byte-compile one file. diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 2ebcb424095d8..cb59fd71b3825 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -212,6 +212,47 @@ def test_compile_dir_maxlevels(self): compileall.compile_dir(self.directory, quiet=True, maxlevels=depth) self.assertTrue(os.path.isfile(pyc_filename)) + def _test_ddir_only(self, *, ddir, parallel=True): + """Recursive compile_dir ddir must contain package paths; bpo39769.""" + fullpath = ["test", "foo"] + path = self.directory + mods = [] + for subdir in fullpath: + path = os.path.join(path, subdir) + os.mkdir(path) + script_helper.make_script(path, "__init__", "") + mods.append(script_helper.make_script(path, "mod", + "def fn(): 1/0\nfn()\n")) + compileall.compile_dir( + self.directory, quiet=True, ddir=ddir, + workers=2 if parallel else 1) + self.assertTrue(mods) + for mod in mods: + self.assertTrue(mod.startswith(self.directory), mod) + modcode = importlib.util.cache_from_source(mod) + modpath = mod[len(self.directory+os.sep):] + _, _, err = script_helper.assert_python_failure(modcode) + expected_in = os.path.join(ddir, modpath) + mod_code_obj = test.test_importlib.util.get_code_from_pyc(modcode) + self.assertEqual(mod_code_obj.co_filename, expected_in) + self.assertIn(f'"{expected_in}"', os.fsdecode(err)) + + def test_ddir_only_one_worker(self): + """Recursive compile_dir ddir= contains package paths; bpo39769.""" + return self._test_ddir_only(ddir="", parallel=False) + + def test_ddir_multiple_workers(self): + """Recursive compile_dir ddir= contains package paths; bpo39769.""" + return self._test_ddir_only(ddir="", parallel=True) + + def test_ddir_empty_only_one_worker(self): + """Recursive compile_dir ddir='' contains package paths; bpo39769.""" + return self._test_ddir_only(ddir="", parallel=False) + + def test_ddir_empty_multiple_workers(self): + """Recursive compile_dir ddir='' contains package paths; bpo39769.""" + return self._test_ddir_only(ddir="", parallel=True) + def test_strip_only(self): fullpath = ["test", "build", "real", "path"] path = os.path.join(self.directory, *fullpath) diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index 5aaf277e1f372..de6e0b0256018 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -7,6 +7,7 @@ from importlib import machinery, util, invalidate_caches from importlib.abc import ResourceReader import io +import marshal import os import os.path from pathlib import Path, PurePath @@ -118,6 +119,16 @@ def submodule(parent, name, pkg_dir, content=''): return '{}.{}'.format(parent, name), path +def get_code_from_pyc(pyc_path): + """Reads a pyc file and returns the unmarshalled code object within. + + No header validation is performed. + """ + with open(pyc_path, 'rb') as pyc_f: + pyc_f.seek(16) + return marshal.load(pyc_f) + + @contextlib.contextmanager def uncache(*names): """Uncache a module from sys.modules. diff --git a/Misc/NEWS.d/next/Library/2020-02-27-00-40-21.bpo-39769.hJmxu4.rst b/Misc/NEWS.d/next/Library/2020-02-27-00-40-21.bpo-39769.hJmxu4.rst new file mode 100644 index 0000000000000..9b564bd10d3b3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-27-00-40-21.bpo-39769.hJmxu4.rst @@ -0,0 +1,4 @@ +The :func:`compileall.compile_dir` function's *ddir* parameter and the +compileall command line flag `-d` no longer write the wrong pathname to the +generated pyc file for submodules beneath the root of the directory tree +being compiled. This fixes a regression introduced with Python 3.5. From webhook-mailer at python.org Sat Feb 29 03:22:42 2020 From: webhook-mailer at python.org (Henry Harutyunyan) Date: Sat, 29 Feb 2020 08:22:42 -0000 Subject: [Python-checkins] bpo-37534: Allow adding Standalone Document Declaration when generating XML documents (GH-14912) Message-ID: https://github.com/python/cpython/commit/dc04a0571e362cd3de040771d7705cb107ae26fc commit: dc04a0571e362cd3de040771d7705cb107ae26fc branch: master author: Henry Harutyunyan committer: GitHub date: 2020-02-29T09:22:19+01:00 summary: bpo-37534: Allow adding Standalone Document Declaration when generating XML documents (GH-14912) files: A Misc/NEWS.d/next/Library/2019-08-20-00-02-37.bpo-37534.TvjAUi.rst M Doc/library/xml.dom.minidom.rst M Lib/test/test_minidom.py M Lib/xml/dom/minidom.py M Misc/ACKS diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 8711242d95d74..2c78cd939243a 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -132,7 +132,8 @@ module documentation. This section lists the differences between the API and ... # Work with dom. -.. method:: Node.writexml(writer, indent="", addindent="", newl="") +.. method:: Node.writexml(writer, indent="", addindent="", newl="", + encoding=None, standalone=None) Write XML to the writer object. The writer receives texts but not bytes as input, it should have a :meth:`write` method which matches that of the file object @@ -144,11 +145,18 @@ module documentation. This section lists the differences between the API and For the :class:`Document` node, an additional keyword argument *encoding* can be used to specify the encoding field of the XML header. + Silimarly, explicitly stating the *standalone* argument causes the + standalone document declarations to be added to the prologue of the XML + document. + If the value is set to `True`, `standalone="yes"` is added, + otherwise it is set to `"no"`. + Not stating the argument will omit the declaration from the document. + .. versionchanged:: 3.8 The :meth:`writexml` method now preserves the attribute order specified by the user. -.. method:: Node.toxml(encoding=None) +.. method:: Node.toxml(encoding=None, standalone=None) Return a string or byte string containing the XML represented by the DOM node. @@ -160,11 +168,14 @@ module documentation. This section lists the differences between the API and encoding. Encoding this string in an encoding other than UTF-8 is likely incorrect, since UTF-8 is the default encoding of XML. + The *standalone* argument behaves exactly as in :meth:`writexml`. + .. versionchanged:: 3.8 The :meth:`toxml` method now preserves the attribute order specified by the user. -.. method:: Node.toprettyxml(indent="\\t", newl="\\n", encoding=None) +.. method:: Node.toprettyxml(indent="\\t", newl="\\n", encoding=None, + standalone=None) Return a pretty-printed version of the document. *indent* specifies the indentation string and defaults to a tabulator; *newl* specifies the string @@ -173,6 +184,8 @@ module documentation. This section lists the differences between the API and The *encoding* argument behaves like the corresponding argument of :meth:`toxml`. + The *standalone* argument behaves exactly as in :meth:`writexml`. + .. versionchanged:: 3.8 The :meth:`toprettyxml` method now preserves the attribute order specified by the user. diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 70965854ed1b1..1663b1f1143dd 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1152,6 +1152,22 @@ def testEncodings(self): doc.unlink() + def testStandalone(self): + doc = parseString('') + self.assertEqual(doc.toxml(), + '\u20ac') + self.assertEqual(doc.toxml(standalone=None), + '\u20ac') + self.assertEqual(doc.toxml(standalone=True), + '\u20ac') + self.assertEqual(doc.toxml(standalone=False), + '\u20ac') + self.assertEqual(doc.toxml('utf-8', True), + b'' + b'\xe2\x82\xac') + + doc.unlink() + class UserDataHandler: called = 0 def handle(self, operation, key, data, src, dst): diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index 464420b76598e..1083b48138710 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -43,10 +43,11 @@ class Node(xml.dom.Node): def __bool__(self): return True - def toxml(self, encoding=None): - return self.toprettyxml("", "", encoding) + def toxml(self, encoding=None, standalone=None): + return self.toprettyxml("", "", encoding, standalone) - def toprettyxml(self, indent="\t", newl="\n", encoding=None): + def toprettyxml(self, indent="\t", newl="\n", encoding=None, + standalone=None): if encoding is None: writer = io.StringIO() else: @@ -56,7 +57,7 @@ def toprettyxml(self, indent="\t", newl="\n", encoding=None): newline='\n') if self.nodeType == Node.DOCUMENT_NODE: # Can pass encoding only to document, to put it into XML header - self.writexml(writer, "", indent, newl, encoding) + self.writexml(writer, "", indent, newl, encoding, standalone) else: self.writexml(writer, "", indent, newl) if encoding is None: @@ -1787,12 +1788,17 @@ def importNode(self, node, deep): raise xml.dom.NotSupportedErr("cannot import document type nodes") return _clone_node(node, deep, self) - def writexml(self, writer, indent="", addindent="", newl="", encoding=None): - if encoding is None: - writer.write(''+newl) - else: - writer.write('%s' % ( - encoding, newl)) + def writexml(self, writer, indent="", addindent="", newl="", encoding=None, + standalone=None): + declarations = [] + + if encoding: + declarations.append(f'encoding="{encoding}"') + if standalone is not None: + declarations.append(f'standalone="{"yes" if standalone else "no"}"') + + writer.write(f'{newl}') + for node in self.childNodes: node.writexml(writer, indent, addindent, newl) diff --git a/Misc/ACKS b/Misc/ACKS index fe24a5636ccc2..1b5febb1d19d8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -659,6 +659,7 @@ David Harrigan Brian Harring Jonathan Hartley Travis B. Hartwell +Henrik Harutyunyan Shane Harvey Larry Hastings Tim Hatch diff --git a/Misc/NEWS.d/next/Library/2019-08-20-00-02-37.bpo-37534.TvjAUi.rst b/Misc/NEWS.d/next/Library/2019-08-20-00-02-37.bpo-37534.TvjAUi.rst new file mode 100644 index 0000000000000..0c9dd29251af0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-08-20-00-02-37.bpo-37534.TvjAUi.rst @@ -0,0 +1,2 @@ +When using minidom module to generate XML documents the ability to add Standalone Document Declaration is added. +All the changes are made to generate a document in compliance with Extensible Markup Language (XML) 1.0 (Fifth Edition) W3C Recommendation (available here: https://www.w3.org/TR/xml/#sec-prolog-dtd). \ No newline at end of file From webhook-mailer at python.org Sat Feb 29 07:25:35 2020 From: webhook-mailer at python.org (Ananthakrishnan) Date: Sat, 29 Feb 2020 12:25:35 -0000 Subject: [Python-checkins] bpo-39379: Remove reference to sys.path[0] being absolute path in whatsnew (GH-18561) Message-ID: https://github.com/python/cpython/commit/1f0cd3c61a5ae3aac5ebaccc75ae9828ca4f96c4 commit: 1f0cd3c61a5ae3aac5ebaccc75ae9828ca4f96c4 branch: master author: Ananthakrishnan committer: GitHub date: 2020-02-29T17:55:22+05:30 summary: bpo-39379: Remove reference to sys.path[0] being absolute path in whatsnew (GH-18561) Remove reference to sys.path[0] being absolute path in whatsnew Co-Authored-By: Kyle Stanley Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Kyle Stanley files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 8ad26d6978605..3364f392f15c7 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -89,11 +89,10 @@ Other Language Changes * Python now gets the absolute path of the script filename specified on the command line (ex: ``python3 script.py``): the ``__file__`` attribute of - the :mod:`__main__` module and ``sys.path[0]`` become an - absolute path, rather than a relative path. These paths now remain valid - after the current directory is changed by :func:`os.chdir`. As a side effect, - a traceback also displays the absolute path for :mod:`__main__` module frames - in this case. + the :mod:`__main__` module became an absolute path, rather than a relative + path. These paths now remain valid after the current directory is changed + by :func:`os.chdir`. As a side effect, the traceback also displays the + absolute path for :mod:`__main__` module frames in this case. (Contributed by Victor Stinner in :issue:`20443`.) * In the :ref:`Python Development Mode ` and in debug build, the From webhook-mailer at python.org Sat Feb 29 11:34:23 2020 From: webhook-mailer at python.org (Jason R. Coombs) Date: Sat, 29 Feb 2020 16:34:23 -0000 Subject: [Python-checkins] bpo-39667: Sync zipp 3.0 (GH-18540) Message-ID: https://github.com/python/cpython/commit/0aeab5c4381f0cc11479362af2533b3a391312ac commit: 0aeab5c4381f0cc11479362af2533b3a391312ac branch: master author: Jason R. Coombs committer: GitHub date: 2020-02-29T10:34:11-06:00 summary: bpo-39667: Sync zipp 3.0 (GH-18540) * bpo-39667: Improve pathlib.Path compatibility on zipfile.Path and correct performance degradation as found in zipp 3.0 * ?? Added by blurb_it. * Update docs for new zipfile.Path.open * Rely on dict, faster than OrderedDict. * Syntax edits on docs Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2020-02-17-22-38-15.bpo-39667.QuzEHH.rst M Doc/library/zipfile.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index e8a2530fb8c17..7126d8bd703f6 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -489,10 +489,20 @@ Path objects are traversable using the ``/`` operator. The final path component. -.. method:: Path.open(*, **) - - Invoke :meth:`ZipFile.open` on the current path. Accepts - the same arguments as :meth:`ZipFile.open`. +.. method:: Path.open(mode='r', *, pwd, **) + + Invoke :meth:`ZipFile.open` on the current path. + Allows opening for read or write, text or binary + through supported modes: 'r', 'w', 'rb', 'wb'. + Positional and keyword arguments are passed through to + :class:`io.TextIOWrapper` when opened as text and + ignored otherwise. + ``pwd`` is the ``pwd`` parameter to + :meth:`ZipFile.open`. + + .. versionchanged:: 3.9 + Added support for text and binary modes for open. Default + mode is now text. .. method:: Path.iterdir() diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 09fc850600610..643c5b477bab3 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -5,6 +5,7 @@ import os import pathlib import posixpath +import string import struct import subprocess import sys @@ -2880,7 +2881,7 @@ def test_open(self): a, b, g = root.iterdir() with a.open() as strm: data = strm.read() - assert data == b"content of a" + assert data == "content of a" def test_read(self): for alpharep in self.zipfile_alpharep(): @@ -2974,6 +2975,11 @@ def test_joinpath_constant_time(self): # Check the file iterated all items assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES + # @func_timeout.func_set_timeout(3) + def test_implied_dirs_performance(self): + data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] + zipfile.CompleteDirs._implied_dirs(data) + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 4510fac250b97..55993c89b5bcd 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -17,7 +17,6 @@ import threading import time import contextlib -from collections import OrderedDict try: import zlib # We may need its compression method @@ -2102,24 +2101,6 @@ def _compile(file, optimize=-1): return (fname, archivename) -def _unique_everseen(iterable, key=None): - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() - seen_add = seen.add - if key is None: - for element in itertools.filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element - else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element - - def _parents(path): """ Given a path with elements separated by @@ -2161,6 +2142,18 @@ def _ancestry(path): path, tail = posixpath.split(path) +_dedupe = dict.fromkeys +"""Deduplicate an iterable in original order""" + + +def _difference(minuend, subtrahend): + """ + Return items in minuend not in subtrahend, retaining order + with O(1) lookup. + """ + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + class CompleteDirs(ZipFile): """ A ZipFile subclass that ensures that implied directories @@ -2170,13 +2163,8 @@ class CompleteDirs(ZipFile): @staticmethod def _implied_dirs(names): parents = itertools.chain.from_iterable(map(_parents, names)) - # Deduplicate entries in original order - implied_dirs = OrderedDict.fromkeys( - p + posixpath.sep for p in parents - # Cast names to a set for O(1) lookups - if p + posixpath.sep not in set(names) - ) - return implied_dirs + as_dirs = (p + posixpath.sep for p in parents) + return _dedupe(_difference(as_dirs, names)) def namelist(self): names = super(CompleteDirs, self).namelist() @@ -2305,20 +2293,31 @@ def __init__(self, root, at=""): self.root = FastLookup.make(root) self.at = at - @property - def open(self): - return functools.partial(self.root.open, self.at) + def open(self, mode='r', *args, **kwargs): + """ + Open this entry as text or binary following the semantics + of ``pathlib.Path.open()`` by passing arguments through + to io.TextIOWrapper(). + """ + pwd = kwargs.pop('pwd', None) + zip_mode = mode[0] + stream = self.root.open(self.at, zip_mode, pwd=pwd) + if 'b' in mode: + if args or kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + return io.TextIOWrapper(stream, *args, **kwargs) @property def name(self): return posixpath.basename(self.at.rstrip("/")) def read_text(self, *args, **kwargs): - with self.open() as strm: - return io.TextIOWrapper(strm, *args, **kwargs).read() + with self.open('r', *args, **kwargs) as strm: + return strm.read() def read_bytes(self): - with self.open() as strm: + with self.open('rb') as strm: return strm.read() def _is_child(self, path): diff --git a/Misc/NEWS.d/next/Library/2020-02-17-22-38-15.bpo-39667.QuzEHH.rst b/Misc/NEWS.d/next/Library/2020-02-17-22-38-15.bpo-39667.QuzEHH.rst new file mode 100644 index 0000000000000..acf503cc998d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-17-22-38-15.bpo-39667.QuzEHH.rst @@ -0,0 +1 @@ +Improve pathlib.Path compatibility on zipfile.Path and correct performance degradation as found in zipp 3.0. \ No newline at end of file From webhook-mailer at python.org Sat Feb 29 13:43:51 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 18:43:51 -0000 Subject: [Python-checkins] bpo-39794: Add --without-decimal-contextvar (#18702) Message-ID: https://github.com/python/cpython/commit/815280eb160af637e1347213659f9236adf78f80 commit: 815280eb160af637e1347213659f9236adf78f80 branch: master author: Stefan Krah committer: GitHub date: 2020-02-29T19:43:42+01:00 summary: bpo-39794: Add --without-decimal-contextvar (#18702) files: A Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst M Doc/library/decimal.rst M Lib/_pydecimal.py M Lib/test/test_asyncio/test_context.py M Modules/_decimal/_decimal.c M Modules/_decimal/tests/runall-memorydebugger.sh M PC/pyconfig.h M aclocal.m4 M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 4e640cc695990..9e317816abb50 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1475,9 +1475,18 @@ are also included in the pure Python version for compatibility. .. data:: HAVE_THREADS - The default value is ``True``. If Python is compiled without threads, the - C version automatically disables the expensive thread local context - machinery. In this case, the value is ``False``. + The value is ``True``. Deprecated, because Python now always has threads. + +.. deprecated:: 3.9 + +.. data:: HAVE_CONTEXTVAR + + The default value is ``True``. If Python is compiled ``--without-decimal-contextvar``, + the C version uses a thread-local rather than a coroutine-local context and the value + is ``False``. This is slightly faster in some nested context scenarios. + +.. versionadded:: 3.9 + Rounding modes -------------- diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index c14d8ca86a118..ab989e5206a9e 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -140,8 +140,11 @@ # Limits for the C version for compatibility 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' + # C version: compile time choice that enables the thread local context (deprecated, now always true) + 'HAVE_THREADS', + + # C version: compile time choice that enables the coroutine local context + 'HAVE_CONTEXTVAR' ] __xname__ = __name__ # sys.modules lookup (--without-threads) @@ -172,6 +175,7 @@ # Compatibility with the C version HAVE_THREADS = True +HAVE_CONTEXTVAR = True if sys.maxsize == 2**63-1: MAX_PREC = 999999999999999999 MAX_EMAX = 999999999999999999 diff --git a/Lib/test/test_asyncio/test_context.py b/Lib/test/test_asyncio/test_context.py index c309faa90062e..63b1eb320ce16 100644 --- a/Lib/test/test_asyncio/test_context.py +++ b/Lib/test/test_asyncio/test_context.py @@ -7,6 +7,7 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) + at unittest.skipUnless(decimal.HAVE_CONTEXTVAR, "decimal is built with a thread-local context") class DecimalContextTest(unittest.TestCase): def test_asyncio_task_decimal_context(self): diff --git a/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst new file mode 100644 index 0000000000000..b2a4726068af9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst @@ -0,0 +1,2 @@ +Add --without-decimal-contextvar build option. This enables a thread-local +rather than a coroutine local context. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e2f6ea17f8927..617941bc5ec88 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -122,7 +122,14 @@ incr_false(void) } +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Key for thread state dictionary */ +static PyObject *tls_context_key = NULL; +/* Invariant: NULL or the most recently accessed thread local context */ +static PyDecContextObject *cached_context = NULL; +#else static PyObject *current_context_var; +#endif /* Template for creating new thread contexts, calling Context() without * arguments and initializing the module_context on first access. */ @@ -1217,6 +1224,12 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) static void context_dealloc(PyDecContextObject *self) { +#ifndef WITH_DECIMAL_CONTEXTVAR + if (self == cached_context) { + cached_context = NULL; + } +#endif + Py_XDECREF(self->traps); Py_XDECREF(self->flags); Py_TYPE(self)->tp_free(self); @@ -1491,6 +1504,134 @@ static PyGetSetDef context_getsets [] = * operation. */ +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Get the context from the thread state dictionary. */ +static PyObject * +current_context_from_dict(void) +{ + PyObject *dict; + PyObject *tl_context; + PyThreadState *tstate; + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + tl_context = PyDict_GetItemWithError(dict, tls_context_key); + if (tl_context != NULL) { + /* We already have a thread local context. */ + CONTEXT_CHECK(tl_context); + } + else { + if (PyErr_Occurred()) { + return NULL; + } + + /* Set up a new thread local context. */ + tl_context = context_copy(default_context_template, NULL); + if (tl_context == NULL) { + return NULL; + } + CTX(tl_context)->status = 0; + + if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { + Py_DECREF(tl_context); + return NULL; + } + Py_DECREF(tl_context); + } + + /* Cache the context of the current thread, assuming that it + * will be accessed several times before a thread switch. */ + tstate = PyThreadState_GET(); + if (tstate) { + cached_context = (PyDecContextObject *)tl_context; + cached_context->tstate = tstate; + } + + /* Borrowed reference with refcount==1 */ + return tl_context; +} + +/* Return borrowed reference to thread local context. */ +static PyObject * +current_context(void) +{ + PyThreadState *tstate; + + tstate = PyThreadState_GET(); + if (cached_context && cached_context->tstate == tstate) { + return (PyObject *)cached_context; + } + + return current_context_from_dict(); +} + +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context(); \ + if (ctxobj == NULL) { \ + return NULL; \ + } + +/* Return a new reference to the current context */ +static PyObject * +PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +{ + PyObject *context; + + context = current_context(); + if (context == NULL) { + return NULL; + } + + Py_INCREF(context); + return context; +} + +/* Set the thread local context to a new context, decrement old reference */ +static PyObject * +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +{ + PyObject *dict; + + CONTEXT_CHECK(v); + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + v = context_copy(v, NULL); + if (v == NULL) { + return NULL; + } + CTX(v)->status = 0; + } + else { + Py_INCREF(v); + } + + cached_context = NULL; + if (PyDict_SetItem(dict, tls_context_key, v) < 0) { + Py_DECREF(v); + return NULL; + } + + Py_DECREF(v); + Py_RETURN_NONE; +} +#else static PyObject * init_current_context(void) { @@ -1570,6 +1711,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) Py_RETURN_NONE; } +#endif /* Context manager object for the 'with' statement. The manager * owns one reference to the global (outer) context and one @@ -4388,15 +4530,8 @@ _dec_hash(PyDecObject *v) mpd_ssize_t exp; uint32_t status = 0; mpd_context_t maxctx; - PyObject *context; - context = current_context(); - if (context == NULL) { - return -1; - } - Py_DECREF(context); - if (mpd_isspecial(MPD(v))) { if (mpd_issnan(MPD(v))) { PyErr_SetString(PyExc_TypeError, @@ -5538,11 +5673,6 @@ PyInit__decimal(void) mpd_free = PyMem_Free; mpd_setminalloc(_Py_DEC_MINALLOC); - /* Init context variable */ - current_context_var = PyContextVar_New("decimal_context", NULL); - if (current_context_var == NULL) { - goto error; - } /* Init external C-API functions */ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5714,6 +5844,15 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "DefaultContext", default_context_template)); +#ifndef WITH_DECIMAL_CONTEXTVAR + ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); + Py_INCREF(Py_False); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); +#else + ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); + Py_INCREF(Py_True); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); +#endif Py_INCREF(Py_True); CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); @@ -5773,9 +5912,13 @@ PyInit__decimal(void) Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */ +#ifndef WITH_DECIMAL_CONTEXTVAR + Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */ +#else + Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ +#endif Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ Py_CLEAR(m); /* GCOV_NOT_REACHED */ return NULL; /* GCOV_NOT_REACHED */ diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 29b7723dd50c0..7f3e527461871 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -1,8 +1,8 @@ #!/bin/sh # -# Purpose: test all machine configurations, pydebug, refleaks, release build -# and release build with valgrind. +# Purpose: test with and without contextvar, all machine configurations, pydebug, +# refleaks, release build and release build with valgrind. # # Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32] # @@ -57,7 +57,8 @@ print_config () cd .. # test_decimal: refleak, regular and Valgrind tests -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE libmpdec_config=$config @@ -69,12 +70,12 @@ for config in $CONFIGS; do fi ############ refleak tests ########### - print_config "refleak tests: config=$config" + print_config "refleak tests: config=$config" $args printf "\nbuilding python ...\n\n" cd ../../ $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" @@ -82,11 +83,11 @@ for config in $CONFIGS; do ############ regular tests ########### - print_config "regular tests: config=$config" + print_config "regular tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular tests ===========================\n\n" @@ -103,21 +104,23 @@ for config in $CONFIGS; do esac esac - print_config "valgrind tests: config=$config" + print_config "valgrind tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind tests ===========================\n\n" $valgrind ./python -m test -uall test_decimal cd Modules/_decimal + done done # deccheck cd ../../ -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE if [ X"$config" != X"auto" ]; then @@ -126,22 +129,22 @@ for config in $CONFIGS; do fi ############ debug ############ - print_config "deccheck: config=$config --with-pydebug" + print_config "deccheck: config=$config --with-pydebug" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ========================== debug ===========================\n\n" ./python Modules/_decimal/tests/deccheck.py ########### regular ########### - print_config "deccheck: config=$config " + print_config "deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular ===========================\n\n" @@ -157,15 +160,16 @@ for config in $CONFIGS; do esac esac - print_config "valgrind deccheck: config=$config " + print_config "valgrind deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind ==========================\n\n" $valgrind ./python Modules/_decimal/tests/deccheck.py + done done diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 424c5be370927..0aa4f95bf8d2f 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -465,6 +465,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ (which you can't on SCO ODT 3.0). */ /* #undef SYS_SELECT_WITH_SYS_TIME */ +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#define WITH_DECIMAL_CONTEXTVAR 1 + /* Define if you want documentation strings in extension modules */ #define WITH_DOC_STRINGS 1 diff --git a/aclocal.m4 b/aclocal.m4 index 85f00dd5fac7f..f98db73656d30 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index 846116e1128ee..0bffe8b035686 100755 --- a/configure +++ b/configure @@ -826,6 +826,7 @@ with_libs with_system_expat with_system_ffi with_system_libmpdec +with_decimal_contextvar enable_loadable_sqlite_extensions with_tcltk_includes with_tcltk_libs @@ -1548,6 +1549,9 @@ Optional Packages: system-dependent) --with-system-libmpdec build _decimal module using an installed libmpdec library, see Doc/library/decimal.rst (default is no) + --with-decimal-contextvar + build _decimal module using a coroutine-local rather + than a thread-local context (default is yes) --with-tcltk-includes='-I...' override search for Tcl and Tk include files --with-tcltk-libs='-L...' @@ -10496,6 +10500,28 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_libmpdec" >&5 $as_echo "$with_system_libmpdec" >&6; } +# Check whether _decimal should use a coroutine-local or thread-local context +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 +$as_echo_n "checking for --with-decimal-contextvar... " >&6; } + +# Check whether --with-decimal_contextvar was given. +if test "${with_decimal_contextvar+set}" = set; then : + withval=$with_decimal_contextvar; +else + with_decimal_contextvar="yes" +fi + + +if test "$with_decimal_contextvar" != "no" +then + +$as_echo "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 +$as_echo "$with_decimal_contextvar" >&6; } + # Check for support for loadable sqlite extensions { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 $as_echo_n "checking for --enable-loadable-sqlite-extensions... " >&6; } diff --git a/configure.ac b/configure.ac index 840caf352d1dd..bdd607390da90 100644 --- a/configure.ac +++ b/configure.ac @@ -3050,6 +3050,21 @@ AC_ARG_WITH(system_libmpdec, AC_MSG_RESULT($with_system_libmpdec) +# Check whether _decimal should use a coroutine-local or thread-local context +AC_MSG_CHECKING(for --with-decimal-contextvar) +AC_ARG_WITH(decimal_contextvar, + AS_HELP_STRING([--with-decimal-contextvar], [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)]), + [], + [with_decimal_contextvar="yes"]) + +if test "$with_decimal_contextvar" != "no" +then + AC_DEFINE(WITH_DECIMAL_CONTEXTVAR, 1, + [Define if you want build the _decimal module using a coroutine-local rather than a thread-local context]) +fi + +AC_MSG_RESULT($with_decimal_contextvar) + # Check for support for loadable sqlite extensions AC_MSG_CHECKING(for --enable-loadable-sqlite-extensions) AC_ARG_ENABLE(loadable-sqlite-extensions, diff --git a/pyconfig.h.in b/pyconfig.h.in index b5602134d703a..2a72e9ed7fe9c 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1512,6 +1512,10 @@ /* Define if WINDOW in curses.h offers a field _flags. */ #undef WINDOW_HAS_FLAGS +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#undef WITH_DECIMAL_CONTEXTVAR + /* Define if you want documentation strings in extension modules */ #undef WITH_DOC_STRINGS From webhook-mailer at python.org Sat Feb 29 14:07:56 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 19:07:56 -0000 Subject: [Python-checkins] Cosmetic change to match the surrounding code. (#18704) Message-ID: https://github.com/python/cpython/commit/eb47fd58ab6483857661aa0822986538a68aa0e5 commit: eb47fd58ab6483857661aa0822986538a68aa0e5 branch: master author: Stefan Krah committer: GitHub date: 2020-02-29T20:07:48+01:00 summary: Cosmetic change to match the surrounding code. (#18704) files: M Modules/_decimal/_decimal.c diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 617941bc5ec88..b36e30972172d 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -128,7 +128,7 @@ static PyObject *tls_context_key = NULL; /* Invariant: NULL or the most recently accessed thread local context */ static PyDecContextObject *cached_context = NULL; #else -static PyObject *current_context_var; +static PyObject *current_context_var = NULL; #endif /* Template for creating new thread contexts, calling Context() without From webhook-mailer at python.org Sat Feb 29 15:32:02 2020 From: webhook-mailer at python.org (Stephen Balousek) Date: Sat, 29 Feb 2020 20:32:02 -0000 Subject: [Python-checkins] bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) Message-ID: https://github.com/python/cpython/commit/5e260e0fde211829fcb67060cfd602f4b679f802 commit: 5e260e0fde211829fcb67060cfd602f4b679f802 branch: master author: Stephen Balousek committer: GitHub date: 2020-02-29T12:31:58-08:00 summary: bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - The 'qop' value in the 'WWW-Authenticate' header is optional. The presence of 'qop' in the header should be checked before its value is parsed with 'split'. Signed-off-by: Stephen Balousek * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - Add NEWS item Signed-off-by: Stephen Balousek * Update Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst Co-Authored-By: Brandt Bucher Co-authored-by: Brandt Bucher files: A Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index a6d350a97a452..7fe50535da138 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1138,7 +1138,9 @@ def get_authorization(self, req, chal): req.selector) # 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 qop is None: + respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) + elif 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1148,8 +1150,6 @@ def get_authorization(self, req, chal): cnonce = self.get_cnonce(nonce) 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))) else: # XXX handle auth-int. raise URLError("qop '%s' is not supported." % qop) diff --git a/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst new file mode 100644 index 0000000000000..4cf32487b1f7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst @@ -0,0 +1,2 @@ +Fix handling of header in :class:`urllib.request.AbstractDigestAuthHandler` when the optional ``qop`` parameter +is not present. From webhook-mailer at python.org Sat Feb 29 15:49:25 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 29 Feb 2020 20:49:25 -0000 Subject: [Python-checkins] bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) Message-ID: https://github.com/python/cpython/commit/cf347f3089631c3c2467e46ed609bfe67e539487 commit: cf347f3089631c3c2467e46ed609bfe67e539487 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-29T12:49:20-08:00 summary: bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - The 'qop' value in the 'WWW-Authenticate' header is optional. The presence of 'qop' in the header should be checked before its value is parsed with 'split'. Signed-off-by: Stephen Balousek * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - Add NEWS item Signed-off-by: Stephen Balousek * Update Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst Co-Authored-By: Brandt Bucher Co-authored-by: Brandt Bucher (cherry picked from commit 5e260e0fde211829fcb67060cfd602f4b679f802) Co-authored-by: Stephen Balousek files: A Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 211cb6857f728..0d3f9670fef40 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1145,7 +1145,9 @@ def get_authorization(self, req, chal): req.selector) # 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 qop is None: + respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) + elif 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1155,8 +1157,6 @@ def get_authorization(self, req, chal): cnonce = self.get_cnonce(nonce) 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))) else: # XXX handle auth-int. raise URLError("qop '%s' is not supported." % qop) diff --git a/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst new file mode 100644 index 0000000000000..4cf32487b1f7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst @@ -0,0 +1,2 @@ +Fix handling of header in :class:`urllib.request.AbstractDigestAuthHandler` when the optional ``qop`` parameter +is not present. From webhook-mailer at python.org Sat Feb 29 16:05:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 29 Feb 2020 21:05:28 -0000 Subject: [Python-checkins] bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) Message-ID: https://github.com/python/cpython/commit/e4686b79798f7a492dcbaa62cf51f4d07fd5ae78 commit: e4686b79798f7a492dcbaa62cf51f4d07fd5ae78 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-02-29T13:05:23-08:00 summary: bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest Auth (GH-18338) * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - The 'qop' value in the 'WWW-Authenticate' header is optional. The presence of 'qop' in the header should be checked before its value is parsed with 'split'. Signed-off-by: Stephen Balousek * bpo-39548: Fix handling of 'WWW-Authenticate' header for Digest authentication - Add NEWS item Signed-off-by: Stephen Balousek * Update Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst Co-Authored-By: Brandt Bucher Co-authored-by: Brandt Bucher (cherry picked from commit 5e260e0fde211829fcb67060cfd602f4b679f802) Co-authored-by: Stephen Balousek files: A Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 6f6577bf1d902..fd91b9d1d0beb 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1146,7 +1146,9 @@ def get_authorization(self, req, chal): req.selector) # 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 qop is None: + respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) + elif 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1156,8 +1158,6 @@ def get_authorization(self, req, chal): cnonce = self.get_cnonce(nonce) 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))) else: # XXX handle auth-int. raise URLError("qop '%s' is not supported." % qop) diff --git a/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst new file mode 100644 index 0000000000000..4cf32487b1f7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-06-05-33-52.bpo-39548.DF4FFe.rst @@ -0,0 +1,2 @@ +Fix handling of header in :class:`urllib.request.AbstractDigestAuthHandler` when the optional ``qop`` parameter +is not present. From webhook-mailer at python.org Sat Feb 29 16:16:36 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 21:16:36 -0000 Subject: [Python-checkins] [3.8] bpo-39794: Add --without-decimal-contextvar (GH-18702) Message-ID: https://github.com/python/cpython/commit/4d7012410cf4f91cbca4c406f4747289c2802333 commit: 4d7012410cf4f91cbca4c406f4747289c2802333 branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-02-29T22:16:32+01:00 summary: [3.8] bpo-39794: Add --without-decimal-contextvar (GH-18702) (cherry picked from commit 815280eb160af637e1347213659f9236adf78f80) files: A Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst M Doc/library/decimal.rst M Lib/_pydecimal.py M Lib/test/test_asyncio/test_context.py M Modules/_decimal/_decimal.c M Modules/_decimal/tests/runall-memorydebugger.sh M PC/pyconfig.h M aclocal.m4 M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 4e640cc695990..c8a4bcfdc79a0 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1475,9 +1475,18 @@ are also included in the pure Python version for compatibility. .. data:: HAVE_THREADS - The default value is ``True``. If Python is compiled without threads, the - C version automatically disables the expensive thread local context - machinery. In this case, the value is ``False``. + The value is ``True``. Deprecated, because Python now always has threads. + +.. deprecated:: 3.9 + +.. data:: HAVE_CONTEXTVAR + + The default value is ``True``. If Python is compiled ``--without-decimal-contextvar``, + the C version uses a thread-local rather than a coroutine-local context and the value + is ``False``. This is slightly faster in some nested context scenarios. + +.. versionadded:: 3.9, backported to 3.7 and 3.8 + Rounding modes -------------- diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index c14d8ca86a118..ab989e5206a9e 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -140,8 +140,11 @@ # Limits for the C version for compatibility 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' + # C version: compile time choice that enables the thread local context (deprecated, now always true) + 'HAVE_THREADS', + + # C version: compile time choice that enables the coroutine local context + 'HAVE_CONTEXTVAR' ] __xname__ = __name__ # sys.modules lookup (--without-threads) @@ -172,6 +175,7 @@ # Compatibility with the C version HAVE_THREADS = True +HAVE_CONTEXTVAR = True if sys.maxsize == 2**63-1: MAX_PREC = 999999999999999999 MAX_EMAX = 999999999999999999 diff --git a/Lib/test/test_asyncio/test_context.py b/Lib/test/test_asyncio/test_context.py index c309faa90062e..63b1eb320ce16 100644 --- a/Lib/test/test_asyncio/test_context.py +++ b/Lib/test/test_asyncio/test_context.py @@ -7,6 +7,7 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) + at unittest.skipUnless(decimal.HAVE_CONTEXTVAR, "decimal is built with a thread-local context") class DecimalContextTest(unittest.TestCase): def test_asyncio_task_decimal_context(self): diff --git a/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst new file mode 100644 index 0000000000000..b2a4726068af9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst @@ -0,0 +1,2 @@ +Add --without-decimal-contextvar build option. This enables a thread-local +rather than a coroutine local context. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e2ac19800315c..4358c4d686758 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -122,7 +122,14 @@ incr_false(void) } +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Key for thread state dictionary */ +static PyObject *tls_context_key = NULL; +/* Invariant: NULL or the most recently accessed thread local context */ +static PyDecContextObject *cached_context = NULL; +#else static PyObject *current_context_var; +#endif /* Template for creating new thread contexts, calling Context() without * arguments and initializing the module_context on first access. */ @@ -1217,6 +1224,12 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) static void context_dealloc(PyDecContextObject *self) { +#ifndef WITH_DECIMAL_CONTEXTVAR + if (self == cached_context) { + cached_context = NULL; + } +#endif + Py_XDECREF(self->traps); Py_XDECREF(self->flags); Py_TYPE(self)->tp_free(self); @@ -1491,6 +1504,134 @@ static PyGetSetDef context_getsets [] = * operation. */ +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Get the context from the thread state dictionary. */ +static PyObject * +current_context_from_dict(void) +{ + PyObject *dict; + PyObject *tl_context; + PyThreadState *tstate; + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + tl_context = PyDict_GetItemWithError(dict, tls_context_key); + if (tl_context != NULL) { + /* We already have a thread local context. */ + CONTEXT_CHECK(tl_context); + } + else { + if (PyErr_Occurred()) { + return NULL; + } + + /* Set up a new thread local context. */ + tl_context = context_copy(default_context_template, NULL); + if (tl_context == NULL) { + return NULL; + } + CTX(tl_context)->status = 0; + + if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { + Py_DECREF(tl_context); + return NULL; + } + Py_DECREF(tl_context); + } + + /* Cache the context of the current thread, assuming that it + * will be accessed several times before a thread switch. */ + tstate = PyThreadState_GET(); + if (tstate) { + cached_context = (PyDecContextObject *)tl_context; + cached_context->tstate = tstate; + } + + /* Borrowed reference with refcount==1 */ + return tl_context; +} + +/* Return borrowed reference to thread local context. */ +static PyObject * +current_context(void) +{ + PyThreadState *tstate; + + tstate = PyThreadState_GET(); + if (cached_context && cached_context->tstate == tstate) { + return (PyObject *)cached_context; + } + + return current_context_from_dict(); +} + +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context(); \ + if (ctxobj == NULL) { \ + return NULL; \ + } + +/* Return a new reference to the current context */ +static PyObject * +PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +{ + PyObject *context; + + context = current_context(); + if (context == NULL) { + return NULL; + } + + Py_INCREF(context); + return context; +} + +/* Set the thread local context to a new context, decrement old reference */ +static PyObject * +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +{ + PyObject *dict; + + CONTEXT_CHECK(v); + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + v = context_copy(v, NULL); + if (v == NULL) { + return NULL; + } + CTX(v)->status = 0; + } + else { + Py_INCREF(v); + } + + cached_context = NULL; + if (PyDict_SetItem(dict, tls_context_key, v) < 0) { + Py_DECREF(v); + return NULL; + } + + Py_DECREF(v); + Py_RETURN_NONE; +} +#else static PyObject * init_current_context(void) { @@ -1570,6 +1711,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) Py_RETURN_NONE; } +#endif /* Context manager object for the 'with' statement. The manager * owns one reference to the global (outer) context and one @@ -4388,15 +4530,8 @@ _dec_hash(PyDecObject *v) mpd_ssize_t exp; uint32_t status = 0; mpd_context_t maxctx; - PyObject *context; - context = current_context(); - if (context == NULL) { - return -1; - } - Py_DECREF(context); - if (mpd_isspecial(MPD(v))) { if (mpd_issnan(MPD(v))) { PyErr_SetString(PyExc_TypeError, @@ -5538,11 +5673,6 @@ PyInit__decimal(void) mpd_free = PyMem_Free; mpd_setminalloc(_Py_DEC_MINALLOC); - /* Init context variable */ - current_context_var = PyContextVar_New("decimal_context", NULL); - if (current_context_var == NULL) { - goto error; - } /* Init external C-API functions */ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5714,6 +5844,15 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "DefaultContext", default_context_template)); +#ifndef WITH_DECIMAL_CONTEXTVAR + ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); + Py_INCREF(Py_False); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); +#else + ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); + Py_INCREF(Py_True); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); +#endif Py_INCREF(Py_True); CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); @@ -5773,9 +5912,13 @@ PyInit__decimal(void) Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */ +#ifndef WITH_DECIMAL_CONTEXTVAR + Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */ +#else + Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ +#endif Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ Py_CLEAR(m); /* GCOV_NOT_REACHED */ return NULL; /* GCOV_NOT_REACHED */ diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 29b7723dd50c0..7f3e527461871 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -1,8 +1,8 @@ #!/bin/sh # -# Purpose: test all machine configurations, pydebug, refleaks, release build -# and release build with valgrind. +# Purpose: test with and without contextvar, all machine configurations, pydebug, +# refleaks, release build and release build with valgrind. # # Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32] # @@ -57,7 +57,8 @@ print_config () cd .. # test_decimal: refleak, regular and Valgrind tests -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE libmpdec_config=$config @@ -69,12 +70,12 @@ for config in $CONFIGS; do fi ############ refleak tests ########### - print_config "refleak tests: config=$config" + print_config "refleak tests: config=$config" $args printf "\nbuilding python ...\n\n" cd ../../ $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" @@ -82,11 +83,11 @@ for config in $CONFIGS; do ############ regular tests ########### - print_config "regular tests: config=$config" + print_config "regular tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular tests ===========================\n\n" @@ -103,21 +104,23 @@ for config in $CONFIGS; do esac esac - print_config "valgrind tests: config=$config" + print_config "valgrind tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind tests ===========================\n\n" $valgrind ./python -m test -uall test_decimal cd Modules/_decimal + done done # deccheck cd ../../ -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE if [ X"$config" != X"auto" ]; then @@ -126,22 +129,22 @@ for config in $CONFIGS; do fi ############ debug ############ - print_config "deccheck: config=$config --with-pydebug" + print_config "deccheck: config=$config --with-pydebug" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ========================== debug ===========================\n\n" ./python Modules/_decimal/tests/deccheck.py ########### regular ########### - print_config "deccheck: config=$config " + print_config "deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular ===========================\n\n" @@ -157,15 +160,16 @@ for config in $CONFIGS; do esac esac - print_config "valgrind deccheck: config=$config " + print_config "valgrind deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind ==========================\n\n" $valgrind ./python Modules/_decimal/tests/deccheck.py + done done diff --git a/PC/pyconfig.h b/PC/pyconfig.h index b40e24f438ef6..b6b8d445869bc 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -470,6 +470,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ (which you can't on SCO ODT 3.0). */ /* #undef SYS_SELECT_WITH_SYS_TIME */ +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#define WITH_DECIMAL_CONTEXTVAR 1 + /* Define if you want documentation strings in extension modules */ #define WITH_DOC_STRINGS 1 diff --git a/aclocal.m4 b/aclocal.m4 index 85f00dd5fac7f..f98db73656d30 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index a979363acffc4..3dfd6cce69e4e 100755 --- a/configure +++ b/configure @@ -826,6 +826,7 @@ with_libs with_system_expat with_system_ffi with_system_libmpdec +with_decimal_contextvar enable_loadable_sqlite_extensions with_tcltk_includes with_tcltk_libs @@ -1529,6 +1530,9 @@ Optional Packages: --with-system-ffi build _ctypes module using an installed ffi library --with-system-libmpdec build _decimal module using an installed libmpdec library + --with-decimal-contextvar + build _decimal module using a coroutine-local rather + than a thread-local context (default is yes) --with-tcltk-includes='-I...' override search for Tcl and Tk include files --with-tcltk-libs='-L...' @@ -10419,6 +10423,28 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_libmpdec" >&5 $as_echo "$with_system_libmpdec" >&6; } +# Check whether _decimal should use a coroutine-local or thread-local context +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 +$as_echo_n "checking for --with-decimal-contextvar... " >&6; } + +# Check whether --with-decimal_contextvar was given. +if test "${with_decimal_contextvar+set}" = set; then : + withval=$with_decimal_contextvar; +else + with_decimal_contextvar="yes" +fi + + +if test "$with_decimal_contextvar" != "no" +then + +$as_echo "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 +$as_echo "$with_decimal_contextvar" >&6; } + # Check for support for loadable sqlite extensions { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 $as_echo_n "checking for --enable-loadable-sqlite-extensions... " >&6; } diff --git a/configure.ac b/configure.ac index e57ef7c38bf7f..d8de9d49439c3 100644 --- a/configure.ac +++ b/configure.ac @@ -3004,6 +3004,21 @@ AC_ARG_WITH(system_libmpdec, AC_MSG_RESULT($with_system_libmpdec) +# Check whether _decimal should use a coroutine-local or thread-local context +AC_MSG_CHECKING(for --with-decimal-contextvar) +AC_ARG_WITH(decimal_contextvar, + AS_HELP_STRING([--with-decimal-contextvar], [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)]), + [], + [with_decimal_contextvar="yes"]) + +if test "$with_decimal_contextvar" != "no" +then + AC_DEFINE(WITH_DECIMAL_CONTEXTVAR, 1, + [Define if you want build the _decimal module using a coroutine-local rather than a thread-local context]) +fi + +AC_MSG_RESULT($with_decimal_contextvar) + # Check for support for loadable sqlite extensions AC_MSG_CHECKING(for --enable-loadable-sqlite-extensions) AC_ARG_ENABLE(loadable-sqlite-extensions, diff --git a/pyconfig.h.in b/pyconfig.h.in index aaa7b72cac884..4263a712c3278 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1518,6 +1518,10 @@ /* Define if WINDOW in curses.h offers a field _flags. */ #undef WINDOW_HAS_FLAGS +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#undef WITH_DECIMAL_CONTEXTVAR + /* Define if you want documentation strings in extension modules */ #undef WITH_DOC_STRINGS From webhook-mailer at python.org Sat Feb 29 16:39:27 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 21:39:27 -0000 Subject: [Python-checkins] Mention backports (GH-18715) Message-ID: https://github.com/python/cpython/commit/0b0d29fce568e61e0d7d9f4a362e6dbf1e7fb80a commit: 0b0d29fce568e61e0d7d9f4a362e6dbf1e7fb80a branch: master author: Stefan Krah committer: GitHub date: 2020-02-29T22:39:23+01:00 summary: Mention backports (GH-18715) files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 9e317816abb50..69a20fca17898 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1485,7 +1485,7 @@ are also included in the pure Python version for compatibility. the C version uses a thread-local rather than a coroutine-local context and the value is ``False``. This is slightly faster in some nested context scenarios. -.. versionadded:: 3.9 +.. versionadded:: 3.9 backported to 3.7 and 3.8. Rounding modes From webhook-mailer at python.org Sat Feb 29 16:42:10 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 21:42:10 -0000 Subject: [Python-checkins] [3.8] Fix syntax (GH-18716) Message-ID: https://github.com/python/cpython/commit/70d7a62c7c8fd6baabf1e13c33773db79db7a9f4 commit: 70d7a62c7c8fd6baabf1e13c33773db79db7a9f4 branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-02-29T22:42:06+01:00 summary: [3.8] Fix syntax (GH-18716) files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index c8a4bcfdc79a0..3dda35fbd35db 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1485,7 +1485,7 @@ are also included in the pure Python version for compatibility. the C version uses a thread-local rather than a coroutine-local context and the value is ``False``. This is slightly faster in some nested context scenarios. -.. versionadded:: 3.9, backported to 3.7 and 3.8 +.. versionadded:: 3.9 backported to 3.7 and 3.8 Rounding modes From webhook-mailer at python.org Sat Feb 29 17:08:08 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 22:08:08 -0000 Subject: [Python-checkins] [3.8] Explicitly initialize like the surrounding code (GH-18717) Message-ID: https://github.com/python/cpython/commit/fec6681f7ae3e8867bd0446aa993a0b5f23045f9 commit: fec6681f7ae3e8867bd0446aa993a0b5f23045f9 branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-02-29T23:08:04+01:00 summary: [3.8] Explicitly initialize like the surrounding code (GH-18717) files: M Modules/_decimal/_decimal.c diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 4358c4d686758..df7c6e254bcf2 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -128,7 +128,7 @@ static PyObject *tls_context_key = NULL; /* Invariant: NULL or the most recently accessed thread local context */ static PyDecContextObject *cached_context = NULL; #else -static PyObject *current_context_var; +static PyObject *current_context_var = NULL; #endif /* Template for creating new thread contexts, calling Context() without From webhook-mailer at python.org Sat Feb 29 17:10:30 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Sat, 29 Feb 2020 22:10:30 -0000 Subject: [Python-checkins] [3.7] bpo-39794: Add --without-decimal-contextvar (GH-18702) Message-ID: https://github.com/python/cpython/commit/c4ca1f8f24118dc5c29e16118fb35a13963af290 commit: c4ca1f8f24118dc5c29e16118fb35a13963af290 branch: 3.7 author: Stefan Krah committer: GitHub date: 2020-02-29T23:10:26+01:00 summary: [3.7] bpo-39794: Add --without-decimal-contextvar (GH-18702) * bpo-39794: Add --without-decimal-contextvar (#18702) (cherry picked from commit 815280eb160af637e1347213659f9236adf78f80) files: A Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst M Doc/library/decimal.rst M Lib/_pydecimal.py M Lib/test/test_asyncio/test_context.py M Modules/_decimal/_decimal.c M Modules/_decimal/tests/runall-memorydebugger.sh M PC/pyconfig.h M aclocal.m4 M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 4e640cc695990..3dda35fbd35db 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1475,9 +1475,18 @@ are also included in the pure Python version for compatibility. .. data:: HAVE_THREADS - The default value is ``True``. If Python is compiled without threads, the - C version automatically disables the expensive thread local context - machinery. In this case, the value is ``False``. + The value is ``True``. Deprecated, because Python now always has threads. + +.. deprecated:: 3.9 + +.. data:: HAVE_CONTEXTVAR + + The default value is ``True``. If Python is compiled ``--without-decimal-contextvar``, + the C version uses a thread-local rather than a coroutine-local context and the value + is ``False``. This is slightly faster in some nested context scenarios. + +.. versionadded:: 3.9 backported to 3.7 and 3.8 + Rounding modes -------------- diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 44ea5b41b2a1f..27ff963303dad 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -140,8 +140,11 @@ # Limits for the C version for compatibility 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' + # C version: compile time choice that enables the thread local context (deprecated, now always true) + 'HAVE_THREADS', + + # C version: compile time choice that enables the coroutine local context + 'HAVE_CONTEXTVAR' ] __xname__ = __name__ # sys.modules lookup (--without-threads) @@ -172,6 +175,7 @@ # Compatibility with the C version HAVE_THREADS = True +HAVE_CONTEXTVAR = True if sys.maxsize == 2**63-1: MAX_PREC = 999999999999999999 MAX_EMAX = 999999999999999999 diff --git a/Lib/test/test_asyncio/test_context.py b/Lib/test/test_asyncio/test_context.py index 6abddd9f2515e..728ce808a24c5 100644 --- a/Lib/test/test_asyncio/test_context.py +++ b/Lib/test/test_asyncio/test_context.py @@ -3,6 +3,7 @@ import unittest + at unittest.skipUnless(decimal.HAVE_CONTEXTVAR, "decimal is built with a thread-local context") class DecimalContextTest(unittest.TestCase): def test_asyncio_task_decimal_context(self): diff --git a/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst new file mode 100644 index 0000000000000..b2a4726068af9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-29-19-17-39.bpo-39794.7VjatS.rst @@ -0,0 +1,2 @@ +Add --without-decimal-contextvar build option. This enables a thread-local +rather than a coroutine local context. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 1e58d3d5b7796..93e29509c8db9 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -122,7 +122,14 @@ incr_false(void) } -static PyObject *current_context_var; +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Key for thread state dictionary */ +static PyObject *tls_context_key = NULL; +/* Invariant: NULL or the most recently accessed thread local context */ +static PyDecContextObject *cached_context = NULL; +#else +static PyObject *current_context_var = NULL; +#endif /* Template for creating new thread contexts, calling Context() without * arguments and initializing the module_context on first access. */ @@ -1217,6 +1224,12 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) static void context_dealloc(PyDecContextObject *self) { +#ifndef WITH_DECIMAL_CONTEXTVAR + if (self == cached_context) { + cached_context = NULL; + } +#endif + Py_XDECREF(self->traps); Py_XDECREF(self->flags); Py_TYPE(self)->tp_free(self); @@ -1491,6 +1504,134 @@ static PyGetSetDef context_getsets [] = * operation. */ +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Get the context from the thread state dictionary. */ +static PyObject * +current_context_from_dict(void) +{ + PyObject *dict; + PyObject *tl_context; + PyThreadState *tstate; + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + tl_context = PyDict_GetItemWithError(dict, tls_context_key); + if (tl_context != NULL) { + /* We already have a thread local context. */ + CONTEXT_CHECK(tl_context); + } + else { + if (PyErr_Occurred()) { + return NULL; + } + + /* Set up a new thread local context. */ + tl_context = context_copy(default_context_template, NULL); + if (tl_context == NULL) { + return NULL; + } + CTX(tl_context)->status = 0; + + if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { + Py_DECREF(tl_context); + return NULL; + } + Py_DECREF(tl_context); + } + + /* Cache the context of the current thread, assuming that it + * will be accessed several times before a thread switch. */ + tstate = PyThreadState_GET(); + if (tstate) { + cached_context = (PyDecContextObject *)tl_context; + cached_context->tstate = tstate; + } + + /* Borrowed reference with refcount==1 */ + return tl_context; +} + +/* Return borrowed reference to thread local context. */ +static PyObject * +current_context(void) +{ + PyThreadState *tstate; + + tstate = PyThreadState_GET(); + if (cached_context && cached_context->tstate == tstate) { + return (PyObject *)cached_context; + } + + return current_context_from_dict(); +} + +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context(); \ + if (ctxobj == NULL) { \ + return NULL; \ + } + +/* Return a new reference to the current context */ +static PyObject * +PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +{ + PyObject *context; + + context = current_context(); + if (context == NULL) { + return NULL; + } + + Py_INCREF(context); + return context; +} + +/* Set the thread local context to a new context, decrement old reference */ +static PyObject * +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +{ + PyObject *dict; + + CONTEXT_CHECK(v); + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + v = context_copy(v, NULL); + if (v == NULL) { + return NULL; + } + CTX(v)->status = 0; + } + else { + Py_INCREF(v); + } + + cached_context = NULL; + if (PyDict_SetItem(dict, tls_context_key, v) < 0) { + Py_DECREF(v); + return NULL; + } + + Py_DECREF(v); + Py_RETURN_NONE; +} +#else static PyObject * init_current_context(void) { @@ -1570,6 +1711,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) Py_RETURN_NONE; } +#endif /* Context manager object for the 'with' statement. The manager * owns one reference to the global (outer) context and one @@ -4388,15 +4530,8 @@ _dec_hash(PyDecObject *v) mpd_ssize_t exp; uint32_t status = 0; mpd_context_t maxctx; - PyObject *context; - context = current_context(); - if (context == NULL) { - return -1; - } - Py_DECREF(context); - if (mpd_isspecial(MPD(v))) { if (mpd_issnan(MPD(v))) { PyErr_SetString(PyExc_TypeError, @@ -5538,11 +5673,6 @@ PyInit__decimal(void) mpd_free = PyMem_Free; mpd_setminalloc(_Py_DEC_MINALLOC); - /* Init context variable */ - current_context_var = PyContextVar_New("decimal_context", NULL); - if (current_context_var == NULL) { - goto error; - } /* Init external C-API functions */ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5714,6 +5844,15 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "DefaultContext", default_context_template)); +#ifndef WITH_DECIMAL_CONTEXTVAR + ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); + Py_INCREF(Py_False); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); +#else + ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); + Py_INCREF(Py_True); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); +#endif Py_INCREF(Py_True); CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); @@ -5773,9 +5912,13 @@ PyInit__decimal(void) Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */ +#ifndef WITH_DECIMAL_CONTEXTVAR + Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */ +#else + Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ +#endif Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ Py_CLEAR(m); /* GCOV_NOT_REACHED */ return NULL; /* GCOV_NOT_REACHED */ diff --git a/Modules/_decimal/tests/runall-memorydebugger.sh b/Modules/_decimal/tests/runall-memorydebugger.sh index 29b7723dd50c0..7f3e527461871 100755 --- a/Modules/_decimal/tests/runall-memorydebugger.sh +++ b/Modules/_decimal/tests/runall-memorydebugger.sh @@ -1,8 +1,8 @@ #!/bin/sh # -# Purpose: test all machine configurations, pydebug, refleaks, release build -# and release build with valgrind. +# Purpose: test with and without contextvar, all machine configurations, pydebug, +# refleaks, release build and release build with valgrind. # # Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32] # @@ -57,7 +57,8 @@ print_config () cd .. # test_decimal: refleak, regular and Valgrind tests -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE libmpdec_config=$config @@ -69,12 +70,12 @@ for config in $CONFIGS; do fi ############ refleak tests ########### - print_config "refleak tests: config=$config" + print_config "refleak tests: config=$config" $args printf "\nbuilding python ...\n\n" cd ../../ $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== refleak tests ===========================\n\n" @@ -82,11 +83,11 @@ for config in $CONFIGS; do ############ regular tests ########### - print_config "regular tests: config=$config" + print_config "regular tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular tests ===========================\n\n" @@ -103,21 +104,23 @@ for config in $CONFIGS; do esac esac - print_config "valgrind tests: config=$config" + print_config "valgrind tests: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind tests ===========================\n\n" $valgrind ./python -m test -uall test_decimal cd Modules/_decimal + done done # deccheck cd ../../ -for config in $CONFIGS; do +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do unset PYTHON_DECIMAL_WITH_MACHINE if [ X"$config" != X"auto" ]; then @@ -126,22 +129,22 @@ for config in $CONFIGS; do fi ############ debug ############ - print_config "deccheck: config=$config --with-pydebug" + print_config "deccheck: config=$config --with-pydebug" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ========================== debug ===========================\n\n" ./python Modules/_decimal/tests/deccheck.py ########### regular ########### - print_config "deccheck: config=$config " + print_config "deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== regular ===========================\n\n" @@ -157,15 +160,16 @@ for config in $CONFIGS; do esac esac - print_config "valgrind deccheck: config=$config " + print_config "valgrind deccheck: config=$config" $args printf "\nbuilding python ...\n\n" $GMAKE distclean > /dev/null 2>&1 - ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 $GMAKE | grep _decimal printf "\n\n# ======================== valgrind ==========================\n\n" $valgrind ./python Modules/_decimal/tests/deccheck.py + done done diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 6e33f12e0df62..81e76562dd576 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -463,6 +463,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ (which you can't on SCO ODT 3.0). */ /* #undef SYS_SELECT_WITH_SYS_TIME */ +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#define WITH_DECIMAL_CONTEXTVAR 1 + /* Define if you want documentation strings in extension modules */ #define WITH_DOC_STRINGS 1 diff --git a/aclocal.m4 b/aclocal.m4 index 85a0dbba27173..69205776ed4c9 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index b769d59629637..57b36e29b97f4 100755 --- a/configure +++ b/configure @@ -824,6 +824,7 @@ with_libs with_system_expat with_system_ffi with_system_libmpdec +with_decimal_contextvar enable_loadable_sqlite_extensions with_tcltk_includes with_tcltk_libs @@ -1516,6 +1517,9 @@ Optional Packages: --with-system-ffi build _ctypes module using an installed ffi library --with-system-libmpdec build _decimal module using an installed libmpdec library + --with-decimal-contextvar + build _decimal module using a coroutine-local rather + than a thread-local context (default is yes) --with-tcltk-includes='-I...' override search for Tcl and Tk include files --with-tcltk-libs='-L...' @@ -10400,6 +10404,28 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_libmpdec" >&5 $as_echo "$with_system_libmpdec" >&6; } +# Check whether _decimal should use a coroutine-local or thread-local context +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 +$as_echo_n "checking for --with-decimal-contextvar... " >&6; } + +# Check whether --with-decimal_contextvar was given. +if test "${with_decimal_contextvar+set}" = set; then : + withval=$with_decimal_contextvar; +else + with_decimal_contextvar="yes" +fi + + +if test "$with_decimal_contextvar" != "no" +then + +$as_echo "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 +$as_echo "$with_decimal_contextvar" >&6; } + # Check for support for loadable sqlite extensions { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 $as_echo_n "checking for --enable-loadable-sqlite-extensions... " >&6; } diff --git a/configure.ac b/configure.ac index 49acff31363b0..f9dabd86c2cfc 100644 --- a/configure.ac +++ b/configure.ac @@ -3012,6 +3012,21 @@ AC_ARG_WITH(system_libmpdec, AC_MSG_RESULT($with_system_libmpdec) +# Check whether _decimal should use a coroutine-local or thread-local context +AC_MSG_CHECKING(for --with-decimal-contextvar) +AC_ARG_WITH(decimal_contextvar, + AS_HELP_STRING([--with-decimal-contextvar], [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)]), + [], + [with_decimal_contextvar="yes"]) + +if test "$with_decimal_contextvar" != "no" +then + AC_DEFINE(WITH_DECIMAL_CONTEXTVAR, 1, + [Define if you want build the _decimal module using a coroutine-local rather than a thread-local context]) +fi + +AC_MSG_RESULT($with_decimal_contextvar) + # Check for support for loadable sqlite extensions AC_MSG_CHECKING(for --enable-loadable-sqlite-extensions) AC_ARG_ENABLE(loadable-sqlite-extensions, diff --git a/pyconfig.h.in b/pyconfig.h.in index f4816fdcdfc4b..ebab5ff518db2 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1447,6 +1447,10 @@ /* Define if WINDOW in curses.h offers a field _flags. */ #undef WINDOW_HAS_FLAGS +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#undef WITH_DECIMAL_CONTEXTVAR + /* Define if you want documentation strings in extension modules */ #undef WITH_DOC_STRINGS From webhook-mailer at python.org Tue Feb 11 07:39:49 2020 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 11 Feb 2020 12:39:49 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.8.2rc1 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/8623e68ea856830e084839e1d726c1f5be72= 7203 commit: 8623e68ea856830e084839e1d726c1f5be727203 branch: 3.8 author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2020-02-10T20:08:24+01:00 summary: Python 3.8.2rc1 files: A Misc/NEWS.d/3.8.2rc1.rst D Misc/NEWS.d/next/Build/2019-12-27-22-18-26.bpo-39144.dwHMlR.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-31-14-30-39.bpo-38610.fHdVMS.rst D Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-04-17-25-34.bpo-39215.xiqiIz.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-06-10-29-16.bpo-39209.QHAONe.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-09-10-01-18.bpo-39235.RYwjoc.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-20-21-40-57.bpo-39386.ULqD8t.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-22-15-53-37.bpo-39421.O3nG7u.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst D Misc/NEWS.d/next/Documentation/2019-11-17-11-53-10.bpo-3530.8zFUMc.rst D Misc/NEWS.d/next/Documentation/2019-12-15-22-04-41.bpo-38918.8JnDTS.rst D Misc/NEWS.d/next/Documentation/2020-01-18-15-37-56.bpo-39381.wTWe8d.rst D Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO.rst D Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV.rst D Misc/NEWS.d/next/IDLE/2018-03-03-12-56-26.bpo-32989.FVhmhH.rst D Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst D Misc/NEWS.d/next/IDLE/2019-12-30-16-44-07.bpo-34118.FaNW0a.rst D Misc/NEWS.d/next/IDLE/2020-01-22-22-28-06.bpo-39050.zkn0FO.rst D Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst D Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst D Misc/NEWS.d/next/Library/2019-09-29-08-17-03.bpo-38293.wls5s3.rst D Misc/NEWS.d/next/Library/2019-10-14-21-14-55.bpo-38473.uXpVld.rst D Misc/NEWS.d/next/Library/2019-10-31-19-23-25.bpo-35182.hzeNl9.rst D Misc/NEWS.d/next/Library/2019-11-22-12-08-52.bpo-38878.EJ0cFf.rst D Misc/NEWS.d/next/Library/2019-12-13-18-54-49.bpo-39033.cepuyD.rst D Misc/NEWS.d/next/Library/2019-12-15-19-23-23.bpo-39055.FmN3un.rst D Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst D Misc/NEWS.d/next/Library/2019-12-15-21-47-54.bpo-39057.FOxn-w.rst D Misc/NEWS.d/next/Library/2019-12-24-10-43-13.bpo-39129.jVx5rW.rst D Misc/NEWS.d/next/Library/2019-12-31-19-27-23.bpo-39142.oqU5iD.rst D Misc/NEWS.d/next/Library/2020-01-01-18-44-52.bpo-38871.3EEOLg.rst D Misc/NEWS.d/next/Library/2020-01-02-17-28-03.bpo-39191.ur_scy.rst D Misc/NEWS.d/next/Library/2020-01-02-20-21-03.bpo-39198.nzwGyG.rst D Misc/NEWS.d/next/Library/2020-01-03-18-02-50.bpo-39152.JgPjCC.rst D Misc/NEWS.d/next/Library/2020-01-06-02-14-38.bpo-38907.F1RkCR.rst D Misc/NEWS.d/next/Library/2020-01-08-23-25-27.bpo-39242.bnL65N.rst D Misc/NEWS.d/next/Library/2020-01-11-01-15-37.bpo-39297.y98Z6Q.rst D Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst D Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst D Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst D Misc/NEWS.d/next/Library/2020-01-24-11-05-21.bpo-39430.I0UQzM.rst D Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst D Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst D Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst D Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst D Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst D Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst D Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst D Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst D Misc/NEWS.d/next/Tests/2019-12-18-14-52-08.bpo-38546.2kxNuM.rst D Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst D Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst D Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst D Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst D Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.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 503d3aa85676f..a40ef8232ece9 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 8 -#define PY_MICRO_VERSION 1 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL -#define PY_RELEASE_SERIAL 0 +#define PY_MICRO_VERSION 2 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 =20 /* Version as a string */ -#define PY_VERSION "3.8.1+" +#define PY_VERSION "3.8.2rc1" /*--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 9d779d1e69f23..b9e741707cba5 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed Dec 18 18:17:58 2019 +# Autogenerated by Sphinx on Mon Feb 10 19:25:27 2020 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -470,24 +470,25 @@ 'The following code:\n' '\n' ' async for TARGET in ITER:\n' - ' BLOCK\n' + ' SUITE\n' ' else:\n' - ' BLOCK2\n' + ' SUITE2\n' '\n' 'Is semantically equivalent to:\n' '\n' ' iter =3D (ITER)\n' ' iter =3D type(iter).__aiter__(iter)\n' ' running =3D True\n' + '\n' ' while running:\n' ' try:\n' ' TARGET =3D await type(iter).__anext__(iter)\n' ' except StopAsyncIteration:\n' ' running =3D False\n' ' else:\n' - ' BLOCK\n' + ' SUITE\n' ' else:\n' - ' BLOCK2\n' + ' SUITE2\n' '\n' 'See also "__aiter__()" and "__anext__()" for details.\n' '\n' @@ -507,23 +508,27 @@ '\n' 'The following code:\n' '\n' - ' async with EXPR as VAR:\n' - ' BLOCK\n' + ' async with EXPRESSION as TARGET:\n' + ' SUITE\n' '\n' - 'Is semantically equivalent to:\n' + 'is semantically equivalent to:\n' '\n' - ' mgr =3D (EXPR)\n' - ' aexit =3D type(mgr).__aexit__\n' - ' aenter =3D type(mgr).__aenter__(mgr)\n' + ' manager =3D (EXPRESSION)\n' + ' aexit =3D type(manager).__aexit__\n' + ' aenter =3D type(manager).__aenter__\n' + ' value =3D await aenter(manager)\n' + ' hit_except =3D False\n' '\n' - ' VAR =3D await aenter\n' ' try:\n' - ' BLOCK\n' + ' TARGET =3D value\n' + ' SUITE\n' ' except:\n' - ' if not await aexit(mgr, *sys.exc_info()):\n' + ' hit_except =3D True\n' + ' if not await aexit(manager, *sys.exc_info()):\n' ' raise\n' - ' else:\n' - ' await aexit(mgr, None, None, None)\n' + ' finally:\n' + ' if not hit_except:\n' + ' await aexit(manager, None, None, None)\n' '\n' 'See also "__aenter__()" and "__aexit__()" for details.\n' '\n' @@ -2518,11 +2523,13 @@ '"with_item")\n' ' is evaluated to obtain a context manager.\n' '\n' - '2. The context manager=E2=80=99s "__exit__()" is loaded for la= ter use.\n' + '2. The context manager=E2=80=99s "__enter__()" is loaded for l= ater use.\n' + '\n' + '3. The context manager=E2=80=99s "__exit__()" is loaded for la= ter use.\n' '\n' - '3. The context manager=E2=80=99s "__enter__()" method is invok= ed.\n' + '4. The context manager=E2=80=99s "__enter__()" method is invok= ed.\n' '\n' - '4. If a target was included in the "with" statement, the retur= n\n' + '5. If a target was included in the "with" statement, the retur= n\n' ' value from "__enter__()" is assigned to it.\n' '\n' ' Note: The "with" statement guarantees that if the ' @@ -2535,9 +2542,9 @@ 'occurring\n' ' within the suite would be. See step 6 below.\n' '\n' - '5. The suite is executed.\n' + '6. The suite is executed.\n' '\n' - '6. The context manager=E2=80=99s "__exit__()" method is invoke= d. If an\n' + '7. The context manager=E2=80=99s "__exit__()" method is invoke= d. If an\n' ' exception caused the suite to be exited, its type, value, ' 'and\n' ' traceback are passed as arguments to "__exit__()". Otherwis= e, ' @@ -2559,18 +2566,42 @@ 'proceeds\n' ' at the normal location for the kind of exit that was taken.= \n' '\n' + 'The following code:\n' + '\n' + ' with EXPRESSION as TARGET:\n' + ' SUITE\n' + '\n' + 'is semantically equivalent to:\n' + '\n' + ' manager =3D (EXPRESSION)\n' + ' enter =3D type(manager).__enter__\n' + ' exit =3D type(manager).__exit__\n' + ' value =3D enter(manager)\n' + ' hit_except =3D False\n' + '\n' + ' try:\n' + ' TARGET =3D value\n' + ' SUITE\n' + ' except:\n' + ' hit_except =3D True\n' + ' if not exit(manager, *sys.exc_info()):\n' + ' raise\n' + ' finally:\n' + ' if not hit_except:\n' + ' exit(manager, None, None, None)\n' + '\n' 'With more than one item, the context managers are processed as= ' 'if\n' 'multiple "with" statements were nested:\n' '\n' ' with A() as a, B() as b:\n' - ' suite\n' + ' SUITE\n' '\n' - 'is equivalent to\n' + 'is semantically equivalent to:\n' '\n' ' with A() as a:\n' ' with B() as b:\n' - ' suite\n' + ' SUITE\n' '\n' 'Changed in version 3.1: Support for multiple context ' 'expressions.\n' @@ -2934,24 +2965,25 @@ 'The following code:\n' '\n' ' async for TARGET in ITER:\n' - ' BLOCK\n' + ' SUITE\n' ' else:\n' - ' BLOCK2\n' + ' SUITE2\n' '\n' 'Is semantically equivalent to:\n' '\n' ' iter =3D (ITER)\n' ' iter =3D type(iter).__aiter__(iter)\n' ' running =3D True\n' + '\n' ' while running:\n' ' try:\n' ' TARGET =3D await type(iter).__anext__(iter)\n' ' except StopAsyncIteration:\n' ' running =3D False\n' ' else:\n' - ' BLOCK\n' + ' SUITE\n' ' else:\n' - ' BLOCK2\n' + ' SUITE2\n' '\n' 'See also "__aiter__()" and "__anext__()" for details.\n' '\n' @@ -2971,23 +3003,27 @@ '\n' 'The following code:\n' '\n' - ' async with EXPR as VAR:\n' - ' BLOCK\n' + ' async with EXPRESSION as TARGET:\n' + ' SUITE\n' '\n' - 'Is semantically equivalent to:\n' + 'is semantically equivalent to:\n' '\n' - ' mgr =3D (EXPR)\n' - ' aexit =3D type(mgr).__aexit__\n' - ' aenter =3D type(mgr).__aenter__(mgr)\n' + ' manager =3D (EXPRESSION)\n' + ' aexit =3D type(manager).__aexit__\n' + ' aenter =3D type(manager).__aenter__\n' + ' value =3D await aenter(manager)\n' + ' hit_except =3D False\n' '\n' - ' VAR =3D await aenter\n' ' try:\n' - ' BLOCK\n' + ' TARGET =3D value\n' + ' SUITE\n' ' except:\n' - ' if not await aexit(mgr, *sys.exc_info()):\n' + ' hit_except =3D True\n' + ' if not await aexit(manager, *sys.exc_info()):\n' ' raise\n' - ' else:\n' - ' await aexit(mgr, None, None, None)\n' + ' finally:\n' + ' if not hit_except:\n' + ' await aexit(manager, None, None, None)\n' '\n' 'See also "__aenter__()" and "__aexit__()" for details.\n' '\n' @@ -6803,7 +6839,7 @@ 'object.__rfloordiv__(self, other)\n' 'object.__rmod__(self, other)\n' 'object.__rdivmod__(self, other)\n' - 'object.__rpow__(self, other)\n' + 'object.__rpow__(self, other[, modulo])\n' 'object.__rlshift__(self, other)\n' 'object.__rrshift__(self, other)\n' 'object.__rand__(self, other)\n' @@ -8963,7 +8999,9 @@ 'bases,\n' '**kwds)" (where the additional keyword arguments, if any, ' 'come from\n' - 'the class definition).\n' + 'the class definition). The "__prepare__" method should be ' + 'implemented\n' + 'as a "classmethod()".\n' '\n' 'If the metaclass has no "__prepare__" attribute, then the ' 'class\n' @@ -9477,7 +9515,7 @@ 'object.__rfloordiv__(self, other)\n' 'object.__rmod__(self, other)\n' 'object.__rdivmod__(self, other)\n' - 'object.__rpow__(self, other)\n' + 'object.__rpow__(self, other[, modulo])\n' 'object.__rlshift__(self, other)\n' 'object.__rrshift__(self, other)\n' 'object.__rand__(self, other)\n' @@ -11918,8 +11956,9 @@ ' bytecode offsets to line numbers (for details see the sourc= e\n' ' code of the interpreter); "co_stacksize" is the required ' 'stack\n' - ' size (including local variables); "co_flags" is an integer\= n' - ' encoding a number of flags for the interpreter.\n' + ' size; "co_flags" is an integer encoding a number of flags ' + 'for\n' + ' the interpreter.\n' '\n' ' The following flag bits are defined for "co_flags": bit ' '"0x04"\n' @@ -12372,6 +12411,8 @@ 'dictionary. This\n' ' is a shortcut for "reversed(d.keys())".\n' '\n' + ' New in version 3.8.\n' + '\n' ' setdefault(key[, default])\n' '\n' ' If *key* is in the dictionary, return its value. If= ' @@ -13577,11 +13618,13 @@ '1. The context expression (the expression given in the "with_item"= )\n' ' is evaluated to obtain a context manager.\n' '\n' - '2. The context manager=E2=80=99s "__exit__()" is loaded for later = use.\n' + '2. The context manager=E2=80=99s "__enter__()" is loaded for later= use.\n' '\n' - '3. The context manager=E2=80=99s "__enter__()" method is invoked.\= n' + '3. The context manager=E2=80=99s "__exit__()" is loaded for later = use.\n' '\n' - '4. If a target was included in the "with" statement, the return\n' + '4. The context manager=E2=80=99s "__enter__()" method is invoked.\= n' + '\n' + '5. If a target was included in the "with" statement, the return\n' ' value from "__enter__()" is assigned to it.\n' '\n' ' Note: The "with" statement guarantees that if the "__enter__()"= \n' @@ -13591,9 +13634,9 @@ ' target list, it will be treated the same as an error occurrin= g\n' ' within the suite would be. See step 6 below.\n' '\n' - '5. The suite is executed.\n' + '6. The suite is executed.\n' '\n' - '6. The context manager=E2=80=99s "__exit__()" method is invoked. = If an\n' + '7. The context manager=E2=80=99s "__exit__()" method is invoked. = If an\n' ' exception caused the suite to be exited, its type, value, and\n' ' traceback are passed as arguments to "__exit__()". Otherwise, ' 'three\n' @@ -13613,17 +13656,41 @@ 'proceeds\n' ' at the normal location for the kind of exit that was taken.\n' '\n' + 'The following code:\n' + '\n' + ' with EXPRESSION as TARGET:\n' + ' SUITE\n' + '\n' + 'is semantically equivalent to:\n' + '\n' + ' manager =3D (EXPRESSION)\n' + ' enter =3D type(manager).__enter__\n' + ' exit =3D type(manager).__exit__\n' + ' value =3D enter(manager)\n' + ' hit_except =3D False\n' + '\n' + ' try:\n' + ' TARGET =3D value\n' + ' SUITE\n' + ' except:\n' + ' hit_except =3D True\n' + ' if not exit(manager, *sys.exc_info()):\n' + ' raise\n' + ' finally:\n' + ' if not hit_except:\n' + ' exit(manager, None, None, None)\n' + '\n' 'With more than one item, the context managers are processed as if\= n' 'multiple "with" statements were nested:\n' '\n' ' with A() as a, B() as b:\n' - ' suite\n' + ' SUITE\n' '\n' - 'is equivalent to\n' + 'is semantically equivalent to:\n' '\n' ' with A() as a:\n' ' with B() as b:\n' - ' suite\n' + ' SUITE\n' '\n' 'Changed in version 3.1: Support for multiple context expressions.\= n' '\n' diff --git a/Misc/NEWS.d/3.8.2rc1.rst b/Misc/NEWS.d/3.8.2rc1.rst new file mode 100644 index 0000000000000..a4b8a1ed8fb4f --- /dev/null +++ b/Misc/NEWS.d/3.8.2rc1.rst @@ -0,0 +1,580 @@ +.. bpo: 39401 +.. date: 2020-01-28-20-54-09 +.. nonce: he7h_A +.. release date: 2020-02-10 +.. section: Security + +Avoid unsafe load of ``api-ms-win-core-path-l1-1-0.dll`` at startup on +Windows 7. + +.. + +.. bpo: 39184 +.. date: 2020-01-07-00-42-08 +.. nonce: fe7NgK +.. section: Security + +Add audit events to command execution functions in os and pty modules. + +.. + +.. bpo: 39579 +.. date: 2020-02-07-15-18-35 +.. nonce: itNmC0 +.. section: Core and Builtins + +Change the ending column offset of `Attribute` nodes constructed in +`ast_for_dotted_name` to point at the end of the current node and not at the +end of the last `NAME` node. + +.. + +.. bpo: 39510 +.. date: 2020-02-04-10-27-41 +.. nonce: PMIh-f +.. section: Core and Builtins + +Fix segfault in ``readinto()`` method on closed BufferedReader. + +.. + +.. bpo: 39492 +.. date: 2020-01-30-01-14-42 +.. nonce: eTuy0F +.. section: Core and Builtins + +Fix a reference cycle in the C Pickler that was preventing the garbage +collection of deleted, pickled objects. + +.. + +.. bpo: 39421 +.. date: 2020-01-22-15-53-37 +.. nonce: O3nG7u +.. section: Core and Builtins + +Fix possible crashes when operating with the functions in the :mod:`heapq` +module and custom comparison operators. + +.. + +.. bpo: 39386 +.. date: 2020-01-20-21-40-57 +.. nonce: ULqD8t +.. section: Core and Builtins + +Prevent double awaiting of async iterator. + +.. + +.. bpo: 39235 +.. date: 2020-01-09-10-01-18 +.. nonce: RYwjoc +.. section: Core and Builtins + +Fix AST end location for lone generator expression in function call, e.g. +f(i for i in a). + +.. + +.. bpo: 39209 +.. date: 2020-01-06-10-29-16 +.. nonce: QHAONe +.. section: Core and Builtins + +Correctly handle multi-line tokens in interactive mode. Patch by Pablo +Galindo. + +.. + +.. bpo: 39216 +.. date: 2020-01-05-06-55-52 +.. nonce: 74jLh9 +.. section: Core and Builtins + +Fix constant folding optimization for positional only arguments - by Anthony +Sottile. + +.. + +.. bpo: 39215 +.. date: 2020-01-04-17-25-34 +.. nonce: xiqiIz +.. section: Core and Builtins + +Fix ``SystemError`` when nested function has annotation on positional-only +argument - by Anthony Sottile. + +.. + +.. bpo: 38588 +.. date: 2019-12-29-19-13-54 +.. nonce: pgXnNS +.. section: Core and Builtins + +Fix possible crashes in dict and list when calling +:c:func:`PyObject_RichCompareBool`. + +.. + +.. bpo: 38610 +.. date: 2019-10-31-14-30-39 +.. nonce: fHdVMS +.. section: Core and Builtins + +Fix possible crashes in several list methods by holding strong references to +list elements when calling :c:func:`PyObject_RichCompareBool`. + +.. + +.. bpo: 39590 +.. date: 2020-02-09-05-51-05 +.. nonce: rf98GU +.. section: Library + +Collections.deque now holds strong references during deque.__contains__ and +deque.count, fixing crashes. + +.. + +.. bpo: 38149 +.. date: 2020-02-05-11-24-16 +.. nonce: GWsjHE +.. section: Library + +:func:`sys.audit` is now called only once per call of :func:`glob.glob` and +:func:`glob.iglob`. + +.. + +.. bpo: 39450 +.. date: 2020-02-02-14-46-34 +.. nonce: 48R274 +.. section: Library + +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. + +.. + +.. bpo: 39493 +.. date: 2020-01-30-01-13-19 +.. nonce: CbFRi7 +.. section: Library + +Mark ``typing.IO.closed`` as a property + +.. + +.. bpo: 39485 +.. date: 2020-01-29-14-58-27 +.. nonce: Zy3ot6 +.. section: Library + +Fix a bug in :func:`unittest.mock.create_autospec` that would complain about +the wrong number of arguments for custom descriptors defined in an extension +module returning functions. + +.. + +.. bpo: 39082 +.. date: 2020-01-24-13-24-35 +.. nonce: qKgrq_ +.. section: Library + +Allow AsyncMock to correctly patch static/class methods + +.. + +.. bpo: 39430 +.. date: 2020-01-24-11-05-21 +.. nonce: I0UQzM +.. section: Library + +Fixed race condition in lazy imports in :mod:`tarfile`. + +.. + +.. bpo: 39390 +.. date: 2020-01-23-21-34-29 +.. nonce: D2tSXk +.. section: Library + +Fixed a regression with the `ignore` callback of :func:`shutil.copytree`. +The argument types are now str and List[str] again. + +.. + +.. bpo: 39389 +.. date: 2020-01-20-00-56-01 +.. nonce: fEirIS +.. section: Library + +Write accurate compression level metadata in :mod:`gzip` archives, rather +than always signaling maximum compression. + +.. + +.. bpo: 39274 +.. date: 2020-01-15-23-13-03 +.. nonce: lpc0-n +.. section: Library + +``bool(fraction.Fraction)`` now returns a boolean even if (numerator !=3D 0) +does not return a boolean (ex: numpy number). + +.. + +.. bpo: 39297 +.. date: 2020-01-11-01-15-37 +.. nonce: y98Z6Q +.. section: Library + +Improved performance of importlib.metadata distribution discovery and +resilients to inaccessible sys.path entries (importlib_metadata v1.4.0). + +.. + +.. bpo: 39242 +.. date: 2020-01-08-23-25-27 +.. nonce: bnL65N +.. section: Library + +Updated the Gmane domain from news.gmane.org to news.gmane.io which is used +for examples of :class:`~nntplib.NNTP` news reader server and nntplib tests. + +.. + +.. bpo: 38907 +.. date: 2020-01-06-02-14-38 +.. nonce: F1RkCR +.. section: Library + +In http.server script, restore binding to IPv4 on Windows. + +.. + +.. bpo: 39152 +.. date: 2020-01-03-18-02-50 +.. nonce: JgPjCC +.. section: Library + +Fix ttk.Scale.configure([name]) to return configuration tuple for name or +all options. Giovanni Lombardo contributed part of the patch. + +.. + +.. bpo: 39198 +.. date: 2020-01-02-20-21-03 +.. nonce: nzwGyG +.. section: Library + +If an exception were to be thrown in `Logger.isEnabledFor` (say, by asyncio +timeouts or stopit) , the `logging` global lock may not be released +appropriately, resulting in deadlock. This change wraps that block of code +with `try...finally` to ensure the lock is released. + +.. + +.. bpo: 39191 +.. date: 2020-01-02-17-28-03 +.. nonce: ur_scy +.. section: Library + +Perform a check for running loop before starting a new task in +``loop.run_until_complete()`` to fail fast; it prevents the side effect of +new task spawning before exception raising. + +.. + +.. bpo: 38871 +.. date: 2020-01-01-18-44-52 +.. nonce: 3EEOLg +.. section: Library + +Correctly parenthesize filter-based statements that contain lambda +expressions in mod:`lib2to3`. Patch by Dong-hee Na. + +.. + +.. bpo: 39142 +.. date: 2019-12-31-19-27-23 +.. nonce: oqU5iD +.. section: Library + +A change was made to logging.config.dictConfig to avoid converting instances +of named tuples to ConvertingTuple. It's assumed that named tuples are too +specialised to be treated like ordinary tuples; if a user of named tuples +requires ConvertingTuple functionality, they will have to implement that +themselves in their named tuple class. + +.. + +.. bpo: 39129 +.. date: 2019-12-24-10-43-13 +.. nonce: jVx5rW +.. section: Library + +Fix import path for ``asyncio.TimeoutError`` + +.. + +.. bpo: 39057 +.. date: 2019-12-15-21-47-54 +.. nonce: FOxn-w +.. section: Library + +:func:`urllib.request.proxy_bypass_environment` now ignores leading dots and +no longer ignores a trailing newline. + +.. + +.. bpo: 39056 +.. date: 2019-12-15-21-05-16 +.. nonce: nEfUM9 +.. section: Library + +Fixed handling invalid warning category in the -W option. No longer import +the re module if it is not needed. + +.. + +.. bpo: 39055 +.. date: 2019-12-15-19-23-23 +.. nonce: FmN3un +.. section: Library + +:func:`base64.b64decode` with ``validate=3DTrue`` raises now a binascii.Error +if the input ends with a single ``\n``. + +.. + +.. bpo: 39033 +.. date: 2019-12-13-18-54-49 +.. nonce: cepuyD +.. section: Library + +Fix :exc:`NameError` in :mod:`zipimport`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 38878 +.. date: 2019-11-22-12-08-52 +.. nonce: EJ0cFf +.. section: Library + +Fixed __subclasshook__ of :class:`os.PathLike` to return a correct result +upon inheritence. Patch by Bar Harel. + +.. + +.. bpo: 35182 +.. date: 2019-10-31-19-23-25 +.. nonce: hzeNl9 +.. section: Library + +Fixed :func:`Popen.communicate` subsequent call crash when the child process +has already closed any piped standard stream, but still continues to be +running. Patch by Andriy Maletsky. + +.. + +.. bpo: 38473 +.. date: 2019-10-14-21-14-55 +.. nonce: uXpVld +.. section: Library + +Use signature from inner mock for autospecced methods attached with +:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 38293 +.. date: 2019-09-29-08-17-03 +.. nonce: wls5s3 +.. section: Library + +Add :func:`copy.copy` and :func:`copy.deepcopy` support to :func:`property` +objects. + +.. + +.. bpo: 39153 +.. date: 2020-01-27-22-24-51 +.. nonce: Pjl8jV +.. section: Documentation + +Clarify refcounting semantics for the following functions: - +PyObject_SetItem - PyMapping_SetItemString - PyDict_SetItem - +PyDict_SetItemString + +.. + +.. bpo: 39392 +.. date: 2020-01-27-18-18-42 +.. nonce: oiqcLO +.. section: Documentation + +Explain that when filling with turtle, overlap regions may be left unfilled. + +.. + +.. bpo: 39381 +.. date: 2020-01-18-15-37-56 +.. nonce: wTWe8d +.. section: Documentation + +Mention in docs that :func:`asyncio.get_event_loop` implicitly creates new +event loop only if called from the main thread. + +.. + +.. bpo: 38918 +.. date: 2019-12-15-22-04-41 +.. nonce: 8JnDTS +.. section: Documentation + +Add an entry for ``__module__`` in the "function" & "method" sections of the +`inspect docs types and members table +`_ + +.. + +.. bpo: 3530 +.. date: 2019-11-17-11-53-10 +.. nonce: 8zFUMc +.. section: Documentation + +In the :mod:`ast` module documentation, fix a misleading ``NodeTransformer`` +example and add advice on when to use the ``fix_missing_locations`` +function. + +.. + +.. bpo: 39502 +.. date: 2020-01-30-15-04-54 +.. nonce: chbpII +.. section: Tests + +Skip test_zipfile.test_add_file_after_2107() if :func:`time.localtime` fails +with :exc:`OverflowError`. It is the case on AIX 6.1 for example. + +.. + +.. bpo: 38546 +.. date: 2019-12-18-14-52-08 +.. nonce: 2kxNuM +.. section: Tests + +Fix test_ressources_gced_in_workers() of test_concurrent_futures: explicitly +stop the manager to prevent leaking a child process running in the +background after the test completes. + +.. + +.. bpo: 39144 +.. date: 2019-12-27-22-18-26 +.. nonce: dwHMlR +.. section: Build + +The ctags and etags build targets both include Modules/_ctypes and Python +standard library source files. + +.. + +.. bpo: 39439 +.. date: 2020-01-24-03-15-05 +.. nonce: sFxGfR +.. section: Windows + +Honor the Python path when a virtualenv is active on Windows. + +.. + +.. bpo: 39393 +.. date: 2020-01-20-23-42-53 +.. nonce: gWlJDG +.. section: Windows + +Improve the error message when attempting to load a DLL with unresolved +dependencies. + +.. + +.. bpo: 38883 +.. date: 2020-01-11-22-53-55 +.. nonce: X7FRaN +.. section: Windows + +:meth:`~pathlib.Path.home()` and :meth:`~pathlib.Path.expanduser()` on +Windows now prefer :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, +which is not normally set for regular user accounts. This makes them again +behave like :func:`os.path.expanduser`, which was changed to ignore +:envvar:`HOME` in 3.8, see :issue:`36264`. + +.. + +.. bpo: 39185 +.. date: 2020-01-02-01-11-53 +.. nonce: T4herN +.. section: Windows + +The build.bat script has additional options for very-quiet output (-q) and +very-verbose output (-vv) + +.. + +.. bpo: 30780 +.. date: 2020-01-27-16-44-29 +.. nonce: nR80qu +.. section: IDLE + +Add remaining configdialog tests for buttons and highlights and keys tabs. + +.. + +.. bpo: 39388 +.. date: 2020-01-25-02-26-45 +.. nonce: x4TQNh +.. section: IDLE + +IDLE Settings Cancel button now cancels pending changes + +.. + +.. bpo: 39050 +.. date: 2020-01-22-22-28-06 +.. nonce: zkn0FO +.. section: IDLE + +Make IDLE Settings dialog Help button work again. + +.. + +.. bpo: 34118 +.. date: 2019-12-30-16-44-07 +.. nonce: FaNW0a +.. section: IDLE + +Tag memoryview, range, and tuple as classes, the same as list, etcetera, in +the library manual built-in functions list. + +.. + +.. bpo: 38792 +.. date: 2019-11-13-23-51-39 +.. nonce: xhTC5a +.. section: IDLE + +Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` or shell restart +occurs. Patch by Zackery Spytz. + +.. + +.. bpo: 32989 +.. date: 2018-03-03-12-56-26 +.. nonce: FVhmhH +.. section: IDLE + +Add tests for editor newline_and_indent_event method. Remove dead code from +pyparse find_good_parse_start method. diff --git a/Misc/NEWS.d/next/Build/2019-12-27-22-18-26.bpo-39144.dwHMlR.rst = b/Misc/NEWS.d/next/Build/2019-12-27-22-18-26.bpo-39144.dwHMlR.rst deleted file mode 100644 index 8b90da19622e6..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-12-27-22-18-26.bpo-39144.dwHMlR.rst +++ /dev/null @@ -1 +0,0 @@ -The ctags and etags build targets both include Modules/_ctypes and Python st= andard library source files. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-31-14-30-39.bpo-38610= .fHdVMS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-31-14-30-39.bpo-3861= 0.fHdVMS.rst deleted file mode 100644 index 0ee63bbb40dc6..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-31-14-30-39.bpo-38610.fHdVMS= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible crashes in several list methods by holding strong references to -list elements when calling :c:func:`PyObject_RichCompareBool`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588= .pgXnNS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-3858= 8.pgXnNS.rst deleted file mode 100644 index 0b81085a89d25..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible crashes in dict and list when calling -:c:func:`PyObject_RichCompareBool`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-04-17-25-34.bpo-39215= .xiqiIz.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-04-17-25-34.bpo-3921= 5.xiqiIz.rst deleted file mode 100644 index 9a3178f9c6218..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-04-17-25-34.bpo-39215.xiqiIz= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``SystemError`` when nested function has annotation on positional-only -argument - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216= .74jLh9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-3921= 6.74jLh9.rst deleted file mode 100644 index 971b06552973e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix constant folding optimization for positional only arguments - by Anthony -Sottile. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-06-10-29-16.bpo-39209= .QHAONe.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-06-10-29-16.bpo-3920= 9.QHAONe.rst deleted file mode 100644 index c05b3f8dfa4d4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-06-10-29-16.bpo-39209.QHAONe= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Correctly handle multi-line tokens in interactive mode. Patch by Pablo -Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-09-10-01-18.bpo-39235= .RYwjoc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-09-10-01-18.bpo-3923= 5.RYwjoc.rst deleted file mode 100644 index 5fb0d45356bad..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-09-10-01-18.bpo-39235.RYwjoc= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix AST end location for lone generator expression in function call, e.g. -f(i for i in a). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-20-21-40-57.bpo-39386= .ULqD8t.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-20-21-40-57.bpo-3938= 6.ULqD8t.rst deleted file mode 100644 index f24e1f4e8a183..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-20-21-40-57.bpo-39386.ULqD8t= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Prevent double awaiting of async iterator. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-15-53-37.bpo-39421= .O3nG7u.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-15-53-37.bpo-3942= 1.O3nG7u.rst deleted file mode 100644 index bae008150ee12..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-15-53-37.bpo-39421.O3nG7u= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible crashes when operating with the functions in the :mod:`heapq` -module and custom comparison operators. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492= .eTuy0F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-3949= 2.eTuy0F.rst deleted file mode 100644 index 6e8b715c46365..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix a reference cycle in the C Pickler that was preventing the garbage colle= ction of deleted, pickled objects. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510= .PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-3951= 0.PMIh-f.rst deleted file mode 100644 index 9a38e4ab76228..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579= .itNmC0.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-3957= 9.itNmC0.rst deleted file mode 100644 index 36d5c425670c2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Change the ending column offset of `Attribute` nodes constructed in `ast_for= _dotted_name` to point at the end of the current node and not at the end of t= he last `NAME` node. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-11-17-11-53-10.bpo-3530.8zFU= Mc.rst b/Misc/NEWS.d/next/Documentation/2019-11-17-11-53-10.bpo-3530.8zFUMc.r= st deleted file mode 100644 index 65f1a6d156a12..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-11-17-11-53-10.bpo-3530.8zFUMc.rst +++ /dev/null @@ -1,2 +0,0 @@ -In the :mod:`ast` module documentation, fix a misleading ``NodeTransformer``= example and add -advice on when to use the ``fix_missing_locations`` function. diff --git a/Misc/NEWS.d/next/Documentation/2019-12-15-22-04-41.bpo-38918.8Jn= DTS.rst b/Misc/NEWS.d/next/Documentation/2019-12-15-22-04-41.bpo-38918.8JnDTS= .rst deleted file mode 100644 index 5747936dd64d5..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-12-15-22-04-41.bpo-38918.8JnDTS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add an entry for ``__module__`` in the "function" & "method" sections of the -`inspect docs types and members table -`_ diff --git a/Misc/NEWS.d/next/Documentation/2020-01-18-15-37-56.bpo-39381.wTW= e8d.rst b/Misc/NEWS.d/next/Documentation/2020-01-18-15-37-56.bpo-39381.wTWe8d= .rst deleted file mode 100644 index 37b66ad9dfd17..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-18-15-37-56.bpo-39381.wTWe8d.rst +++ /dev/null @@ -1,2 +0,0 @@ -Mention in docs that :func:`asyncio.get_event_loop` implicitly creates new -event loop only if called from the main thread. diff --git a/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiq= cLO.rst b/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO= .rst deleted file mode 100644 index 715874981f735..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO.rst +++ /dev/null @@ -1 +0,0 @@ -Explain that when filling with turtle, overlap regions may be left unfilled. diff --git a/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl= 8jV.rst b/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV= .rst deleted file mode 100644 index 95be00b4b777f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV.rst +++ /dev/null @@ -1,5 +0,0 @@ -Clarify refcounting semantics for the following functions: -- PyObject_SetItem -- PyMapping_SetItemString -- PyDict_SetItem -- PyDict_SetItemString \ No newline at end of file diff --git a/Misc/NEWS.d/next/IDLE/2018-03-03-12-56-26.bpo-32989.FVhmhH.rst b= /Misc/NEWS.d/next/IDLE/2018-03-03-12-56-26.bpo-32989.FVhmhH.rst deleted file mode 100644 index 38f0fb6e10452..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2018-03-03-12-56-26.bpo-32989.FVhmhH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add tests for editor newline_and_indent_event method. -Remove dead code from pyparse find_good_parse_start method. diff --git a/Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst b= /Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst deleted file mode 100644 index 9aa2f0ffddfaf..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst +++ /dev/null @@ -1,2 +0,0 @@ -Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` -or shell restart occurs. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/IDLE/2019-12-30-16-44-07.bpo-34118.FaNW0a.rst b= /Misc/NEWS.d/next/IDLE/2019-12-30-16-44-07.bpo-34118.FaNW0a.rst deleted file mode 100644 index ce95eb5482f2b..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-12-30-16-44-07.bpo-34118.FaNW0a.rst +++ /dev/null @@ -1,2 +0,0 @@ -Tag memoryview, range, and tuple as classes, the same as list, etcetera, in -the library manual built-in functions list. diff --git a/Misc/NEWS.d/next/IDLE/2020-01-22-22-28-06.bpo-39050.zkn0FO.rst b= /Misc/NEWS.d/next/IDLE/2020-01-22-22-28-06.bpo-39050.zkn0FO.rst deleted file mode 100644 index e71265cdf109b..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-01-22-22-28-06.bpo-39050.zkn0FO.rst +++ /dev/null @@ -1 +0,0 @@ -Make IDLE Settings dialog Help button work again. diff --git a/Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst b= /Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst deleted file mode 100644 index 42bbfb168c19d..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst +++ /dev/null @@ -1 +0,0 @@ -IDLE Settings Cancel button now cancels pending changes diff --git a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst b= /Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst deleted file mode 100644 index 2f65a00a5af3b..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst +++ /dev/null @@ -1 +0,0 @@ -Add remaining configdialog tests for buttons and highlights and keys tabs. diff --git a/Misc/NEWS.d/next/Library/2019-09-29-08-17-03.bpo-38293.wls5s3.rs= t b/Misc/NEWS.d/next/Library/2019-09-29-08-17-03.bpo-38293.wls5s3.rst deleted file mode 100644 index 0b19551970eb0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-29-08-17-03.bpo-38293.wls5s3.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`copy.copy` and :func:`copy.deepcopy` support to :func:`property` = objects. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-10-14-21-14-55.bpo-38473.uXpVld.rs= t b/Misc/NEWS.d/next/Library/2019-10-14-21-14-55.bpo-38473.uXpVld.rst deleted file mode 100644 index de80e89e00e2d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-14-21-14-55.bpo-38473.uXpVld.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use signature from inner mock for autospecced methods attached with -:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-10-31-19-23-25.bpo-35182.hzeNl9.rs= t b/Misc/NEWS.d/next/Library/2019-10-31-19-23-25.bpo-35182.hzeNl9.rst deleted file mode 100644 index 9438cd8f9fd0b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-31-19-23-25.bpo-35182.hzeNl9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed :func:`Popen.communicate` subsequent call crash when the child process -has already closed any piped standard stream, but still continues to be -running. Patch by Andriy Maletsky. diff --git a/Misc/NEWS.d/next/Library/2019-11-22-12-08-52.bpo-38878.EJ0cFf.rs= t b/Misc/NEWS.d/next/Library/2019-11-22-12-08-52.bpo-38878.EJ0cFf.rst deleted file mode 100644 index 9cbdf08dd53e3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-22-12-08-52.bpo-38878.EJ0cFf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed __subclasshook__ of :class:`os.PathLike` to return a correct result -upon inheritence. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2019-12-13-18-54-49.bpo-39033.cepuyD.rs= t b/Misc/NEWS.d/next/Library/2019-12-13-18-54-49.bpo-39033.cepuyD.rst deleted file mode 100644 index 3dee3c08cc5be..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-13-18-54-49.bpo-39033.cepuyD.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :exc:`NameError` in :mod:`zipimport`. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-12-15-19-23-23.bpo-39055.FmN3un.rs= t b/Misc/NEWS.d/next/Library/2019-12-15-19-23-23.bpo-39055.FmN3un.rst deleted file mode 100644 index 83b1431e92fcb..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-15-19-23-23.bpo-39055.FmN3un.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`base64.b64decode` with ``validate=3DTrue`` raises now a binascii.Error -if the input ends with a single ``\n``. diff --git a/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rs= t b/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst deleted file mode 100644 index d5d2b98e9b0b3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed handling invalid warning category in the -W option. No longer import -the re module if it is not needed. diff --git a/Misc/NEWS.d/next/Library/2019-12-15-21-47-54.bpo-39057.FOxn-w.rs= t b/Misc/NEWS.d/next/Library/2019-12-15-21-47-54.bpo-39057.FOxn-w.rst deleted file mode 100644 index 24a17444b97da..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-15-21-47-54.bpo-39057.FOxn-w.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`urllib.request.proxy_bypass_environment` now ignores leading dots and -no longer ignores a trailing newline. diff --git a/Misc/NEWS.d/next/Library/2019-12-24-10-43-13.bpo-39129.jVx5rW.rs= t b/Misc/NEWS.d/next/Library/2019-12-24-10-43-13.bpo-39129.jVx5rW.rst deleted file mode 100644 index 6667697671a28..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-24-10-43-13.bpo-39129.jVx5rW.rst +++ /dev/null @@ -1 +0,0 @@ -Fix import path for ``asyncio.TimeoutError`` diff --git a/Misc/NEWS.d/next/Library/2019-12-31-19-27-23.bpo-39142.oqU5iD.rs= t b/Misc/NEWS.d/next/Library/2019-12-31-19-27-23.bpo-39142.oqU5iD.rst deleted file mode 100644 index 508d1338d7c31..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-31-19-27-23.bpo-39142.oqU5iD.rst +++ /dev/null @@ -1,5 +0,0 @@ -A change was made to logging.config.dictConfig to avoid converting instances -of named tuples to ConvertingTuple. It's assumed that named tuples are too -specialised to be treated like ordinary tuples; if a user of named tuples -requires ConvertingTuple functionality, they will have to implement that -themselves in their named tuple class. diff --git a/Misc/NEWS.d/next/Library/2020-01-01-18-44-52.bpo-38871.3EEOLg.rs= t b/Misc/NEWS.d/next/Library/2020-01-01-18-44-52.bpo-38871.3EEOLg.rst deleted file mode 100644 index fe970fd9e3fa1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-01-18-44-52.bpo-38871.3EEOLg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly parenthesize filter-based statements that contain lambda -expressions in mod:`lib2to3`. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2020-01-02-17-28-03.bpo-39191.ur_scy.rs= t b/Misc/NEWS.d/next/Library/2020-01-02-17-28-03.bpo-39191.ur_scy.rst deleted file mode 100644 index 138c93c2e4877..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-02-17-28-03.bpo-39191.ur_scy.rst +++ /dev/null @@ -1,3 +0,0 @@ -Perform a check for running loop before starting a new task in -``loop.run_until_complete()`` to fail fast; it prevents the side effect of -new task spawning before exception raising. diff --git a/Misc/NEWS.d/next/Library/2020-01-02-20-21-03.bpo-39198.nzwGyG.rs= t b/Misc/NEWS.d/next/Library/2020-01-02-20-21-03.bpo-39198.nzwGyG.rst deleted file mode 100644 index ec4e81e2bbe4a..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-02-20-21-03.bpo-39198.nzwGyG.rst +++ /dev/null @@ -1 +0,0 @@ -If an exception were to be thrown in `Logger.isEnabledFor` (say, by asyncio = timeouts or stopit) , the `logging` global lock may not be released appropria= tely, resulting in deadlock. This change wraps that block of code with `try.= ..finally` to ensure the lock is released. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-01-03-18-02-50.bpo-39152.JgPjCC.rs= t b/Misc/NEWS.d/next/Library/2020-01-03-18-02-50.bpo-39152.JgPjCC.rst deleted file mode 100644 index abb3df0da0fe4..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-03-18-02-50.bpo-39152.JgPjCC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ttk.Scale.configure([name]) to return configuration tuple for name -or all options. Giovanni Lombardo contributed part of the patch. diff --git a/Misc/NEWS.d/next/Library/2020-01-06-02-14-38.bpo-38907.F1RkCR.rs= t b/Misc/NEWS.d/next/Library/2020-01-06-02-14-38.bpo-38907.F1RkCR.rst deleted file mode 100644 index a6e79f7809521..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-06-02-14-38.bpo-38907.F1RkCR.rst +++ /dev/null @@ -1 +0,0 @@ -In http.server script, restore binding to IPv4 on Windows. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-01-08-23-25-27.bpo-39242.bnL65N.rs= t b/Misc/NEWS.d/next/Library/2020-01-08-23-25-27.bpo-39242.bnL65N.rst deleted file mode 100644 index a87dddf81dcd5..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-08-23-25-27.bpo-39242.bnL65N.rst +++ /dev/null @@ -1,3 +0,0 @@ -Updated the Gmane domain from news.gmane.org to news.gmane.io=20 -which is used for examples of :class:`~nntplib.NNTP` news reader server and -nntplib tests. diff --git a/Misc/NEWS.d/next/Library/2020-01-11-01-15-37.bpo-39297.y98Z6Q.rs= t b/Misc/NEWS.d/next/Library/2020-01-11-01-15-37.bpo-39297.y98Z6Q.rst deleted file mode 100644 index 618f6f9f2b7ff..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-11-01-15-37.bpo-39297.y98Z6Q.rst +++ /dev/null @@ -1 +0,0 @@ -Improved performance of importlib.metadata distribution discovery and resili= ents to inaccessible sys.path entries (importlib_metadata v1.4.0). diff --git a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rs= t b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst deleted file mode 100644 index 4c398682b98ab..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst +++ /dev/null @@ -1 +0,0 @@ -``bool(fraction.Fraction)`` now returns a boolean even if (numerator !=3D 0)= does not return a boolean (ex: numpy number). diff --git a/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rs= t b/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst deleted file mode 100644 index d4c80506f7d6b..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Write accurate compression level metadata in :mod:`gzip` archives, rather -than always signaling maximum compression. diff --git a/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rs= t b/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst deleted file mode 100644 index ffa961ea4cd22..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a regression with the `ignore` callback of :func:`shutil.copytree`. -The argument types are now str and List[str] again. diff --git a/Misc/NEWS.d/next/Library/2020-01-24-11-05-21.bpo-39430.I0UQzM.rs= t b/Misc/NEWS.d/next/Library/2020-01-24-11-05-21.bpo-39430.I0UQzM.rst deleted file mode 100644 index 712fc5d34bbe0..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-24-11-05-21.bpo-39430.I0UQzM.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed race condition in lazy imports in :mod:`tarfile`. diff --git a/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rs= t b/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst deleted file mode 100644 index 52c4ee1b33bda..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst +++ /dev/null @@ -1 +0,0 @@ -Allow AsyncMock to correctly patch static/class methods diff --git a/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rs= t b/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst deleted file mode 100644 index f62c31fc686ad..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug in :func:`unittest.mock.create_autospec` that would complain about -the wrong number of arguments for custom descriptors defined in an extension -module returning functions. diff --git a/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rs= t b/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst deleted file mode 100644 index b676629a4414a..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst +++ /dev/null @@ -1 +0,0 @@ -Mark ``typing.IO.closed`` as a property \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rs= t b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst deleted file mode 100644 index 55fed519a2d80..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst +++ /dev/null @@ -1,2 +0,0 @@ -Striped whitespace from docstring before returning it from -:func:`unittest.case.shortDescription`. diff --git a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rs= t b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst deleted file mode 100644 index b4ec60b2abad1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`sys.audit` is now called only once per call of :func:`glob.glob` and -:func:`glob.iglob`. diff --git a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rs= t b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst deleted file mode 100644 index 68625028fb7af..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst +++ /dev/null @@ -1 +0,0 @@ -Collections.deque now holds strong references during deque.__contains__ and = deque.count, fixing crashes. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.r= st b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst deleted file mode 100644 index 1ab5d4d70eec5..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst +++ /dev/null @@ -1 +0,0 @@ -Add audit events to command execution functions in os and pty modules. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.r= st b/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst deleted file mode 100644 index 5071e126b70d0..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid unsafe load of ``api-ms-win-core-path-l1-1-0.dll`` at startup on Windo= ws 7. diff --git a/Misc/NEWS.d/next/Tests/2019-12-18-14-52-08.bpo-38546.2kxNuM.rst = b/Misc/NEWS.d/next/Tests/2019-12-18-14-52-08.bpo-38546.2kxNuM.rst deleted file mode 100644 index d8ec7cabbbab8..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-12-18-14-52-08.bpo-38546.2kxNuM.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_ressources_gced_in_workers() of test_concurrent_futures: explicitly -stop the manager to prevent leaking a child process running in the background -after the test completes. diff --git a/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst = b/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst deleted file mode 100644 index 0a13746e34759..0000000000000 --- a/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip test_zipfile.test_add_file_after_2107() if :func:`time.localtime` fails -with :exc:`OverflowError`. It is the case on AIX 6.1 for example. diff --git a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rs= t b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst deleted file mode 100644 index 3b84bd5217264..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst +++ /dev/null @@ -1 +0,0 @@ -The build.bat script has additional options for very-quiet output (-q) and v= ery-verbose output (-vv) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rs= t b/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst deleted file mode 100644 index c552e850a3684..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst +++ /dev/null @@ -1,5 +0,0 @@ -:meth:`~pathlib.Path.home()` and :meth:`~pathlib.Path.expanduser()` on Windo= ws -now prefer :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, which is = not -normally set for regular user accounts. This makes them again behave like -:func:`os.path.expanduser`, which was changed to ignore :envvar:`HOME` in 3.= 8, -see :issue:`36264`. diff --git a/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rs= t b/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst deleted file mode 100644 index 025b7e96a6e74..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the error message when attempting to load a DLL with unresolved -dependencies. diff --git a/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rs= t b/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rst deleted file mode 100644 index d677c4c3e02d5..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rst +++ /dev/null @@ -1 +0,0 @@ -Honor the Python path when a virtualenv is active on Windows. \ No newline at end of file diff --git a/README.rst b/README.rst index be371c6498079..0b4695ce0e509 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.8.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 +This is Python version 3.8.2rc1 +=3D=3D=3D=3D=3D=3D=3D=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=3D3.8 :alt: CPython build status on Travis CI From webhook-mailer at python.org Tue Feb 18 07:02:18 2020 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 18 Feb 2020 12:02:18 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.8.2rc2 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/777ba072d61f50cc39427ae87ab63eb3d3d8= 8542 commit: 777ba072d61f50cc39427ae87ab63eb3d3d88542 branch: 3.8 author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2020-02-17T23:45:14+01:00 summary: Python 3.8.2rc2 files: A Misc/NEWS.d/3.8.2rc2.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master= _chroot.rst D Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst D Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst D Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst D Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst D Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst D Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.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 506f43c3e0adc..fc1c0f591f8d4 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 2 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 =20 /* Version as a string */ -#define PY_VERSION "3.8.2rc1+" +#define PY_VERSION "3.8.2rc2" /*--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 b9e741707cba5..3c1b780384570 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 Feb 10 19:25:27 2020 +# Autogenerated by Sphinx on Mon Feb 17 23:43:37 2020 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' diff --git a/Misc/NEWS.d/3.8.2rc2.rst b/Misc/NEWS.d/3.8.2rc2.rst new file mode 100644 index 0000000000000..fed6ceadb28c5 --- /dev/null +++ b/Misc/NEWS.d/3.8.2rc2.rst @@ -0,0 +1,103 @@ +.. bpo: 39184 +.. date: 2020-02-07-23-54-18 +.. nonce: v-ue-v +.. release date: 2020-02-17 +.. section: Security + +Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, +`shutil`, `signal` and `syslog`. + +.. + +.. bpo: 39619 +.. date: 2020-02-13-07-35-00 +.. nonce: inb_master_chroot +.. section: Core and Builtins + +Enable use of :func:`os.chroot` on HP-UX systems. + +.. + +.. bpo: 39606 +.. date: 2020-02-11-23-59-07 +.. nonce: a72Sxc +.. section: Core and Builtins + +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. + +.. + +.. bpo: 39453 +.. date: 2020-01-25-23-51-17 +.. nonce: xCOkYk +.. section: Core and Builtins + +Fixed a possible crash in :meth:`list.__contains__` when a list is changed +during comparing items. Patch by Dong-hee Na. + +.. + +.. bpo: 39219 +.. date: 2020-01-05-13-36-08 +.. nonce: uHtKd4 +.. section: Core and Builtins + +Syntax errors raised in the tokenizer now always set correct "text" and +"offset" attributes. + +.. + +.. bpo: 27657 +.. date: 2020-02-16-07-08-54 +.. nonce: 9atgcz +.. section: Library + +The original fix for bpo-27657, "Fix urlparse() with numeric paths" +(GH-16839) included in 3.8.1, inadvertently introduced a behavior change +that broke several third-party packages relying on the original undefined +parsing behavior. The change is reverted in 3.8.2, restoring the behavior of +3.8.0 and earlier releases. + +.. + +.. bpo: 39474 +.. date: 2020-02-12-12-01-26 +.. nonce: RZMEUH +.. section: Library + +Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` +and ``(a).b``. + +.. + +.. bpo: 21016 +.. date: 2020-02-12-10-04-39 +.. nonce: bFXPH7 +.. section: Library + +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. Patch by Jan +Mat=C4=9Bjek. + +.. + +.. bpo: 39595 +.. date: 2020-02-07-23-14-14 +.. nonce: DHwddE +.. section: Library + +Improved performance of zipfile.Path for files with a large number of +entries. Also improved performance and fixed minor issue as published with +`importlib_metadata 1.5 +`_. + +.. + +.. bpo: 39600 +.. date: 2020-02-10-17-09-48 +.. nonce: X6NsyM +.. section: IDLE + +In the font configuration window, remove duplicated font names. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219= .uHtKd4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-3921= 9.uHtKd4.rst deleted file mode 100644 index dac8360df712c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Syntax errors raised in the tokenizer now always set correct "text" and -"offset" attributes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453= .xCOkYk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-3945= 3.xCOkYk.rst deleted file mode 100644 index 8c2e49f9474c4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a possible crash in :meth:`list.__contains__` when a list is changed -during comparing items. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606= .a72Sxc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-3960= 6.a72Sxc.rst deleted file mode 100644 index b7cbe4e91f59c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix regression caused by fix for bpo-39386, that prevented calling -``aclose`` on an async generator that had already been closed or exhausted. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619= .inb_master_chroot.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-= 00.bpo-39619.inb_master_chroot.rst deleted file mode 100644 index 18f32f7e804bd..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_ma= ster_chroot.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Enable use of :func:`os.chroot` on HP-UX systems. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst b= /Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst deleted file mode 100644 index 102aa75f5813e..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst +++ /dev/null @@ -1 +0,0 @@ -In the font configuration window, remove duplicated font names. diff --git a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rs= t b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst deleted file mode 100644 index 3a461389af7d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst +++ /dev/null @@ -1 +0,0 @@ -Improved performance of zipfile.Path for files with a large number of entrie= s. Also improved performance and fixed minor issue as published with `importl= ib_metadata 1.5 `_. diff --git a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rs= t b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst deleted file mode 100644 index fb91bb3825555..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` -module to get the path to the Python standard library, to support uncommon -installation path like ``/usr/lib64/python3.9/`` on Fedora. -Patch by Jan Mat=C4=9Bjek. diff --git a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rs= t b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst deleted file mode 100644 index e990f84a9dbf2..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` -and ``(a).b``. diff --git a/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rs= t b/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst deleted file mode 100644 index 50bf8b28217b1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-16-07-08-54.bpo-27657.9atgcz.rst +++ /dev/null @@ -1,5 +0,0 @@ -The original fix for bpo-27657, "Fix urlparse() with numeric paths" (GH-1683= 9) -included in 3.8.1, inadvertently introduced a behavior change that broke -several third-party packages relying on the original undefined parsing -behavior. The change is reverted in 3.8.2, restoring the behavior of 3.8.0 a= nd -earlier releases. diff --git a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.r= st b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst deleted file mode 100644 index cf25c24d58788..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst +++ /dev/null @@ -1 +0,0 @@ -Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shuti= l`, `signal` and `syslog`. \ No newline at end of file diff --git a/README.rst b/README.rst index 0b4695ce0e509..5858120b42929 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.8.2rc1 +This is Python version 3.8.2rc2 =3D=3D=3D=3D=3D=3D=3D=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=3D3.8 From webhook-mailer at python.org Sun Feb 23 21:00:45 2020 From: webhook-mailer at python.org (Hakan =?utf-8?q?=C3=87elik?=) Date: Mon, 24 Feb 2020 02:00:45 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: bpo-39654: Update pyclbr doc to reflect additional information returned (GH-18528) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/aea045adb8c90394264908670cbc495c5a41= b65e commit: aea045adb8c90394264908670cbc495c5a41b65e branch: master author: Hakan =C3=87elik committer: GitHub date: 2020-02-23T21:00:40-05:00 summary: bpo-39654: Update pyclbr doc to reflect additional information returned (GH-1= 8528) Full nested function and class info makes it a module browser. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.co= m> Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst M Doc/library/pyclbr.rst diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index b80a2faed9b42..36e83e85c2314 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -1,8 +1,8 @@ -:mod:`pyclbr` --- Python class browser support -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +:mod:`pyclbr` --- Python module browser support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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 .. module:: pyclbr - :synopsis: Supports information extraction for a Python class browser. + :synopsis: Supports information extraction for a Python module browser. =20 .. sectionauthor:: Fred L. Drake, Jr. =20 @@ -29,6 +29,9 @@ modules. *path* is a sequence of directory paths prepended to ``sys.path``, which is used to locate the module source code. =20 + This function is the original interface and is only kept for back + compatibility. It returns a filtered version of the following. + =20 .. function:: readmodule_ex(module, path=3DNone) =20 diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT= 1jI.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI= .rst new file mode 100644 index 0000000000000..cff201d812476 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst @@ -0,0 +1,2 @@ +In pyclbr doc, update 'class' to 'module' where appropriate and add readmodu= le comment. +Patch by Hakan =C3=87elik. From webhook-mailer at python.org Tue Feb 25 06:47:08 2020 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 25 Feb 2020 11:47:08 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.8.2 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/7b3ab5921fa25ed8b97b6296f97c5c78aacf= 5447 commit: 7b3ab5921fa25ed8b97b6296f97c5c78aacf5447 branch: 3.8 author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2020-02-24T22:36:25+01:00 summary: Python 3.8.2 files: A Misc/NEWS.d/3.8.2.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst D Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst D Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst D Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst D Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst D Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst D Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst D Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst D Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.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 bbdb7a2aa6a0d..3671bb35829cf 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 2 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 =20 /* Version as a string */ -#define PY_VERSION "3.8.2rc2+" +#define PY_VERSION "3.8.2" /*--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 3c1b780384570..f1fdb7fc8617c 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 Feb 17 23:43:37 2020 +# Autogenerated by Sphinx on Mon Feb 24 21:52:17 2020 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -5286,9 +5286,12 @@ 'Changed in version 3.6: Added the "\'_\'" option (see als= o ' '**PEP 515**).\n' '\n' - '*width* is a decimal integer defining the minimum field ' - 'width. If not\n' - 'specified, then the field width will be determined by the= ' + '*width* is a decimal integer defining the minimum total ' + 'field width,\n' + 'including any prefixes, separators, and other formatting ' + 'characters.\n' + 'If not specified, then the field width will be determined= ' + 'by the\n' 'content.\n' '\n' 'When no explicit alignment is given, preceding the *width= * ' @@ -9001,11 +9004,15 @@ 'come from\n' 'the class definition). The "__prepare__" method should be ' 'implemented\n' - 'as a "classmethod()".\n' + 'as a "classmethod()". The namespace returned by ' + '"__prepare__" is\n' + 'passed in to "__new__", but when the final class object is= ' + 'created the\n' + 'namespace is copied into a new "dict".\n' '\n' 'If the metaclass has no "__prepare__" attribute, then the ' 'class\n' - 'namespace is initialised as an empty ordered mapping.\n' + 'namespace is initialised as an empty "dict()".\n' '\n' 'See also:\n' '\n' diff --git a/Misc/NEWS.d/3.8.2.rst b/Misc/NEWS.d/3.8.2.rst new file mode 100644 index 0000000000000..bde681204cb0c --- /dev/null +++ b/Misc/NEWS.d/3.8.2.rst @@ -0,0 +1,97 @@ +.. bpo: 39382 +.. date: 2020-02-18-01-40-13 +.. nonce: OLSJu9 +.. release date: 2020-02-24 +.. section: Core and Builtins + +Fix a use-after-free in the single inheritance path of ``issubclass()``, +when the ``__bases__`` of an object has a single reference, and so does its +first item. Patch by Yonatan Goldschmidt. + +.. + +.. bpo: 39427 +.. date: 2020-01-22-22-28-04 +.. nonce: LiO-Eo +.. section: Core and Builtins + +Document all possibilities for the ``-X`` options in the command line help +section. Patch by Pablo Galindo. + +.. + +.. bpo: 39649 +.. date: 2020-02-23-21-27-10 +.. nonce: qiubSp +.. section: Library + +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. + +.. + +.. bpo: 39681 +.. date: 2020-02-21-13-58-40 +.. nonce: zN8hf0 +.. section: Library + +Fix a regression where the C pickle module wouldn't allow unpickling from a +file-like object that doesn't expose a readinto() method. + +.. + +.. bpo: 39546 +.. date: 2020-02-03-15-12-51 +.. nonce: _Kj0Pn +.. section: Library + +Fix a regression in :class:`~argparse.ArgumentParser` where +``allow_abbrev=3DFalse`` was ignored for long options that used a prefix +character other than "-". + +.. + +.. bpo: 39432 +.. date: 2020-01-23-16-08-58 +.. nonce: Cee6mi +.. section: Library + +Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in +distutils to make it export the correct init symbol also on Windows. + +.. + +.. bpo: 17422 +.. date: 2020-02-19-11-13-47 +.. nonce: g7_9zz +.. section: Documentation + +The language reference now specifies restrictions on class namespaces. +Adapted from a patch by Ethan Furman. + +.. + +.. bpo: 39572 +.. date: 2020-02-18-18-37-07 +.. nonce: CCtzy1 +.. section: Documentation + +Updated documentation of ``total`` flag of TypeDict. + +.. + +.. bpo: 39654 +.. date: 2020-02-18-07-42-20 +.. nonce: MoT1jI +.. section: Documentation + +In pyclbr doc, update 'class' to 'module' where appropriate and add +readmodule comment. Patch by Hakan =C3=87elik. + +.. + +.. bpo: 39663 +.. date: 2020-02-17-21-09-03 +.. nonce: wexcsH +.. section: IDLE + +Add tests for pyparse find_good_parse_start(). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427= .LiO-Eo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-3942= 7.LiO-Eo.rst deleted file mode 100644 index a3915a4d81c79..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-22-22-28-04.bpo-39427.LiO-Eo= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Document all possibilities for the ``-X`` options in the command line help -section. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382= .OLSJu9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-3938= 2.OLSJu9.rst deleted file mode 100644 index 605f4c8e5dfd1..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fix a use-after-free in the single inheritance path of ``issubclass()``, when -the ``__bases__`` of an object has a single reference, and so does its first= item. -Patch by Yonatan Goldschmidt. diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT= 1jI.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI= .rst deleted file mode 100644 index cff201d812476..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst +++ /dev/null @@ -1,2 +0,0 @@ -In pyclbr doc, update 'class' to 'module' where appropriate and add readmodu= le comment. -Patch by Hakan =C3=87elik. diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCt= zy1.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1= .rst deleted file mode 100644 index d47bb455e71d1..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst +++ /dev/null @@ -1 +0,0 @@ -Updated documentation of ``total`` flag of TypeDict. diff --git a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_= 9zz.rst b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz= .rst deleted file mode 100644 index f071d286176ae..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst +++ /dev/null @@ -1 +0,0 @@ -The language reference now specifies restrictions on class namespaces. Adap= ted from a patch by Ethan Furman. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst b= /Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst deleted file mode 100644 index 19e16329ce0a0..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for pyparse find_good_parse_start(). diff --git a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rs= t b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst deleted file mode 100644 index 21c4ba8620755..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst +++ /dev/null @@ -1 +0,0 @@ -Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in dist= utils to make it export the correct init symbol also on Windows. diff --git a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rs= t b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst deleted file mode 100644 index 8f035e79963e0..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a regression in :class:`~argparse.ArgumentParser` where -``allow_abbrev=3DFalse`` was ignored for long options that used a prefix -character other than "-". diff --git a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rs= t b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst deleted file mode 100644 index c10e2fd7a4b6d..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a regression where the C pickle module wouldn't allow unpickling from a -file-like object that doesn't expose a readinto() method. diff --git a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rs= t b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst deleted file mode 100644 index 5a88f79f05f0e..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst +++ /dev/null @@ -1 +0,0 @@ -Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. diff --git a/README.rst b/README.rst index 5858120b42929..cf74d1d8ee6b3 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.8.2rc2 -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D +This is Python version 3.8.2 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 .. image:: https://travis-ci.org/python/cpython.svg?branch=3D3.8 :alt: CPython build status on Travis CI From webhook-mailer at python.org Tue Feb 25 19:32:46 2020 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Wed, 26 Feb 2020 00:32:46 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.9.0a4 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/6e02691f300c9918ac5806dafa1f2ecef451= d733 commit: 6e02691f300c9918ac5806dafa1f2ecef451d733 branch: master author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2020-02-25T22:06:39+01:00 summary: Python 3.9.0a4 files: A Misc/NEWS.d/3.9.0a4.rst D Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst D Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst D Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst D Misc/NEWS.d/next/C API/2020-01-31-16-35-21.bpo-39511.nv9yEn.rst D Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst D Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst D Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst D Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst D Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst D Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst D Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst D Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst D Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst D Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD.rst D Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR.rst D Misc/NEWS.d/next/Core and Builtins/2019-12-03-16-41-22.bpo-38960.kvoFM0.rst D Misc/NEWS.d/next/Core and Builtins/2019-12-30-15-56-07.bpo-36051.imaVlq.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-15-15-50-22.bpo-39320.oWARyk.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqoBG.r= st D Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKROOt.r= st D Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjsfm.r= st D Misc/NEWS.d/next/Core and Builtins/2020-01-24-01-07-04.bpo-39434.S5ehj9.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F.rst D Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe1j.r= st D Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6gq.r= st D Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_master= _chroot.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M.rst D Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9.rst D Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst D Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst D Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO.rst D Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV.rst D Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst D Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst D Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst D Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst D Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst D Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst D Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst D Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst D Misc/NEWS.d/next/Library/2017-12-04-10-14-23.bpo-32173.e0C5dF.rst D Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst D Misc/NEWS.d/next/Library/2019-03-18-16-17-59.bpo-36350.udRSWE.rst D Misc/NEWS.d/next/Library/2019-09-12-12-11-05.bpo-25597.mPMzVx.rst D Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst D Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst D Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst D Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst D Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst D Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst D Misc/NEWS.d/next/Library/2020-01-25-13-41-27.bpo-38932.1pu_8I.rst D Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst D Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst D Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst D Misc/NEWS.d/next/Library/2020-01-30-09-07-16.bpo-39353.wTl9hc.rst D Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst D Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst D Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst D Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst D Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst D Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst D Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst D Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst D Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst D Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst D Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst D Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst D Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst D Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst D Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst D Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst D Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst D Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst D Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst D Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst D Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst D Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst D Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst D Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst D Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst D Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst D Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst D Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst D Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst D Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rst D Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.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 a62e175d96651..5a1de0a8962ff 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 3 +#define PY_RELEASE_SERIAL 4 =20 /* Version as a string */ -#define PY_VERSION "3.9.0a3+" +#define PY_VERSION "3.9.0a4" /*--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 fd91446587239..c6ba945425a77 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Fri Jan 24 22:03:37 2020 +# Autogenerated by Sphinx on Tue Feb 25 13:20:31 2020 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -5291,9 +5291,12 @@ 'Changed in version 3.6: Added the "\'_\'" option (see als= o ' '**PEP 515**).\n' '\n' - '*width* is a decimal integer defining the minimum field ' - 'width. If not\n' - 'specified, then the field width will be determined by the= ' + '*width* is a decimal integer defining the minimum total ' + 'field width,\n' + 'including any prefixes, separators, and other formatting ' + 'characters.\n' + 'If not specified, then the field width will be determined= ' + 'by the\n' 'content.\n' '\n' 'When no explicit alignment is given, preceding the *width= * ' @@ -9005,11 +9008,17 @@ 'bases,\n' '**kwds)" (where the additional keyword arguments, if any, ' 'come from\n' - 'the class definition).\n' + 'the class definition). The "__prepare__" method should be ' + 'implemented\n' + 'as a "classmethod()". The namespace returned by ' + '"__prepare__" is\n' + 'passed in to "__new__", but when the final class object is= ' + 'created the\n' + 'namespace is copied into a new "dict".\n' '\n' 'If the metaclass has no "__prepare__" attribute, then the ' 'class\n' - 'namespace is initialised as an empty ordered mapping.\n' + 'namespace is initialised as an empty "dict()".\n' '\n' 'See also:\n' '\n' diff --git a/Misc/NEWS.d/3.9.0a4.rst b/Misc/NEWS.d/3.9.0a4.rst new file mode 100644 index 0000000000000..e91135deb6654 --- /dev/null +++ b/Misc/NEWS.d/3.9.0a4.rst @@ -0,0 +1,949 @@ +.. bpo: 39184 +.. date: 2020-02-07-23-54-18 +.. nonce: v-ue-v +.. release date: 2020-02-25 +.. section: Security + +Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, +`shutil`, `signal` and `syslog`. + +.. + +.. bpo: 39401 +.. date: 2020-01-28-20-54-09 +.. nonce: he7h_A +.. section: Security + +Avoid unsafe DLL load at startup on Windows 7 and earlier. + +.. + +.. bpo: 39184 +.. date: 2020-01-07-00-42-08 +.. nonce: fe7NgK +.. section: Security + +Add audit events to command execution functions in os and pty modules. + +.. + +.. bpo: 39382 +.. date: 2020-02-18-01-40-13 +.. nonce: OLSJu9 +.. section: Core and Builtins + +Fix a use-after-free in the single inheritance path of ``issubclass()``, +when the ``__bases__`` of an object has a single reference, and so does its +first item. Patch by Yonatan Goldschmidt. + +.. + +.. bpo: 39573 +.. date: 2020-02-14-10-08-53 +.. nonce: BIIX2M +.. section: Core and Builtins + +Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Dong-hee Na. + +.. + +.. bpo: 39619 +.. date: 2020-02-13-07-35-00 +.. nonce: inb_master_chroot +.. section: Core and Builtins + +Enable use of :func:`os.chroot` on HP-UX systems. + +.. + +.. bpo: 39573 +.. date: 2020-02-13-01-30-22 +.. nonce: uTFj1m +.. section: Core and Builtins + +Add :c:func:`Py_IS_TYPE` static inline function to check whether the object +*o* type is *type*. + +.. + +.. bpo: 39606 +.. date: 2020-02-11-23-59-07 +.. nonce: a72Sxc +.. section: Core and Builtins + +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. + +.. + +.. bpo: 39579 +.. date: 2020-02-07-15-18-35 +.. nonce: itNmC0 +.. section: Core and Builtins + +Change the ending column offset of `Attribute` nodes constructed in +`ast_for_dotted_name` to point at the end of the current node and not at the +end of the last `NAME` node. + +.. + +.. bpo: 1635741 +.. date: 2020-02-07-12-57-40 +.. nonce: ySW6gq +.. section: Core and Builtins + +Port _crypt extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-02-06-09-00-35 +.. nonce: oaxe1j +.. section: Core and Builtins + +Port _contextvars extension module to multiphase initialization +(:pep:`489`). + +.. + +.. bpo: 39510 +.. date: 2020-02-04-10-27-41 +.. nonce: PMIh-f +.. section: Core and Builtins + +Fix segfault in ``readinto()`` method on closed BufferedReader. + +.. + +.. bpo: 39502 +.. date: 2020-01-30-14-36-31 +.. nonce: IJu0rl +.. section: Core and Builtins + +Fix :func:`time.localtime` on 64-bit AIX to support years before 1902 and +after 2038. Patch by M Felt. + +.. + +.. bpo: 39492 +.. date: 2020-01-30-01-14-42 +.. nonce: eTuy0F +.. section: Core and Builtins + +Fix a reference cycle in the C Pickler that was preventing the garbage +collection of deleted, pickled objects. + +.. + +.. bpo: 39453 +.. date: 2020-01-25-23-51-17 +.. nonce: xCOkYk +.. section: Core and Builtins + +Fixed a possible crash in :meth:`list.__contains__` when a list is changed +during comparing items. Patch by Dong-hee Na. + +.. + +.. bpo: 39434 +.. date: 2020-01-24-01-07-04 +.. nonce: S5ehj9 +.. section: Core and Builtins + +:term:`floor division` of float operation now has a better performance. Also +the message of :exc:`ZeroDivisionError` for this operation is updated. Patch +by Dong-hee Na. + +.. + +.. bpo: 1635741 +.. date: 2020-01-19-11-06-30 +.. nonce: 0mjsfm +.. section: Core and Builtins + +Port _codecs extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-01-18-11-06-28 +.. nonce: OKROOt +.. section: Core and Builtins + +Port _bz2 extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-01-16-12-00-04 +.. nonce: fuqoBG +.. section: Core and Builtins + +Port _abc extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39320 +.. date: 2020-01-15-15-50-22 +.. nonce: oWARyk +.. section: Core and Builtins + +Replace two complex bytecodes for building dicts with two simpler ones. The +new bytecodes ``DICT_MERGE`` and ``DICT_UPDATE`` have been added The old +bytecodes ``BUILD_MAP_UNPACK`` and ``BUILD_MAP_UNPACK_WITH_CALL`` have been +removed. + +.. + +.. bpo: 39219 +.. date: 2020-01-05-13-36-08 +.. nonce: uHtKd4 +.. section: Core and Builtins + +Syntax errors raised in the tokenizer now always set correct "text" and +"offset" attributes. + +.. + +.. bpo: 36051 +.. date: 2019-12-30-15-56-07 +.. nonce: imaVlq +.. section: Core and Builtins + +Drop the GIL during large ``bytes.join`` operations. Patch by Bruce Merry. + +.. + +.. bpo: 38960 +.. date: 2019-12-03-16-41-22 +.. nonce: kvoFM0 +.. section: Core and Builtins + +Fix DTrace build issues on FreeBSD. Patch by David Carlier. + +.. + +.. bpo: 37207 +.. date: 2019-06-09-10-54-31 +.. nonce: bLjgLR +.. section: Core and Builtins + +Speed up calls to ``range()`` by about 30%, by using the PEP 590 +``vectorcall`` calling convention. Patch by Mark Shannon. + +.. + +.. bpo: 36144 +.. date: 2019-03-02-23-03-34 +.. nonce: LRl4LS +.. section: Core and Builtins + +:class:`dict` (and :class:`collections.UserDict`) objects now support PEP +584's merge (``|``) and update (``|=3D``) operators. Patch by Brandt Bucher. + +.. + +.. bpo: 32856 +.. date: 2018-02-16-10-44-24 +.. nonce: UjR8SD +.. section: Core and Builtins + +Optimized the idiom for assignment a temporary variable in comprehensions. +Now ``for y in [expr]`` in comprehensions is as fast as a simple assignment +``y =3D expr``. + +.. + +.. bpo: 30566 +.. date: 2020-02-24-03-45-28 +.. nonce: qROxty +.. section: Library + +Fix :exc:`IndexError` when trying to decode an invalid string with punycode +codec. + +.. + +.. bpo: 39649 +.. date: 2020-02-23-21-27-10 +.. nonce: qiubSp +.. section: Library + +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. + +.. + +.. bpo: 39648 +.. date: 2020-02-22-12-49-04 +.. nonce: Y-9N7F +.. section: Library + +Expanded :func:`math.gcd` and :func:`math.lcm` to handle multiple arguments. + +.. + +.. bpo: 39681 +.. date: 2020-02-21-13-58-40 +.. nonce: zN8hf0 +.. section: Library + +Fix a regression where the C pickle module wouldn't allow unpickling from a +file-like object that doesn't expose a readinto() method. + +.. + +.. bpo: 35950 +.. date: 2020-02-21-02-42-41 +.. nonce: 9G3-wl +.. section: Library + +Raise :exc:`io.UnsupportedOperation` in :meth:`io.BufferedReader.truncate` +when it is called on a read-only :class:`io.BufferedReader` instance. + +.. + +.. bpo: 39479 +.. date: 2020-02-18-12-37-16 +.. nonce: j3UcCq +.. section: Library + +Add :func:`math.lcm` function: least common multiple. + +.. + +.. bpo: 39674 +.. date: 2020-02-18-12-31-24 +.. nonce: S_zqVM +.. section: Library + +Revert "Do not expose abstract collection classes in the collections module" +change (bpo-25988). Aliases to ABC like collections.Mapping are kept in +Python 3.9 to ease transition from Python 2.7, but will be removed in Python +3.10. + +.. + +.. bpo: 39104 +.. date: 2020-02-16-18-49-16 +.. nonce: cI5MJY +.. section: Library + +Fix hanging ProcessPoolExcutor on ``shutdown(wait=3DFalse)`` when a task has +failed pickling. + +.. + +.. bpo: 39627 +.. date: 2020-02-13-18-14-15 +.. nonce: Q0scyQ +.. section: Library + +Fixed TypedDict totality check for inherited keys. + +.. + +.. bpo: 39474 +.. date: 2020-02-12-12-01-26 +.. nonce: RZMEUH +.. section: Library + +Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` +and ``(a).b``. + +.. + +.. bpo: 21016 +.. date: 2020-02-12-10-04-39 +.. nonce: bFXPH7 +.. section: Library + +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. Patch by Jan +Mat=C4=9Bjek. + +.. + +.. bpo: 39590 +.. date: 2020-02-09-05-51-05 +.. nonce: rf98GU +.. section: Library + +Collections.deque now holds strong references during deque.__contains__ and +deque.count, fixing crashes. + +.. + +.. bpo: 39586 +.. date: 2020-02-08-13-37-00 +.. nonce: nfTPxX +.. section: Library + +The distutils ``bdist_msi`` command is deprecated in Python 3.9, use +``bdist_wheel`` (wheel packages) instead. + +.. + +.. bpo: 39595 +.. date: 2020-02-07-23-14-14 +.. nonce: DHwddE +.. section: Library + +Improved performance of zipfile.Path for files with a large number of +entries. Also improved performance and fixed minor issue as published with +`importlib_metadata 1.5 +`_. + +.. + +.. bpo: 39350 +.. date: 2020-02-06-13-34-52 +.. nonce: wRwup1 +.. section: Library + +Fix regression in :class:`fractions.Fraction` if the numerator and/or the +denominator is an :class:`int` subclass. The :func:`math.gcd` function is +now used to normalize the *numerator* and *denominator*. :func:`math.gcd` +always return a :class:`int` type. Previously, the GCD type depended on +*numerator* and *denominator*. + +.. + +.. bpo: 39567 +.. date: 2020-02-06-10-23-32 +.. nonce: VpFBxt +.. section: Library + +Added audit for :func:`os.walk`, :func:`os.fwalk`, :meth:`pathlib.Path.glob` +and :meth:`pathlib.Path.rglob`. + +.. + +.. bpo: 39559 +.. date: 2020-02-05-18-29-14 +.. nonce: L8i5YB +.. section: Library + +Remove unused, undocumented argument ``getters`` from :func:`uuid.getnode` + +.. + +.. bpo: 38149 +.. date: 2020-02-05-11-24-16 +.. nonce: GWsjHE +.. section: Library + +:func:`sys.audit` is now called only once per call of :func:`glob.glob` and +:func:`glob.iglob`. + +.. + +.. bpo: 39546 +.. date: 2020-02-03-15-12-51 +.. nonce: _Kj0Pn +.. section: Library + +Fix a regression in :class:`~argparse.ArgumentParser` where +``allow_abbrev=3DFalse`` was ignored for long options that used a prefix +character other than "-". + +.. + +.. bpo: 39450 +.. date: 2020-02-02-14-46-34 +.. nonce: 48R274 +.. section: Library + +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. + +.. + +.. bpo: 12915 +.. date: 2020-02-02-10-08-25 +.. nonce: d6r50- +.. section: Library + +A new function ``resolve_name`` has been added to the ``pkgutil`` module. +This resolves a string of the form ``'a.b.c.d'`` or ``'a.b:c.d'`` to an +object. In the example, ``a.b`` is a package/module and ``c.d`` is an object +within that package/module reached via recursive attribute access. + +.. + +.. bpo: 39353 +.. date: 2020-01-30-09-07-16 +.. nonce: wTl9hc +.. section: Library + +The :func:`binascii.crc_hqx` function is no longer deprecated. + +.. + +.. bpo: 39493 +.. date: 2020-01-30-01-13-19 +.. nonce: CbFRi7 +.. section: Library + +Mark ``typing.IO.closed`` as a property + +.. + +.. bpo: 39491 +.. date: 2020-01-29-22-47-12 +.. nonce: tdl17b +.. section: Library + +Add :data:`typing.Annotated` and ``include_extras`` parameter to +:func:`typing.get_type_hints` as part of :pep:`593`. Patch by Till +Varoquaux, documentation by Till Varoquaux and Konstantin Kashin. + +.. + +.. bpo: 39485 +.. date: 2020-01-29-14-58-27 +.. nonce: Zy3ot6 +.. section: Library + +Fix a bug in :func:`unittest.mock.create_autospec` that would complain about +the wrong number of arguments for custom descriptors defined in an extension +module returning functions. + +.. + +.. bpo: 38932 +.. date: 2020-01-25-13-41-27 +.. nonce: 1pu_8I +.. section: Library + +Mock fully resets child objects on reset_mock(). Patch by Vegard Stikbakke + +.. + +.. bpo: 39082 +.. date: 2020-01-24-13-24-35 +.. nonce: qKgrq_ +.. section: Library + +Allow AsyncMock to correctly patch static/class methods + +.. + +.. bpo: 39432 +.. date: 2020-01-23-16-08-58 +.. nonce: Cee6mi +.. section: Library + +Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in +distutils to make it export the correct init symbol also on Windows. + +.. + +.. bpo: 18819 +.. date: 2020-01-20-10-06-19 +.. nonce: H4qsoS +.. section: Library + +Omit ``devmajor`` and ``devminor`` fields for non-device files in +:mod:`tarfile` archives, enabling bit-for-bit compatibility with GNU +``tar(1)``. + +.. + +.. bpo: 39349 +.. date: 2020-01-19-04-12-34 +.. nonce: 7CV-LC +.. section: Library + +Added a new *cancel_futures* parameter to +:meth:`concurrent.futures.Executor.shutdown` that cancels all pending +futures which have not started running, instead of waiting for them to +complete before shutting down the executor. + +.. + +.. bpo: 39274 +.. date: 2020-01-15-23-13-03 +.. nonce: lpc0-n +.. section: Library + +``bool(fraction.Fraction)`` now returns a boolean even if (numerator !=3D 0) +does not return a boolean (ex: numpy number). + +.. + +.. bpo: 34793 +.. date: 2019-12-09-17-24-29 +.. nonce: D82Dyu +.. section: Library + +Remove support for ``with (await asyncio.lock):`` and ``with (yield from +asyncio.lock):``. The same is correct for ``asyncio.Condition`` and +``asyncio.Semaphore``. + +.. + +.. bpo: 25597 +.. date: 2019-09-12-12-11-05 +.. nonce: mPMzVx +.. section: Library + +Ensure, if ``wraps`` is supplied to :class:`unittest.mock.MagicMock`, it is +used to calculate return values for the magic methods instead of using the +default return values. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36350 +.. date: 2019-03-18-16-17-59 +.. nonce: udRSWE +.. section: Library + +`inspect.Signature.parameters` and `inspect.BoundArguments.arguments` are +now dicts instead of OrderedDicts. Patch contributed by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 35727 +.. date: 2019-01-12-20-39-34 +.. nonce: FWrbHn +.. section: Library + +Fix sys.exit() and sys.exit(None) exit code propagation when used in +multiprocessing.Process. + +.. + +.. bpo: 32173 +.. date: 2017-12-04-10-14-23 +.. nonce: e0C5dF +.. section: Library + +* Add `lazycache` function to `__all__`. +* Use `dict.clear` to clear the cache. +* Refactoring `getline` function and `checkcache` function. + +.. + +.. bpo: 17422 +.. date: 2020-02-19-11-13-47 +.. nonce: g7_9zz +.. section: Documentation + +The language reference now specifies restrictions on class namespaces. +Adapted from a patch by Ethan Furman. + +.. + +.. bpo: 39572 +.. date: 2020-02-18-18-37-07 +.. nonce: CCtzy1 +.. section: Documentation + +Updated documentation of ``total`` flag of TypeDict. + +.. + +.. bpo: 39654 +.. date: 2020-02-18-07-42-20 +.. nonce: MoT1jI +.. section: Documentation + +In pyclbr doc, update 'class' to 'module' where appropriate and add +readmodule comment. Patch by Hakan =C3=87elik. + +.. + +.. bpo: 39153 +.. date: 2020-01-27-22-24-51 +.. nonce: Pjl8jV +.. section: Documentation + +Clarify refcounting semantics for the following functions: - +PyObject_SetItem - PyMapping_SetItemString - PyDict_SetItem - +PyDict_SetItemString + +.. + +.. bpo: 39392 +.. date: 2020-01-27-18-18-42 +.. nonce: oiqcLO +.. section: Documentation + +Explain that when filling with turtle, overlap regions may be left unfilled. + +.. + +.. bpo: 39369 +.. date: 2020-01-17-13-59-21 +.. nonce: Bx5yE3 +.. section: Documentation + +Update mmap readline method description. The fact that the readline method +does update the file position should not be ignored since this might give +the impression for the programmer that it doesn't update it. + +.. + +.. bpo: 9056 +.. date: 2018-09-28-18-13-08 +.. nonce: -sFOwU +.. section: Documentation + +Include subsection in TOC for PDF version of docs. + +.. + +.. bpo: 38325 +.. date: 2020-02-11-00-38-32 +.. nonce: HgmfoE +.. section: Tests + +Skip tests on non-BMP characters of test_winconsoleio. + +.. + +.. bpo: 39502 +.. date: 2020-01-30-15-04-54 +.. nonce: chbpII +.. section: Tests + +Skip test_zipfile.test_add_file_after_2107() if :func:`time.localtime` fails +with :exc:`OverflowError`. It is the case on AIX 6.1 for example. + +.. + +.. bpo: 39489 +.. date: 2020-01-29-19-17-02 +.. nonce: HKPzv- +.. section: Build + +Remove ``COUNT_ALLOCS`` special build. + +.. + +.. bpo: 39553 +.. date: 2020-02-04-19-50-53 +.. nonce: _EnweA +.. section: Windows + +Delete unused code related to SxS manifests. + +.. + +.. bpo: 39439 +.. date: 2020-01-24-03-15-05 +.. nonce: sFxGfR +.. section: Windows + +Honor the Python path when a virtualenv is active on Windows. + +.. + +.. bpo: 39393 +.. date: 2020-01-20-23-42-53 +.. nonce: gWlJDG +.. section: Windows + +Improve the error message when attempting to load a DLL with unresolved +dependencies. + +.. + +.. bpo: 38883 +.. date: 2020-01-11-22-53-55 +.. nonce: X7FRaN +.. section: Windows + +:meth:`~pathlib.Path.home()` and :meth:`~pathlib.Path.expanduser()` on +Windows now prefer :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, +which is not normally set for regular user accounts. This makes them again +behave like :func:`os.path.expanduser`, which was changed to ignore +:envvar:`HOME` in 3.8, see :issue:`36264`. + +.. + +.. bpo: 39185 +.. date: 2020-01-02-01-11-53 +.. nonce: T4herN +.. section: Windows + +The build.bat script has additional options for very-quiet output (-q) and +very-verbose output (-vv) + +.. + +.. bpo: 39663 +.. date: 2020-02-17-21-09-03 +.. nonce: wexcsH +.. section: IDLE + +Add tests for pyparse find_good_parse_start(). + +.. + +.. bpo: 39600 +.. date: 2020-02-10-17-09-48 +.. nonce: X6NsyM +.. section: IDLE + +In the font configuration window, remove duplicated font names. + +.. + +.. bpo: 30780 +.. date: 2020-01-27-16-44-29 +.. nonce: nR80qu +.. section: IDLE + +Add remaining configdialog tests for buttons and highlights and keys tabs. + +.. + +.. bpo: 39388 +.. date: 2020-01-25-02-26-45 +.. nonce: x4TQNh +.. section: IDLE + +IDLE Settings Cancel button now cancels pending changes + +.. + +.. bpo: 38792 +.. date: 2019-11-13-23-51-39 +.. nonce: xhTC5a +.. section: IDLE + +Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` or shell restart +occurs. Patch by Zackery Spytz. + +.. + +.. bpo: 35081 +.. date: 2020-02-12-21-38-49 +.. nonce: 5tj1yC +.. section: C API + +Move the ``bytes_methods.h`` header file to the internal C API as +``pycore_bytes_methods.h``: it only contains private symbols (prefixed by +``_Py``), except of the ``PyDoc_STRVAR_shared()`` macro. + +.. + +.. bpo: 35081 +.. date: 2020-02-12-21-24-02 +.. nonce: at7BjN +.. section: C API + +Move the ``dtoa.h`` header file to the internal C API as ``pycore_dtoa.h``: +it only contains private functions (prefixed by ``_Py``). The :mod:`math` +and :mod:`cmath` modules must now be compiled with the ``Py_BUILD_CORE`` +macro defined. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-10-41-53 +.. nonce: EG9VDI +.. section: C API + +Add :c:func:`Py_SET_SIZE` function to set the size of an object. + +.. + +.. bpo: 39500 +.. date: 2020-02-07-09-35-43 +.. nonce: xRAEgX +.. section: C API + +:c:func:`PyUnicode_IsIdentifier` does not call :c:func:`Py_FatalError` +anymore if the string is not ready. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-03-39-03 +.. nonce: Oa8cL1 +.. section: C API + +Add :c:func:`Py_SET_TYPE` function to set the type of an object. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-00-23-44 +.. nonce: nRD1q7 +.. section: C API + +Add a :c:func:`Py_SET_REFCNT` function to set the reference counter of an +object. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-13-14-20 +.. nonce: 5mleGX +.. section: C API + +Convert :c:func:`PyType_HasFeature`, :c:func:`PyType_Check` and +:c:func:`PyType_CheckExact` macros to static inline functions. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-12-40-51 +.. nonce: si-_Zq +.. section: C API + +In the limited C API, ``PyObject_INIT()`` and ``PyObject_INIT_VAR()`` are +now defined as aliases to :c:func:`PyObject_Init` and +:c:func:`PyObject_InitVar` to make their implementation opaque. It avoids to +leak implementation details in the limited C API. Exclude the following +functions from the limited C API: ``_Py_NewReference()``, +``_Py_ForgetReference()``, ``_PyTraceMalloc_NewReference()`` and +``_Py_GetRefTotal()``. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-12-00-18 +.. nonce: RJCUKR +.. section: C API + +Exclude trashcan mechanism from the limited C API: it requires access to +PyTypeObject and PyThreadState structure fields, whereas these structures +are opaque in the limited C API. + +.. + +.. bpo: 39511 +.. date: 2020-01-31-16-35-21 +.. nonce: nv9yEn +.. section: C API + +The :c:func:`PyThreadState_Clear` function now calls the +:c:member:`PyThreadState.on_delete` callback. Previously, that happened in +:c:func:`PyThreadState_Delete`. + +.. + +.. bpo: 38076 +.. date: 2020-01-17-11-37-05 +.. nonce: cxfw2x +.. section: C API + +Fix to clear the interpreter state only after clearing module globals to +guarantee module state access from C Extensions during runtime destruction + +.. + +.. bpo: 39245 +.. date: 2020-01-07-13-46-40 +.. nonce: G7wog6 +.. section: C API + +The Vectorcall API (PEP 590) was made public, adding the functions +``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``, +``PyVectorcall_Function``, ``PyObject_CallOneArg``, +``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``, +``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``. diff --git a/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst = b/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst deleted file mode 100644 index 652a4356e227f..0000000000000 --- a/Misc/NEWS.d/next/Build/2020-01-29-19-17-02.bpo-39489.HKPzv-.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``COUNT_ALLOCS`` special build. diff --git a/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst = b/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst deleted file mode 100644 index e5836b5255d3d..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-01-07-13-46-40.bpo-39245.G7wog6.rst=09 +++ /dev/null @@ -1,5 +0,0 @@ -The Vectorcall API (PEP 590) was made public, adding the functions -``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``, -``PyVectorcall_Function``, ``PyObject_CallOneArg``, -``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``, -``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``. diff --git a/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst = b/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst deleted file mode 100644 index d9f6dc31efd8d..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix to clear the interpreter state only after clearing module globals to -guarantee module state access from C Extensions during runtime destruction diff --git a/Misc/NEWS.d/next/C API/2020-01-31-16-35-21.bpo-39511.nv9yEn.rst = b/Misc/NEWS.d/next/C API/2020-01-31-16-35-21.bpo-39511.nv9yEn.rst deleted file mode 100644 index 14a04875a8894..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-01-31-16-35-21.bpo-39511.nv9yEn.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The :c:func:`PyThreadState_Clear` function now calls the -:c:member:`PyThreadState.on_delete` callback. Previously, that happened in -:c:func:`PyThreadState_Delete`. diff --git a/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst = b/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst deleted file mode 100644 index 5829d6e97480e..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-05-12-00-18.bpo-39542.RJCUKR.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Exclude trashcan mechanism from the limited C API: it requires access to -PyTypeObject and PyThreadState structure fields, whereas these structures -are opaque in the limited C API. diff --git a/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst = b/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst deleted file mode 100644 index 7473577b0a943..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-05-12-40-51.bpo-39542.si-_Zq.rst=09 +++ /dev/null @@ -1,7 +0,0 @@ -In the limited C API, ``PyObject_INIT()`` and ``PyObject_INIT_VAR()`` are -now defined as aliases to :c:func:`PyObject_Init` and -:c:func:`PyObject_InitVar` to make their implementation opaque. It avoids to -leak implementation details in the limited C API. Exclude the following -functions from the limited C API: ``_Py_NewReference()``, -``_Py_ForgetReference()``, ``_PyTraceMalloc_NewReference()`` and -``_Py_GetRefTotal()``. diff --git a/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst = b/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst deleted file mode 100644 index 46fb1d257e8e9..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-05-13-14-20.bpo-39542.5mleGX.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Convert :c:func:`PyType_HasFeature`, :c:func:`PyType_Check` and -:c:func:`PyType_CheckExact` macros to static inline functions. diff --git a/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst = b/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst deleted file mode 100644 index 310933a6d4076..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-07-00-23-44.bpo-39573.nRD1q7.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add a :c:func:`Py_SET_REFCNT` function to set the reference counter of an -object. diff --git a/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst = b/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst deleted file mode 100644 index 22d3d693ac0c9..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-07-03-39-03.bpo-39573.Oa8cL1.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`Py_SET_TYPE` function to set the type of an object. diff --git a/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst = b/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst deleted file mode 100644 index 2ca359f0ec11a..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-07-09-35-43.bpo-39500.xRAEgX.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`PyUnicode_IsIdentifier` does not call :c:func:`Py_FatalError` -anymore if the string is not ready. diff --git a/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst = b/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst deleted file mode 100644 index d84cddc57636b..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-07-10-41-53.bpo-39573.EG9VDI.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`Py_SET_SIZE` function to set the size of an object. diff --git a/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst = b/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst deleted file mode 100644 index 94e6ae7e42cc8..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-12-21-24-02.bpo-35081.at7BjN.rst=09 +++ /dev/null @@ -1,5 +0,0 @@ -Move the ``dtoa.h`` header file to the internal C API as ``pycore_dtoa.h``: -it only contains private functions (prefixed by ``_Py``). The :mod:`math` and -:mod:`cmath` modules must now be compiled with the ``Py_BUILD_CORE`` macro -defined. - diff --git a/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst = b/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst deleted file mode 100644 index 6be33200d9e2b..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-12-21-38-49.bpo-35081.5tj1yC.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Move the ``bytes_methods.h`` header file to the internal C API as -``pycore_bytes_methods.h``: it only contains private symbols (prefixed by -``_Py``), except of the ``PyDoc_STRVAR_shared()`` macro. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856= .UjR8SD.rst b/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-3285= 6.UjR8SD.rst deleted file mode 100644 index c1cd68f672712..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-02-16-10-44-24.bpo-32856.UjR8SD= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Optimized the idiom for assignment a temporary variable in comprehensions. -Now ``for y in [expr]`` in comprehensions is as fast as a simple assignment -``y =3D expr``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144= .LRl4LS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-3614= 4.LRl4LS.rst deleted file mode 100644 index 7d6d076ea7d4d..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-02-23-03-34.bpo-36144.LRl4LS= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -:class:`dict` (and :class:`collections.UserDict`) objects now support PEP 58= 4's merge (``|``) and update (``|=3D``) operators. -Patch by Brandt Bucher. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207= .bLjgLR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-3720= 7.bLjgLR.rst deleted file mode 100644 index c20d48a493c34..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLR= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Speed up calls to ``range()`` by about 30%, by using the -PEP 590 ``vectorcall`` calling convention. Patch by Mark Shannon. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-03-16-41-22.bpo-38960= .kvoFM0.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-03-16-41-22.bpo-3896= 0.kvoFM0.rst deleted file mode 100644 index 50d4b6c286843..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-12-03-16-41-22.bpo-38960.kvoFM0= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix DTrace build issues on FreeBSD. Patch by David Carlier. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-30-15-56-07.bpo-36051= .imaVlq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-30-15-56-07.bpo-3605= 1.imaVlq.rst deleted file mode 100644 index f9d449216ebed..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-12-30-15-56-07.bpo-36051.imaVlq= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Drop the GIL during large ``bytes.join`` operations. Patch by Bruce Merry. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219= .uHtKd4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-3921= 9.uHtKd4.rst deleted file mode 100644 index dac8360df712c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-13-36-08.bpo-39219.uHtKd4= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Syntax errors raised in the tokenizer now always set correct "text" and -"offset" attributes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-15-15-50-22.bpo-39320= .oWARyk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-15-15-50-22.bpo-3932= 0.oWARyk.rst deleted file mode 100644 index 9508574f6c0f4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-15-15-50-22.bpo-39320.oWARyk= .rst=09 +++ /dev/null @@ -1,4 +0,0 @@ - -Replace two complex bytecodes for building dicts with two simpler ones. -The new bytecodes ``DICT_MERGE`` and ``DICT_UPDATE`` have been added -The old bytecodes ``BUILD_MAP_UNPACK`` and ``BUILD_MAP_UNPACK_WITH_CALL`` ha= ve been removed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-16357= 41.fuqoBG.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-16= 35741.fuqoBG.rst deleted file mode 100644 index 4dd37a65b0e99..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-16-12-00-04.bpo-1635741.fuqo= BG.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Port _abc extension module to multiphase initialization (:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-16357= 41.OKROOt.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-16= 35741.OKROOt.rst deleted file mode 100644 index d3f12a747963a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-18-11-06-28.bpo-1635741.OKRO= Ot.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Port _bz2 extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-16357= 41.0mjsfm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-16= 35741.0mjsfm.rst deleted file mode 100644 index 10fc23bcfa117..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-19-11-06-30.bpo-1635741.0mjs= fm.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Port _codecs extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-24-01-07-04.bpo-39434= .S5ehj9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-24-01-07-04.bpo-3943= 4.S5ehj9.rst deleted file mode 100644 index e5a413323ac43..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-24-01-07-04.bpo-39434.S5ehj9= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -:term:`floor division` of float operation now has a better performance. Also -the message of :exc:`ZeroDivisionError` for this operation is updated. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453= .xCOkYk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-3945= 3.xCOkYk.rst deleted file mode 100644 index 8c2e49f9474c4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-25-23-51-17.bpo-39453.xCOkYk= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a possible crash in :meth:`list.__contains__` when a list is changed -during comparing items. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492= .eTuy0F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-3949= 2.eTuy0F.rst deleted file mode 100644 index 6e8b715c46365..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-01-14-42.bpo-39492.eTuy0F= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix a reference cycle in the C Pickler that was preventing the garbage colle= ction of deleted, pickled objects. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502= .IJu0rl.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-3950= 2.IJu0rl.rst deleted file mode 100644 index 93b3639c80c5b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-01-30-14-36-31.bpo-39502.IJu0rl= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`time.localtime` on 64-bit AIX to support years before 1902 and a= fter 2038. -Patch by M Felt. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510= .PMIh-f.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-3951= 0.PMIh-f.rst deleted file mode 100644 index 9a38e4ab76228..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-04-10-27-41.bpo-39510.PMIh-f= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix segfault in ``readinto()`` method on closed BufferedReader. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-16357= 41.oaxe1j.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-16= 35741.oaxe1j.rst deleted file mode 100644 index 49336f02a3e40..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-06-09-00-35.bpo-1635741.oaxe= 1j.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Port _contextvars extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-16357= 41.ySW6gq.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-16= 35741.ySW6gq.rst deleted file mode 100644 index 6b35bdc474fbe..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-12-57-40.bpo-1635741.ySW6= gq.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Port _crypt extension module to multiphase initialization (:pep:`489`). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579= .itNmC0.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-3957= 9.itNmC0.rst deleted file mode 100644 index 36d5c425670c2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-07-15-18-35.bpo-39579.itNmC0= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Change the ending column offset of `Attribute` nodes constructed in `ast_for= _dotted_name` to point at the end of the current node and not at the end of t= he last `NAME` node. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606= .a72Sxc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-3960= 6.a72Sxc.rst deleted file mode 100644 index b7cbe4e91f59c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-11-23-59-07.bpo-39606.a72Sxc= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix regression caused by fix for bpo-39386, that prevented calling -``aclose`` on an async generator that had already been closed or exhausted. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573= .uTFj1m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-3957= 3.uTFj1m.rst deleted file mode 100644 index 56e7e1ba3242c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-01-30-22.bpo-39573.uTFj1m= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`Py_IS_TYPE` static inline function to check -whether the object *o* type is *type*. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619= .inb_master_chroot.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-= 00.bpo-39619.inb_master_chroot.rst deleted file mode 100644 index 18f32f7e804bd..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-13-07-35-00.bpo-39619.inb_ma= ster_chroot.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Enable use of :func:`os.chroot` on HP-UX systems. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573= .BIIX2M.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-3957= 3.BIIX2M.rst deleted file mode 100644 index 23396d3bd2b73..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-14-10-08-53.bpo-39573.BIIX2M= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382= .OLSJu9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-3938= 2.OLSJu9.rst deleted file mode 100644 index 605f4c8e5dfd1..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-02-18-01-40-13.bpo-39382.OLSJu9= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fix a use-after-free in the single inheritance path of ``issubclass()``, when -the ``__bases__`` of an object has a single reference, and so does its first= item. -Patch by Yonatan Goldschmidt. diff --git a/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFO= wU.rst b/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.r= st deleted file mode 100644 index 98e1c286e8613..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-09-28-18-13-08.bpo-9056.-sFOwU.rst +++ /dev/null @@ -1 +0,0 @@ -Include subsection in TOC for PDF version of docs. diff --git a/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5= yE3.rst b/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3= .rst deleted file mode 100644 index 7f41735b9d3e3..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-17-13-59-21.bpo-39369.Bx5yE3.rst +++ /dev/null @@ -1 +0,0 @@ -Update mmap readline method description. The fact that the readline method d= oes update the file position should not be ignored since this might give the = impression for the programmer that it doesn't update it. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiq= cLO.rst b/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO= .rst deleted file mode 100644 index 715874981f735..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-27-18-18-42.bpo-39392.oiqcLO.rst +++ /dev/null @@ -1 +0,0 @@ -Explain that when filling with turtle, overlap regions may be left unfilled. diff --git a/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl= 8jV.rst b/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV= .rst deleted file mode 100644 index 95be00b4b777f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-01-27-22-24-51.bpo-39153.Pjl8jV.rst +++ /dev/null @@ -1,5 +0,0 @@ -Clarify refcounting semantics for the following functions: -- PyObject_SetItem -- PyMapping_SetItemString -- PyDict_SetItem -- PyDict_SetItemString \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT= 1jI.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI= .rst deleted file mode 100644 index cff201d812476..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-18-07-42-20.bpo-39654.MoT1jI.rst +++ /dev/null @@ -1,2 +0,0 @@ -In pyclbr doc, update 'class' to 'module' where appropriate and add readmodu= le comment. -Patch by Hakan =C3=87elik. diff --git a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCt= zy1.rst b/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1= .rst deleted file mode 100644 index d47bb455e71d1..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-18-18-37-07.bpo-39572.CCtzy1.rst +++ /dev/null @@ -1 +0,0 @@ -Updated documentation of ``total`` flag of TypeDict. diff --git a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_= 9zz.rst b/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz= .rst deleted file mode 100644 index f071d286176ae..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-02-19-11-13-47.bpo-17422.g7_9zz.rst +++ /dev/null @@ -1 +0,0 @@ -The language reference now specifies restrictions on class namespaces. Adap= ted from a patch by Ethan Furman. diff --git a/Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst b= /Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst deleted file mode 100644 index 9aa2f0ffddfaf..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-11-13-23-51-39.bpo-38792.xhTC5a.rst +++ /dev/null @@ -1,2 +0,0 @@ -Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` -or shell restart occurs. Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst b= /Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst deleted file mode 100644 index 42bbfb168c19d..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-01-25-02-26-45.bpo-39388.x4TQNh.rst +++ /dev/null @@ -1 +0,0 @@ -IDLE Settings Cancel button now cancels pending changes diff --git a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst b= /Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst deleted file mode 100644 index 2f65a00a5af3b..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst +++ /dev/null @@ -1 +0,0 @@ -Add remaining configdialog tests for buttons and highlights and keys tabs. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst b= /Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst deleted file mode 100644 index 102aa75f5813e..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-02-10-17-09-48.bpo-39600.X6NsyM.rst +++ /dev/null @@ -1 +0,0 @@ -In the font configuration window, remove duplicated font names. diff --git a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst b= /Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst deleted file mode 100644 index 19e16329ce0a0..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-02-17-21-09-03.bpo-39663.wexcsH.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for pyparse find_good_parse_start(). diff --git a/Misc/NEWS.d/next/Library/2017-12-04-10-14-23.bpo-32173.e0C5dF.rs= t b/Misc/NEWS.d/next/Library/2017-12-04-10-14-23.bpo-32173.e0C5dF.rst deleted file mode 100644 index fc8f36fb02194..0000000000000 --- a/Misc/NEWS.d/next/Library/2017-12-04-10-14-23.bpo-32173.e0C5dF.rst +++ /dev/null @@ -1,3 +0,0 @@ -* Add `lazycache` function to `__all__`. -* Use `dict.clear` to clear the cache. -* Refactoring `getline` function and `checkcache` function. diff --git a/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rs= t b/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst deleted file mode 100644 index 9f3fa40e51bf3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-12-20-39-34.bpo-35727.FWrbHn.rst +++ /dev/null @@ -1 +0,0 @@ -Fix sys.exit() and sys.exit(None) exit code propagation when used in multipr= ocessing.Process. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-03-18-16-17-59.bpo-36350.udRSWE.rs= t b/Misc/NEWS.d/next/Library/2019-03-18-16-17-59.bpo-36350.udRSWE.rst deleted file mode 100644 index 43363fce1652c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-18-16-17-59.bpo-36350.udRSWE.rst +++ /dev/null @@ -1,2 +0,0 @@ -`inspect.Signature.parameters` and `inspect.BoundArguments.arguments` are -now dicts instead of OrderedDicts. Patch contributed by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-12-11-05.bpo-25597.mPMzVx.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-12-11-05.bpo-25597.mPMzVx.rst deleted file mode 100644 index 5ad8c6d90fa03..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-12-11-05.bpo-25597.mPMzVx.rst +++ /dev/null @@ -1,3 +0,0 @@ -Ensure, if ``wraps`` is supplied to :class:`unittest.mock.MagicMock`, it is = used -to calculate return values for the magic methods instead of using the default -return values. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rs= t b/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst deleted file mode 100644 index 2089285ecdb7f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-09-17-24-29.bpo-34793.D82Dyu.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove support for ``with (await asyncio.lock):`` and ``with (yield from -asyncio.lock):``. The same is correct for ``asyncio.Condition`` and -``asyncio.Semaphore``. diff --git a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rs= t b/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst deleted file mode 100644 index 4c398682b98ab..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-15-23-13-03.bpo-39274.lpc0-n.rst +++ /dev/null @@ -1 +0,0 @@ -``bool(fraction.Fraction)`` now returns a boolean even if (numerator !=3D 0)= does not return a boolean (ex: numpy number). diff --git a/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rs= t b/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst deleted file mode 100644 index cc52700f67031..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-19-04-12-34.bpo-39349.7CV-LC.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added a new *cancel_futures* parameter to -:meth:`concurrent.futures.Executor.shutdown` that cancels all pending futures -which have not started running, instead of waiting for them to complete befo= re -shutting down the executor. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rs= t b/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst deleted file mode 100644 index e9f111ad62e28..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-20-10-06-19.bpo-18819.H4qsoS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Omit ``devmajor`` and ``devminor`` fields for non-device files in -:mod:`tarfile` archives, enabling bit-for-bit compatibility with GNU -``tar(1)``. diff --git a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rs= t b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst deleted file mode 100644 index 21c4ba8620755..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst +++ /dev/null @@ -1 +0,0 @@ -Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in dist= utils to make it export the correct init symbol also on Windows. diff --git a/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rs= t b/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst deleted file mode 100644 index 52c4ee1b33bda..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-24-13-24-35.bpo-39082.qKgrq_.rst +++ /dev/null @@ -1 +0,0 @@ -Allow AsyncMock to correctly patch static/class methods diff --git a/Misc/NEWS.d/next/Library/2020-01-25-13-41-27.bpo-38932.1pu_8I.rs= t b/Misc/NEWS.d/next/Library/2020-01-25-13-41-27.bpo-38932.1pu_8I.rst deleted file mode 100644 index d9ce8e816bc0a..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-25-13-41-27.bpo-38932.1pu_8I.rst +++ /dev/null @@ -1 +0,0 @@ -Mock fully resets child objects on reset_mock(). Patch by Vegard Stikbakke diff --git a/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rs= t b/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst deleted file mode 100644 index f62c31fc686ad..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-29-14-58-27.bpo-39485.Zy3ot6.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug in :func:`unittest.mock.create_autospec` that would complain about -the wrong number of arguments for custom descriptors defined in an extension -module returning functions. diff --git a/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rs= t b/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst deleted file mode 100644 index 1dd36454dc243..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-29-22-47-12.bpo-39491.tdl17b.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :data:`typing.Annotated` and ``include_extras`` parameter to -:func:`typing.get_type_hints` as part of :pep:`593`. Patch by Till -Varoquaux, documentation by Till Varoquaux and Konstantin Kashin. diff --git a/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rs= t b/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst deleted file mode 100644 index b676629a4414a..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-30-01-13-19.bpo-39493.CbFRi7.rst +++ /dev/null @@ -1 +0,0 @@ -Mark ``typing.IO.closed`` as a property \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-01-30-09-07-16.bpo-39353.wTl9hc.rs= t b/Misc/NEWS.d/next/Library/2020-01-30-09-07-16.bpo-39353.wTl9hc.rst deleted file mode 100644 index b6db7c5c58842..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-01-30-09-07-16.bpo-39353.wTl9hc.rst +++ /dev/null @@ -1 +0,0 @@ -The :func:`binascii.crc_hqx` function is no longer deprecated. diff --git a/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rs= t b/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst deleted file mode 100644 index 90ee0bcac7915..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-02-10-08-25.bpo-12915.d6r50-.rst +++ /dev/null @@ -1,4 +0,0 @@ -A new function ``resolve_name`` has been added to the ``pkgutil`` module. -This resolves a string of the form ``'a.b.c.d'`` or ``'a.b:c.d'`` to an -object. In the example, ``a.b`` is a package/module and ``c.d`` is an object -within that package/module reached via recursive attribute access. diff --git a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rs= t b/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst deleted file mode 100644 index 55fed519a2d80..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-02-14-46-34.bpo-39450.48R274.rst +++ /dev/null @@ -1,2 +0,0 @@ -Striped whitespace from docstring before returning it from -:func:`unittest.case.shortDescription`. diff --git a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rs= t b/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst deleted file mode 100644 index 8f035e79963e0..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-03-15-12-51.bpo-39546._Kj0Pn.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a regression in :class:`~argparse.ArgumentParser` where -``allow_abbrev=3DFalse`` was ignored for long options that used a prefix -character other than "-". diff --git a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rs= t b/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst deleted file mode 100644 index b4ec60b2abad1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-05-11-24-16.bpo-38149.GWsjHE.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`sys.audit` is now called only once per call of :func:`glob.glob` and -:func:`glob.iglob`. diff --git a/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rs= t b/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst deleted file mode 100644 index 881f26bdb7bac..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-05-18-29-14.bpo-39559.L8i5YB.rst +++ /dev/null @@ -1 +0,0 @@ -Remove unused, undocumented argument ``getters`` from :func:`uuid.getnode` \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rs= t b/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst deleted file mode 100644 index 3c4700f455b5e..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-06-10-23-32.bpo-39567.VpFBxt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added audit for :func:`os.walk`, :func:`os.fwalk`, :meth:`pathlib.Path.glob` -and :meth:`pathlib.Path.rglob`. diff --git a/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rs= t b/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst deleted file mode 100644 index 1a09358082ef6..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-06-13-34-52.bpo-39350.wRwup1.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix regression in :class:`fractions.Fraction` if the numerator and/or the -denominator is an :class:`int` subclass. The :func:`math.gcd` function is now -used to normalize the *numerator* and *denominator*. :func:`math.gcd` always -return a :class:`int` type. Previously, the GCD type depended on *numerator* -and *denominator*. diff --git a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rs= t b/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst deleted file mode 100644 index 3a461389af7d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-07-23-14-14.bpo-39595.DHwddE.rst +++ /dev/null @@ -1 +0,0 @@ -Improved performance of zipfile.Path for files with a large number of entrie= s. Also improved performance and fixed minor issue as published with `importl= ib_metadata 1.5 `_. diff --git a/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rs= t b/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst deleted file mode 100644 index 5189f131afd98..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-08-13-37-00.bpo-39586.nfTPxX.rst +++ /dev/null @@ -1,2 +0,0 @@ -The distutils ``bdist_msi`` command is deprecated in Python 3.9, use -``bdist_wheel`` (wheel packages) instead. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rs= t b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst deleted file mode 100644 index 68625028fb7af..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst +++ /dev/null @@ -1 +0,0 @@ -Collections.deque now holds strong references during deque.__contains__ and = deque.count, fixing crashes. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rs= t b/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst deleted file mode 100644 index fb91bb3825555..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-12-10-04-39.bpo-21016.bFXPH7.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` -module to get the path to the Python standard library, to support uncommon -installation path like ``/usr/lib64/python3.9/`` on Fedora. -Patch by Jan Mat=C4=9Bjek. diff --git a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rs= t b/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst deleted file mode 100644 index e990f84a9dbf2..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-12-12-01-26.bpo-39474.RZMEUH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` -and ``(a).b``. diff --git a/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rs= t b/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst deleted file mode 100644 index 4806aa67d9535..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-13-18-14-15.bpo-39627.Q0scyQ.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed TypedDict totality check for inherited keys. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rs= t b/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst deleted file mode 100644 index 52779bf098232..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-16-18-49-16.bpo-39104.cI5MJY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix hanging ProcessPoolExcutor on ``shutdown(wait=3DFalse)`` when a task has -failed pickling. diff --git a/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rs= t b/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst deleted file mode 100644 index 1d0e906242ae1..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-18-12-31-24.bpo-39674.S_zqVM.rst +++ /dev/null @@ -1,4 +0,0 @@ -Revert "Do not expose abstract collection classes in the collections module" -change (bpo-25988). Aliases to ABC like collections.Mapping are kept in -Python 3.9 to ease transition from Python 2.7, but will be removed in Python -3.10. diff --git a/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rs= t b/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst deleted file mode 100644 index 6f16623a8f5cd..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-18-12-37-16.bpo-39479.j3UcCq.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`math.lcm` function: least common multiple. diff --git a/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rs= t b/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst deleted file mode 100644 index 92e3b2399238e..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`io.UnsupportedOperation` in :meth:`io.BufferedReader.truncate` -when it is called on a read-only :class:`io.BufferedReader` instance. diff --git a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rs= t b/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst deleted file mode 100644 index c10e2fd7a4b6d..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-21-13-58-40.bpo-39681.zN8hf0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a regression where the C pickle module wouldn't allow unpickling from a -file-like object that doesn't expose a readinto() method. diff --git a/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rs= t b/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst deleted file mode 100644 index f205911ad9bfd..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-22-12-49-04.bpo-39648.Y-9N7F.rst +++ /dev/null @@ -1 +0,0 @@ -Expanded :func:`math.gcd` and :func:`math.lcm` to handle multiple arguments. diff --git a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rs= t b/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst deleted file mode 100644 index 5a88f79f05f0e..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-23-21-27-10.bpo-39649.qiubSp.rst +++ /dev/null @@ -1 +0,0 @@ -Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. diff --git a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rs= t b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst deleted file mode 100644 index c780633030090..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :exc:`IndexError` when trying to decode an invalid string with punycode -codec. diff --git a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.r= st b/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst deleted file mode 100644 index 1ab5d4d70eec5..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-01-07-00-42-08.bpo-39184.fe7NgK.rst +++ /dev/null @@ -1 +0,0 @@ -Add audit events to command execution functions in os and pty modules. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.r= st b/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst deleted file mode 100644 index 78274acfcb743..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-01-28-20-54-09.bpo-39401.he7h_A.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid unsafe DLL load at startup on Windows 7 and earlier. diff --git a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.r= st b/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst deleted file mode 100644 index cf25c24d58788..0000000000000 --- a/Misc/NEWS.d/next/Security/2020-02-07-23-54-18.bpo-39184.v-ue-v.rst +++ /dev/null @@ -1 +0,0 @@ -Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, `shuti= l`, `signal` and `syslog`. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst = b/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst deleted file mode 100644 index 0a13746e34759..0000000000000 --- a/Misc/NEWS.d/next/Tests/2020-01-30-15-04-54.bpo-39502.chbpII.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip test_zipfile.test_add_file_after_2107() if :func:`time.localtime` fails -with :exc:`OverflowError`. It is the case on AIX 6.1 for example. diff --git a/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst = b/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst deleted file mode 100644 index 7503379915260..0000000000000 --- a/Misc/NEWS.d/next/Tests/2020-02-11-00-38-32.bpo-38325.HgmfoE.rst +++ /dev/null @@ -1 +0,0 @@ -Skip tests on non-BMP characters of test_winconsoleio. diff --git a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rs= t b/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst deleted file mode 100644 index 3b84bd5217264..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-02-01-11-53.bpo-39185.T4herN.rst +++ /dev/null @@ -1 +0,0 @@ -The build.bat script has additional options for very-quiet output (-q) and v= ery-verbose output (-vv) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rs= t b/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst deleted file mode 100644 index c552e850a3684..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-11-22-53-55.bpo-38883.X7FRaN.rst +++ /dev/null @@ -1,5 +0,0 @@ -:meth:`~pathlib.Path.home()` and :meth:`~pathlib.Path.expanduser()` on Windo= ws -now prefer :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, which is = not -normally set for regular user accounts. This makes them again behave like -:func:`os.path.expanduser`, which was changed to ignore :envvar:`HOME` in 3.= 8, -see :issue:`36264`. diff --git a/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rs= t b/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst deleted file mode 100644 index 025b7e96a6e74..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-20-23-42-53.bpo-39393.gWlJDG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the error message when attempting to load a DLL with unresolved -dependencies. diff --git a/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rs= t b/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rst deleted file mode 100644 index d677c4c3e02d5..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-01-24-03-15-05.bpo-39439.sFxGfR.rst +++ /dev/null @@ -1 +0,0 @@ -Honor the Python path when a virtualenv is active on Windows. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rs= t b/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst deleted file mode 100644 index bf6496fa561db..0000000000000 --- a/Misc/NEWS.d/next/Windows/2020-02-04-19-50-53.bpo-39553._EnweA.rst +++ /dev/null @@ -1 +0,0 @@ -Delete unused code related to SxS manifests. diff --git a/README.rst b/README.rst index 5971d4aefcba1..1dc45593afa1d 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.9.0 alpha 3 +This is Python version 3.9.0 alpha 4 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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