From 13907968d73b3b602c81e240fb7892a2627974d6 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Fri, 2 Feb 2024 05:53:53 +0900 Subject: [PATCH 01/62] gh-111968: Use per-thread freelists for dict in free-threading (gh-114323) --- Include/internal/pycore_dict.h | 3 +- Include/internal/pycore_dict_state.h | 19 ------ Include/internal/pycore_freelist.h | 13 ++++ Include/internal/pycore_gc.h | 2 +- Include/internal/pycore_interp.h | 2 +- Objects/dictobject.c | 88 ++++++++++++---------------- Objects/floatobject.c | 4 ++ Objects/genobject.c | 4 ++ Objects/listobject.c | 4 ++ Python/context.c | 4 ++ Python/gc_free_threading.c | 2 - Python/gc_gil.c | 2 - Python/pystate.c | 3 + 13 files changed, 75 insertions(+), 75 deletions(-) diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index b4e1f8cf1e320b..60acd89cf6c34a 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -9,6 +9,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_freelist.h" // _PyFreeListState #include "pycore_identifier.h" // _Py_Identifier #include "pycore_object.h" // PyDictOrValues @@ -69,7 +70,7 @@ extern PyObject* _PyDictView_Intersect(PyObject* self, PyObject *other); /* runtime lifecycle */ -extern void _PyDict_Fini(PyInterpreterState *interp); +extern void _PyDict_Fini(PyInterpreterState *state); /* other API */ diff --git a/Include/internal/pycore_dict_state.h b/Include/internal/pycore_dict_state.h index ece0f10ca25170..a6dd63d36e040e 100644 --- a/Include/internal/pycore_dict_state.h +++ b/Include/internal/pycore_dict_state.h @@ -8,16 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif - -#ifndef WITH_FREELISTS -// without freelists -# define PyDict_MAXFREELIST 0 -#endif - -#ifndef PyDict_MAXFREELIST -# define PyDict_MAXFREELIST 80 -#endif - #define DICT_MAX_WATCHERS 8 struct _Py_dict_state { @@ -26,15 +16,6 @@ struct _Py_dict_state { * time that a dictionary is modified. */ uint64_t global_version; uint32_t next_keys_version; - -#if PyDict_MAXFREELIST > 0 - /* Dictionary reuse scheme to save calls to malloc and free */ - PyDictObject *free_list[PyDict_MAXFREELIST]; - PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; - int numfree; - int keys_numfree; -#endif - PyDict_WatchCallback watchers[DICT_MAX_WATCHERS]; }; diff --git a/Include/internal/pycore_freelist.h b/Include/internal/pycore_freelist.h index b91d2bc066b783..82a42300991ecc 100644 --- a/Include/internal/pycore_freelist.h +++ b/Include/internal/pycore_freelist.h @@ -17,6 +17,7 @@ extern "C" { # define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE # define PyTuple_MAXFREELIST 2000 # define PyList_MAXFREELIST 80 +# define PyDict_MAXFREELIST 80 # define PyFloat_MAXFREELIST 100 # define PyContext_MAXFREELIST 255 # define _PyAsyncGen_MAXFREELIST 80 @@ -25,6 +26,7 @@ extern "C" { # define PyTuple_NFREELISTS 0 # define PyTuple_MAXFREELIST 0 # define PyList_MAXFREELIST 0 +# define PyDict_MAXFREELIST 0 # define PyFloat_MAXFREELIST 0 # define PyContext_MAXFREELIST 0 # define _PyAsyncGen_MAXFREELIST 0 @@ -65,6 +67,16 @@ struct _Py_float_state { #endif }; +struct _Py_dict_freelist { +#ifdef WITH_FREELISTS + /* Dictionary reuse scheme to save calls to malloc and free */ + PyDictObject *free_list[PyDict_MAXFREELIST]; + PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; + int numfree; + int keys_numfree; +#endif +}; + struct _Py_slice_state { #ifdef WITH_FREELISTS /* Using a cache is very effective since typically only a single slice is @@ -106,6 +118,7 @@ typedef struct _Py_freelist_state { struct _Py_float_state floats; struct _Py_tuple_state tuples; struct _Py_list_state lists; + struct _Py_dict_freelist dicts; struct _Py_slice_state slices; struct _Py_context_state contexts; struct _Py_async_gen_state async_gens; diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index b362a294a59042..ca1d9fdf5253b8 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -267,7 +267,7 @@ extern void _PyTuple_ClearFreeList(_PyFreeListState *state, int is_finalization) extern void _PyFloat_ClearFreeList(_PyFreeListState *state, int is_finalization); extern void _PyList_ClearFreeList(_PyFreeListState *state, int is_finalization); extern void _PySlice_ClearCache(_PyFreeListState *state); -extern void _PyDict_ClearFreeList(PyInterpreterState *interp); +extern void _PyDict_ClearFreeList(_PyFreeListState *state, int is_finalization); extern void _PyAsyncGen_ClearFreeLists(_PyFreeListState *state, int is_finalization); extern void _PyContext_ClearFreeList(_PyFreeListState *state, int is_finalization); extern void _Py_ScheduleGC(PyInterpreterState *interp); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 04e75940dcb573..c4732b1534199b 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -20,6 +20,7 @@ extern "C" { #include "pycore_dtoa.h" // struct _dtoa_state #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_floatobject.h" // struct _Py_float_state +#include "pycore_freelist.h" // struct _Py_freelist_state #include "pycore_function.h" // FUNC_MAX_WATCHERS #include "pycore_gc.h" // struct _gc_runtime_state #include "pycore_genobject.h" // struct _Py_async_gen_state @@ -230,7 +231,6 @@ struct _is { struct _dtoa_state dtoa; struct _py_func_state func_state; - struct _Py_tuple_state tuple; struct _Py_dict_state dict_state; struct _Py_exc_state exc_state; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 23d7e9b5e38a35..e24887b7d781bb 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -118,6 +118,7 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_code.h" // stats #include "pycore_dict.h" // export _PyDict_SizeOf() +#include "pycore_freelist.h" // _PyFreeListState_GET() #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() @@ -242,40 +243,44 @@ static PyObject* dict_iter(PyObject *dict); #include "clinic/dictobject.c.h" -#if PyDict_MAXFREELIST > 0 -static struct _Py_dict_state * -get_dict_state(PyInterpreterState *interp) +#ifdef WITH_FREELISTS +static struct _Py_dict_freelist * +get_dict_state(void) { - return &interp->dict_state; + _PyFreeListState *state = _PyFreeListState_GET(); + return &state->dicts; } #endif void -_PyDict_ClearFreeList(PyInterpreterState *interp) +_PyDict_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) { -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = &interp->dict_state; - while (state->numfree) { +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = &freelist_state->dicts; + while (state->numfree > 0) { PyDictObject *op = state->free_list[--state->numfree]; assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } - while (state->keys_numfree) { + while (state->keys_numfree > 0) { PyMem_Free(state->keys_free_list[--state->keys_numfree]); } + if (is_finalization) { + state->numfree = -1; + state->keys_numfree = -1; + } #endif } - void -_PyDict_Fini(PyInterpreterState *interp) +_PyDict_Fini(PyInterpreterState *Py_UNUSED(interp)) { - _PyDict_ClearFreeList(interp); -#if defined(Py_DEBUG) && PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = &interp->dict_state; - state->numfree = -1; - state->keys_numfree = -1; + // With Py_GIL_DISABLED: + // the freelists for the current thread state have already been cleared. +#ifndef Py_GIL_DISABLED + _PyFreeListState *state = _PyFreeListState_GET(); + _PyDict_ClearFreeList(state, 1); #endif } @@ -290,9 +295,8 @@ unicode_get_hash(PyObject *o) void _PyDict_DebugMallocStats(FILE *out) { -#if PyDict_MAXFREELIST > 0 - PyInterpreterState *interp = _PyInterpreterState_GET(); - struct _Py_dict_state *state = get_dict_state(interp); +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = get_dict_state(); _PyDebugAllocatorStats(out, "free PyDictObject", state->numfree, sizeof(PyDictObject)); #endif @@ -300,7 +304,7 @@ _PyDict_DebugMallocStats(FILE *out) #define DK_MASK(dk) (DK_SIZE(dk)-1) -static void free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys); +static void free_keys_object(PyDictKeysObject *keys); /* PyDictKeysObject has refcounts like PyObject does, so we have the following two functions to mirror what Py_INCREF() and Py_DECREF() do. @@ -348,7 +352,7 @@ dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk) Py_XDECREF(entries[i].me_value); } } - free_keys_object(interp, dk); + free_keys_object(dk); } } @@ -643,12 +647,8 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode) log2_bytes = log2_size + 2; } -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(interp); -#ifdef Py_DEBUG - // new_keys_object() must not be called after _PyDict_Fini() - assert(state->keys_numfree != -1); -#endif +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = get_dict_state(); if (log2_size == PyDict_LOG_MINSIZE && unicode && state->keys_numfree > 0) { dk = state->keys_free_list[--state->keys_numfree]; OBJECT_STAT_INC(from_freelist); @@ -680,16 +680,13 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode) } static void -free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys) +free_keys_object(PyDictKeysObject *keys) { -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(interp); -#ifdef Py_DEBUG - // free_keys_object() must not be called after _PyDict_Fini() - assert(state->keys_numfree != -1); -#endif +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = get_dict_state(); if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST + && state->keys_numfree >= 0 && DK_IS_UNICODE(keys)) { state->keys_free_list[state->keys_numfree++] = keys; OBJECT_STAT_INC(to_freelist); @@ -730,13 +727,9 @@ new_dict(PyInterpreterState *interp, { PyDictObject *mp; assert(keys != NULL); -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(interp); -#ifdef Py_DEBUG - // new_dict() must not be called after _PyDict_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree) { +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = get_dict_state(); + if (state->numfree > 0) { mp = state->free_list[--state->numfree]; assert (mp != NULL); assert (Py_IS_TYPE(mp, &PyDict_Type)); @@ -1547,7 +1540,7 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp, #endif assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); assert(oldkeys->dk_refcnt == 1); - free_keys_object(interp, oldkeys); + free_keys_object(oldkeys); } } @@ -2458,13 +2451,10 @@ dict_dealloc(PyObject *self) assert(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); dictkeys_decref(interp, keys); } -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(interp); -#ifdef Py_DEBUG - // new_dict() must not be called after _PyDict_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) { +#ifdef WITH_FREELISTS + struct _Py_dict_freelist *state = get_dict_state(); + if (state->numfree < PyDict_MAXFREELIST && state->numfree >=0 && + Py_IS_TYPE(mp, &PyDict_Type)) { state->free_list[state->numfree++] = mp; OBJECT_STAT_INC(to_freelist); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index b7611d5f96ac3b..c440e0dab0e79f 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -2013,7 +2013,11 @@ _PyFloat_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) void _PyFloat_Fini(_PyFreeListState *state) { + // With Py_GIL_DISABLED: + // the freelists for the current thread state have already been cleared. +#ifndef Py_GIL_DISABLED _PyFloat_ClearFreeList(state, 1); +#endif } void diff --git a/Objects/genobject.c b/Objects/genobject.c index f47197330fdd80..ab523e46cceaa3 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1685,7 +1685,11 @@ _PyAsyncGen_ClearFreeLists(_PyFreeListState *freelist_state, int is_finalization void _PyAsyncGen_Fini(_PyFreeListState *state) { + // With Py_GIL_DISABLED: + // the freelists for the current thread state have already been cleared. +#ifndef Py_GIL_DISABLED _PyAsyncGen_ClearFreeLists(state, 1); +#endif } diff --git a/Objects/listobject.c b/Objects/listobject.c index 80a1f1da55b8bc..da2b9cc32697dd 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -138,7 +138,11 @@ _PyList_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) void _PyList_Fini(_PyFreeListState *state) { + // With Py_GIL_DISABLED: + // the freelists for the current thread state have already been cleared. +#ifndef Py_GIL_DISABLED _PyList_ClearFreeList(state, 1); +#endif } /* Print summary info about the state of the optimized allocator */ diff --git a/Python/context.c b/Python/context.c index 294485e5b407df..793dfa2b72c7e3 100644 --- a/Python/context.c +++ b/Python/context.c @@ -1287,7 +1287,11 @@ _PyContext_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) void _PyContext_Fini(_PyFreeListState *state) { + // With Py_GIL_DISABLED: + // the freelists for the current thread state have already been cleared. +#ifndef Py_GIL_DISABLED _PyContext_ClearFreeList(state, 1); +#endif } diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 53f927bfa65310..8fbcdb15109b76 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -1676,8 +1676,6 @@ PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg) void _PyGC_ClearAllFreeLists(PyInterpreterState *interp) { - _PyDict_ClearFreeList(interp); - HEAD_LOCK(&_PyRuntime); _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head; while (tstate != NULL) { diff --git a/Python/gc_gil.c b/Python/gc_gil.c index 04c1c184250c60..4e2aa8f7af746c 100644 --- a/Python/gc_gil.c +++ b/Python/gc_gil.c @@ -11,8 +11,6 @@ void _PyGC_ClearAllFreeLists(PyInterpreterState *interp) { - _PyDict_ClearFreeList(interp); - _Py_ClearFreeLists(&interp->freelist_state, 0); } diff --git a/Python/pystate.c b/Python/pystate.c index 430121a6a35d7f..27b6d0573ade3b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1461,9 +1461,12 @@ clear_datastack(PyThreadState *tstate) void _Py_ClearFreeLists(_PyFreeListState *state, int is_finalization) { + // In the free-threaded build, freelists are per-PyThreadState and cleared in PyThreadState_Clear() + // In the default build, freelists are per-interpreter and cleared in finalize_interp_types() _PyFloat_ClearFreeList(state, is_finalization); _PyTuple_ClearFreeList(state, is_finalization); _PyList_ClearFreeList(state, is_finalization); + _PyDict_ClearFreeList(state, is_finalization); _PyContext_ClearFreeList(state, is_finalization); _PyAsyncGen_ClearFreeLists(state, is_finalization); _PyObjectStackChunk_ClearFreeList(state, is_finalization); From 618d7256e78da8200f6e2c6235094a1ef885dca4 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 1 Feb 2024 17:54:02 -0600 Subject: [PATCH 02/62] gh-111239: Update Windows build to use zlib 1.3.1 (GH-114877) --- .../next/Windows/2024-02-01-14-35-05.gh-issue-111239.SO7SUF.rst | 1 + PCbuild/get_externals.bat | 2 +- PCbuild/python.props | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2024-02-01-14-35-05.gh-issue-111239.SO7SUF.rst diff --git a/Misc/NEWS.d/next/Windows/2024-02-01-14-35-05.gh-issue-111239.SO7SUF.rst b/Misc/NEWS.d/next/Windows/2024-02-01-14-35-05.gh-issue-111239.SO7SUF.rst new file mode 100644 index 00000000000000..ea82c3b941f802 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2024-02-01-14-35-05.gh-issue-111239.SO7SUF.rst @@ -0,0 +1 @@ +Update Windows builds to use zlib v1.3.1. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 3919c0592ec00d..de73d923d8f4df 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -58,7 +58,7 @@ set libraries=%libraries% sqlite-3.44.2.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.1 set libraries=%libraries% xz-5.2.5 -set libraries=%libraries% zlib-1.2.13 +set libraries=%libraries% zlib-1.3.1 for %%e in (%libraries%) do ( if exist "%EXTERNALS_DIR%\%%e" ( diff --git a/PCbuild/python.props b/PCbuild/python.props index e8796081c4eaf3..2cb16693e546b1 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -78,7 +78,7 @@ $(ExternalsDir)openssl-bin-3.0.11\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ - $(ExternalsDir)\zlib-1.2.13\ + $(ExternalsDir)\zlib-1.3.1\ From 1aec0644447e69e981d582449849761b23702ec8 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 2 Feb 2024 04:44:01 +0300 Subject: [PATCH 03/62] GH-114849: Set a 60-minute timeout for JIT CI jobs (GH-114850) --- .github/workflows/jit.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml index 22e0bdba53ffd6..69648d87947ad6 100644 --- a/.github/workflows/jit.yml +++ b/.github/workflows/jit.yml @@ -18,6 +18,7 @@ jobs: jit: name: ${{ matrix.target }} (${{ matrix.debug && 'Debug' || 'Release' }}) runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: fail-fast: false matrix: From 53339a0ef72fcfc15221792b117c4670b07a0b20 Mon Sep 17 00:00:00 2001 From: Michal Kaptur Date: Fri, 2 Feb 2024 11:00:18 +0100 Subject: [PATCH 04/62] Move "format" param doc of shutil.make_archive() on its own paragraph (GH-103829) --- Doc/library/shutil.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index d9ec2cbc47e611..7a7dd23177e672 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -586,7 +586,9 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Create an archive file (such as zip or tar) and return its name. *base_name* is the name of the file to create, including the path, minus - any format-specific extension. *format* is the archive format: one of + any format-specific extension. + + *format* is the archive format: one of "zip" (if the :mod:`zlib` module is available), "tar", "gztar" (if the :mod:`zlib` module is available), "bztar" (if the :mod:`bz2` module is available), or "xztar" (if the :mod:`lzma` module is available). From d25d4ee60cc789a8b9c222859bb720ade1ab2e30 Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Fri, 2 Feb 2024 04:38:43 -0600 Subject: [PATCH 05/62] gh-103820: IDLE: Do not interpret buttons 4/5 as scrolling on non-X11 (GH-103821) Also fix test_mousewheel: do not skip a check which was broken due to incorrect delta on Aqua and XQuartz, and probably not because of `.update_idletasks()`. --- Lib/idlelib/editor.py | 5 +++-- Lib/idlelib/idle_test/test_sidebar.py | 22 ++++++++++++------- Lib/idlelib/tree.py | 10 +++++---- ...-04-25-03-01-23.gh-issue-103820.LCSpza.rst | 2 ++ 4 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2023-04-25-03-01-23.gh-issue-103820.LCSpza.rst diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 6ad383f460c7ee..8ee8eba64367a5 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -166,8 +166,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<3>",self.right_menu_event) text.bind('', wheel_event) - text.bind('', wheel_event) - text.bind('', wheel_event) + if text._windowingsystem == 'x11': + text.bind('', wheel_event) + text.bind('', wheel_event) text.bind('', self.handle_winconfig) text.bind("<>", self.cut) text.bind("<>", self.copy) diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py index fb52b3a0179553..605e7a892570d7 100644 --- a/Lib/idlelib/idle_test/test_sidebar.py +++ b/Lib/idlelib/idle_test/test_sidebar.py @@ -690,16 +690,22 @@ def test_mousewheel(self): last_lineno = get_end_linenumber(text) self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) - # Scroll up using the event. - # The meaning of delta is platform-dependent. - delta = -1 if sys.platform == 'darwin' else 120 - sidebar.canvas.event_generate('', x=0, y=0, delta=delta) + # Delta for , whose meaning is platform-dependent. + delta = 1 if sidebar.canvas._windowingsystem == 'aqua' else 120 + + # Scroll up. + if sidebar.canvas._windowingsystem == 'x11': + sidebar.canvas.event_generate('', x=0, y=0) + else: + sidebar.canvas.event_generate('', x=0, y=0, delta=delta) yield - if sys.platform != 'darwin': # .update_idletasks() does not work. - self.assertIsNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) + self.assertIsNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) - # Scroll back down using the event. - sidebar.canvas.event_generate('', x=0, y=0) + # Scroll back down. + if sidebar.canvas._windowingsystem == 'x11': + sidebar.canvas.event_generate('', x=0, y=0) + else: + sidebar.canvas.event_generate('', x=0, y=0, delta=-delta) yield self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index 9c2eb47b24aec9..0726d7e23660f6 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -285,8 +285,9 @@ def drawtext(self): self.label.bind("<1>", self.select_or_edit) self.label.bind("", self.flip) self.label.bind("", lambda e: wheel_event(e, self.canvas)) - self.label.bind("", lambda e: wheel_event(e, self.canvas)) - self.label.bind("", lambda e: wheel_event(e, self.canvas)) + if self.label._windowingsystem == 'x11': + self.label.bind("", lambda e: wheel_event(e, self.canvas)) + self.label.bind("", lambda e: wheel_event(e, self.canvas)) self.text_id = id def select_or_edit(self, event=None): @@ -460,8 +461,9 @@ def __init__(self, master, **opts): self.canvas.bind("", self.unit_up) self.canvas.bind("", self.unit_down) self.canvas.bind("", wheel_event) - self.canvas.bind("", wheel_event) - self.canvas.bind("", wheel_event) + if self.canvas._windowingsystem == 'x11': + self.canvas.bind("", wheel_event) + self.canvas.bind("", wheel_event) #if isinstance(master, Toplevel) or isinstance(master, Tk): self.canvas.bind("", self.zoom_height) self.canvas.focus_set() diff --git a/Misc/NEWS.d/next/IDLE/2023-04-25-03-01-23.gh-issue-103820.LCSpza.rst b/Misc/NEWS.d/next/IDLE/2023-04-25-03-01-23.gh-issue-103820.LCSpza.rst new file mode 100644 index 00000000000000..b9d7faf047b28e --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2023-04-25-03-01-23.gh-issue-103820.LCSpza.rst @@ -0,0 +1,2 @@ +Revise IDLE bindings so that events from mouse button 4/5 on non-X11 +windowing systems (i.e. Win32 and Aqua) are not mistaken for scrolling. From 41fde89e471003b3e70fdd76d6726fba9982a1eb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 2 Feb 2024 10:41:28 +0000 Subject: [PATCH 06/62] GH-113655 Lower C recursion limit from 4000 to 3000 on Windows. (GH-114896) --- Include/cpython/pystate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 1dbf97660f382f..9bc8758e72bd8f 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -229,7 +229,7 @@ struct _ts { #elif defined(__s390x__) # define Py_C_RECURSION_LIMIT 800 #elif defined(_WIN32) -# define Py_C_RECURSION_LIMIT 4000 +# define Py_C_RECURSION_LIMIT 3000 #elif defined(_Py_ADDRESS_SANITIZER) # define Py_C_RECURSION_LIMIT 4000 #else From 2091fb2a85c1aa2d9b22c02736b07831bd875c2a Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:26:31 +0000 Subject: [PATCH 07/62] gh-107901: make compiler inline basic blocks with no line number and no fallthrough (#114750) --- Lib/test/test_compile.py | 62 ++++++++++++++++++++++++------ Lib/test/test_monitoring.py | 10 ++--- Python/flowgraph.c | 75 ++++++++++++++++++++++++++----------- 3 files changed, 108 insertions(+), 39 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 3b1ceceaa6305f..ebb479f2de7c63 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1104,6 +1104,17 @@ async def test(aseq): code_lines = self.get_code_lines(test.__code__) self.assertEqual(expected_lines, code_lines) + def check_line_numbers(self, code, opnames=None): + # Check that all instructions whose op matches opnames + # have a line number. opnames can be a single name, or + # a sequence of names. If it is None, match all ops. + + if isinstance(opnames, str): + opnames = (opnames, ) + for inst in dis.Bytecode(code): + if opnames and inst.opname in opnames: + self.assertIsNotNone(inst.positions.lineno) + def test_line_number_synthetic_jump_multiple_predecessors(self): def f(): for x in it: @@ -1113,25 +1124,52 @@ def f(): except OSError: pass - # Ensure that all JUMP_BACKWARDs have line number - code = f.__code__ - for inst in dis.Bytecode(code): - if inst.opname == 'JUMP_BACKWARD': - self.assertIsNotNone(inst.positions.lineno) + self.check_line_numbers(f.__code__, 'JUMP_BACKWARD') - def test_lineno_of_backward_jump(self): + def test_line_number_synthetic_jump_multiple_predecessors_nested(self): + def f(): + for x in it: + try: + X = 3 + except OSError: + try: + if C3: + X = 4 + except OSError: + pass + return 42 + + self.check_line_numbers(f.__code__, 'JUMP_BACKWARD') + + def test_line_number_synthetic_jump_multiple_predecessors_more_nested(self): + def f(): + for x in it: + try: + X = 3 + except OSError: + try: + if C3: + if C4: + X = 4 + except OSError: + try: + if C3: + if C4: + X = 5 + except OSError: + pass + return 42 + + self.check_line_numbers(f.__code__, 'JUMP_BACKWARD') + + def test_lineno_of_backward_jump_conditional_in_loop(self): # Issue gh-107901 def f(): for i in x: if y: pass - linenos = list(inst.positions.lineno - for inst in dis.get_instructions(f.__code__) - if inst.opname == 'JUMP_BACKWARD') - - self.assertTrue(len(linenos) > 0) - self.assertTrue(all(l is not None for l in linenos)) + self.check_line_numbers(f.__code__, 'JUMP_BACKWARD') def test_big_dict_literal(self): # The compiler has a flushing point in "compiler_dict" that calls compiles diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index a64d1ed79decd8..60b6326bfbad5e 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1466,9 +1466,8 @@ def func(): ('branch', 'func', 4, 4), ('line', 'func', 5), ('line', 'meth', 1), - ('jump', 'func', 5, 5), - ('jump', 'func', 5, '[offset=114]'), - ('branch', 'func', '[offset=120]', '[offset=124]'), + ('jump', 'func', 5, '[offset=118]'), + ('branch', 'func', '[offset=122]', '[offset=126]'), ('line', 'get_events', 11)]) self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ @@ -1482,9 +1481,8 @@ def func(): ('line', 'func', 5), ('line', 'meth', 1), ('return', 'meth', None), - ('jump', 'func', 5, 5), - ('jump', 'func', 5, '[offset=114]'), - ('branch', 'func', '[offset=120]', '[offset=124]'), + ('jump', 'func', 5, '[offset=118]'), + ('branch', 'func', '[offset=122]', '[offset=126]'), ('return', 'func', None), ('line', 'get_events', 11)]) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index bfc23a298ff492..1a648edf0880c0 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -212,14 +212,14 @@ basicblock_add_jump(basicblock *b, int opcode, basicblock *target, location loc) } static inline int -basicblock_append_instructions(basicblock *target, basicblock *source) +basicblock_append_instructions(basicblock *to, basicblock *from) { - for (int i = 0; i < source->b_iused; i++) { - int n = basicblock_next_instr(target); + for (int i = 0; i < from->b_iused; i++) { + int n = basicblock_next_instr(to); if (n < 0) { return ERROR; } - target->b_instr[n] = source->b_instr[i]; + to->b_instr[n] = from->b_instr[i]; } return SUCCESS; } @@ -292,9 +292,9 @@ static void dump_basicblock(const basicblock *b) { const char *b_return = basicblock_returns(b) ? "return " : ""; - fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, %s\n", + fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, preds: %d %s\n", b->b_label.id, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused, - b->b_startdepth, b_return); + b->b_startdepth, b->b_predecessors, b_return); if (b->b_instr) { int i; for (i = 0; i < b->b_iused; i++) { @@ -1165,15 +1165,26 @@ remove_redundant_jumps(cfg_builder *g) { return changes; } +static inline bool +basicblock_has_no_lineno(basicblock *b) { + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_loc.lineno >= 0) { + return false; + } + } + return true; +} + /* Maximum size of basic block that should be copied in optimizer */ #define MAX_COPY_SIZE 4 -/* If this block ends with an unconditional jump to a small exit block, then +/* If this block ends with an unconditional jump to a small exit block or + * a block that has no line numbers (and no fallthrough), then * remove the jump and extend this block with the target. * Returns 1 if extended, 0 if no change, and -1 on error. */ static int -inline_small_exit_blocks(basicblock *bb) { +basicblock_inline_small_or_no_lineno_blocks(basicblock *bb) { cfg_instr *last = basicblock_last_instr(bb); if (last == NULL) { return 0; @@ -1182,14 +1193,46 @@ inline_small_exit_blocks(basicblock *bb) { return 0; } basicblock *target = last->i_target; - if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) { + bool small_exit_block = (basicblock_exits_scope(target) && + target->b_iused <= MAX_COPY_SIZE); + bool no_lineno_no_fallthrough = (basicblock_has_no_lineno(target) && + !BB_HAS_FALLTHROUGH(target)); + if (small_exit_block || no_lineno_no_fallthrough) { + assert(is_jump(last)); + int removed_jump_opcode = last->i_opcode; INSTR_SET_OP0(last, NOP); RETURN_IF_ERROR(basicblock_append_instructions(bb, target)); + if (no_lineno_no_fallthrough) { + last = basicblock_last_instr(bb); + if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode) && + removed_jump_opcode == JUMP) + { + /* Make sure we don't lose eval breaker checks */ + last->i_opcode = JUMP; + } + } + target->b_predecessors--; return 1; } return 0; } +static int +inline_small_or_no_lineno_blocks(basicblock *entryblock) { + bool changes; + do { + changes = false; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + int res = basicblock_inline_small_or_no_lineno_blocks(b); + RETURN_IF_ERROR(res); + if (res) { + changes = true; + } + } + } while(changes); /* every change removes a jump, ensuring convergence */ + return changes; +} + // Attempt to eliminate jumps to jumps by updating inst to jump to // target->i_target using the provided opcode. Return whether or not the // optimization was successful. @@ -1804,9 +1847,7 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache, int firstl { assert(PyDict_CheckExact(const_cache)); RETURN_IF_ERROR(check_cfg(g)); - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - RETURN_IF_ERROR(inline_small_exit_blocks(b)); - } + RETURN_IF_ERROR(inline_small_or_no_lineno_blocks(g->g_entryblock)); RETURN_IF_ERROR(remove_unreachable(g->g_entryblock)); RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); RETURN_IF_ERROR(optimize_load_const(const_cache, g, consts)); @@ -1814,9 +1855,6 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache, int firstl RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts)); } RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock)); - for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - RETURN_IF_ERROR(inline_small_exit_blocks(b)); - } RETURN_IF_ERROR(remove_unreachable(g->g_entryblock)); int removed_nops, removed_jumps; @@ -2333,12 +2371,7 @@ convert_pseudo_ops(cfg_builder *g) static inline bool is_exit_or_eval_check_without_lineno(basicblock *b) { if (basicblock_exits_scope(b) || basicblock_has_eval_break(b)) { - for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_loc.lineno >= 0) { - return false; - } - } - return true; + return basicblock_has_no_lineno(b); } else { return false; From 0e71a295e9530c939a5efcb45db23cf31e0303b4 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 2 Feb 2024 12:14:34 +0000 Subject: [PATCH 08/62] GH-113710: Add a "globals to constants" pass (GH-114592) Converts specializations of `LOAD_GLOBAL` into constants during tier 2 optimization. --- Include/cpython/dictobject.h | 3 + Include/cpython/optimizer.h | 8 +- Include/internal/pycore_dict.h | 6 +- Include/internal/pycore_dict_state.h | 1 + Include/internal/pycore_interp.h | 2 +- Include/internal/pycore_optimizer.h | 5 +- Include/internal/pycore_uop_ids.h | 8 +- Include/internal/pycore_uop_metadata.h | 8 + Lib/test/test_capi/test_watchers.py | 12 +- Modules/_testcapi/watchers.c | 4 +- Objects/dictobject.c | 3 +- Python/bytecodes.c | 24 +++ Python/executor_cases.c.h | 42 +++++ Python/optimizer.c | 52 +++--- Python/optimizer_analysis.c | 230 ++++++++++++++++++++++++- Python/pylifecycle.c | 22 ++- 16 files changed, 375 insertions(+), 55 deletions(-) diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index 944965fb9e5351..1720fe6f01ea37 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -17,6 +17,9 @@ typedef struct { /* Dictionary version: globally unique, value change each time the dictionary is modified */ #ifdef Py_BUILD_CORE + /* Bits 0-7 are for dict watchers. + * Bits 8-11 are for the watched mutation counter (used by tier2 optimization) + * The remaining bits (12-63) are the actual version tag. */ uint64_t ma_version_tag; #else Py_DEPRECATED(3.12) uint64_t ma_version_tag; diff --git a/Include/cpython/optimizer.h b/Include/cpython/optimizer.h index ecf3cae4cbc3f1..5a9ccaea3b2209 100644 --- a/Include/cpython/optimizer.h +++ b/Include/cpython/optimizer.h @@ -47,7 +47,10 @@ typedef struct _PyExecutorObject { typedef struct _PyOptimizerObject _PyOptimizerObject; /* Should return > 0 if a new executor is created. O if no executor is produced and < 0 if an error occurred. */ -typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **, int curr_stackentries); +typedef int (*optimize_func)( + _PyOptimizerObject* self, struct _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr, _PyExecutorObject **exec_ptr, + int curr_stackentries); typedef struct _PyOptimizerObject { PyObject_HEAD @@ -94,6 +97,9 @@ PyAPI_FUNC(PyObject *)PyUnstable_Optimizer_NewUOpOptimizer(void); /* Minimum of 16 additional executions before retry */ #define MINIMUM_TIER2_BACKOFF 4 +#define _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS 3 +#define _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS 6 + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 60acd89cf6c34a..233da058f464d1 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -207,8 +207,8 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { #define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) -#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS) -#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1) +#define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) +#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1) #ifdef Py_GIL_DISABLED #define DICT_NEXT_VERSION(INTERP) \ @@ -234,7 +234,7 @@ _PyDict_NotifyEvent(PyInterpreterState *interp, PyObject *value) { assert(Py_REFCNT((PyObject*)mp) > 0); - int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK; + int watcher_bits = mp->ma_version_tag & DICT_WATCHER_MASK; if (watcher_bits) { _PyDict_SendEvent(watcher_bits, event, mp, key, value); return DICT_NEXT_VERSION(interp) | watcher_bits; diff --git a/Include/internal/pycore_dict_state.h b/Include/internal/pycore_dict_state.h index a6dd63d36e040e..1a44755c7a01a3 100644 --- a/Include/internal/pycore_dict_state.h +++ b/Include/internal/pycore_dict_state.h @@ -9,6 +9,7 @@ extern "C" { #endif #define DICT_MAX_WATCHERS 8 +#define DICT_WATCHED_MUTATION_BITS 4 struct _Py_dict_state { /*Global counter used to set ma_version_tag field of dictionary. diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index c4732b1534199b..f7c332ed747cfa 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -72,7 +72,6 @@ typedef struct _rare_events { uint8_t set_eval_frame_func; /* Modifying the builtins, __builtins__.__dict__[var] = ... */ uint8_t builtin_dict; - int builtins_dict_watcher_id; /* Modifying a function, e.g. func.__defaults__ = ..., etc. */ uint8_t func_modification; } _rare_events; @@ -243,6 +242,7 @@ struct _is { uint16_t optimizer_backedge_threshold; uint32_t next_func_version; _rare_events rare_events; + PyDict_WatchCallback builtins_dict_watcher; _Py_GlobalMonitors monitors; bool sys_profile_initialized; diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 31f30c673f207a..e21412fc815540 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -8,8 +8,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -int _Py_uop_analyze_and_optimize(PyCodeObject *code, - _PyUOpInstruction *trace, int trace_len, int curr_stackentries); +int _Py_uop_analyze_and_optimize(_PyInterpreterFrame *frame, + _PyUOpInstruction *trace, int trace_len, int curr_stackentries, + _PyBloomFilter *dependencies); extern PyTypeObject _PyCounterExecutor_Type; extern PyTypeObject _PyCounterOptimizer_Type; diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index a7056586ff04c0..b2476e1c6e5c4b 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -232,8 +232,12 @@ extern "C" { #define _CHECK_VALIDITY 379 #define _LOAD_CONST_INLINE 380 #define _LOAD_CONST_INLINE_BORROW 381 -#define _INTERNAL_INCREMENT_OPT_COUNTER 382 -#define MAX_UOP_ID 382 +#define _LOAD_CONST_INLINE_WITH_NULL 382 +#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 383 +#define _CHECK_GLOBALS 384 +#define _CHECK_BUILTINS 385 +#define _INTERNAL_INCREMENT_OPT_COUNTER 386 +#define MAX_UOP_ID 386 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 14d3382e895cdf..2b5b37e6b8d6a4 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -204,6 +204,10 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_CHECK_VALIDITY] = HAS_DEOPT_FLAG, [_LOAD_CONST_INLINE] = 0, [_LOAD_CONST_INLINE_BORROW] = 0, + [_LOAD_CONST_INLINE_WITH_NULL] = 0, + [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = 0, + [_CHECK_GLOBALS] = HAS_DEOPT_FLAG, + [_CHECK_BUILTINS] = HAS_DEOPT_FLAG, [_INTERNAL_INCREMENT_OPT_COUNTER] = 0, }; @@ -250,10 +254,12 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT", [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE", [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT", + [_CHECK_BUILTINS] = "_CHECK_BUILTINS", [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS", [_CHECK_EG_MATCH] = "_CHECK_EG_MATCH", [_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH", [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS", + [_CHECK_GLOBALS] = "_CHECK_GLOBALS", [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES", [_CHECK_PEP_523] = "_CHECK_PEP_523", [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE", @@ -332,6 +338,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_CONST] = "_LOAD_CONST", [_LOAD_CONST_INLINE] = "_LOAD_CONST_INLINE", [_LOAD_CONST_INLINE_BORROW] = "_LOAD_CONST_INLINE_BORROW", + [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = "_LOAD_CONST_INLINE_BORROW_WITH_NULL", + [_LOAD_CONST_INLINE_WITH_NULL] = "_LOAD_CONST_INLINE_WITH_NULL", [_LOAD_DEREF] = "_LOAD_DEREF", [_LOAD_FAST] = "_LOAD_FAST", [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR", diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 5981712c80c3a9..ae062b1bda26b7 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -151,8 +151,8 @@ def test_watch_out_of_range_watcher_id(self): def test_watch_unassigned_watcher_id(self): d = {} - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): - self.watch(1, d) + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 3"): + self.watch(3, d) def test_unwatch_non_dict(self): with self.watcher() as wid: @@ -168,8 +168,8 @@ def test_unwatch_out_of_range_watcher_id(self): def test_unwatch_unassigned_watcher_id(self): d = {} - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): - self.unwatch(1, d) + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 3"): + self.unwatch(3, d) def test_clear_out_of_range_watcher_id(self): with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): @@ -178,8 +178,8 @@ def test_clear_out_of_range_watcher_id(self): self.clear_watcher(8) # DICT_MAX_WATCHERS = 8 def test_clear_unassigned_watcher_id(self): - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): - self.clear_watcher(1) + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 3"): + self.clear_watcher(3) class TestTypeWatchers(unittest.TestCase): diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index a763ff46a3c290..1eb0db2c2e6576 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -15,8 +15,8 @@ module _testcapi /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ // Test dict watching -static PyObject *g_dict_watch_events; -static int g_dict_watchers_installed; +static PyObject *g_dict_watch_events = NULL; +static int g_dict_watchers_installed = 0; static int dict_watch_callback(PyDict_WatchEvent event, diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e24887b7d781bb..4bb818b90a4a72 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5943,7 +5943,8 @@ PyDict_AddWatcher(PyDict_WatchCallback callback) { PyInterpreterState *interp = _PyInterpreterState_GET(); - for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + /* Start at 2, as 0 and 1 are reserved for CPython */ + for (int i = 2; i < DICT_MAX_WATCHERS; i++) { if (!interp->dict_state.watchers[i]) { interp->dict_state.watchers[i] = callback; return i; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ebd5b06abb2d4e..6fb4d719e43991 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4071,11 +4071,35 @@ dummy_func( } op(_LOAD_CONST_INLINE, (ptr/4 -- value)) { + TIER_TWO_ONLY value = Py_NewRef(ptr); } op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) { + TIER_TWO_ONLY + value = ptr; + } + + op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) { + TIER_TWO_ONLY + value = Py_NewRef(ptr); + null = NULL; + } + + op(_LOAD_CONST_INLINE_BORROW_WITH_NULL, (ptr/4 -- value, null)) { + TIER_TWO_ONLY value = ptr; + null = NULL; + } + + op(_CHECK_GLOBALS, (dict/4 -- )) { + TIER_TWO_ONLY + DEOPT_IF(GLOBALS() != dict); + } + + op(_CHECK_BUILTINS, (dict/4 -- )) { + TIER_TWO_ONLY + DEOPT_IF(BUILTINS() != dict); } /* Internal -- for testing executors */ diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 241b9056207715..2d914b82dbf88f 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3393,6 +3393,7 @@ case _LOAD_CONST_INLINE: { PyObject *value; PyObject *ptr = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY value = Py_NewRef(ptr); stack_pointer[0] = value; stack_pointer += 1; @@ -3402,12 +3403,53 @@ case _LOAD_CONST_INLINE_BORROW: { PyObject *value; PyObject *ptr = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY value = ptr; stack_pointer[0] = value; stack_pointer += 1; break; } + case _LOAD_CONST_INLINE_WITH_NULL: { + PyObject *value; + PyObject *null; + PyObject *ptr = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY + value = Py_NewRef(ptr); + null = NULL; + stack_pointer[0] = value; + stack_pointer[1] = null; + stack_pointer += 2; + break; + } + + case _LOAD_CONST_INLINE_BORROW_WITH_NULL: { + PyObject *value; + PyObject *null; + PyObject *ptr = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY + value = ptr; + null = NULL; + stack_pointer[0] = value; + stack_pointer[1] = null; + stack_pointer += 2; + break; + } + + case _CHECK_GLOBALS: { + PyObject *dict = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY + if (GLOBALS() != dict) goto deoptimize; + break; + } + + case _CHECK_BUILTINS: { + PyObject *dict = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY + if (BUILTINS() != dict) goto deoptimize; + break; + } + case _INTERNAL_INCREMENT_OPT_COUNTER: { PyObject *opt; opt = stack_pointer[-1]; diff --git a/Python/optimizer.c b/Python/optimizer.c index 0d04b09fef1e84..d71ca0aef0e11a 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -108,16 +108,14 @@ PyUnstable_Replace_Executor(PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutor } static int -error_optimize( +never_optimize( _PyOptimizerObject* self, - PyCodeObject *code, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _PyExecutorObject **exec, int Py_UNUSED(stack_entries)) { - assert(0); - PyErr_Format(PyExc_SystemError, "Should never call error_optimize"); - return -1; + return 0; } PyTypeObject _PyDefaultOptimizer_Type = { @@ -130,7 +128,7 @@ PyTypeObject _PyDefaultOptimizer_Type = { _PyOptimizerObject _PyOptimizer_Default = { PyObject_HEAD_INIT(&_PyDefaultOptimizer_Type) - .optimize = error_optimize, + .optimize = never_optimize, .resume_threshold = INT16_MAX, .backedge_threshold = INT16_MAX, }; @@ -174,7 +172,7 @@ _PyOptimizer_Optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject } _PyOptimizerObject *opt = interp->optimizer; _PyExecutorObject *executor = NULL; - int err = opt->optimize(opt, code, start, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame))); + int err = opt->optimize(opt, frame, start, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame))); if (err <= 0) { assert(executor == NULL); return err; @@ -363,7 +361,8 @@ BRANCH_TO_GUARD[4][2] = { ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \ goto done; \ } \ - trace_stack[trace_stack_depth].code = code; \ + assert(func->func_code == (PyObject *)code); \ + trace_stack[trace_stack_depth].func = func; \ trace_stack[trace_stack_depth].instr = instr; \ trace_stack_depth++; #define TRACE_STACK_POP() \ @@ -371,7 +370,8 @@ BRANCH_TO_GUARD[4][2] = { Py_FatalError("Trace stack underflow\n"); \ } \ trace_stack_depth--; \ - code = trace_stack[trace_stack_depth].code; \ + func = trace_stack[trace_stack_depth].func; \ + code = (PyCodeObject *)trace_stack[trace_stack_depth].func->func_code; \ instr = trace_stack[trace_stack_depth].instr; /* Returns 1 on success, @@ -380,20 +380,23 @@ BRANCH_TO_GUARD[4][2] = { */ static int translate_bytecode_to_trace( - PyCodeObject *code, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _PyUOpInstruction *trace, int buffer_size, _PyBloomFilter *dependencies) { bool progress_needed = true; + PyCodeObject *code = (PyCodeObject *)frame->f_executable; + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + assert(PyFunction_Check(func)); PyCodeObject *initial_code = code; _Py_BloomFilter_Add(dependencies, initial_code); _Py_CODEUNIT *initial_instr = instr; int trace_length = 0; int max_length = buffer_size; struct { - PyCodeObject *code; + PyFunctionObject *func; _Py_CODEUNIT *instr; } trace_stack[TRACE_STACK_SIZE]; int trace_stack_depth = 0; @@ -593,9 +596,9 @@ translate_bytecode_to_trace( ADD_TO_TRACE(uop, oparg, operand, target); if (uop == _POP_FRAME) { TRACE_STACK_POP(); - /* Set the operand to the code object returned to, + /* Set the operand to the function object returned to, * to assist optimization passes */ - trace[trace_length-1].operand = (uintptr_t)code; + trace[trace_length-1].operand = (uintptr_t)func; DPRINTF(2, "Returning to %s (%s:%d) at byte offset %d\n", PyUnicode_AsUTF8(code->co_qualname), @@ -611,10 +614,10 @@ translate_bytecode_to_trace( // Add one to account for the actual opcode/oparg pair: + 1; uint32_t func_version = read_u32(&instr[func_version_offset].cache); - PyFunctionObject *func = _PyFunction_LookupByVersion(func_version); + PyFunctionObject *new_func = _PyFunction_LookupByVersion(func_version); DPRINTF(3, "Function object: %p\n", func); - if (func != NULL) { - PyCodeObject *new_code = (PyCodeObject *)PyFunction_GET_CODE(func); + if (new_func != NULL) { + PyCodeObject *new_code = (PyCodeObject *)PyFunction_GET_CODE(new_func); if (new_code == code) { // Recursive call, bail (we could be here forever). DPRINTF(2, "Bailing on recursive call to %s (%s:%d)\n", @@ -639,8 +642,9 @@ translate_bytecode_to_trace( _Py_BloomFilter_Add(dependencies, new_code); /* Set the operand to the callee's code object, * to assist optimization passes */ - trace[trace_length-1].operand = (uintptr_t)new_code; + trace[trace_length-1].operand = (uintptr_t)new_func; code = new_code; + func = new_func; instr = _PyCode_CODE(code); DPRINTF(2, "Continuing in %s (%s:%d) at byte offset %d\n", @@ -808,7 +812,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies) static int uop_optimize( _PyOptimizerObject *self, - PyCodeObject *code, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _PyExecutorObject **exec_ptr, int curr_stackentries) @@ -816,7 +820,7 @@ uop_optimize( _PyBloomFilter dependencies; _Py_BloomFilter_Init(&dependencies); _PyUOpInstruction buffer[UOP_MAX_TRACE_LENGTH]; - int err = translate_bytecode_to_trace(code, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies); + int err = translate_bytecode_to_trace(frame, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies); if (err <= 0) { // Error or nothing translated return err; @@ -824,9 +828,10 @@ uop_optimize( OPT_STAT_INC(traces_created); char *uop_optimize = Py_GETENV("PYTHONUOPSOPTIMIZE"); if (uop_optimize == NULL || *uop_optimize > '0') { - err = _Py_uop_analyze_and_optimize(code, buffer, UOP_MAX_TRACE_LENGTH, curr_stackentries); - if (err < 0) { - return -1; + err = _Py_uop_analyze_and_optimize(frame, buffer, + UOP_MAX_TRACE_LENGTH, curr_stackentries, &dependencies); + if (err <= 0) { + return err; } } _PyExecutorObject *executor = make_executor_from_uops(buffer, &dependencies); @@ -887,12 +892,13 @@ PyTypeObject _PyCounterExecutor_Type = { static int counter_optimize( _PyOptimizerObject* self, - PyCodeObject *code, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _PyExecutorObject **exec_ptr, int Py_UNUSED(curr_stackentries) ) { + PyCodeObject *code = (PyCodeObject *)frame->f_executable; int oparg = instr->op.arg; while (instr->op.code == EXTENDED_ARG) { instr++; diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index d1225997e10be2..2cfbf4b349d0f5 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -1,10 +1,12 @@ #include "Python.h" #include "opcode.h" +#include "pycore_dict.h" #include "pycore_interp.h" #include "pycore_opcode_metadata.h" #include "pycore_opcode_utils.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_uop_metadata.h" +#include "pycore_dict.h" #include "pycore_long.h" #include "cpython/optimizer.h" #include @@ -12,9 +14,210 @@ #include #include "pycore_optimizer.h" +static int +get_mutations(PyObject* dict) { + assert(PyDict_CheckExact(dict)); + PyDictObject *d = (PyDictObject *)dict; + return (d->ma_version_tag >> DICT_MAX_WATCHERS) & ((1 << DICT_WATCHED_MUTATION_BITS)-1); +} + static void -peephole_opt(PyCodeObject *co, _PyUOpInstruction *buffer, int buffer_size) +increment_mutations(PyObject* dict) { + assert(PyDict_CheckExact(dict)); + PyDictObject *d = (PyDictObject *)dict; + d->ma_version_tag += (1 << DICT_MAX_WATCHERS); +} + +static int +globals_watcher_callback(PyDict_WatchEvent event, PyObject* dict, + PyObject* key, PyObject* new_value) +{ + if (event == PyDict_EVENT_CLONED) { + return 0; + } + uint64_t watched_mutations = get_mutations(dict); + if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) { + _Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict); + increment_mutations(dict); + } + else { + PyDict_Unwatch(1, dict); + } + return 0; +} + + +static void +global_to_const(_PyUOpInstruction *inst, PyObject *obj) +{ + assert(inst->opcode == _LOAD_GLOBAL_MODULE || inst->opcode == _LOAD_GLOBAL_BUILTINS); + assert(PyDict_CheckExact(obj)); + PyDictObject *dict = (PyDictObject *)obj; + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + assert(inst->operand <= UINT16_MAX); + PyObject *res = entries[inst->operand].me_value; + if (res == NULL) { + return; + } + if (_Py_IsImmortal(res)) { + inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_BORROW_WITH_NULL : _LOAD_CONST_INLINE_BORROW; + } + else { + inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE; + } + inst->operand = (uint64_t)res; +} + +static int +incorrect_keys(_PyUOpInstruction *inst, PyObject *obj) { + if (!PyDict_CheckExact(obj)) { + return 1; + } + PyDictObject *dict = (PyDictObject *)obj; + if (dict->ma_keys->dk_version != inst->operand) { + return 1; + } + return 0; +} + +/* The first two dict watcher IDs are reserved for CPython, + * so we don't need to check that they haven't been used */ +#define BUILTINS_WATCHER_ID 0 +#define GLOBALS_WATCHER_ID 1 + +/* Returns 1 if successfully optimized + * 0 if the trace is not suitable for optimization (yet) + * -1 if there was an error. */ +static int +remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, + int buffer_size, _PyBloomFilter *dependencies) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *builtins = frame->f_builtins; + if (builtins != interp->builtins) { + return 1; + } + PyObject *globals = frame->f_globals; + assert(PyFunction_Check(((PyFunctionObject *)frame->f_funcobj))); + assert(((PyFunctionObject *)frame->f_funcobj)->func_builtins == builtins); + assert(((PyFunctionObject *)frame->f_funcobj)->func_globals == globals); + /* In order to treat globals as constants, we need to + * know that the globals dict is the one we expected, and + * that it hasn't changed + * In order to treat builtins as constants, we need to + * know that the builtins dict is the one we expected, and + * that it hasn't changed and that the global dictionary's + * keys have not changed */ + + /* These values represent stacks of booleans (one bool per bit). + * Pushing a frame shifts left, popping a frame shifts right. */ + uint32_t builtins_checked = 0; + uint32_t builtins_watched = 0; + uint32_t globals_checked = 0; + uint32_t globals_watched = 0; + if (interp->dict_state.watchers[1] == NULL) { + interp->dict_state.watchers[1] = globals_watcher_callback; + } + for (int pc = 0; pc < buffer_size; pc++) { + _PyUOpInstruction *inst = &buffer[pc]; + int opcode = inst->opcode; + switch(opcode) { + case _GUARD_BUILTINS_VERSION: + if (incorrect_keys(inst, builtins)) { + return 0; + } + if (interp->rare_events.builtin_dict >= _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) { + continue; + } + if ((builtins_watched & 1) == 0) { + PyDict_Watch(BUILTINS_WATCHER_ID, builtins); + builtins_watched |= 1; + } + if (builtins_checked & 1) { + buffer[pc].opcode = NOP; + } + else { + buffer[pc].opcode = _CHECK_BUILTINS; + buffer[pc].operand = (uintptr_t)builtins; + builtins_checked |= 1; + } + break; + case _GUARD_GLOBALS_VERSION: + if (incorrect_keys(inst, globals)) { + return 0; + } + uint64_t watched_mutations = get_mutations(globals); + if (watched_mutations >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) { + continue; + } + if ((globals_watched & 1) == 0) { + PyDict_Watch(GLOBALS_WATCHER_ID, globals); + _Py_BloomFilter_Add(dependencies, globals); + globals_watched |= 1; + } + if (globals_checked & 1) { + buffer[pc].opcode = NOP; + } + else { + buffer[pc].opcode = _CHECK_GLOBALS; + buffer[pc].operand = (uintptr_t)globals; + globals_checked |= 1; + } + break; + case _LOAD_GLOBAL_BUILTINS: + if (globals_checked & builtins_checked & globals_watched & builtins_watched & 1) { + global_to_const(inst, builtins); + } + break; + case _LOAD_GLOBAL_MODULE: + if (globals_checked & globals_watched & 1) { + global_to_const(inst, globals); + } + break; + case _PUSH_FRAME: + { + globals_checked <<= 1; + globals_watched <<= 1; + builtins_checked <<= 1; + builtins_watched <<= 1; + PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand; + if (func == NULL) { + return 1; + } + assert(PyFunction_Check(func)); + globals = func->func_globals; + builtins = func->func_builtins; + if (builtins != interp->builtins) { + return 1; + } + break; + } + case _POP_FRAME: + { + globals_checked >>= 1; + globals_watched >>= 1; + builtins_checked >>= 1; + builtins_watched >>= 1; + PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand; + assert(PyFunction_Check(func)); + globals = func->func_globals; + builtins = func->func_builtins; + break; + } + case _JUMP_TO_TOP: + case _EXIT_TRACE: + return 1; + } + } + return 0; +} + +static void +peephole_opt(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, int buffer_size) +{ + PyCodeObject *co = (PyCodeObject *)frame->f_executable; for (int pc = 0; pc < buffer_size; pc++) { int opcode = buffer[pc].opcode; switch(opcode) { @@ -36,8 +239,17 @@ peephole_opt(PyCodeObject *co, _PyUOpInstruction *buffer, int buffer_size) } case _PUSH_FRAME: case _POP_FRAME: - co = (PyCodeObject *)buffer[pc].operand; + { + PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand; + if (func == NULL) { + co = NULL; + } + else { + assert(PyFunction_Check(func)); + co = (PyCodeObject *)func->func_code; + } break; + } case _JUMP_TO_TOP: case _EXIT_TRACE: return; @@ -83,16 +295,20 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size) } } - int _Py_uop_analyze_and_optimize( - PyCodeObject *co, + _PyInterpreterFrame *frame, _PyUOpInstruction *buffer, int buffer_size, - int curr_stacklen + int curr_stacklen, + _PyBloomFilter *dependencies ) { - peephole_opt(co, buffer, buffer_size); + int err = remove_globals(frame, buffer, buffer_size, dependencies); + if (err <= 0) { + return err; + } + peephole_opt(frame, buffer, buffer_size); remove_unneeded_uops(buffer, buffer_size); - return 0; + return 1; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 372f60602375b6..0cac7109340129 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -32,6 +32,7 @@ #include "pycore_typevarobject.h" // _Py_clear_generic_types() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() #include "pycore_weakref.h" // _PyWeakref_GET_REF() +#include "cpython/optimizer.h" // _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS #include "pycore_obmalloc.h" // _PyMem_init_obmalloc() #include "opcode.h" @@ -609,7 +610,11 @@ init_interp_create_gil(PyThreadState *tstate, int gil) static int builtins_dict_watcher(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value) { - RARE_EVENT_INC(builtin_dict); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (event != PyDict_EVENT_CLONED && interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) { + _Py_Executors_InvalidateAll(interp); + } + RARE_EVENT_INTERP_INC(interp, builtin_dict); return 0; } @@ -1287,11 +1292,9 @@ init_interp_main(PyThreadState *tstate) } } - if ((interp->rare_events.builtins_dict_watcher_id = PyDict_AddWatcher(&builtins_dict_watcher)) == -1) { - return _PyStatus_ERR("failed to add builtin dict watcher"); - } - if (PyDict_Watch(interp->rare_events.builtins_dict_watcher_id, interp->builtins) != 0) { + interp->dict_state.watchers[0] = &builtins_dict_watcher; + if (PyDict_Watch(0, interp->builtins) != 0) { return _PyStatus_ERR("failed to set builtin dict watcher"); } @@ -1622,8 +1625,13 @@ finalize_modules(PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; - // Stop collecting stats on __builtin__ modifications during teardown - PyDict_Unwatch(interp->rare_events.builtins_dict_watcher_id, interp->builtins); + // Invalidate all executors and turn off tier 2 optimizer + _Py_Executors_InvalidateAll(interp); + Py_XDECREF(interp->optimizer); + interp->optimizer = &_PyOptimizer_Default; + + // Stop watching __builtin__ modifications + PyDict_Unwatch(0, interp->builtins); PyObject *modules = _PyImport_GetModules(interp); if (modules == NULL) { From d0f1307580a69372611d27b04bbf2551dc85a1ef Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 2 Feb 2024 08:03:15 -0500 Subject: [PATCH 09/62] gh-114329: Add `PyList_GetItemRef` function (GH-114504) The new `PyList_GetItemRef` is similar to `PyList_GetItem`, but returns a strong reference instead of a borrowed reference. Additionally, if the passed "list" object is not a list, the function sets a `TypeError` instead of calling `PyErr_BadInternalCall()`. --- Doc/c-api/list.rst | 12 ++++++++-- Doc/data/refcounts.dat | 4 ++++ Doc/data/stable_abi.dat | 1 + Doc/whatsnew/3.13.rst | 4 ++++ Include/listobject.h | 1 + Lib/test/test_capi/test_list.py | 22 +++++++++++-------- Lib/test/test_stable_abi_ctypes.py | 1 + ...-01-23-21-45-02.gh-issue-114329.YRaBoe.rst | 3 +++ Misc/stable_abi.toml | 2 ++ Modules/_testcapi/list.c | 13 +++++++++++ Objects/listobject.c | 15 +++++++++++++ PC/python3dll.c | 1 + 12 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2024-01-23-21-45-02.gh-issue-114329.YRaBoe.rst diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index c8b64bad702f50..53eb54d3e1021a 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -56,13 +56,21 @@ List Objects Similar to :c:func:`PyList_Size`, but without error checking. -.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) +.. c:function:: PyObject* PyList_GetItemRef(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The position must be non-negative; indexing from the end of the list is not - supported. If *index* is out of bounds (<0 or >=len(list)), + supported. If *index* is out of bounds (:code:`<0 or >=len(list)`), return ``NULL`` and set an :exc:`IndexError` exception. + .. versionadded:: 3.13 + + +.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) + + Like :c:func:`PyList_GetItemRef`, but returns a + :term:`borrowed reference` instead of a :term:`strong reference`. + .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index f719ce153b239a..62a96146d605ff 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1133,6 +1133,10 @@ PyList_GetItem:PyObject*::0: PyList_GetItem:PyObject*:list:0: PyList_GetItem:Py_ssize_t:index:: +PyList_GetItemRef:PyObject*::+1: +PyList_GetItemRef:PyObject*:list:0: +PyList_GetItemRef:Py_ssize_t:index:: + PyList_GetSlice:PyObject*::+1: PyList_GetSlice:PyObject*:list:0: PyList_GetSlice:Py_ssize_t:low:: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index da28a2be60bc1b..def1903204add7 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -336,6 +336,7 @@ var,PyListRevIter_Type,3.2,, function,PyList_Append,3.2,, function,PyList_AsTuple,3.2,, function,PyList_GetItem,3.2,, +function,PyList_GetItemRef,3.13,, function,PyList_GetSlice,3.2,, function,PyList_Insert,3.2,, function,PyList_New,3.2,, diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 887c3009f88504..f17c6ec0775bef 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1376,6 +1376,10 @@ New Features UTF-8 encoded bytes string, rather than a :c:expr:`PyObject*`. (Contributed by Victor Stinner in :gh:`108314`.) +* Added :c:func:`PyList_GetItemRef` function: similar to + :c:func:`PyList_GetItem` but returns a :term:`strong reference` instead of + a :term:`borrowed reference`. + * Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter is :term:`shutting down `. (Contributed by Victor Stinner in :gh:`108014`.) diff --git a/Include/listobject.h b/Include/listobject.h index 6b7041ba0b05d5..4e4084b43483a2 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -29,6 +29,7 @@ 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(PyObject *) PyList_GetItemRef(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 *); diff --git a/Lib/test/test_capi/test_list.py b/Lib/test/test_capi/test_list.py index eb03d51d3def37..dceb4fce3c077b 100644 --- a/Lib/test/test_capi/test_list.py +++ b/Lib/test/test_capi/test_list.py @@ -82,10 +82,8 @@ def test_list_get_size(self): # CRASHES size(UserList()) # CRASHES size(NULL) - - def test_list_getitem(self): - # Test PyList_GetItem() - getitem = _testcapi.list_getitem + def check_list_get_item(self, getitem, exctype): + # Common test cases for PyList_GetItem() and PyList_GetItemRef() lst = [1, 2, 3] self.assertEqual(getitem(lst, 0), 1) self.assertEqual(getitem(lst, 2), 3) @@ -93,12 +91,19 @@ def test_list_getitem(self): self.assertRaises(IndexError, getitem, lst, -1) self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MIN) self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MAX) - self.assertRaises(SystemError, getitem, 42, 1) - self.assertRaises(SystemError, getitem, (1, 2, 3), 1) - self.assertRaises(SystemError, getitem, {1: 2}, 1) - + self.assertRaises(exctype, getitem, 42, 1) + self.assertRaises(exctype, getitem, (1, 2, 3), 1) + self.assertRaises(exctype, getitem, {1: 2}, 1) # CRASHES getitem(NULL, 1) + def test_list_getitem(self): + # Test PyList_GetItem() + self.check_list_get_item(_testcapi.list_getitem, SystemError) + + def test_list_get_item_ref(self): + # Test PyList_GetItemRef() + self.check_list_get_item(_testcapi.list_get_item_ref, TypeError) + def test_list_get_item(self): # Test PyList_GET_ITEM() get_item = _testcapi.list_get_item @@ -112,7 +117,6 @@ def test_list_get_item(self): # CRASHES get_item(21, 2) # CRASHES get_item(NULL, 1) - def test_list_setitem(self): # Test PyList_SetItem() setitem = _testcapi.list_setitem diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 054e7f0feb1a19..8bd373976426ef 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -372,6 +372,7 @@ def test_windows_feature_macros(self): "PyList_Append", "PyList_AsTuple", "PyList_GetItem", + "PyList_GetItemRef", "PyList_GetSlice", "PyList_Insert", "PyList_New", diff --git a/Misc/NEWS.d/next/C API/2024-01-23-21-45-02.gh-issue-114329.YRaBoe.rst b/Misc/NEWS.d/next/C API/2024-01-23-21-45-02.gh-issue-114329.YRaBoe.rst new file mode 100644 index 00000000000000..62d4ce0cfb8de5 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2024-01-23-21-45-02.gh-issue-114329.YRaBoe.rst @@ -0,0 +1,3 @@ +Add :c:func:`PyList_GetItemRef`, which is similar to +:c:func:`PyList_GetItem` but returns a :term:`strong reference` instead of a +:term:`borrowed reference`. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index ae19d25809ec86..a9875f6ffd1a56 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2487,3 +2487,5 @@ abi_only = true [data.PyExc_IncompleteInputError] added = '3.13' +[function.PyList_GetItemRef] + added = '3.13' diff --git a/Modules/_testcapi/list.c b/Modules/_testcapi/list.c index 10e18699f01bc1..2cb6499e28336d 100644 --- a/Modules/_testcapi/list.c +++ b/Modules/_testcapi/list.c @@ -59,6 +59,18 @@ list_get_item(PyObject *Py_UNUSED(module), PyObject *args) return Py_XNewRef(PyList_GET_ITEM(obj, i)); } +static PyObject * +list_get_item_ref(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &obj, &i)) { + return NULL; + } + NULLABLE(obj); + return PyList_GetItemRef(obj, i); +} + static PyObject * list_setitem(PyObject *Py_UNUSED(module), PyObject *args) { @@ -191,6 +203,7 @@ static PyMethodDef test_methods[] = { {"list_get_size", list_get_size, METH_O}, {"list_getitem", list_getitem, METH_VARARGS}, {"list_get_item", list_get_item, METH_VARARGS}, + {"list_get_item_ref", list_get_item_ref, METH_VARARGS}, {"list_setitem", list_setitem, METH_VARARGS}, {"list_set_item", list_set_item, METH_VARARGS}, {"list_insert", list_insert, METH_VARARGS}, diff --git a/Objects/listobject.c b/Objects/listobject.c index da2b9cc32697dd..82a4ba952de07d 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -257,6 +257,21 @@ PyList_GetItem(PyObject *op, Py_ssize_t i) return ((PyListObject *)op) -> ob_item[i]; } +PyObject * +PyList_GetItemRef(PyObject *op, Py_ssize_t i) +{ + if (!PyList_Check(op)) { + PyErr_SetString(PyExc_TypeError, "expected a list"); + return NULL; + } + if (!valid_index(i, Py_SIZE(op))) { + _Py_DECLARE_STR(list_err, "list index out of range"); + PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err)); + return NULL; + } + return Py_NewRef(PyList_GET_ITEM(op, i)); +} + int PyList_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) diff --git a/PC/python3dll.c b/PC/python3dll.c index 09ecf98fe56ea6..aa6bfe2c4022db 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -324,6 +324,7 @@ EXPORT_FUNC(PyIter_Send) EXPORT_FUNC(PyList_Append) EXPORT_FUNC(PyList_AsTuple) EXPORT_FUNC(PyList_GetItem) +EXPORT_FUNC(PyList_GetItemRef) EXPORT_FUNC(PyList_GetSlice) EXPORT_FUNC(PyList_Insert) EXPORT_FUNC(PyList_New) From d29f57f6036353b4e705a42637177442bf7e07e5 Mon Sep 17 00:00:00 2001 From: Justin Williams <97240811+juswil@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:32:46 -0500 Subject: [PATCH 10/62] gh-103360: Add link in stdtypes.rst to escape sequences in lexical_analysis.rst (GH-103638) --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 9028ff5c134fa9..1a4c12590c1018 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1528,7 +1528,7 @@ between them will be implicitly converted to a single string literal. That is, ``("spam " "eggs") == "spam eggs"``. See :ref:`strings` for more about the various forms of string literal, -including supported escape sequences, and the ``r`` ("raw") prefix that +including supported :ref:`escape sequences `, and the ``r`` ("raw") prefix that disables most escape sequence processing. Strings may also be created from other objects using the :class:`str` From b3f0b698daf2438a6e59d5d19ccb34acdba0bffc Mon Sep 17 00:00:00 2001 From: Andrew Rogers <32688592+adr26@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:50:51 +0000 Subject: [PATCH 11/62] gh-104530: Enable native Win32 condition variables by default (GH-104531) --- Include/internal/pycore_condvar.h | 10 ++++---- ...-05-16-06-52-34.gh-issue-104530.mJnA0W.rst | 1 + Python/ceval_gil.c | 8 +++++++ Python/condvar.h | 23 +++++++++++-------- Python/pystate.c | 12 +++++++++- Python/thread_nt.h | 22 ++---------------- 6 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h index 34c21aaad43197..ee9533484e8048 100644 --- a/Include/internal/pycore_condvar.h +++ b/Include/internal/pycore_condvar.h @@ -35,14 +35,14 @@ #include // CRITICAL_SECTION /* options */ -/* non-emulated condition variables are provided for those that want - * to target Windows Vista. Modify this macro to enable them. +/* emulated condition variables are provided for those that want + * to target Windows XP or earlier. Modify this macro to enable them. */ #ifndef _PY_EMULATED_WIN_CV -#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */ +#define _PY_EMULATED_WIN_CV 0 /* use non-emulated condition variables */ #endif -/* fall back to emulation if not targeting Vista */ +/* fall back to emulation if targeting earlier than Vista */ #if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA #undef _PY_EMULATED_WIN_CV #define _PY_EMULATED_WIN_CV 1 @@ -77,7 +77,7 @@ typedef struct _PyCOND_T #else /* !_PY_EMULATED_WIN_CV */ -/* Use native Win7 primitives if build target is Win7 or higher */ +/* Use native Windows primitives if build target is Vista or higher */ /* SRWLOCK is faster and better than CriticalSection */ typedef SRWLOCK PyMUTEX_T; diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst new file mode 100644 index 00000000000000..8643a25ae51b13 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-05-16-06-52-34.gh-issue-104530.mJnA0W.rst @@ -0,0 +1 @@ +Use native Win32 condition variables. diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index f3b169241535f3..ad90359318761a 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -610,8 +610,16 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { +#ifdef MS_WINDOWS + int err = GetLastError(); +#endif + _Py_EnsureTstateNotNULL(tstate); _PyThreadState_Attach(tstate); + +#ifdef MS_WINDOWS + SetLastError(err); +#endif } diff --git a/Python/condvar.h b/Python/condvar.h index d54db94f2c871d..dcabed6d55928c 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -260,13 +260,13 @@ PyMUTEX_UNLOCK(PyMUTEX_T *cs) return 0; } - Py_LOCAL_INLINE(int) PyCOND_INIT(PyCOND_T *cv) { InitializeConditionVariable(cv); return 0; } + Py_LOCAL_INLINE(int) PyCOND_FINI(PyCOND_T *cv) { @@ -279,27 +279,32 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) return SleepConditionVariableSRW(cv, cs, INFINITE, 0) ? 0 : -1; } -/* This implementation makes no distinction about timeouts. Signal - * 2 to indicate that we don't know. - */ +/* return 0 for success, 1 on timeout, -1 on error */ Py_LOCAL_INLINE(int) PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) { - return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1; + BOOL success = SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0); + if (!success) { + if (GetLastError() == ERROR_TIMEOUT) { + return 1; + } + return -1; + } + return 0; } Py_LOCAL_INLINE(int) PyCOND_SIGNAL(PyCOND_T *cv) { - WakeConditionVariable(cv); - return 0; + WakeConditionVariable(cv); + return 0; } Py_LOCAL_INLINE(int) PyCOND_BROADCAST(PyCOND_T *cv) { - WakeAllConditionVariable(cv); - return 0; + WakeAllConditionVariable(cv); + return 0; } diff --git a/Python/pystate.c b/Python/pystate.c index 27b6d0573ade3b..7836c172bbfb61 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -2488,7 +2488,17 @@ PyGILState_Check(void) return 0; } - return (tstate == gilstate_tss_get(runtime)); +#ifdef MS_WINDOWS + int err = GetLastError(); +#endif + + PyThreadState *tcur = gilstate_tss_get(runtime); + +#ifdef MS_WINDOWS + SetLastError(err); +#endif + + return (tstate == tcur); } PyGILState_STATE diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 14b9cddc24c0ec..044e9fa111e979 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -444,16 +444,7 @@ PyThread_set_key_value(int key, void *value) void * PyThread_get_key_value(int key) { - /* because TLS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key); - SetLastError(error); - return result; + return TlsGetValue(key); } void @@ -525,14 +516,5 @@ void * PyThread_tss_get(Py_tss_t *key) { assert(key != NULL); - /* because TSS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key->_key); - SetLastError(error); - return result; + return TlsGetValue(key->_key); } From ee66c333493105e014678be118850e138e3c62a8 Mon Sep 17 00:00:00 2001 From: Steven Ward Date: Fri, 2 Feb 2024 10:13:00 -0500 Subject: [PATCH 12/62] gh-114909: Add --first-weekday option to usage message (#114910) --- Doc/library/calendar.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index c4dcf5641d6066..e699a7284ac802 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -512,7 +512,7 @@ to interactively print a calendar. python -m calendar [-h] [-L LOCALE] [-e ENCODING] [-t {text,html}] [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS] [-c CSS] - [year] [month] + [-f FIRST_WEEKDAY] [year] [month] For example, to print a calendar for the year 2000: @@ -586,12 +586,13 @@ The following options are accepted: or as an HTML document. -.. option:: --first-weekday WEEKDAY, -f WEEKDAY +.. option:: --first-weekday FIRST_WEEKDAY, -f FIRST_WEEKDAY The weekday to start each week. Must be a number between 0 (Monday) and 6 (Sunday). Defaults to 0. + .. versionadded:: 3.13 .. option:: year From 9872855a31720f514b84373848b49fca09d66ecd Mon Sep 17 00:00:00 2001 From: patenaud <33957588+patenaud@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:31:55 -0500 Subject: [PATCH 13/62] GH-69695: Update ``PyImport_ImportModule`` description (GH-103836) Co-authored-by: Alex Waygood Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Doc/c-api/import.rst | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 51c20b202f091c..7c74e9e88678dc 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -13,20 +13,8 @@ Importing Modules single: __all__ (package variable) single: modules (in module sys) - This is a simplified interface to :c:func:`PyImport_ImportModuleEx` below, - leaving the *globals* and *locals* arguments set to ``NULL`` and *level* set - to 0. When the *name* - argument contains a dot (when it specifies a submodule of a package), the - *fromlist* argument is set to the list ``['*']`` so that the return value is the - named module rather than the top-level package containing it as would otherwise - be the case. (Unfortunately, this has an additional side effect when *name* in - fact specifies a subpackage instead of a submodule: the submodules specified in - the package's ``__all__`` variable are loaded.) Return a new reference to the - imported module, or ``NULL`` with an exception set on failure. A failing - import of a module doesn't leave the module in :data:`sys.modules`. - - This function always uses absolute imports. - + This is a wrapper around :c:func:`PyImport_Import()` which takes a + :c:expr:`const char *` as an argument instead of a :c:expr:`PyObject *`. .. c:function:: PyObject* PyImport_ImportModuleNoBlock(const char *name) From c12240ed28aac6494750e00143bc550c4d6d8ad1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 2 Feb 2024 20:53:24 +0200 Subject: [PATCH 14/62] gh-114728: Fix documentation for comparison of objects in datetime module (GH-114749) --- Doc/library/datetime.rst | 118 +++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 68 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index db9a92ae4111e3..096670634ee956 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -400,30 +400,7 @@ objects (see below). the :func:`divmod` function. True division and multiplication of a :class:`timedelta` object by a :class:`float` object are now supported. - -Comparisons of :class:`timedelta` objects are supported, with some caveats. - -The comparisons ``==`` or ``!=`` *always* return a :class:`bool`, no matter -the type of the compared object:: - - >>> from datetime import timedelta - >>> delta1 = timedelta(seconds=57) - >>> delta2 = timedelta(hours=25, seconds=2) - >>> delta2 != delta1 - True - >>> delta2 == 5 - False - -For all other comparisons (such as ``<`` and ``>``), when a :class:`timedelta` -object is compared to an object of a different type, :exc:`TypeError` -is raised:: - - >>> delta2 > delta1 - True - >>> delta2 > 5 - Traceback (most recent call last): - File "", line 1, in - TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int' +:class:`timedelta` objects support equality and order comparisons. In Boolean contexts, a :class:`timedelta` object is considered to be true if and only if it isn't equal to ``timedelta(0)``. @@ -614,8 +591,13 @@ Supported operations: +-------------------------------+----------------------------------------------+ | ``timedelta = date1 - date2`` | \(3) | +-------------------------------+----------------------------------------------+ -| ``date1 < date2`` | *date1* is considered less than *date2* when | -| | *date1* precedes *date2* in time. (4) | +| | ``date1 == date2`` | Equality comparison. (4) | +| | ``date1 != date2`` | | ++-------------------------------+----------------------------------------------+ +| | ``date1 < date2`` | Order comparison. (5) | +| | ``date1 > date2`` | | +| | ``date1 <= date2`` | | +| | ``date1 >= date2`` | | +-------------------------------+----------------------------------------------+ Notes: @@ -635,15 +617,12 @@ Notes: timedelta.microseconds are 0, and date2 + timedelta == date1 after. (4) + :class:`date` objects are equal if they represent the same date. + +(5) + *date1* is considered less than *date2* when *date1* precedes *date2* in time. In other words, ``date1 < date2`` if and only if ``date1.toordinal() < - date2.toordinal()``. Date comparison raises :exc:`TypeError` if - the other comparand isn't also a :class:`date` object. However, - ``NotImplemented`` is returned instead if the other comparand has a - :attr:`~date.timetuple` attribute. This hook gives other kinds of date objects a - chance at implementing mixed-type comparison. If not, when a :class:`date` - object is compared to an object of a different type, :exc:`TypeError` is raised - unless the comparison is ``==`` or ``!=``. The latter cases return - :const:`False` or :const:`True`, respectively. + date2.toordinal()``. In Boolean contexts, all :class:`date` objects are considered to be true. @@ -1170,8 +1149,13 @@ Supported operations: +---------------------------------------+--------------------------------+ | ``timedelta = datetime1 - datetime2`` | \(3) | +---------------------------------------+--------------------------------+ -| ``datetime1 < datetime2`` | Compares :class:`.datetime` to | -| | :class:`.datetime`. (4) | +| | ``datetime1 == datetime2`` | Equality comparison. (4) | +| | ``datetime1 != datetime2`` | | ++---------------------------------------+--------------------------------+ +| | ``datetime1 < datetime2`` | Order comparison. (5) | +| | ``datetime1 > datetime2`` | | +| | ``datetime1 <= datetime2`` | | +| | ``datetime1 >= datetime2`` | | +---------------------------------------+--------------------------------+ (1) @@ -1199,40 +1183,41 @@ Supported operations: are done in this case. If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts - as if *a* and *b* were first converted to naive UTC datetimes first. The + as if *a* and *b* were first converted to naive UTC datetimes. The result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())`` except that the implementation never overflows. (4) + :class:`.datetime` objects are equal if they represent the same date + and time, taking into account the time zone. + + Naive and aware :class:`!datetime` objects are never equal. + :class:`!datetime` objects are never equal to :class:`date` objects + that are not also :class:`!datetime` instances, even if they represent + the same date. + + If both comparands are aware and have different :attr:`~.datetime.tzinfo` + attributes, the comparison acts as comparands were first converted to UTC + datetimes except that the implementation never overflows. + :class:`!datetime` instances in a repeated interval are never equal to + :class:`!datetime` instances in other time zone. + +(5) *datetime1* is considered less than *datetime2* when *datetime1* precedes - *datetime2* in time. + *datetime2* in time, taking into account the time zone. - If one comparand is naive and the other is aware, :exc:`TypeError` - is raised if an order comparison is attempted. For equality - comparisons, naive instances are never equal to aware instances. + Order comparison between naive and aware :class:`.datetime` objects, + as well as a :class:`!datetime` object and a :class:`!date` object + that is not also a :class:`!datetime` instance, raises :exc:`TypeError`. - If both comparands are aware, and have the same :attr:`~.datetime.tzinfo` attribute, the - common :attr:`~.datetime.tzinfo` attribute is ignored and the base datetimes are - compared. If both comparands are aware and have different :attr:`~.datetime.tzinfo` - attributes, the comparands are first adjusted by subtracting their UTC - offsets (obtained from ``self.utcoffset()``). + If both comparands are aware and have different :attr:`~.datetime.tzinfo` + attributes, the comparison acts as comparands were first converted to UTC + datetimes except that the implementation never overflows. .. versionchanged:: 3.3 Equality comparisons between aware and naive :class:`.datetime` instances don't raise :exc:`TypeError`. - .. note:: - - In order to stop comparison from falling back to the default scheme of comparing - object addresses, datetime comparison normally raises :exc:`TypeError` if the - other comparand isn't also a :class:`.datetime` object. However, - ``NotImplemented`` is returned instead if the other comparand has a - :attr:`~.datetime.timetuple` attribute. This hook gives other kinds of date objects a - chance at implementing mixed-type comparison. If not, when a :class:`.datetime` - object is compared to an object of a different type, :exc:`TypeError` is raised - unless the comparison is ``==`` or ``!=``. The latter cases return - :const:`False` or :const:`True`, respectively. - Instance methods: .. method:: datetime.date() @@ -1766,21 +1751,18 @@ Instance attributes (read-only): .. versionadded:: 3.6 -:class:`.time` objects support comparison of :class:`.time` to :class:`.time`, -where *a* is considered less -than *b* when *a* precedes *b* in time. If one comparand is naive and the other -is aware, :exc:`TypeError` is raised if an order comparison is attempted. For equality -comparisons, naive instances are never equal to aware instances. +:class:`.time` objects support equality and order comparisons, +where *a* is considered less than *b* when *a* precedes *b* in time. + +Naive and aware :class:`!time` objects are never equal. +Order comparison between naive and aware :class:`!time` objects raises +:exc:`TypeError`. If both comparands are aware, and have the same :attr:`~.time.tzinfo` attribute, the common :attr:`!tzinfo` attribute is ignored and the base times are compared. If both comparands are aware and have different :attr:`!tzinfo` attributes, the comparands are first adjusted by -subtracting their UTC offsets (obtained from ``self.utcoffset()``). In order -to stop mixed-type comparisons from falling back to the default comparison by -object address, when a :class:`.time` object is compared to an object of a -different type, :exc:`TypeError` is raised unless the comparison is ``==`` or -``!=``. The latter cases return :const:`False` or :const:`True`, respectively. +subtracting their UTC offsets (obtained from ``self.utcoffset()``). .. versionchanged:: 3.3 Equality comparisons between aware and naive :class:`.time` instances From 7e2703bbff09c3c72c225790e5c71f423351b2d1 Mon Sep 17 00:00:00 2001 From: GILGAMESH <~@gilgamesh.cc> Date: Fri, 2 Feb 2024 10:59:53 -0800 Subject: [PATCH 15/62] Update venv activate.bat to escape custom PROMPT variables on Windows (GH-114885) --- Lib/venv/scripts/nt/activate.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat index 2c98122362a060..dd5ea8eb67b90a 100644 --- a/Lib/venv/scripts/nt/activate.bat +++ b/Lib/venv/scripts/nt/activate.bat @@ -15,8 +15,8 @@ if not defined PROMPT set PROMPT=$P$G if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% -set _OLD_VIRTUAL_PROMPT=%PROMPT% -set PROMPT=(__VENV_PROMPT__) %PROMPT% +set "_OLD_VIRTUAL_PROMPT=%PROMPT%" +set "PROMPT=(__VENV_PROMPT__) %PROMPT%" if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% set PYTHONHOME= From 920b89f62751e64a35fa1bebc03701af6d6f31f2 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 2 Feb 2024 21:04:15 +0000 Subject: [PATCH 16/62] Bump ruff to 0.2.0 (#114932) --- .pre-commit-config.yaml | 2 +- Lib/test/.ruff.toml | 8 +++++--- Tools/clinic/.ruff.toml | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19033ce243d9d3..69d85238985150 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.7 + rev: v0.2.0 hooks: - id: ruff name: Run Ruff on Lib/test/ diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index d6c1d8745036ec..1c9bac507209b1 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -1,7 +1,4 @@ fix = true -select = [ - "F811", # Redefinition of unused variable (useful for finding test methods with the same name) -] extend-exclude = [ # Excluded (run with the other AC files in its own separate ruff job in pre-commit) "test_clinic.py", @@ -21,3 +18,8 @@ extend-exclude = [ "test_pkg.py", "test_yield_from.py", ] + +[lint] +select = [ + "F811", # Redefinition of unused variable (useful for finding test methods with the same name) +] diff --git a/Tools/clinic/.ruff.toml b/Tools/clinic/.ruff.toml index cbb3a9a8f3a8c2..c019572d0cb186 100644 --- a/Tools/clinic/.ruff.toml +++ b/Tools/clinic/.ruff.toml @@ -1,5 +1,7 @@ target-version = "py310" fix = true + +[lint] select = [ "F", # Enable all pyflakes rules "UP", # Enable all pyupgrade rules by default From b27812d6320e35d62d91f1b3714be1e38021101a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 2 Feb 2024 23:09:16 +0200 Subject: [PATCH 17/62] Fix indentation of "versionchanged" in datetime.rst (GH-114933) --- Doc/library/datetime.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 096670634ee956..735c3b24f81509 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -1214,9 +1214,9 @@ Supported operations: attributes, the comparison acts as comparands were first converted to UTC datetimes except that the implementation never overflows. - .. versionchanged:: 3.3 - Equality comparisons between aware and naive :class:`.datetime` - instances don't raise :exc:`TypeError`. +.. versionchanged:: 3.3 + Equality comparisons between aware and naive :class:`.datetime` + instances don't raise :exc:`TypeError`. Instance methods: From 73d20cafb54193c94577ca60df1ba0410b3ced74 Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Sat, 3 Feb 2024 06:42:17 +0900 Subject: [PATCH 18/62] Correct timedelta description (GH-101417) It only represents the difference between two datetime or date objects, not between two time objects. --- Doc/library/datetime.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 735c3b24f81509..930af6cbbe9e8d 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -130,8 +130,8 @@ Available Types .. class:: timedelta :noindex: - A duration expressing the difference between two :class:`date`, :class:`.time`, - or :class:`.datetime` instances to microsecond resolution. + A duration expressing the difference between two :class:`.datetime` + or :class:`date` instances to microsecond resolution. .. class:: tzinfo @@ -203,7 +203,7 @@ objects. -------------------------- A :class:`timedelta` object represents a duration, the difference between two -dates or times. +:class:`.datetime` or :class:`date` instances. .. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) From c4a2e8a2c5188c3288d57b80852e92c83f46f6f3 Mon Sep 17 00:00:00 2001 From: Jokimax <77680901+Jokimax@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:13:00 +0200 Subject: [PATCH 19/62] gh-101599: argparse: simplify the option help string (GH-103372) If the option with argument has short and long names, output argument only once, after the long name: -o, --option ARG description instead of -o ARG, --option ARG description --- Lib/argparse.py | 10 +++------- Lib/test/test_argparse.py | 6 +++--- .../2023-04-08-11-41-07.gh-issue-101599.PaWNFh.rst | 1 + 3 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-04-08-11-41-07.gh-issue-101599.PaWNFh.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index a32884db80d1ea..9e19f39fadd87b 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -564,22 +564,18 @@ def _format_action_invocation(self, action): return metavar else: - parts = [] # if the Optional doesn't take a value, format is: # -s, --long if action.nargs == 0: - parts.extend(action.option_strings) + return ', '.join(action.option_strings) # if the Optional takes a value, format is: - # -s ARGS, --long ARGS + # -s, --long ARGS else: default = self._get_default_metavar_for_optional(action) args_string = self._format_args(action, default) - for option_string in action.option_strings: - parts.append('%s %s' % (option_string, args_string)) - - return ', '.join(parts) + return ', '.join(action.option_strings) + ' ' + args_string def _metavar_formatter(self, action, default_metavar): if action.metavar is not None: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 7c1f5d36999a3d..940d7e95f96e20 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -3922,7 +3922,7 @@ class TestHelpUsageWithParentheses(HelpTestCase): options: -h, --help show this help message and exit - -p {1 (option A), 2 (option B)}, --optional {1 (option A), 2 (option B)} + -p, --optional {1 (option A), 2 (option B)} ''' version = '' @@ -4405,8 +4405,8 @@ class TestHelpAlternatePrefixChars(HelpTestCase): help = usage + '''\ options: - ^^foo foo help - ;b BAR, ;;bar BAR bar help + ^^foo foo help + ;b, ;;bar BAR bar help ''' version = '' diff --git a/Misc/NEWS.d/next/Library/2023-04-08-11-41-07.gh-issue-101599.PaWNFh.rst b/Misc/NEWS.d/next/Library/2023-04-08-11-41-07.gh-issue-101599.PaWNFh.rst new file mode 100644 index 00000000000000..a1608a1ae0d2fa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-08-11-41-07.gh-issue-101599.PaWNFh.rst @@ -0,0 +1 @@ +Changed argparse flag options formatting to remove redundancy. From 1183f1e6bfba06ae6c8ea362f96e977bc288e627 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 2 Feb 2024 18:14:32 -0500 Subject: [PATCH 20/62] gh-114913: Add newline to subprocess doc (#114941) *creationflags* is a separate topic from *startupinfo*. Start sentence with 'If given', like previous sentence. --- Doc/library/subprocess.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index c437ce770b37d0..f63ca73b3ec067 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -664,7 +664,8 @@ functions. If given, *startupinfo* will be a :class:`STARTUPINFO` object, which is passed to the underlying ``CreateProcess`` function. - *creationflags*, if given, can be one or more of the following flags: + + If given, *creationflags*, can be one or more of the following flags: * :data:`CREATE_NEW_CONSOLE` * :data:`CREATE_NEW_PROCESS_GROUP` From f35c7c070ca6b49c5d6a97be34e6c02f828f5873 Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Fri, 2 Feb 2024 23:30:52 +0000 Subject: [PATCH 21/62] gh-114875: Require getgrent for building the grp extension module (#114876) Co-authored-by: Erlend E. Aasland --- .../Build/2024-02-01-20-08-11.gh-issue-114875.x_2iZ9.rst | 1 + configure | 9 ++++++++- configure.ac | 6 ++++-- pyconfig.h.in | 3 +++ 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2024-02-01-20-08-11.gh-issue-114875.x_2iZ9.rst diff --git a/Misc/NEWS.d/next/Build/2024-02-01-20-08-11.gh-issue-114875.x_2iZ9.rst b/Misc/NEWS.d/next/Build/2024-02-01-20-08-11.gh-issue-114875.x_2iZ9.rst new file mode 100644 index 00000000000000..20e9d6376b973c --- /dev/null +++ b/Misc/NEWS.d/next/Build/2024-02-01-20-08-11.gh-issue-114875.x_2iZ9.rst @@ -0,0 +1 @@ +Add :c:func:`!getgrent` as a prerequisite for building the :mod:`grp` module. diff --git a/configure b/configure index 7b2119ff7f4f78..1d41d7ba66470d 100755 --- a/configure +++ b/configure @@ -17475,6 +17475,12 @@ if test "x$ac_cv_func_getgid" = xyes then : printf "%s\n" "#define HAVE_GETGID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getgrent" "ac_cv_func_getgrent" +if test "x$ac_cv_func_getgrent" = xyes +then : + printf "%s\n" "#define HAVE_GETGRENT 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "getgrgid" "ac_cv_func_getgrgid" if test "x$ac_cv_func_getgrgid" = xyes @@ -28968,7 +28974,8 @@ then : if true then : - if test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes + if test "$ac_cv_func_getgrent" = "yes" && + { test "$ac_cv_func_getgrgid" = "yes" || test "$ac_cv_func_getgrgid_r" = "yes"; } then : py_cv_module_grp=yes else $as_nop diff --git a/configure.ac b/configure.ac index 5bef2351c987e8..b29cd028f8f200 100644 --- a/configure.ac +++ b/configure.ac @@ -4787,7 +4787,7 @@ AC_CHECK_FUNCS([ \ copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ - gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ + gai_strerror getegid getentropy geteuid getgid getgrent getgrgid getgrgid_r \ getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ getpeername getpgid getpid getppid getpriority _getpty \ getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ @@ -7313,7 +7313,9 @@ PY_STDLIB_MOD([_socket], -a "$ac_cv_header_netinet_in_h" = "yes"])) dnl platform specific extensions -PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes]) +PY_STDLIB_MOD([grp], [], + [test "$ac_cv_func_getgrent" = "yes" && + { test "$ac_cv_func_getgrgid" = "yes" || test "$ac_cv_func_getgrgid_r" = "yes"; }]) PY_STDLIB_MOD([pwd], [], [test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes]) PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes]) PY_STDLIB_MOD([_scproxy], diff --git a/pyconfig.h.in b/pyconfig.h.in index b22740710bcbee..2b4bb1a2b52866 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -474,6 +474,9 @@ /* Define to 1 if you have the `getgid' function. */ #undef HAVE_GETGID +/* Define to 1 if you have the `getgrent' function. */ +#undef HAVE_GETGRENT + /* Define to 1 if you have the `getgrgid' function. */ #undef HAVE_GETGRGID From f3cdd64de8a9d5bad122cc0b285b5c44cd9b202b Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Sat, 3 Feb 2024 04:52:58 +0300 Subject: [PATCH 22/62] ``Tools/cases_generator``: Fix typos and incorrect comments. (#114892) --- Tools/cases_generator/opcode_id_generator.py | 2 +- Tools/cases_generator/opcode_metadata_generator.py | 4 ++-- Tools/cases_generator/py_metadata_generator.py | 4 ++-- Tools/cases_generator/uop_metadata_generator.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Tools/cases_generator/opcode_id_generator.py b/Tools/cases_generator/opcode_id_generator.py index dbea3d0b622c87..5a3009a5c04c27 100644 --- a/Tools/cases_generator/opcode_id_generator.py +++ b/Tools/cases_generator/opcode_id_generator.py @@ -1,6 +1,6 @@ """Generate the list of opcode IDs. Reads the instruction definitions from bytecodes.c. -Writes the IDs to opcode._ids.h by default. +Writes the IDs to opcode_ids.h by default. """ import argparse diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py index 1826a0b645c3b8..3e9fa3e26daa53 100644 --- a/Tools/cases_generator/opcode_metadata_generator.py +++ b/Tools/cases_generator/opcode_metadata_generator.py @@ -1,6 +1,6 @@ -"""Generate uop metedata. +"""Generate opcode metadata. Reads the instruction definitions from bytecodes.c. -Writes the metadata to pycore_uop_metadata.h by default. +Writes the metadata to pycore_opcode_metadata.h by default. """ import argparse diff --git a/Tools/cases_generator/py_metadata_generator.py b/Tools/cases_generator/py_metadata_generator.py index 43811fdacc8a9e..0dbcd599f9d4d9 100644 --- a/Tools/cases_generator/py_metadata_generator.py +++ b/Tools/cases_generator/py_metadata_generator.py @@ -1,6 +1,6 @@ -"""Generate uop metedata. +"""Generate opcode metadata for Python. Reads the instruction definitions from bytecodes.c. -Writes the metadata to pycore_uop_metadata.h by default. +Writes the metadata to _opcode_metadata.py by default. """ import argparse diff --git a/Tools/cases_generator/uop_metadata_generator.py b/Tools/cases_generator/uop_metadata_generator.py index d4f3a096d2acc1..9083ecc48bdf5b 100644 --- a/Tools/cases_generator/uop_metadata_generator.py +++ b/Tools/cases_generator/uop_metadata_generator.py @@ -1,4 +1,4 @@ -"""Generate uop metedata. +"""Generate uop metadata. Reads the instruction definitions from bytecodes.c. Writes the metadata to pycore_uop_metadata.h by default. """ From 00d7109075dfaadf438362c084e8a1890c53d4c8 Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Fri, 2 Feb 2024 19:56:00 -0600 Subject: [PATCH 23/62] Normalize heading underline in multiprocessing.rst (#114923) This gets rid of the mildly confusing `>>>>>>>' underlines which look vaguely like `diff` punctuation. --- Doc/library/multiprocessing.rst | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 789a84b02d59d2..b104a6483b70e6 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -56,7 +56,7 @@ will print to standard output :: The :class:`Process` class -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ In :mod:`multiprocessing`, processes are spawned by creating a :class:`Process` object and then calling its :meth:`~Process.start` method. :class:`Process` @@ -102,7 +102,7 @@ necessary, see :ref:`multiprocessing-programming`. .. _multiprocessing-start-methods: Contexts and start methods -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ Depending on the platform, :mod:`multiprocessing` supports three ways to start a process. These *start methods* are @@ -231,7 +231,7 @@ library user. Exchanging objects between processes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :mod:`multiprocessing` supports two types of communication channel between processes: @@ -283,7 +283,7 @@ processes: Synchronization between processes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :mod:`multiprocessing` contains equivalents of all the synchronization primitives from :mod:`threading`. For instance one can use a lock to ensure @@ -309,7 +309,7 @@ mixed up. Sharing state between processes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As mentioned above, when doing concurrent programming it is usually best to avoid using shared state as far as possible. This is particularly true when @@ -399,7 +399,7 @@ However, if you really do need to use some shared data then Using a pool of workers -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ The :class:`~multiprocessing.pool.Pool` class represents a pool of worker processes. It has methods which allows tasks to be offloaded to the worker @@ -490,7 +490,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the :class:`Process` and exceptions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: Process(group=None, target=None, name=None, args=(), kwargs={}, \ *, daemon=None) @@ -724,7 +724,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the Raised by methods with a timeout when the timeout expires. Pipes and Queues -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ When using multiple processes, one generally uses message passing for communication between processes and avoids having to use any synchronization @@ -981,7 +981,7 @@ For an example of the usage of queues for interprocess communication see Miscellaneous -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ .. function:: active_children() @@ -1150,7 +1150,7 @@ Miscellaneous Connection Objects -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ .. currentmodule:: multiprocessing.connection @@ -1292,7 +1292,7 @@ For example: Synchronization primitives -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. currentmodule:: multiprocessing @@ -1481,7 +1481,7 @@ object -- see :ref:`multiprocessing-managers`. Shared :mod:`ctypes` Objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It is possible to create shared objects using shared memory which can be inherited by child processes. @@ -1543,7 +1543,7 @@ inherited by child processes. The :mod:`multiprocessing.sharedctypes` module ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +"""""""""""""""""""""""""""""""""""""""""""""" .. module:: multiprocessing.sharedctypes :synopsis: Allocate ctypes objects from shared memory. @@ -1709,7 +1709,7 @@ The results printed are :: .. _multiprocessing-managers: Managers -~~~~~~~~ +^^^^^^^^ Managers provide a way to create data which can be shared between different processes, including sharing over a network between processes running on @@ -1954,7 +1954,7 @@ their parent process exits. The manager classes are defined in the Customized managers ->>>>>>>>>>>>>>>>>>> +""""""""""""""""""" To create one's own manager, one creates a subclass of :class:`BaseManager` and uses the :meth:`~BaseManager.register` classmethod to register new types or @@ -1981,7 +1981,7 @@ callables with the manager class. For example:: Using a remote manager ->>>>>>>>>>>>>>>>>>>>>> +"""""""""""""""""""""" It is possible to run a manager server on one machine and have clients use it from other machines (assuming that the firewalls involved allow it). @@ -2044,7 +2044,7 @@ client to access it remotely:: .. _multiprocessing-proxy_objects: Proxy Objects -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ A proxy is an object which *refers* to a shared object which lives (presumably) in a different process. The shared object is said to be the *referent* of the @@ -2196,7 +2196,7 @@ demonstrates a level of control over the synchronization. Cleanup ->>>>>>> +""""""" A proxy object uses a weakref callback so that when it gets garbage collected it deregisters itself from the manager which owns its referent. @@ -2206,7 +2206,7 @@ any proxies referring to it. Process Pools -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ .. module:: multiprocessing.pool :synopsis: Create pools of processes. @@ -2442,7 +2442,7 @@ The following example demonstrates the use of a pool:: .. _multiprocessing-listeners-clients: Listeners and Clients -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ .. module:: multiprocessing.connection :synopsis: API for dealing with sockets. @@ -2665,7 +2665,7 @@ wait for messages from multiple processes at once:: .. _multiprocessing-address-formats: Address Formats ->>>>>>>>>>>>>>> +""""""""""""""" * An ``'AF_INET'`` address is a tuple of the form ``(hostname, port)`` where *hostname* is a string and *port* is an integer. @@ -2685,7 +2685,7 @@ an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address. .. _multiprocessing-auth-keys: Authentication keys -~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ When one uses :meth:`Connection.recv `, the data received is automatically @@ -2711,7 +2711,7 @@ Suitable authentication keys can also be generated by using :func:`os.urandom`. Logging -~~~~~~~ +^^^^^^^ Some support for logging is available. Note, however, that the :mod:`logging` package does not use process shared locks so it is possible (depending on the @@ -2759,7 +2759,7 @@ For a full table of logging levels, see the :mod:`logging` module. The :mod:`multiprocessing.dummy` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: multiprocessing.dummy :synopsis: Dumb wrapper around threading. @@ -2818,7 +2818,7 @@ There are certain guidelines and idioms which should be adhered to when using All start methods -~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^ The following applies to all start methods. @@ -2977,7 +2977,7 @@ Beware of replacing :data:`sys.stdin` with a "file like object" For more information, see :issue:`5155`, :issue:`5313` and :issue:`5331` The *spawn* and *forkserver* start methods -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ There are a few extra restriction which don't apply to the *fork* start method. From 28bb2961ba2f650452c949fcfc75ccfe0b5517e9 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Sat, 3 Feb 2024 08:37:21 +0100 Subject: [PATCH 24/62] Update LOGGING example taken from Django docs. (#114903) For example, Django no longer provides a custom NullHandler https://github.com/django/django/commit/6c66a41c3dc697dc3bda4e31e8b05084d2ede915 * Remove require_debug_true. --- Doc/howto/logging-cookbook.rst | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index ea494f2fdbbce4..80147e31fcbae1 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -1933,30 +1933,28 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration LOGGING = { 'version': 1, - 'disable_existing_loggers': True, + 'disable_existing_loggers': False, 'formatters': { 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' + 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', + 'style': '{', }, 'simple': { - 'format': '%(levelname)s %(message)s' + 'format': '{levelname} {message}', + 'style': '{', }, }, 'filters': { 'special': { '()': 'project.logging.SpecialFilter', 'foo': 'bar', - } + }, }, 'handlers': { - 'null': { - 'level':'DEBUG', - 'class':'django.utils.log.NullHandler', - }, - 'console':{ - 'level':'DEBUG', - 'class':'logging.StreamHandler', - 'formatter': 'simple' + 'console': { + 'level': 'INFO', + 'class': 'logging.StreamHandler', + 'formatter': 'simple', }, 'mail_admins': { 'level': 'ERROR', @@ -1966,9 +1964,8 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration }, 'loggers': { 'django': { - 'handlers':['null'], + 'handlers': ['console'], 'propagate': True, - 'level':'INFO', }, 'django.request': { 'handlers': ['mail_admins'], From efc489021c2a5dba46979bd304563aee0c479a31 Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Sat, 3 Feb 2024 15:11:10 +0000 Subject: [PATCH 25/62] gh-111417: Remove unused code block in math.trunc() and round() (GH-111454) _PyObject_LookupSpecial() now ensures that the type is ready. --- Modules/mathmodule.c | 5 ----- Python/bltinmodule.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 0be46b1574c1fe..a877bfcd6afb68 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2074,11 +2074,6 @@ math_trunc(PyObject *module, PyObject *x) return PyFloat_Type.tp_as_number->nb_int(x); } - if (!_PyType_IsReady(Py_TYPE(x))) { - if (PyType_Ready(Py_TYPE(x)) < 0) - return NULL; - } - math_module_state *state = get_math_module_state(module); trunc = _PyObject_LookupSpecial(x, state->str___trunc__); if (trunc == NULL) { diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index e54d5cbacdc96f..31c1bf07e8fb91 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2382,11 +2382,6 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) { PyObject *round, *result; - if (!_PyType_IsReady(Py_TYPE(number))) { - if (PyType_Ready(Py_TYPE(number)) < 0) - return NULL; - } - round = _PyObject_LookupSpecial(number, &_Py_ID(__round__)); if (round == NULL) { if (!PyErr_Occurred()) From b4240fd68ecd2c22ec82ac549eabfe5fd35fab2a Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 3 Feb 2024 23:33:58 +0800 Subject: [PATCH 26/62] gh-114955: Add clear to MutableSequence's mixin methods in document (gh-114956) --- Doc/library/collections.abc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 582bb18f752bd5..7bcaba60c6ddbd 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -136,8 +136,8 @@ ABC Inherits from Abstract Methods Mi :class:`Collection` ``__len__`` ``index``, and ``count`` :class:`MutableSequence` :class:`Sequence` ``__getitem__``, Inherited :class:`Sequence` methods and - ``__setitem__``, ``append``, ``reverse``, ``extend``, ``pop``, - ``__delitem__``, ``remove``, and ``__iadd__`` + ``__setitem__``, ``append``, ``clear``, ``reverse``, ``extend``, + ``__delitem__``, ``pop``, ``remove``, and ``__iadd__`` ``__len__``, ``insert`` From 96bce033c4a4da7112792ba335ef3eb9a3eb0da0 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 3 Feb 2024 18:18:46 +0200 Subject: [PATCH 27/62] gh-114959: tarfile: do not ignore errors when extract a directory on top of a file (GH-114960) Also, add tests common to tarfile and zipfile. --- Lib/tarfile.py | 3 +- Lib/test/archiver_tests.py | 155 ++++++++++++++++++ Lib/test/test_tarfile.py | 33 ++++ Lib/test/test_zipfile/test_core.py | 28 ++++ ...-02-03-16-59-25.gh-issue-114959.dCfAG2.rst | 2 + 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 Lib/test/archiver_tests.py create mode 100644 Misc/NEWS.d/next/Library/2024-02-03-16-59-25.gh-issue-114959.dCfAG2.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 20e0394507f5db..9775040cbe372c 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2456,7 +2456,8 @@ def makedir(self, tarinfo, targetpath): # later in _extract_member(). os.mkdir(targetpath, 0o700) except FileExistsError: - pass + if not os.path.isdir(targetpath): + raise def makefile(self, tarinfo, targetpath): """Make a file called targetpath. diff --git a/Lib/test/archiver_tests.py b/Lib/test/archiver_tests.py new file mode 100644 index 00000000000000..1a4bbb9e5706c5 --- /dev/null +++ b/Lib/test/archiver_tests.py @@ -0,0 +1,155 @@ +"""Tests common to tarfile and zipfile.""" + +import os +import sys + +from test.support import os_helper + +class OverwriteTests: + + def setUp(self): + os.makedirs(self.testdir) + self.addCleanup(os_helper.rmtree, self.testdir) + + def create_file(self, path, content=b''): + with open(path, 'wb') as f: + f.write(content) + + def open(self, path): + raise NotImplementedError + + def extractall(self, ar): + raise NotImplementedError + + + def test_overwrite_file_as_file(self): + target = os.path.join(self.testdir, 'test') + self.create_file(target, b'content') + with self.open(self.ar_with_file) as ar: + self.extractall(ar) + self.assertTrue(os.path.isfile(target)) + with open(target, 'rb') as f: + self.assertEqual(f.read(), b'newcontent') + + def test_overwrite_dir_as_dir(self): + target = os.path.join(self.testdir, 'test') + os.mkdir(target) + with self.open(self.ar_with_dir) as ar: + self.extractall(ar) + self.assertTrue(os.path.isdir(target)) + + def test_overwrite_dir_as_implicit_dir(self): + target = os.path.join(self.testdir, 'test') + os.mkdir(target) + with self.open(self.ar_with_implicit_dir) as ar: + self.extractall(ar) + self.assertTrue(os.path.isdir(target)) + self.assertTrue(os.path.isfile(os.path.join(target, 'file'))) + with open(os.path.join(target, 'file'), 'rb') as f: + self.assertEqual(f.read(), b'newcontent') + + def test_overwrite_dir_as_file(self): + target = os.path.join(self.testdir, 'test') + os.mkdir(target) + with self.open(self.ar_with_file) as ar: + with self.assertRaises(PermissionError if sys.platform == 'win32' + else IsADirectoryError): + self.extractall(ar) + self.assertTrue(os.path.isdir(target)) + + def test_overwrite_file_as_dir(self): + target = os.path.join(self.testdir, 'test') + self.create_file(target, b'content') + with self.open(self.ar_with_dir) as ar: + with self.assertRaises(FileExistsError): + self.extractall(ar) + self.assertTrue(os.path.isfile(target)) + with open(target, 'rb') as f: + self.assertEqual(f.read(), b'content') + + def test_overwrite_file_as_implicit_dir(self): + target = os.path.join(self.testdir, 'test') + self.create_file(target, b'content') + with self.open(self.ar_with_implicit_dir) as ar: + with self.assertRaises(FileNotFoundError if sys.platform == 'win32' + else NotADirectoryError): + self.extractall(ar) + self.assertTrue(os.path.isfile(target)) + with open(target, 'rb') as f: + self.assertEqual(f.read(), b'content') + + @os_helper.skip_unless_symlink + def test_overwrite_file_symlink_as_file(self): + # XXX: It is potential security vulnerability. + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + self.create_file(target2, b'content') + os.symlink('test2', target) + with self.open(self.ar_with_file) as ar: + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertTrue(os.path.isfile(target2)) + with open(target2, 'rb') as f: + self.assertEqual(f.read(), b'newcontent') + + @os_helper.skip_unless_symlink + def test_overwrite_broken_file_symlink_as_file(self): + # XXX: It is potential security vulnerability. + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + os.symlink('test2', target) + with self.open(self.ar_with_file) as ar: + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertTrue(os.path.isfile(target2)) + with open(target2, 'rb') as f: + self.assertEqual(f.read(), b'newcontent') + + @os_helper.skip_unless_symlink + def test_overwrite_dir_symlink_as_dir(self): + # XXX: It is potential security vulnerability. + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + os.mkdir(target2) + os.symlink('test2', target, target_is_directory=True) + with self.open(self.ar_with_dir) as ar: + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertTrue(os.path.isdir(target2)) + + @os_helper.skip_unless_symlink + def test_overwrite_dir_symlink_as_implicit_dir(self): + # XXX: It is potential security vulnerability. + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + os.mkdir(target2) + os.symlink('test2', target, target_is_directory=True) + with self.open(self.ar_with_implicit_dir) as ar: + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertTrue(os.path.isdir(target2)) + self.assertTrue(os.path.isfile(os.path.join(target2, 'file'))) + with open(os.path.join(target2, 'file'), 'rb') as f: + self.assertEqual(f.read(), b'newcontent') + + @os_helper.skip_unless_symlink + def test_overwrite_broken_dir_symlink_as_dir(self): + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + os.symlink('test2', target, target_is_directory=True) + with self.open(self.ar_with_dir) as ar: + with self.assertRaises(FileExistsError): + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertFalse(os.path.exists(target2)) + + @os_helper.skip_unless_symlink + def test_overwrite_broken_dir_symlink_as_implicit_dir(self): + target = os.path.join(self.testdir, 'test') + target2 = os.path.join(self.testdir, 'test2') + os.symlink('test2', target, target_is_directory=True) + with self.open(self.ar_with_implicit_dir) as ar: + with self.assertRaises(FileExistsError): + self.extractall(ar) + self.assertTrue(os.path.islink(target)) + self.assertFalse(os.path.exists(target2)) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index da5009126b3815..51f070e96047a6 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -15,6 +15,7 @@ import unittest.mock import tarfile +from test import archiver_tests from test import support from test.support import os_helper from test.support import script_helper @@ -4135,6 +4136,38 @@ def valueerror_filter(tarinfo, path): self.expect_exception(TypeError) # errorlevel is not int +class OverwriteTests(archiver_tests.OverwriteTests, unittest.TestCase): + testdir = os.path.join(TEMPDIR, "testoverwrite") + + @classmethod + def setUpClass(cls): + p = cls.ar_with_file = os.path.join(TEMPDIR, 'tar-with-file.tar') + cls.addClassCleanup(os_helper.unlink, p) + with tarfile.open(p, 'w') as tar: + t = tarfile.TarInfo('test') + t.size = 10 + tar.addfile(t, io.BytesIO(b'newcontent')) + + p = cls.ar_with_dir = os.path.join(TEMPDIR, 'tar-with-dir.tar') + cls.addClassCleanup(os_helper.unlink, p) + with tarfile.open(p, 'w') as tar: + tar.addfile(tar.gettarinfo(os.curdir, 'test')) + + p = os.path.join(TEMPDIR, 'tar-with-implicit-dir.tar') + cls.ar_with_implicit_dir = p + cls.addClassCleanup(os_helper.unlink, p) + with tarfile.open(p, 'w') as tar: + t = tarfile.TarInfo('test/file') + t.size = 10 + tar.addfile(t, io.BytesIO(b'newcontent')) + + def open(self, path): + return tarfile.open(path, 'r') + + def extractall(self, ar): + ar.extractall(self.testdir, filter='fully_trusted') + + def setUpModule(): os_helper.unlink(TEMPDIR) os.makedirs(TEMPDIR) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index a177044d735bed..087fa8d65cc336 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -18,6 +18,7 @@ from tempfile import TemporaryFile from random import randint, random, randbytes +from test import archiver_tests from test.support import script_helper from test.support import ( findfile, requires_zlib, requires_bz2, requires_lzma, @@ -1687,6 +1688,33 @@ def _test_extract_hackers_arcnames(self, hacknames): unlink(TESTFN2) +class OverwriteTests(archiver_tests.OverwriteTests, unittest.TestCase): + testdir = TESTFN + + @classmethod + def setUpClass(cls): + p = cls.ar_with_file = TESTFN + '-with-file.zip' + cls.addClassCleanup(unlink, p) + with zipfile.ZipFile(p, 'w') as zipfp: + zipfp.writestr('test', b'newcontent') + + p = cls.ar_with_dir = TESTFN + '-with-dir.zip' + cls.addClassCleanup(unlink, p) + with zipfile.ZipFile(p, 'w') as zipfp: + zipfp.mkdir('test') + + p = cls.ar_with_implicit_dir = TESTFN + '-with-implicit-dir.zip' + cls.addClassCleanup(unlink, p) + with zipfile.ZipFile(p, 'w') as zipfp: + zipfp.writestr('test/file', b'newcontent') + + def open(self, path): + return zipfile.ZipFile(path, 'r') + + def extractall(self, ar): + ar.extractall(self.testdir) + + class OtherTests(unittest.TestCase): def test_open_via_zip_info(self): # Create the ZIP archive diff --git a/Misc/NEWS.d/next/Library/2024-02-03-16-59-25.gh-issue-114959.dCfAG2.rst b/Misc/NEWS.d/next/Library/2024-02-03-16-59-25.gh-issue-114959.dCfAG2.rst new file mode 100644 index 00000000000000..5c6eaa7525e3b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-02-03-16-59-25.gh-issue-114959.dCfAG2.rst @@ -0,0 +1,2 @@ +:mod:`tarfile` no longer ignores errors when trying to extract a directory on +top of a file. From 6b53d5fe04eadad76fb3706f0a4cc42d8f19f948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Sat, 3 Feb 2024 16:19:37 +0000 Subject: [PATCH 28/62] gh-112202: Ensure that condition.notify() succeeds even when racing with Task.cancel() (#112201) Also did a general cleanup of asyncio locks.py comments and docstrings. --- Doc/library/asyncio-sync.rst | 12 +- Lib/asyncio/locks.py | 112 ++++++++++-------- Lib/test/test_asyncio/test_locks.py | 92 ++++++++++++++ ...-01-12-09-35-07.gh-issue-112202.t_0V1m.rst | 1 + 4 files changed, 165 insertions(+), 52 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-12-09-35-07.gh-issue-112202.t_0V1m.rst diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index 05bdf5488af143..3cf8e2737e85dc 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -216,8 +216,8 @@ Condition .. method:: notify(n=1) - Wake up at most *n* tasks (1 by default) waiting on this - condition. The method is no-op if no tasks are waiting. + Wake up *n* tasks (1 by default) waiting on this + condition. If fewer than *n* tasks are waiting they are all awakened. The lock must be acquired before this method is called and released shortly after. If called with an *unlocked* lock @@ -257,12 +257,18 @@ Condition Once awakened, the Condition re-acquires its lock and this method returns ``True``. + Note that a task *may* return from this call spuriously, + which is why the caller should always re-check the state + and be prepared to :meth:`wait` again. For this reason, you may + prefer to use :meth:`wait_for` instead. + .. coroutinemethod:: wait_for(predicate) Wait until a predicate becomes *true*. The predicate must be a callable which result will be - interpreted as a boolean value. The final value is the + interpreted as a boolean value. The method will repeatedly + :meth:`wait` until the predicate evaluates to *true*. The final value is the return value. diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 04158e667a895f..aaee8ff0702923 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -24,25 +24,23 @@ class Lock(_ContextManagerMixin, mixins._LoopBoundMixin): """Primitive lock objects. A primitive lock is a synchronization primitive that is not owned - by a particular coroutine when locked. A primitive lock is in one + by a particular task when locked. A primitive lock is in one of two states, 'locked' or 'unlocked'. It is created in the unlocked state. It has two basic methods, acquire() and release(). When the state is unlocked, acquire() changes the state to locked and returns immediately. When the state is locked, acquire() blocks until a call to release() in - another coroutine changes it to unlocked, then the acquire() call + another task changes it to unlocked, then the acquire() call resets it to locked and returns. The release() method should only be called in the locked state; it changes the state to unlocked and returns immediately. If an attempt is made to release an unlocked lock, a RuntimeError will be raised. - When more than one coroutine is blocked in acquire() waiting for - the state to turn to unlocked, only one coroutine proceeds when a - release() call resets the state to unlocked; first coroutine which - is blocked in acquire() is being processed. - - acquire() is a coroutine and should be called with 'await'. + When more than one task is blocked in acquire() waiting for + the state to turn to unlocked, only one task proceeds when a + release() call resets the state to unlocked; successive release() + calls will unblock tasks in FIFO order. Locks also support the asynchronous context management protocol. 'async with lock' statement should be used. @@ -130,7 +128,7 @@ def release(self): """Release a lock. When the lock is locked, reset it to unlocked, and return. - If any other coroutines are blocked waiting for the lock to become + If any other tasks are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. When invoked on an unlocked lock, a RuntimeError is raised. @@ -182,8 +180,8 @@ def is_set(self): return self._value def set(self): - """Set the internal flag to true. All coroutines waiting for it to - become true are awakened. Coroutine that call wait() once the flag is + """Set the internal flag to true. All tasks waiting for it to + become true are awakened. Tasks that call wait() once the flag is true will not block at all. """ if not self._value: @@ -194,7 +192,7 @@ def set(self): fut.set_result(True) def clear(self): - """Reset the internal flag to false. Subsequently, coroutines calling + """Reset the internal flag to false. Subsequently, tasks calling wait() will block until set() is called to set the internal flag to true again.""" self._value = False @@ -203,7 +201,7 @@ async def wait(self): """Block until the internal flag is true. If the internal flag is true on entry, return True - immediately. Otherwise, block until another coroutine calls + immediately. Otherwise, block until another task calls set() to set the flag to true, then return True. """ if self._value: @@ -222,8 +220,8 @@ class Condition(_ContextManagerMixin, mixins._LoopBoundMixin): """Asynchronous equivalent to threading.Condition. This class implements condition variable objects. A condition variable - allows one or more coroutines to wait until they are notified by another - coroutine. + allows one or more tasks to wait until they are notified by another + task. A new Lock object is created and used as the underlying lock. """ @@ -250,50 +248,64 @@ def __repr__(self): async def wait(self): """Wait until notified. - If the calling coroutine has not acquired the lock when this + If the calling task has not acquired the lock when this method is called, a RuntimeError is raised. This method releases the underlying lock, and then blocks until it is awakened by a notify() or notify_all() call for - the same condition variable in another coroutine. Once + the same condition variable in another task. Once awakened, it re-acquires the lock and returns True. + + This method may return spuriously, + which is why the caller should always + re-check the state and be prepared to wait() again. """ if not self.locked(): raise RuntimeError('cannot wait on un-acquired lock') + fut = self._get_loop().create_future() self.release() try: - fut = self._get_loop().create_future() - self._waiters.append(fut) try: - await fut - return True - finally: - self._waiters.remove(fut) - - finally: - # Must re-acquire lock even if wait is cancelled. - # We only catch CancelledError here, since we don't want any - # other (fatal) errors with the future to cause us to spin. - err = None - while True: - try: - await self.acquire() - break - except exceptions.CancelledError as e: - err = e - - if err: + self._waiters.append(fut) try: - raise err # Re-raise most recent exception instance. + await fut + return True finally: - err = None # Break reference cycles. + self._waiters.remove(fut) + + finally: + # Must re-acquire lock even if wait is cancelled. + # We only catch CancelledError here, since we don't want any + # other (fatal) errors with the future to cause us to spin. + err = None + while True: + try: + await self.acquire() + break + except exceptions.CancelledError as e: + err = e + + if err is not None: + try: + raise err # Re-raise most recent exception instance. + finally: + err = None # Break reference cycles. + except BaseException: + # Any error raised out of here _may_ have occurred after this Task + # believed to have been successfully notified. + # Make sure to notify another Task instead. This may result + # in a "spurious wakeup", which is allowed as part of the + # Condition Variable protocol. + self._notify(1) + raise async def wait_for(self, predicate): """Wait until a predicate becomes true. - The predicate should be a callable which result will be - interpreted as a boolean value. The final predicate value is + The predicate should be a callable whose result will be + interpreted as a boolean value. The method will repeatedly + wait() until it evaluates to true. The final predicate value is the return value. """ result = predicate() @@ -303,20 +315,22 @@ async def wait_for(self, predicate): return result def notify(self, n=1): - """By default, wake up one coroutine waiting on this condition, if any. - If the calling coroutine has not acquired the lock when this method + """By default, wake up one task waiting on this condition, if any. + If the calling task has not acquired the lock when this method is called, a RuntimeError is raised. - This method wakes up at most n of the coroutines waiting for the - condition variable; it is a no-op if no coroutines are waiting. + This method wakes up n of the tasks waiting for the condition + variable; if fewer than n are waiting, they are all awoken. - Note: an awakened coroutine does not actually return from its + Note: an awakened task does not actually return from its wait() call until it can reacquire the lock. Since notify() does not release the lock, its caller should. """ if not self.locked(): raise RuntimeError('cannot notify on un-acquired lock') + self._notify(n) + def _notify(self, n): idx = 0 for fut in self._waiters: if idx >= n: @@ -374,7 +388,7 @@ async def acquire(self): If the internal counter is larger than zero on entry, decrement it by one and return True immediately. If it is - zero on entry, block, waiting until some other coroutine has + zero on entry, block, waiting until some other task has called release() to make it larger than 0, and then return True. """ @@ -414,8 +428,8 @@ async def acquire(self): def release(self): """Release a semaphore, incrementing the internal counter by one. - When it was zero on entry and another coroutine is waiting for it to - become larger than zero again, wake up that coroutine. + When it was zero on entry and another task is waiting for it to + become larger than zero again, wake up that task. """ self._value += 1 self._wake_up_next() diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 9029efd2355b46..a0884bffe6b0de 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -816,6 +816,98 @@ async def func(): # originally raised. self.assertIs(err.exception, raised) + async def test_cancelled_wakeup(self): + # Test that a task cancelled at the "same" time as it is woken + # up as part of a Condition.notify() does not result in a lost wakeup. + # This test simulates a cancel while the target task is awaiting initial + # wakeup on the wakeup queue. + condition = asyncio.Condition() + state = 0 + async def consumer(): + nonlocal state + async with condition: + while True: + await condition.wait_for(lambda: state != 0) + if state < 0: + return + state -= 1 + + # create two consumers + c = [asyncio.create_task(consumer()) for _ in range(2)] + # wait for them to settle + await asyncio.sleep(0) + async with condition: + # produce one item and wake up one + state += 1 + condition.notify(1) + + # Cancel it while it is awaiting to be run. + # This cancellation could come from the outside + c[0].cancel() + + # now wait for the item to be consumed + # if it doesn't means that our "notify" didn"t take hold. + # because it raced with a cancel() + try: + async with asyncio.timeout(0.01): + await condition.wait_for(lambda: state == 0) + except TimeoutError: + pass + self.assertEqual(state, 0) + + # clean up + state = -1 + condition.notify_all() + await c[1] + + async def test_cancelled_wakeup_relock(self): + # Test that a task cancelled at the "same" time as it is woken + # up as part of a Condition.notify() does not result in a lost wakeup. + # This test simulates a cancel while the target task is acquiring the lock + # again. + condition = asyncio.Condition() + state = 0 + async def consumer(): + nonlocal state + async with condition: + while True: + await condition.wait_for(lambda: state != 0) + if state < 0: + return + state -= 1 + + # create two consumers + c = [asyncio.create_task(consumer()) for _ in range(2)] + # wait for them to settle + await asyncio.sleep(0) + async with condition: + # produce one item and wake up one + state += 1 + condition.notify(1) + + # now we sleep for a bit. This allows the target task to wake up and + # settle on re-aquiring the lock + await asyncio.sleep(0) + + # Cancel it while awaiting the lock + # This cancel could come the outside. + c[0].cancel() + + # now wait for the item to be consumed + # if it doesn't means that our "notify" didn"t take hold. + # because it raced with a cancel() + try: + async with asyncio.timeout(0.01): + await condition.wait_for(lambda: state == 0) + except TimeoutError: + pass + self.assertEqual(state, 0) + + # clean up + state = -1 + condition.notify_all() + await c[1] + class SemaphoreTests(unittest.IsolatedAsyncioTestCase): def test_initial_value_zero(self): diff --git a/Misc/NEWS.d/next/Library/2024-01-12-09-35-07.gh-issue-112202.t_0V1m.rst b/Misc/NEWS.d/next/Library/2024-01-12-09-35-07.gh-issue-112202.t_0V1m.rst new file mode 100644 index 00000000000000..9abde13bbf8571 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-12-09-35-07.gh-issue-112202.t_0V1m.rst @@ -0,0 +1 @@ +Ensure that a :func:`asyncio.Condition.notify` call does not get lost if the awakened ``Task`` is simultaneously cancelled or encounters any other error. From 94ec2b9c9ce898723c3fe61fbc64d6c8f4f68700 Mon Sep 17 00:00:00 2001 From: Travis Howse Date: Sun, 4 Feb 2024 03:14:02 +1000 Subject: [PATCH 29/62] gh-114887 Reject only sockets of type SOCK_STREAM in create_datagram_endpoint() (#114893) Also improve exception message. Co-authored-by: Donghee Na --- Lib/asyncio/base_events.py | 4 ++-- Lib/test/test_asyncio/test_base_events.py | 2 +- .../2024-02-03-04-07-18.gh-issue-114887.uLSFmN.rst | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-03-04-07-18.gh-issue-114887.uLSFmN.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index c60d7688ef8c77..aadc4f478f8b56 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1340,9 +1340,9 @@ async def create_datagram_endpoint(self, protocol_factory, allow_broadcast=None, sock=None): """Create datagram connection.""" if sock is not None: - if sock.type != socket.SOCK_DGRAM: + if sock.type == socket.SOCK_STREAM: raise ValueError( - f'A UDP Socket was expected, got {sock!r}') + f'A datagram socket was expected, got {sock!r}') if (local_addr or remote_addr or family or proto or flags or reuse_port or allow_broadcast): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index c2080977e9d587..82071edb252570 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1232,7 +1232,7 @@ def test_create_datagram_endpoint_wrong_sock(self): with sock: coro = self.loop.create_datagram_endpoint(MyProto, sock=sock) with self.assertRaisesRegex(ValueError, - 'A UDP Socket was expected'): + 'A datagram socket was expected'): self.loop.run_until_complete(coro) def test_create_connection_no_host_port_sock(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-03-04-07-18.gh-issue-114887.uLSFmN.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-03-04-07-18.gh-issue-114887.uLSFmN.rst new file mode 100644 index 00000000000000..b4d8cf4089d723 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-03-04-07-18.gh-issue-114887.uLSFmN.rst @@ -0,0 +1,2 @@ +Changed socket type validation in :meth:`~asyncio.loop.create_datagram_endpoint` to accept all non-stream sockets. +This fixes a regression in compatibility with raw sockets. From a4c298c1494b602a9650b597aad50b48e3fa1f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sat, 3 Feb 2024 18:45:09 +0100 Subject: [PATCH 30/62] gh-114965: Updated bundled pip to 24.0 (gh-114966) Updated bundled pip to 24.0 --- Lib/ensurepip/__init__.py | 2 +- ...none-any.whl => pip-24.0-py3-none-any.whl} | Bin 2109393 -> 2110226 bytes ...-02-03-17-54-17.gh-issue-114965.gHksCK.rst | 1 + Misc/sbom.spdx.json | 28 +++++++++--------- 4 files changed, 16 insertions(+), 15 deletions(-) rename Lib/ensurepip/_bundled/{pip-23.3.2-py3-none-any.whl => pip-24.0-py3-none-any.whl} (83%) create mode 100644 Misc/NEWS.d/next/Library/2024-02-03-17-54-17.gh-issue-114965.gHksCK.rst diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 80ee125cfd4ed3..e8dd253bb55520 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] -_PIP_VERSION = "23.3.2" +_PIP_VERSION = "24.0" # Directory of system wheel packages. Some Linux distribution packaging # policies recommend against bundling dependencies. For example, Fedora diff --git a/Lib/ensurepip/_bundled/pip-23.3.2-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-24.0-py3-none-any.whl similarity index 83% rename from Lib/ensurepip/_bundled/pip-23.3.2-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-24.0-py3-none-any.whl index ae78b8a6ce073797af05cd7a833ff23d14cff185..2e6aa9d2cb99232f70d3ffcd0ed8e0b8a730e3ab 100644 GIT binary patch delta 299723 zcmY(qQ*@v~*DM^{wrx*r+qP{^@FWwP6FZsMoY=N)JDJ$${oe0C>#YB(yLYd?skJY5 zRaedJ1cD|V2Z931a^MgcARr(xAdre;+R7_byHEc)nSp|UApd7|wsB@QGO}^BaW^tz za`q8W?vou9M(CQ+3Ndsy$wAdohKDnR5LpavwV-WuSch8AAeAwAdsg&13lknaI6Au1 zjUzwJrg0ZGi>kVnDb#yWlx2PCORsnnOYKz0>=eGM0~()0Sxfq`B$f7--KdX#_ZUq- z7y5CVKWQQS4eHR!&;JvoFQM}BM3Jx&4kD8tf03?y7EwSzTDa0kF+j1> zw&IDAfGIr(r;Sn6uNtHJkzEv6YIX%Z3;|Hv3qC%c0|LIf*W9mR@59Ne%uYLW?k_k()U=&#i>eBDZFVwewjHm@77k(F)lkKU~T0b!l{*Cgx5X zR;5)YY?F^AG&e6Ti@*~{@OjYol_NXos_inO0S;_AC<;v*Dvbz2 z0L(O);#$oI(5HMBd)kVFh?jPWv{#kxLmm!1R_~?Q;7Z!WDR^U!Gs}%lq=fQAt%-Uk@zqomWYDK5E^2gsn0*)b^z63l@AURLet zc}vlJ?Te^2mB}GgaU8w-alP2a&n1@ zBu=bKzwJTVN&I#poH@p|G3z^3CR{KQOC!mwAwoPozxKSTwud_GXh}dl0XoQyLu}L) zPJ-!{;RVq{iRQ@0hn=KO1d%{``9oRpDflqHl5fi@m;GI*2j5}-5a^%SK7RV&jcf8@dcBrW4fj zISxwFuV1(X;8Mi+D!VY!k_9mQD3!ZiRm(2rgEgyBd?7fOLB=xY0CTfR=yS-zfSfV( z+ThrZ9!&DF8fNM0oY$OL{4bd_lLETNCZgc4a&H0F%V15(+|mf{(YOpB4C9*7U37PMhS? z*WN(7^ekDljR1V?NAy+s_Ct#3Ep04YPH!X3)(C#MWh(AYpmx`PG<*LD4NDjnbd40e zkU5~xQdK7G!6b*SAhDkeVp+HEy=fMCC$E>DoV0vT=r@dgxAYhht|o|6ca51?)tl) zN)U%Pnyhk zMq^2Xz~G*~e~O`?jU2Qi$D5G#+kV$YPOy?OyRIO$C(AgMeiwgAb|N!g^y$3M8O@UM zJ0&{#yo-L2q_KuJ@X0Eh)1K2A22k0$*N2S!*cC4#(Z}+k7U%8LY&6{60}Jb)QFm{+ z8T#c8>}?lKE;`-H!CN-JDzZH`_FJxqL8Dgh5fObPvI<{4t`r&pG%bspn#keR!KV{ySXbC}rHCQpaAbufgRM{2N~C%8#*!XH+FA2hNyeGJJ{|Nr zD@OKmS}-n`P($!nL`zeR8seSf0kc$IVUzGcT)_IHtF(nzhoaN6>e8*7jmn?L8V7ou zb^|!tf~xbHZ9XFKCod|GC#Xt|_Ts*0?YuH#^!^Bb5jzTx=8M0mgyoz+BD5KO$DNS~i$^hEIzkno{$hkj?f+46l;wc^_va9vz^GVHUV(UO;V)@pxB@6X z0QJxhg~zopMJLyVI3M)*ZdJf^u}}9t&^TGYGDo0K3rccW9G+x_>Mg&oXt!G2ulXw# zpJr3U(<8r-2WcR$S# zl*(_ouqCbq$mlvq_($Rde5Y~y6;P~f023y9f>Q;ZLxlfWmwlNi<5XVbtD&WqXPY@1 zu^&J?cU=r#r|;m;Wx;=v82ufMT)5M9^eMIrqj!b+q(0#;2}bPccC+e?w}(v0n0uN> zYQ`wHK&v~_%4Xa7E6WI>J@)u2YFAOhCQCLRw=1nNoiOhG>`isKzMSz-xW$4B05?Es z8XM%a&}tIR`4DdpaVO|7 z^9{W<28r_=Y-UdBJi+-$vUD_+DZ9J6sj7`n%04=yqvr4rS6HvcURQ<{4ScD&0c) zc!XUFKesFR{gq9Ay^x^UE|P~}8MM3ZQ)6k{-VPB#R-e)Eb3PwY=sZ}oR3i(G(rT{J zHuwbchTuDPqTESW=nOlklYnY*j(NDf|YA7$W|}ooPz? zlr9G5w#9$+NNfP);SdpelA@8w5U*ckr8>hEs_J>K`@a`=^_EhAl@Ro;S|4e=)Q_U7 zd=`x^yGW;nyHwMjhG&EiV1pT2Ew=0U~k+5;S`*jPuJUivX^i@TyOI`Xho znDOenbkNyf^(d}WdgnDwRMF?)J}}MHM1G|Wt)z36hK^^sP4a;otM|X5`ukbE)h*#r3KTHYMkTF$-hc3a0+EG;0tOY)ivU93crv>Ms zUiZg)PWQx&%~ zeV^urV3z_*;Zdg}O%adI*@i`Cd7Y+Xb1a+LsloSpGGut`E&FjDwPy=jzPWUf$-B2j7|pv9wT|?%ze* z8;V?$qjNe3n%dw&dT!@dv~pVnEDp;pDQb(P(m#DWsqD%?S(HZQYb#xWyYtC_IQQj^A4YGIUdeM~KD-CVt^ZA)r1J_L3 z3S-~Z(N$fHa5;aZLgQ+=IW$_9JX%wIvY1ZcTV9qkOEO!$5MnaHr%SRBpA({S*0<7U z4IfmY>@i9&K5WF{Ul$sTf1Vu6M38AB)06BqI*mA?wB;qQa5XD#sxx8@ce?ExqrI~# z-Dwg5GH*bBT3MSj?H}zGk8;ae!!44~b;E^(rAk+=;o9*gztBxT`lU)C;5$u7fEt!4 z^8;@>QY4M;-zyypI(kJLT*r;_GfCWMeE#xzQ9L_A=O_t_b>f?BouHFOib23fh``Z$%1x{T2Y&H%Hw&Wr$y^iBq z-MnnV=(zg>KO|;rE6`%|-O!VL)ibg?r9}B;^(1c5={F+AZ6l;bz!>H?K-{vOd2^sp zFM(8FRI{M&q+1jQUXBN#xng%fb@o!ICZ}8cP@y#$+*N1#Q6ub?F8~ z1u2;QF3h(qqt@SwZc6;emz(kC=sY{w+WsV8in^ik&odEdKCl@tde)dGNGe$0)*1>- zF%v^1dt_iigA3QlPw&0(`Y9cO?vUm(NMgKm3tiABjH8(3A-0s|Y?c5X%eYWD_^(oE z2Fugkk*50ScZt+S);GblfmgY>w1YTcw+^fGp~E14 z^G&H4ti;5?gTlLyVF4jQubzis&3c;eW$l=5r)!v$$*c9s`Ne}FB;wq<`8Eh(5y5f1 zyEm(5h~yIL_-^>hYh(=Z<;2bMW}dHUQB~r!t~er z?ZA0ya2-e`k*c`)SUkLv23WD8NAZZ(bL&U z)Q!YNAXuy@nAVnGt!nO;7~DQpFrePr7x`YXsK9M#f4sE|UDaQ~@l%LV&n@fMZ?Mcx zGwM+TlYd>9TO8(mJtDvZpX9@nVfN=;8@3ht3X)(Z>(}ze1M0??aw<*l@8#2 z$pK-tWV)&n3S0t0Nl)iD*=K>w%d|%(dEb}ojp^$hedQi!3+WR0RVo6i$HCNQ*|!%G zl95(lmmt~x*)|Q_Rh}V#%uUBV&yG5Bvhjn_|C3Y@|3?_%_EWk2gAW3t+K9?l1Pido zXU8abMd^hPB}Uu$j!c8$v7_ZV5URRg7IyULG$id)E5be+TU}(l>&-RMQlt7quL4P_t{JG^?$aWF|-06q-p} zpeV|?%w9f-kUv7eMsC`d_RePR7YEe1DP+S(iNts6(km|x?oNITT<-^MlZ9B&av?a$ zU38WEijFXjMzulY(riwubR|hDU+EQvAvoTGmRO*`t~yWBkfdV-Dzl?l7nUXG*BD$K zN@9+WyUC9>ehA@2wy~b@tf5J01nIWUuJ_^U)Tcm&OL5Ix8G(oUk8B)rKms{G++ZV>Xj}T@g`Y|_(&8Q)|m9R22cvdXy84OQaIpB1-Ngcb#>6n8oib%gXE~s zY%y{VUZ8em;WV1&$mOvRB{V)Ri$F{Ydaoj;$^zkDXTr0LA#DS_5yeoSn1Du#`rh^- zQ;CfF{(NGP`i-ntQ)`3YC=ku(EXVHMHnQaF;o%V{?7^NpCv_%%j>@pKIp^8={MWUA zj3UD{%5hvqu3l2_=RfP?F%5aEKx?r56DL<_(A8YC8;L?&k=(zW>D$W%PO5FT@o((@ zG+sq=;<|{|Fh7-cGHV%^@`FCFp;$7PUESncS^6A88%6!+tidEzMFPQTV|JY zDBL&f>4?h}(oh}9*$b&6TqJFygufPr-`t2jEmhPjT~EQP&X#UpV$KRb1?&J`xv@Eh ztvFeGT_|*DhBe1`9KdbrTqiTvyS+ZJMac)lJzW-EX<@)IF|oPhgs*_YK{02^P^vB7 zltyJ@9j5USJ8ng_y~L=Js=(T=5{X0@MO&j5Mg{smW3Z{%)miW5ezqs^Z%kC0R^35q z=Uc;nwEdhGC{YYH1O5yrv&Q)3KmHi&2cP+=>NTaB;S894Lk@V_7)bF4F#v7OXrXg=jCQo*msr@)he!TT+MC z(zfs-S1NL}UIjc*Qy@X0s8d5#V@#y7%N_YsiF-vNM#@M>>>)o2qwpMHA$Q#+BpNCx zRUKG*g+)?ENOF@V$FQ6+l>@0#ToFL44vXFRlz#1aWy zss6^^T*(DD@3{}?!mN#S5jrcJ7!TXDT_9fG1x24Z(*rmMo0Gf8Z);QW87m3}0VSx* zM9SdfHOq(;OgNFmwdIE^gteUO&PuUTPTF;Hpy{`r32Ys#cYQ=PIHoN`Ra#s+QE=|Q z5+YGLze_H*g*mU=AsVko`S2&C-UocCAl9^74f@(kG@<|xcW12+)ea2_HYp=)tmMju zoLFwOb>O)-9h?Rv%HmO+MZj7};V5ZJJ&Nu+bFEIJa6!zt0`8pOA)_EH%sMRdhPe9i zM~Ct%Tq+%Zfr8tpgVvGTKCEvyMLFjxIj&c9pXIq!FwqR-C2RDc5!Fsp51#X_<`weY z-Pal)EZG$~{$y65VMSd!p7hw|Q=PEX)+B6pAHXX-b?*ROJjG=VbveZm*1;t%CwzYF zu-oGU^J%sP)-hRVXlatBQcD)8{L*2&g*4-VPZS}cz@NJRC=4)XR&*V#&6h((vU zHSo}<&T`b3qn}s2=ZY5&2GQ_vPnIfCEuX-xQo%7yH)DK>az^UjTJ8F$65~X>^7lCrx$J;#G_*_k^eI3%(p@ z<=|9Myc&|;lR!HlI01Rq3adIozb%*6YOX~How4r3}p z=qjkVz5xxgV3PXU0@`tWAEWZ`hCxzB8WdQZx@k?BFf>sm$$H|4n8=ZGYCxjmUEUWb(b%n;NK8!>d+1-NKvcLGn!TyQV1Hmq>iY>w>ZU40UjG+ ziA@Sp=AKh_ecVUwymPh1F`bkaSwS%-%}BEu#D=aZi5KgPDt13H&xAO_SA>R!m(3<4}yz z+nsi_lJJYdhRt%bRaSf!l&PmM~rkb6)wJGQJ3V%SE!0y!=@s!Y!(>j5!C7JePCm_Yab)}wWZxUR1SEwa9+ zBmqqJfbCQKoGu#Nm(`Lh9RS~)_LnOHmL;r37ZIFFAH%?cqAB*Fk}>^;EcCoDk^`x# z-PsI;qL;Y;Z8uc$_gVT9POJ!vg**?e<+Ev;HO3H$GcuYu7o5HPIXFaJBNk8afXH7q z8ZAZ3L@t)gt(~^4jutysOz7RFcGFmMIx=;$qZCX@tjNry+~E^aeGIoTQ2Euv-w&74 zO_jwEGYAjuf=Q=P4tkfht zQ~c{cifT$=hO%P6v_D{Y`!ESNWOC_`VZpm|5l)7eV1$&g6@X+<7LXtW6RAnommma^ zXFUq*Pj1~c3P-9}Wb(2DeBQP?q8lq^ZqFb7X;j-y;$?HV1;>TifzNj3&aXWKD?Xz)G!xeix{z>O>0A{tOsS|it0uNL zEi+(%ms(46N($%CH4b4DT~9dpD%-*e^NY)8t)8Qx=c`?$v7Hb*IcUR&k<+!?TW0NE zG^y|>O_J)rIq${1PbTXBd_edBjQOe7>MpECMU%Bxx|x*k2XT}gKRMg7BkmVYc5(yQ z+c227=L8s>6l-&P&~6n;)cWt!uy3|!Z=%O~x`aB?J2N`F+TF3Qj@B+BnVYVQJ*qWX zc{G_~C+FiJypjH1v?aoqaY6gtAr0+_{aQl)C-zs|sV}qyUYpfHOIr39@DU9^CXG>L zZ=p!ec#}P8^cGL6)2=TvJmPKumj~)KZ&x;z@;+TOA=;TW;9d_I0QZZRtdds#ghX>< zC`lWk1q3h6eCOC)ht^U2GZWPM6*O@2&N7wgcP$d3nA3V{O)J$3Kl4Q;%xeBVNl?Wi z9Aa3NSGPX#TR z@N$rc^jV6%`lA=}4H-I{@J(r9$jdaGy-*oM{x_r#Yd*0D4^qu9KHI-EggXNSZd)-+Z`{*ulg?yd>EHcp{3>@LRqdSDz4F~#Te2HT>7Bu(nUnv;3R zu=|e?UFuutpTv{=!2RaGU8(^N-T?x~AxTGpAAH8j7r_+^NQ6`sQa1Ms!{cD#34$;` zQXT4SHf*kI43?(_9#TqjYWoDH+=H$QC~fJ_)wO!0P-(One@wNNvWjuhMfEPi4oiMk zxkaJc-Q*rnnmOJ7vwO`Xs1SJ$F^^q-_Ap@NJ^Frsd ztP`y1&6e;-#N>P`YoO&GY7O>?={%HP{W#cS3+t;izbtKH(dRZt8uPo=RN)JWw` zY1zx1z0HdqG!M_2{N+QQv3+L-RoHU7NMUlfvwl#ZM@sFG)#W>Qkpx%m z8U8A-{N&3v1!{>44vg`!>3)+!FjFxr?euiRQ2}k4`key)pKsy2Q)hZCWJVCl(a~Pm z94#lG-XTv7+nCoX@GbaUw$*;AjOv?z5!i8{G^pSI;i!vfL~#)`ZliL@=!*EZtH@^C zC8OoYTn)o?($5T6OaH(@2BBBBl(LA;_Ek<}A{}%F1FYT57)^Ei`i%10=Dk494Fu|~ zd-fvb&xw5F#mN#2D`-$$%`lD<`jt--e@+JPf!O>uaiyz;aNXX|=wR-C`Nu^9$Zc*f z!}Bl0`}uC5F?vU?h)Q~`mkdBI+#zE#PqZ%B@(vXS+Ag_KrgP~wm;F5_FzfF`WVRBr z?WpN21oX-oV23jy%)+HR=tDPL;Y0NRjhq}aEs#YmWEF$;B7AEj83TAtJt!jekP^Fk zBC{ky4c4x-*h|LG`R+aSl1PeHqqMGkGyO2H`L_^tNrd+}(Z2$mM*i=Z5ntC0KHkz+ zgu*Njy)U3FBJaqJw~$R_?vmOr3Ul@1TLp|l0HkGy*qun(sf%yEhYIeVp>8Mv2XQ=X zf{c4Q#^;yVZpZXM|Mth|ecj8QRj5pR1UfZmR*?Yyq8-sGC-O^GZ;pPjL!_T$4J_rf zS8!u(9<&oxS{epl{^DP5z{}?e+wB4*`M#|;#0TM+V*-PBJ7mZyHaVPxNj4@oW8QfT zfSabm%`mHD3#d_A^v^SQ`N}`_b08&D#!SqCr*aP$r}m!wERxKg^{*P+sUiU9L!#XS zn}9Rckq5&WF$s$s#?YLLVD4V@$To##HR7`!V5Rs&XzjN^@`97D40gtmdWs!p;r}8J z-mACg%0LDyK}DR8%&3~N$yc!6U~Mo6n3ua1y8O$5tT=)VO&zou%L-K*X&w*jx8HV} zx=NH?wW0X+)A_dMWuup5xr!L>Za?<3HFlD}-?6iAxVn7_cgwg@vy%*ek7l6H^n* z4lt7b&=Rt%n&iooyBct^a%7Np^9{Z8N{+5IX|hCtn}xY$iR;$H36oh2VJoN zr!1?41p&EjBvpcf1}^qli8o&07eC$`iMR2$8m3W`gRjdB9n9gnE!vB6%Y5i0jAqhcVTdz*DHnXKIc z8TF4iC6e;9UpC1%k7(a8fPxy4@I-*VNgEBOE$60jM2vwJ9L1C>H81wqgjc zzwG1 z4K}5JV~k_K1BN#ZcDQ(>TpUxd@}Sc+j!x@2?BUsaRIOe2;=bpx zU+vG63aoF!TEZu^_g*76GiK?7^+Up<*L+Cg$Fj)8haJdX z;?Mk%^L@Pih8g1vp=UmS4#%NtjluUy=6ocy-jJPNfcX4(mSZdTeR=Y3x%{$3L^f+= zp>Pa8ke-rb4`XKiwqDiwZugd2jZ3S;e}n0@G*e(SL4^Gl<>!upbFX~53loZ>=cZ2Q z#ZJ)+bj0r4_IH+q2(-V<32U&xFhmI&+=pKcv_I6uoRne)w?PF5CtA%*l+OC3IN-i} zD+WCH00obTgUKfTWz;K&&f)4a#Sl|>44FW45Y@rQP%nJQF^$zkSG0EtZA6?0BGcv= zwV0cA8-Dy5U$8j#K17<&R-WOvR(g=T$=CeeVyhG@2 zCoT-$IYT8eA_gP`ekd!RaB3Xosl}>{G5h!i%}{ z;#(g#41Z)tWwvIL#MyKf$#)m~K)AH*dPkFjkb0m$eG+^2GeUS&;i*CzamXd#_7B31 zzMhSOs;GwT#_(X2-{u`PJPlgSmp&Q>k~lXm0_ zsn5{&z&h-`98p+zm1anjQ1jpTT%V=rxE)P0lUlho>Pv-Ds4HXlBNM2ZjK%_Y5Lc zNGkPOGIL+=ZrrgD+fM~E(^bYMQ)|o zPeK=wDwxo(Gw1n#x)Ws3j1xInA!TH|gP+pXpS;>2Wn^ZEEk!=RAVZC+Nydi7u|vy0 z0a>=hZ21-jz5fs-(?sI_Oiuj-wVa1lc1o)QPYbu#ns%!e{&O1M;*=?CIana#cIZXs zMs+WH%X_e8nA^v>*al2?ftrQ>dIXQ~NTbC)^155(+Cq*iNH%3nSQnyr}U1UBbL-yg635UIn>jZk+o#25kWZdujHBsC-V<$Dn68Amu1>co!;!a<%SSZ`DZzxUF~D(y z+{^V5E;lz_QPP%NMRx;nz{&o19uw3_cl(YUe9%cMq8rr2OSSk?qFss9fFmuhbY{}> zp%r}M%(jrs(*ovcm~?5-wTsJsRE#~)D)Dg$@8#2S*a9uHDs>i zS0!f^hKccS>a3ih%$}o$>{N~cEIQJHCl0a2AT8}q7Kw=d&Tqz}<#>z!D3Sbq?_CUC%>|l_UNXuQ&(4fT{>QKn9y(_2j9&$T%oS5;nm+`(&QWj+{WcKs4gg4Bna93@ zlqv^d@5ndA`N_UgO5FNjSgJTFL+q;Z%H&~`cn*iiRS({zjfcTf`!J@`h&G-XVkR!1 z!J}J|+0=Ek0KYr(_w&k`^eM?2n-KijFS_c9Dglw~4@lG8Db2f|&6%TNo5PQp2yk3E z8BH)mcSXHs9G*MqpxiDT?Z8miid>c*;z#5L{ShQ_~4v;?*;&ZMbDvMzT*V_>J_YE!cz%T09e zG+53WBgUulmzZwY4+h9dn2c5kvUswV$?|89h#iqbC?_kNAyc0qckevh$e7WB02wgV zm4HRBqP_-Of)Z5bSmiBO*e5E%2lWXY$MuR!6L~!Y9z9)>!=GrxTgIPITPFpBh;UME zXSTAruBIt$j3QWh39lX@ViB=!CG$*3uw0Yh-M)q7#u;nwoqRTK%<{>zHbg+Pd<`}x zxF|Aen~De|Z=kcfaeaU4wIhvYMd+NX3%H%GtuJ>)WT^=%WBRL(zHT*EqzWTMimTUn zW@bdLM)@{keZ0m6GD!WL>5`R4#Zb`SF&{xLPB=QQC=3zgx+Hn><*slH#I)4-_v)3R zNwH$&5Z5Webtnq%mYKd$D`em-0I?<7I;sCfIU1QU9WNa%cLc}8-1G7WP#fRAgN_9` z`n0RkL;KHoyL=7fhj%XY@d@&a%Pfp@Xd*;R+-aHAe33=(H)~va>S!m(qxog;+b?%) z0d0Mt#+=Y}I#L6jomyu>owe9Xcsr0v1`XCK)*LIJqJILnZ5Cb@td)Fby-cWSW4HRv4E{5`rX*JZ2EWsg+63v}6v+%MCe zm_@0X`I#clP*HiBKgFWx7_1HGfEY;r945q>JpanSADu#T49Rd9}kprNPk?-s)>XNmOyFTa+K;3%+YA1IT!JQ*L_G%T~{7s`FYu_ z=W1^rG%!ZE4TrXE{E2jRrxH`^Zf(vud1$|QUF zw;k|6RgKPKlcrY-vC7p)+)Ani6KCn)(TL8J?dbQM^5#R6g#ZWkZ=D~#9e92dtx!W< zyi98F1m7rE_%FEGiHP7|ryu1yA)peBeOoa~Z%#YK>(O2RJgck}1!Smwgs;1AOF>cfnUH-8 z5mA3ps|3kUTnrC;Ss2(i+a(1m+R`t@;URD9AMs}t z?f_WE!dIG4r!c$MBbyS3V@D2h_VHZBmSVF&Pk=4ohEH-Pw3HiD%W&Bl2CKm-{IHOk z03GVk;CDHHNrQGuaJy92_#P_mY_s}uE(~S$y`&|GJ$0xiGUxVP6dC?V+RO962$ys~ z@=-3j6Yx37qw`Uw?{SY!ER<8R&dx0zleA2I>_%;jT!GT?>;t~ugd-`L zEO(Zp5Rsx%2y=oOEg;h{D+(g3>4{Nw` z*!fjF!bMrD^a(mva1XUe*-;>CP|GfG^e0KeD8@{pvlNUTnz}#$Oa<(PX@_zp_A*T)BYPK`Dx=+Oc#u-Nq7P2jRt&Lp3k` zq8lNGYe$li22Flp2gP%oSiLaY=0A2gQ@-Yp)DN+6$mq z*0<_7>zk|pseJN}Rdj39!B7{SvxW9dn^Q}%*mUXI!!Lu#&a)IktSK=A&Q4?J&W+%( zhpk4y_nbsB3ISnjhcPYYAOJn^6X@kLe4hSHJKa;7CdI8_KMJlR>Iifnwpe;(BtaXM zSV4FXZm+lypWyo_lni8rv+ZCqt``4>H3fm){TwD)SPQ)l)s&i_WJs1xy0aEkD^Qpy zhJR9v7BD6Jea`2K|3POV8`y=tGasH@fA6o$PZuDd6%A?}yu$jo7vuP;9au(E1PP9o zc&DBF1-`nQ@UJCwfP9Nta8LU}3JqBsTDgwHnZM-6OSGYFp-bI6MXTb)%c(A7*uFeq zxu7IBG&;EG~x8L{#%NZjWI-M3k_VygXfiI|d5c=vJx`Dy-iNq)!*FLJ8 zcao!oRtfw+)&cq7Y)bKZYxhl+5u)qlu02pL{#A{a*6VInbRQOhHhi$* z|4YaBzp>c_NdA-IN&XIz1F$K=DacTE!Sc;(CjK*Nax$Z&nA6pCw5t!11!d%B_4wDxTPuFSY+iMr@yM(mhwLY*O_ou>6^Oy#7S{ zubilCtV9!-jDCx!o2uj;yWl8qu1Nd2q+>orG1lNvwJp}FO0AJt2}CO1Lv||J!k-FO zr_p8XrxiIi7+&}-Yb;QNe^0npg4kB`p&RVjba@KF8q$l)g zQV~jH-?IcK4O}!aL@yKRuqymQ5;Dp)j8TeH+RlyxxI1t_j+PH9vg1}L396ADNHmA! ztu*+V$2C;rgQPDSMiKrJpPj)9`Q>|M&OAUbocZ|%JPB{`(z<9~ICO=Ollj-2?(qoN zUC4EyFelrVU+FT}GHv(x3Iw?My&gZf0;L+d3JTaHz;}B(NTMgN^irLOR9L4O&NrjL zMXZh8$U#8q0%&USI7RhC`pl&Ef#HL#{ z4>k<8cK8FiV{oyYSQ(=KagZrdGqG3MflFH%PKv4}707U249f&;z;9pJq(#E(R?&A#MeRAW?%%Blv{&ZFx z%39!wE8(8^93nYVTx9{??!&yWCF&N=I!wXHm_3#B)fn+wSW^AokJQ+7rpE_Qe(*L< zCQf+dl`cG3H6m#~!FBRbYJ_Fcev7mxKwKn$`P+HL+ z03jq5!7a0Lg^~=+8RWuAOh-Tp?2P_N$hqz!Sk%0$Z5*fji{5|XYh?ZG9(FuD1z+t0`&6dz;nxkYPN$+z^qX37@yj zXL+2x6L!IkG!UEwYz9b(2K}@wv$yOCn;0pBA_WcX1>vV+al|Eoic$kkc6V<9MKkN0HcZWJhqWrZ0{M@~vNnq_= z1Hn6Ow-W|osJm1_c4AoU)am%j8Qz>*-%40OP-wn)pAz={D4p4=4G<9OYGUI#t_4)P zV6;#`*WTS?-&$sH7H^V!at%WarWU+)t6ICZmRCss;-7XA<5qW>sLof`8`RBWUkkB7 zA#QcTcvYf>$k@N2dg-8Fxm*bRN8BhsS#qr;eL2zD6ded_Wl??$b(SN#Csz} zr>?Ne%mFcbF2ph>4LUJ%rrg%NV&}w@{UY|0kQhiP0v>I1EuZ{r=A0YD+Z0sIN2yRZkF+R&yp+2MvT zmF5!rY)q)lBP_Fx1_<+PqgDQJAWR*4?Dpb4ZDY(RZE<(-+6JvBX z0iKsk#=fdH4!PNFJqP7yfLc;7EQ{(nV6U1^EL`zJ28sk(EV>t$mwWD-?>S}8655M7 zH@Ml%6^wM-_*n)}5zPqZR%c@*w)oy7mjHD8O0jR^cDg@3 zUKZ{;4pvHq%G~bgywAzlF*F^J^hlo(Q!)7WW$=vh=?dfq_v;Jcc*5pFo zOA_A)TH{~;Nk<_3DjlM##fNzPkM6f}MtDoV3TbY9p+KnT1WGWu#!$T{(7`tcz`-ODbW$!ayUbb?$7iGBByazi`B|Ae+Fq9}vW4jAXKaM?!~M(i%fpxI#4N#V`JJHGWn^yR z(PK!*FYhD*=@h7b6q1n3UT{X{^DA9&q%;X$&JJM0sG{fshE_yk$d70%3~6GTZ#zf~jRYQDhf5Wt;YkbhSa z?s~#w)!lslU4x!*D^#ZP1}Vj}SF&4K2*U?k zz6Cf>)mMfXIpBNf8uR)H&ztcIkfzTjbKJ63uxuyPUUsW&Eklbf7$S@q2ZvS9M?g$5 z#+)McEMr?+gq%N$vEmz;x#S*E%I^_XvevmmVf3;;LMY{7BslZboo7UxBz&s>8@dpW zMcbX2QO=N)V!a!D*JVP?MH1m1@%QV4{2GXpqgT`W8v=2I^}+inLz%H zM-4>8JnSVo&0Cx0b6s6aG1QQ&L39It#+2%}sbIq7=>*!HoC}IxAf>F;$g+9FF#NCxkQ}g$H0`=E2$V-5~oCwNyj(>I1It z@?gJ`ai;glFV=l6xtZl4kZZP*aw1{Cu`vGG8G6n)ICJ9@S)FS5&mNaf1fBo!cU2iE zeGh0K?nxG0<@HwBl6ynvF&pHVtuCG@P1>y~8=3~y@j>=9x6Cqj_-9P60?a4@c;|j_ zT--EDBXE6%*r;8Y$%yT2rof$*8)Xuhb{Xs5D86G0m32UQ^SPm6w+1!Qs*(E`v5CLI zp}sZARMgopZ@fPW4f@!Fv|G2J_4?ZaLukOkiAkDq6UkcNcDS8bqIcFK%oF1@DmlXX z$Pb!2IR9D_T$Omy8ZBx+05gEmu=g&ZQHhO`!CzJZQHhOtBc*`s;;_y_P!A}&W(J{ zj9mG!R^%Mxn`0u%ASt|2$f`6Gzyl>st2Zwng+pc3&zRXMKbr~2-(Ys%-Gq+-K;72H z(e^a>CdGER7#tU<5rRKek07E_B$o=iS#U5vswUS%;$Z8I{A{Av$nTTmyiiKhaDV?* z|NQXYO`)PlEcVq5evgmoYNeY=rsq9rDWEa_f1D`!81a9PU#Ph4+B4v|Z)niR`+fB!Eq7c|+It4|5375O z14yF4W~RFVGUipWsr)OD)5a{C)U0n!9W{XRk)>x&6;9R&Shkbzgb(!e^9(tZ&-ZKr z5aZ=X&dx#}jTb|J7w^Yh3Is<=3!sxftgnBhtYgrS&kpuTV*_`kUZj~4?+tW^*r zx;er7snThbnK?2BZ0*&^)o{@`&=~4oCd1? z@IJkY9~{TgATN3XBwEL+dv=h?Su21tVF#iCyo#LWQ5cwX`rV#+9_-_15l7Z?@CIC_ zQo&*>6YuL1O#S15glkaFCx=U$VvsPpT2RhyO6n;u!jNY`l;s5%_#p}>c!{2%VbjXA zAUf6s36e;7STlN>xVv>t-%N8HjTjR~P{F2x7Mq(4^=J4tQ$srx7QGNZgw8E3-w{jz zOQ(}cb4e0*C|5;4%D>RZ0Np1UT(=Heaj=lq$a)Au>oanCwI#Rc&sbVK*NF+u%|dQy zG`1zECLUwq1Ru}zJ1F0NMK_Xq*?KF#Fbw*C%qOPfWhe)W#)N9@XI1JbuS_ppyN63X zttL$B@0HB;K`;sxLN^!3ErRh(2`v}^1va-7au*;PPHjj)Tp1&ihMa)a)YGIe^OV=P zTq$^ICU+fen}Zf_P$=ezPDv(Bo;Vpgxi8o_zGHSTW(}uLy+04aOP5@iU2z#M2a3=F z()QL`$9hahLl|PUy2{|4@=JEP1=I7xoT~eo?uUVmK4|7=!>XIP4$^8HrA`vCqF7;A zjB|nn*DJP(qmIC>Z*0bCxp7;jfH->+Y9sm^u@^4&?#RC|sOw|_QMUsJtOwz${MQdZ zPhp}DSN>j%q9qx?HvFAI!$s0WdSoOHR>7#3T$Qn_)>1e0wRAhyt znae2vnccXVSsN?h6zv|8)-4l206nq~T2zbDsEb0xCih&)enDEEY|%Wm;-h6t@%&t_ zhnaaYB?E!S&(td~kv%ni$sQa{t@@DtBhMUx>hV2ZhGL?!JSU%N<~AJ2og5VGoyc;P z|B12q3DeMP;E%f06=^VbFxo(}oLnRtcS6*@bjpd%IJ+)!t@YP@65a;@;uXtD0UG~_ zYf7*N#ECb*c5quV0BXL&ABf5$Ry>sBVTO8IA!qGaglfVH-Lf=1iwPZX38!6{TRkml zfRU{+Ka|s`8F8OFNl3#t0fN-NN9scHSFZT!QBB>cyOX~nQM^e^Z^UfS?ov6Y|3je< z=N3rp5h=(?x5%*CAYBKrgKxZO;G=xX0?OAYDS2&fTGrLQv8wDBtlB#qh#%sA2LG4B zMV8fqDyZlCdb~f;c(XrrYXEKqe0I8_3fK+p_T}U3@;sbUCqs8*q5@KGRFvil7=DT8 z!wu~LRex-0S`1jCd|@5&jO<33I0}i-mE)G==yE)a0sdQVB2ffjt_phF?|j!E80>iY z0uMhKfY`mMHkXT8KqlY7ZwXfy7NHeUrm#VJMtVpQ{*zTZ&1Pw6`I#zlP5Sq*=sUE4 zPGSL`;a*Oeja+((NFwy#c&;rKso5;fxK%bj*Zpf=ig=H&T&1b;4-sdqz=NbHd&h$7 z4lCL29n7E=q{>`?!CllE)raGU%UM0mUp3kg{w}PXof#OFDTYmcZTK$A`$FVd>W6mv zPvvSQGG1zy74vB9pY>bn<4ovz)HF816>^`nP<1y z47|Y|C-#Qpe-{K<>uiYQLlCN&ks4lz)OQ_KL=79G%nyKUNiDgyc$V8^D|r;T$oPpn zGY)ryu!1mOQ5k%=v=!8q6a?#t-*bmnHp`bsK$9PJ`}c}?aL{VU(d&JnAaQ^9FL%$v z?g9J91L}a6lRcn>J-5BMHS8H@Sriv`$z?e`E8+6!l813NG3$7A>)^fT_82j6T#mI* zNwsPkW2x56ym9+}$3wzS=B*F!_eRFvx%!#u z=OHO!(E8M{@gC@NCq;ir0BHc<+zx2FA+%;g7a0tZv98_b^fWpCIvkS0DW{6W-&K|Q zdpjxq=A~JFt(-E9WLO%s%mV_o3?yr<=W^O~<8~<5oB({_-%d)t77V z!4m*VC3ml0HjH6ri*IKt0b$1_G^oGBqZto*$lMa<-wSI`LryM`h8G9aie+6uJBEaC zpRGhFz6Nj8#KuXI$2zl*#}rj4t-AeUFnI$;V=oljS+{JZ_*NphF8*PT{XDuLYy zl#JMHS-1u9RI${1%HHC_$FJuM+34#Nhk!R%{NZcs^qB(Cb`Xuz*Mg zG*^rSGf{YH^a)=qSaPP$M?qcnNzSi_0sJ1EXFab?6_mrNa9p@`P$Yj{oD=>-rZg6_ zwEC%$wb8^)#9ld&2c-+{ZtiMUFN8*!RR|!~j(Ifs)fMIMR z=GKOGRi*;5fCi3%sPn^o*PyJ^u>j!i7>6_hwja zDR#C+^?`Vu4tkCZ=@YPFlD`C~E!9U>kE@-Dgrm_4aW?4n=cm=y(Ht-kOk@p|X zw81}?2$H25AV;}?ln-S>hdy;&Qp4bVP6KC5EWlTr2j=!r7S7sdN^drbKIJ@NWZ(U{ zoRyQWi>W3lC?G2G1}l+JJlX!HawqL#D93+G5tUP_zIo?;-3P1&W8cg!@rr!Di&ZB1 z@Xc41-W@@OkP{-S6A*t6PXT*ZYuR*KO#x4{yyI>g(cbF9{$xEhw9mB=+{iH|Utwq+ zvvkP<%N$gR7Ia)DTJu@&DK7TvA3!prYUu4Jjn0aXn+R(d9^<@dq(pU>=fCh2AW7_Z zT~6kiScQv|9s!bg?@zSz%VVp+-g zAV6_t`)->m1wrC;J1dE7jyWR8FNR<(PYFj~N44x>?E)49VcFN5s17tE*b^u6>iZhlq4$*@E_ZjbI5o44U7o%Ax@2e+wnx_{f|I z8-hSpuK@DNulm|V6F-8EVQ?k(QN&LX7%i4Z-#FyzLw4tPBIF9m8#KQBWu3w0&t;r%u0eeFRq&MVOd+g=$3~54ahpy7?CU!SN9nR_3T_2pi(U%fhLX zljFx}&sdw*>8-t*J_2lsvT&cEXt9(!@n}-fzX7A5*MN3dM)}-KQ!6{iIVoC!#%%Hs zTo5i-!Rht@p;})^|8t3Y_biMSH5j}UhlH%JuMm8_KHVJpWh#rHWR$ptw_;*ea5I&AN;aDTGope<7tZ&+}6?9=U zw!>~#!%)?ss-4xBkpW*~5T6r@&SdO+p1;&*wvUM5W)=CtQZ6C+KjN-B?5*HTlmG}4 z37(H1<&JE6`$~LBn{P}8f&8Sd#_tdt^cwD%*22I4h*n7Az zxsO;^zI+;5M_I!KuH@hojr+lO(udip;uKH?)^}Z|2T(?%9}xndMbo^x{bR+&K{uv@ z(U5vGLPHt~8E#AFCAL-y5<5<5BLGwP>HZ$&5TPiN3#sJULOE_d?v{n>5!^z`+V-93 zt_oT9EeTf<`)wL=PT#H*8f~&jFb_kRaGAb!=o!BhSDc!EZM_9J#uDn~zw7SJWbg_l zl6mGK3|PbCrl=yt!)46-5D|8urm>U*XF$WS2$eP%OYi#DG;j4I4P7%-2LN52kQaJb zw^N;uKA)=hAv#oky2cxX-vQEC->0LPPGY$EV&wgYWH}7X-b}EspG2uGciL<8=pRi) z1Fy0uTFit;9%m6olR4@t;(zN?hi@c2cE}K)4)apJht9KhmnpT$g8z(L_?DfEs)jwA zb~J>0*|#!hc%|`!sFKD4;R0eXTpMqZ$AJ;R^%}qWLI`G28IFLC+h*lLjG5AAM8c*O2oHu$Cb zMu$Q5IoA6WzcRr=C%><#BF=sGVi;4_ZV>QUV*=Gnhb)9KdMqT7-zb)cAEQFk(J8-y zv9y$Z_>Drcf8p%FEAF9c_Ri%z{s8@NG`hvN%=-VPUtX4rga4OEV6H8I_z#h=lOfbI z`j3~!PuXkM0sK`Vc6uU;81eqL=#)BfBZ=F* z_3Cj=VA4r&TW}Gi+K*L~ymCPQtgiRn&a?A%CQ7q<6dz%X#N~0*UnpfeSZfLq-|fJ> zWu|QKDs%ar-d0;7^Th4FK;HZ2eu?8@V&UFPD}#{w2}tJ{Wf+`iR(kxb{=Au2+V+WYJKYA-Ac_hbSNP|+5lqJWhL2mLeYYP+Hj{j3_`uvTflcu zofR?08@(F7f9E#YXo|t2@VKnnQ@;f1=GGNCPIJG!b73Xma3-Ub*>tE<_?o4CB!^`dv83HQRSVd*!Giq0FE!!NXQ6Ken=2BJ{Y({-~$SiU%^S{$&2k2 zkmXblL@_BzvoIC-68TZXnSm>+T^+(SkbvMo5KnCdttQ>1ryD=t^puuAuB3@Ab_$NW z)%wfVvo5IG`mlkU`a)un_Sg|Yf$KR@{(!p|?bK{TwYXfca|`s=Us}2qGfhU}+Oaqe z??I#EMXoyVw$6#OldiwnL?Sv8DbzkzwS_QtGKw?g(luML2dza&kj68WkrBWkHA7{W zVah}$m{zNfvT$z=GLg>CG2=QV7<*k8G#bK`Ep4hgt+P5ne;G=vd@*#UjSPpq#sb!j z5Z66#Q#?Y;9z&#VfPTaEj&h~Ri6q6=%)dLS0!XH=J2;I-@&KiJ9tNkr1U)wTwj2pRd&-l;!1v`@nrgYVbyeEfG=s01`?wl=F%9VOT^G| z$4ku7%Q;5-*;8>zHvIZzlpKCI5P;x0&2lu;|h#V1O+ zxy~E~&N$BORnCX~5qX}MTm=uSN}PRsgZ~ay6|*9a6-dg^L(jJy1mydr002JikZ6<< zY?5*#Z0o>W6;EqJn}S~#VD-39Ct$d_DHjj19UO%<(j9TyF}HwwANxSyvvVr(>l8!p zb^J4wg3$E`YhAnACmP*V)e;{P%DQfs&#xmW$69u${nR8kQ}JNJnaF&EX9}20Bt@1W(I3645o&t;%Wf{odP9rC1n&e*We3P{NOk^W(>e`x19k3Gbb8?`rHnx zF_H;vh`@VbC1b`+d_=ECa2jS;0-k%}uR#m-M4Q|v@fXw4vd9!S1hA=W;)EH+iMT0) zvcqVY)pMjexTZkBla`&``x@8gSpb39ut@ziax}<&S`tQ+c7je6TWU8k_R@#pdD3un zQpPFj`72eRa%5o9v_=?gim?-?JmEt6Tq$33MFI(rW4Rq{O7R2qq>DYTF^0q&q8usJ z?-x)&x12_~oETlN2O!0^Z5nZZ8wVZm%1icajAS`3-X?Q(nOk&;D5rP=5$0q0;$4qg zHrU zp5P4tx86*<4nu@tH=U=o(vN_fptb1;878ESQF!AbVj0w6Y`opA?Lq4cu;2e~`vv}% z!xK-^wz`-v1J%!?V6|oBYQvAZNP#r3dv1qMtDbpNOl#3wjcuoeNg=-}ve}#m);5GC z!soDFLp@fs25=#3MjPZ~myINYu_e1h)rA3P(W!M1MjXwbU32Fw_iIerE17t>KEvO-wEH&UPk!JnyP<1Md&vRs{NF|LVSZD_uit8HvcyAU zUKW-rU2%8=bEzSssIvoIS4s05wISmmtmX(Ed4zADA?E=F9xnu}z~umn8;aWNW&)+A z(0ONf0G27;69LaUoYfmTW<+K3_4Gqudv98Ni*4~KC}s3ZLBz=jb><;L)KIOkzmW^r zw{xQH#P0bUvW~D>wVQ26!R?d%SWqgpH4d3;MrT|qPEoU2DKv58nec_E7dmvc&==dF z@%961q~U1y$~bdYk)7JF;M-LlL7Z_nbR6AM0n7P;OAJN;JOFMeTSs$C9`i8vUo;8k z7B+y)Tm9PN`(hO-^A>M7!D4NOc$>p0C_xXF$JH^d!4xmq02BKv5%*^bpJ>b3wOn=@ zGKq~uG+9FOpVv;TMEZTB$MKz@u*xx%C50N*F{za_u|_`c?71-`NCxy~G&v)1+s{^K z0DQ+(AM3&L_Z)U1uLSY$oLt9il>LO6B&DDH^?@-o1bBGT@k19<$+?uAEAT)q@x%n} zX-+>jx7*L78lrc=V>AzF*tlQCf&d)|yQMMHxJ5AYiaaxhz;>->q9(`yNV!rq@Y8M+ z%qN#G){MY%79t~iLImkS^g#@h zvqwMxgt>=!lLDeYb^=WiNmHMSe|=yOEgUJyCF#|f{0=j>pyH(Bq)B^au$+|(z;~1> z)Up`Mz0FprwNahKTmJ?IYcW5k5rGhb9npx$DD?A#ke?O+3o*6g1WZjPO-V89DOpshu$tH>8Y>+~R;35oC1u?qNML3*dne|JPWBeAnTIwo4R!^2 zwu3$5xDs*jAJ++b4oxfr@LG3_IR-XYzIe+HH<54AJ%Z(K%`fJz89nooIdMW4Wi_(v z7++!BOC@*j+EyEcOOYMqZvQo03l@^@j(gl95f6qD1WhVs#)HQ&K4y&ZbHLQ zug|C1Dw^Y(rmhIZ$SihC@HZTr8DS|vrYTs4);m`zhvXoW)D4yc##zZkU5A^jsEmKP zTx-uY>Huj8;?&mVFoDP@M#6>gqeClFTw)+{$-SxV0#P7ZC}7RE1@I7)Lk=b}GJ8na z94QERA)alwT{4E8XT)uk2kpnexCnV0TE3+E*XWy{`UN5-z~o) zi*(l@e|^Zm-m7BWVp^2Y)Ul2tijKQR%eYOj%_sp84I@SHI$f6h3)X@S!>s)LTu^#i zy6-@ct1Y5i0KMbsfBSy$(S(a^?H;!>zn}}~VB+k|s=GR2<%naEE9I5C*W+B)U*%_h zT}dpVE3H;OIx5Vx2GRiD?)ZTF8TkLoo5cZY(Ek=Se}_%c{zGF|&1z5OLjVDNqh=^` z{ll>fQV9`Tk~S(K{&Qan|9;AUA6VU=2m4PIlyyfKy!#K|hDvETQ3RD%PfYLsGz-#(6^fS6PHSr$Ad{Ter*7y{A&h*Bn z=&kmmSR*$?^BI&!Q_^+jU(JSBxsL>xHcaX5Ov;b?oaHD_nrT$ZHnqFAT}BM7@|XOE4;i6Ae7=d)rZm|_+lD;4k0vLhOd{wn zz;%hkyhI8$=a#9o=ANfx&Ar(zHFdp>p3`lu^gyGVyA$A*7}l4Cjy7yEiUHqR-Kp|> zN7|PlvwW1MDbY$4W2f0^SJ#$Cip=1x+*sOh&b0k0z5`*DHJYH&E?hcM+%T`0b(Oc*_S#bj^j%%ywwH9JxSMkGr}Vv93!T@P z9D7iW++bidJ4Z)H-%6dB+Ob>vlzKm9mVOKCbaE9*iAt}g_{|&C9w5|NT|d2eP2ONt z=Ln>BB(XIX9J#({x3I>Tz?*}e5Ttrc;OX4hV~`MQRUoLS{T)4fb3p&G4f3`=2G$x_ z5@Oexco$T?R}gWC12BPJFzPQ>?d}v4R!gz4u=CkSyrIQklj5j`^r_G_T$m5qxP4?f zG92b_0oS$+*Qo~V!KwV_63?zF;zQkQ5?5T^%I@y6=Ydbl+NQ8cdJi%|3H)ymK#;KK zA97NR(C+~tG5stcPk?S>y!scQB?gQ{J2N8YQJ=!?SGvaUXE3h!;;?c;oK8^Ro2T4{ zti-l8wcTj;SF7t;99OwxW1y+UQudrrs>7uDZsgM>xwC&gg@*M+eCpkFUKo%`lAXuy zs?ho-Jmve10H?@ieS|I||HJq~OCyG|-6B5B0QuZ45 zs!I?Jn7WKmrhv;}2gzodPH5ow+){2f4F_8khz%8!xBp!_Dxz5`LPgJIa8 z3nahQ%$TJ$;^vBvu$<)r?np80TE4Zl(M9PCbHJrV$m^wLmLv{u0s`ov zP&cP1un~VY)?Dq;bqmnxZ3~K+_ms6k2{vM+Q!Pws0~Ecv#_ov(c`{vRmV4-3no(r9J7ZXVHx#pCx0g1Xwy;+Si$;v>d#2?5v*;G8VK&&grP z>9!=&;)*O*R+lK8J@;=xXE-E}-m6hO9Pty6*7ATj@`4tV0`OZ22G9}ammiw1+r)Ri zs(*e(OJj5LC*O%%pE&Xjil6XqM~mu4Bwz+iu629(G~;F!!gUJVr7mN;XP~g4&56K3 z>G&}VFcN@(3z9JG!3ZO_#SA(V!;xA5+g2f3h;G7 zy5umw{l|tH9TC(&ExW0MCbOA18dLa(%={PC)Hx1#-maJmrqn$ALVv*Yxq68xd`7=LN%K)I)6PY83N6)-n3hETr_)SUBQ}a@!GNdpIGW+u< z^ZJ|YrO^82JC&>AcF~xs6#iG9L>U(uH;jZo9OhjoOOBU+h-aD%^*PvZ<_L&59>+#a zxqJsbNPT0!1$?RQf6?ET&)^Bnkkma^PP{eJ^Y|c`Pug&!jJAU_o{!SePXp{>{5czl z%I>6vUz+F7fQBP^-N0bfgfJ70P3(+jYgc7N{#qEL$PoFKL9 zu&0SyO>MjdU(};MFc6%58D^dZ)wOyYh<54ZG!d>FOba}q63L$hbtkbwYN(8$!CDSd z1#`l@O{Y}=^vRULxDbDp2LMcsykdvO;WK{*rJD}s7OHA%-mk8XoFdyWCz`i&E&KpFzg3PVZaDab^4ll(N=*j( zOpS$VA+<1qwFBdAIg=o@Rz62&1@j%Y3q8kk4*q|=xBn*mzXOn3r0(;;k^d*kms-=K z9TpY{h=KwLh%)79A14Lr86N;)*0xvT>>tD+-(#e$$~Lzbf(g|uzN2HVOj<@Jk@(Z^ ziXa`8dRlrVj#=17o`27nFUoVEDY9ORv}14JK-m?5HXWckSDkD!mzHf;y2+}%rcQ%y zY4JCq)v8mw1`&O+k@kK@bd6+EuxHOl(Bm8=cZy+ZFo$*d35GQKR-~M*s5J zI!pIm6~Gr>eBJ7RMr5w1o!Zi1$T%QzbN%u3baQQkrka}Lw=;YSor>|BmH0EX*Vn85n|$xeBzOFVG8mX#_JFU;v~P`Sx9LIUJ&unyhJ zAK$#Nwmn=@d)Q(>dIvBw_#?*VzP6eIoqU!|U)y2|)LZCjoSb@1p1anHTolp)wkfzFzwa1&$bg;p#Daap(V{jGD@(Ps(Pu)t zyZ(>vooS1bRJkb}(c+Vwx?i57OTIijcK(^rIovlT5n+MSZxp~NDOY2^1PJQv7G=G% z19LjI72~?M&Y#%5v*&nhZ&P6hHZPdR`cCsR5xU6OAX}N>-tmNt-;;0ETRh>|Hl>sQ zHb3wi1!K^^h#3-OV?pe3_Ro35=&C%c=-4{08L(2Wh*%13JBVXJdYF;UMP-HHVmveN z2S@Ut6Mop%9#BBK0|%ZTWKd3ega-Kwvfjk~ioZIR2ryWqGQ_RbF!?ysKmmKRQBQaM z>en1@2s&(+KWZay@)nLTF4h<^U$__UVJb$Lc^yf+%{6e3+-_Q!R7>alE1pY8pKr}c z=R{yxBM8<5i7AFg>R8YllDaI7m3B6h;6bBGYHk#K&Kv+|%p9zMf_|~HB`bK=jM}M+ z2*V2lxMN3e9Ue`ZY*5w<<%|FYz?O^-TCGIG3AZ&^GKE9tpelyi9r2*d+!NaIn?aM0 z1oc)NVyZ>K-F&-DeN0vZc39k-J!dV*O318CUU|ZP{ok*pF3c3_)X&c8gEuURsQo*I z{0%2e%rKz14(06?X9h+0JABlVXE0!(=fH6OTI&`w+D)f%jrVx3GpF@^TP z6NX39%2=6LqS`PVk5bv?q{Yf9(@wX-LZ>mXE4O>${e;WU?|6D}@7+hu{WnOcF^s5s z-9h-YFM_|t0IWn7OG;@J1YFiHP$H;NNck%bpAk?Uwvh8yVBH{WCaiV@+3}1GkKAGl zp7tx@PtC7?Eft6J0=a;mujyc7VoqWQ)vO9yIso^%Hhh}Y?m6~?38C}$6jxsFu1k4+ zoVEg^GU7w(dooV*Q6#)zc^D3>iBnwoFpIAe`@zDUP*W31U>en%D~w5TLUjb}fChIp z^8i4CwzjrJ=V-WL&1O$33iw0rIY2`Cx`F&A;sIdaD%Y;UrvAq9`Rq8i;9=D_x!1w0O0rZzd&I-o9h-AxkHPSM{8Ld{-5(Hk z3xGl26pk1`#0w?{)lCx$HibNXnb~YtB6JxvE*+~qD{>q{E5^rd2=g#Y)}Erui_l=l zMruN-t?}=JimN`XBp)*_4WVytLd)Xn&mw3lCOF%EhtKvJFL+>2h?575A~tM-TS3bk zP2Ky6zQPn{a^PU*2Q4t-s9pvC(j)N6k6CZY9_GBKWMa1Q;LGHIgjQe^fwB@u`UG zNb2}br@ z<<=+hJm<01#fM|{u20Mc>k(!q;n_vM~Sh6f;! zarwB{Q+J6Z@2#GD>dvEVYMsnBZ0kroAg{+J{xIN&B9-{uMY1xfFt)|x`Ml5<`$Prj z{cLg<*=9DqA;1AX3u6*2SN*0W;w3mth*ONGj|!52h5@L4+&{^DK+l~)+%n-S6Gz^c zUbse)aB(+;(_enj91#yA+`CBac||LaN?}~vFiIM$!4G-C(b!e8G1t<8fIbQquCf?h zJc#DI)AH)lz)cx@%=@?W?yZ!=P#DbS$Eg961COpgGFpJ54eLTX>o7i~{eutGr$Tb` z@Z!lOjuU+{!Z{QdM@bkyq3(x&rSjm(a$bV1Ufo5uLM3cDfme zo4e;+)%~bj6_N4~xO;ZSB>9`?yU?{@{*y)PiL3XkYoJ%($*=n<9{Ok}*WZO({LO=j za0(=iM2vuF@O>!w@aF`gMN4G>ntT?1&h}j3glTHPB}MUiy>KKqW>5asM=w6Ug0N4% z|B~Xw>E%{{DI)B9E?+#4Km?1Xx7$r|t6jvfa}wa!6XM*p)c}Ok0pDfcDCe`b6zfej zm-^Qn*pFZJW(@<5A0=Rj@^CrztN+-xbrcF$ZK_rvHQ{lReBqqTt_^|UW&x}4dn^8W zh%SWwllU`qMCh^#Q19gD)HYFQKM4n64!QVvA%*E@hUh!?9j2gTx@$-Dib%we_)9^g zCkNn~9Wm4()w@CS5}<308UD`0QVP`Ol$dDw;z@HtY3bp93ijDO%HN*0VmaQA#s_XG zr64FjG#rkd&SKT}+2O9Z{^t6}7t?tt3zX{z3#Z%cR+4M%kDUB!iZMMLS;DGFM8K(LCi{Rc|wrRU`{e}Z8-Z=#jm+Ci{>PffA{Ik0Nbg+TwrE%# zyEvn#I6Tg5$ng1F*MOe2LEroH2Aw}CR0YPPCozO$6zxDpqau!J`TJZX{7sr5;^%44 zFcX#v-XZG7``?bfui8{rdkZ07|AH6b9yurtjiZU~_rYs~-N)f`3I2SZmWs{)zDu91 z%u%_~%jkZEthu5E&0#MLYk=f>D>g0|c=YcaIZfF?v!jC+p8;_7EvtrGbaa_dA>iyVblqMd@dn{pexpe)&d@|@V8I8Su>Qw<5VnVBE+-Bp5eK2g~S zQ+kSbnA{t`Kr@;s=q7r%yQyKtxDncVA8(4b;TyA%iD_Xe>dBw2cJ(k+1hK?OGPMeQ zXQ0_%M=l+R#{rgHfK9K~2byI5T5`;4ys)ZK=Nff*#1Df6Hc&&bd@drg%0{+vDmAvB zhAf;X7>nBJUg9|6e;P8T+Jhnz>)r}TkkHCrzpKpsveBq{bo5I~Cw(q`k@tE`!)3T^ zvfeh|`Cx{2dV0Zgt1&w$vy}Y}qd>TTrCC&2a#QVi+XawivE^EfK*tdC1NPyRYhfyp zn0JeMpHzcAV$Nes&cWY>4DX2B-b=!r*YV`-Kxk&1o@CoefwdlKm?#d!YENw1m%5Oe ziQ_r)M{XKQgeWLt2A+Yd4gE~66vifE?6fy%=G1qjv$Zm6c98^k#*Hk*R%$Y(7lVTV z1)?gV@&X8;h)X2wyAP@J%wl`t7WA{pwVcQ;rJ-jQJ624+qcZx0nATrlVJff&aUlWM zHo!Z=Mq%G&A#(Op(kPwO!4tsuFXWKo-{k@2Z142FO9J_&K#)gfkiOLN=a$N~oFU?c ziiiv`X;Jph9{q|v+KgEnQ=aX3`~InOB)UVV7qVQ~UNg4IXL>Bi0PGqV9O$k5QGD9i zVZ_wT0D^e61Qba0C7|R5@(%p{bKRrF8jQ*$8E`jwdyi)gk@yXDG(`F-)T(Wa(NLMBHCW(dq?cCXta%9&N6)dBo;p>CaRm5&P+zmB+2pF=t zv56^u@9FZMQR=v5NZLbY*=FFjyLwMT;3%;FtWg~Q<4_F`2*|-HBZv@~D1(6v7zW_DBb9vcm(~Xxth^D0zh&^2 zKKAUeIm(mLb8B?c^a6t*L{yqS2Q_-NQJPmI@$*(Q;m(3{E0qxXMFC5WteJ3a?YaKi zqiJtVp4Mzd?OAz9FhJeiynlmt>(qX4^I+Ofbwgh_^+j`Ox

pu}HFK2A4c6;LqL2 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 delta 299082 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

aptgBG0vvs{?U@=1usUEj)>)qgaB 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%0Dq*;SPLW^zV~GX;IsiZ5|>$a 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 z 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

wV4KmqWJKX->om=4q4}nQX^O zT$`Z-Ck`qI!?fIdK!j@R%3ND>W)*>s_*$CC>e!I?rypd=Qv)YiKlP%;$3b?mb=m0 z$O{D^Du&hq`xKjA?Qi50Uo4BYRmOIu+jE~v;k!w8>VJaZ)p&%3dIP?9vxRnV1AL>n z&Du@UuEzU?-G@WDY!Pr z!AA(Vsja^{>>H-9jRSn8nKdDw-v-5xnvoG-LYLhK3?2lByPqMK{|5{se^x0AE^ekPI!k#lJLxNltEv_f zm3Q>p9Ceeg&htCJ?tz3|757jRV5cY+T)B1K8tJx)>fFLr7Z9;7sM?`{3RzQF;|NPFK-DJn`-f$>RiH3nZdB%Y!8l!y^^YRR&s*~A4GNzK z2s>=W9sI44v|BZVYL+ZZZ3OgosBX}ypO`gaU*M0Hh-iI%-E%MvQ@ z6aWAK2mmc;kyn=@Ktu)y006=hmr+*|7MI}M9}a(=SbJ~WHWL3|pMr4^NJ?bE>0NQf zq8p%1H?4tSW5kYeKx}MjiMz{0B2|*Iy?4ES_M72DtCw4#3ujj%e>0pnXY!n!zC0y` zEVZf{8PHYMMjz5eDDzWzn7xu6GfNx$$W2iSXFFrisV zj3j?%&&b8W?4=-=a%&!_V&t7{MM({ZHF#i(P&iK*#qU}p;ccfFtC=v!>yk0@{`~D~ zeYwibqajq3;)h+q3U-%L#uDUQ5Fky3ISVa@v z7JFa^C;qXtW>_wlTWl(7z@&8)ZI!G^?i3{f2yPR*jX5+-dq8V=6}Gw9+=Cx7r|rhM z!Q((>jWOV%YdC{e{6DO`_8Xw;`Z|g>8(LMH4Ox=UF<6GFMlloL!p8OL_2%M- ztE<(=H6RqT^6`o#Do&D{@>Oz^!*_rB^5)@X`uj~hUb=~Yzd4yKo}_UaMGzfi!}X@( za44-3nJyv%AHF3*f^M1%ZKx<%BC~-ZQUW1}5a|f;12VTtkax7wEb1-D&u6#jx%ehN ziT#;7W;WhBI??`A#dKR4w8E`@$1tyva%_eiV!A|;JJKV04(?~7OxD*)o$r5?Y#W`V zAVHe;Wzx(f4i8o+DylVE-P5YYKuqM_7giY08IuKnul8IMhlGa^;>-~-pMHcrHW-zl zRo+qC2N&hI0s8&7lQ~{4;{~Z`eOFTQn32PRJVMx$L)M46Kj&kN><|!%X4N*scz~*hwVyqjUaW?w!p|zi5bZ^ga$)4-6@u;VU@Puo+lpfG zt1C8&{nm12Z<1d-b_lRH56FiUx?u(1a$w=b$Y-U1l<%dxlY5ZyN8x`x95MaW9s=;w zCA5XUUYx$Z9bgz#iYb+69c=8Sp5p8Yl*1Ksc@Ty^u9Sl0ja%_m$Ol30sp1qas|9(X zWAeiCOrI9fAM+VuM=7TgLIGgPOl?(iC>aB!Y=Y*oY~tIo`C!{?h@p}n3&e~at(I_K zpVv)g-OWm`ZQyd;2>O4@CLI}juRDR@c_a~2y=^tw=EIAk$0fC?H{G;6(x;RexQq)( z0baTeLvbwyD&hW6l>}waK%>lx38j3%)hTAJ*rlJN2#Gg^Fau_H@RKPHDL1;9(}L z!>$_dvI_I-DRt15K|-i|Syuu7rUb)_ej-eleWMikESuZJdT>DEFK*vh8_-#^+M4zs2dS3ucaB6TGI0C|_u5DX}P zYj@kmvETVCP^mru9g>z9C%sjx+bTAl=){(NB;{2_g&|@kp#lL0041x5|NEVpePb6O zrR1LW_FSDdmVn*a+1c57?aX337(X2c^D@nftG!^=T#o+>pA5DK+rf)+d0%B$*G&+; z7zWdw-Dz-o&4PFL&2?D>C*@^xmsBi&cvY^7G-H3@)Ag3Gd!V=a^UO>)KR z;N9$9JsAv6R?B5sHFc2Wd9W}#EE0Ga?M`+^!R}-i|1-t^eEMuU*(Fq_lj(4Of`bn( zt8x*<@#U&nRV@5H+Rn?xGHGOw zlcoZYhi^wgO~1v>{gTzApkW_>8v0%IS|rsC0FvFZ0%o?XSR-Dq8a)^2Stau(zPOKX z*!?KDVoglX#Kb28BiSC`*Yj&w#SyN}^XEJ9x3lAu!?#EA@oX@_S+gqGm(!m>``7d= zisK?#0NsZ`hnja1>{wdPkbYPQ&enT zUKQCtS^6!f;5sC}DQ=4LuFzvj$``A}1*^Qn92U1po~7$4r-3H^y2Ny!=o>)hwqMO zuV%-`vzL-P!gCyER&c=+tZGu0@mj`DXv%w&0$SJCIn?MXUMR@r_Vpb>DOF;pa2vGVD9g(8SKz* z^brM+FMvS&`tWE*4GzDLcjGC%sTl23Kt2k8ECT-Xz60cEK(F73noG$AHg=le~m})@}xmw7>)*k{S%(779bApvDHgf&#R1h!_)9_L1Q~~ae;lkpBv<;kF$qHtgxA@e6*Yrt4B}6Bpa0hL5DPZejs7LGgO)FF z6J{V2sNYN2wRxGO<8O{%M~~yt35#8Rpo7#GD72+OS4+h>&?OO*T8N>FatuKiIsH?d1}Q=6apF z`m6Wc;<38SK7hh5l3cBt$r0RB0c{3I~pK+A*IuXW3sHPO&~Hd!rUNmyjqSN`|fZs~Zhbg2KmCcOW> zo`V0qo-j;*_WkMc0r*w6#aM-5NG{rs_0#=*_)oMIo&A05{FC9j$X0c>9yHaLuO zRl=b$Q;D}`xUTVi1lDXe&}gl7UM1H^zPey_Bbh7WF0ytyUxIj;Hzf10okA*QOIFbO zlw2YT-x^&)a&oahfxk}bn1?c=8+Koh0uk3RRvZ_IKgHD$@AoXB2K3M^5YC<>^8{6Y zPOFu}7q61MW&?VPebEg*AIOm@Vj?{1Ld;_Vl6_G}29CHOvQ2b$4s83)(bq?BzdHgB zJ}L_~v=N$vz|0B*6C8JvERkwRhatyiS%M{TkuynuLXEcWi0{P_-(2*M+AJf^5a-B2 z$Z!=~l(*m~4>(g@W)-Xy2==fJn(7{Z6%#2M*gRr40f!<_E|aRkNCBWP!*~J@lQ=HL z0TMo!yT|Z$Nw*^U_`;c-O(N&@gwG=)07I)Sk4Q~YcCosOK%dck185hdup}_SC#cYf zt{q4kuBHkVbnr_HQ(>_MpZlh@!xB|_MB*%6yqHWo+-HED4dJO#VNuGm)SO-6?k{o?M6}YUW z@s+b8a_}0W`rdU^x6|%y=bQ$AzQj|R;CI>z=!UwZq1qFCyW&!vSQOoiRXZpRmh~Q= zw9xl0)5afq51rsPzzG%2xWW;d235+c$bJI)O1)k4$#HVk@ou~;WYyP*8-R?F9QhjNJvzaH0*&ron!H&tC3=Ww=;F z$*ft?M0^p3U@5D=rp8}W>)jOJ{kO%+eXR0Bx#GtIS;0@g5L48J&tQ@8SnnB13eJ6+ zh3;5zo!pYE9n7yw@FVdUaA$;PIdmq7G7x@;zM@9}?2Tps%o?nli>ka~MIhox!q~Zh z?QmCCH{2?xv&W_^^V))cu#5bO9z41p)*Hm~1Na^iD1yV$!1-@rN=eH1nbC(1Ez=Ya zUn($+S%OEEwbfus!@(?b@E7Ywt_sOTzBQ!ZAh_H3b85eZg)x1nJ3Q7}>|Ga%#LX!^L(S zw(r1ZZ2+t%R=a7KUWZ=SMSMGg-@XXvx_GM{opnNQM7`60Z{EG0nItr^!SLMd_3X{; z==4M~V`RkF@%=YPhcDi~G(qSvyB$aG2;d`-H-{%D{1mvnz~Li&`0DWW?Bw88D>N3K z{rzD4w`Ba!o$((h=bz{Z7^W>y`T>YP6|ukvBWa9{kkcuf10U~`->-ui$9&J@?oKmI zz5rQHXY;s!ok%&z!)Pue4lgZmB(tj(j3$If63AC$m~FD;r{N0~|H$nAra*cH8}g!r z5eYDgb7^U!yslQD%}dk=#W=~A*GaKjunOci^a>}T0cU=lVCDzriC{*95E`jabphs7 zfRYNw;UowS(lo>QCV0jU!x&)dCG@IgbX%gr^HYL<3kEC0tbqyZ{Xi|?q+VS_Fv^JD zXme79M`bj+oQ#E)J*h{T5P+qgEWPUFVk%;q`UUf`<%BhJq zTuY3FR4ivn&BS7>SYRYj+0Wy{jCjr_#^MqRh;3_mp(PW_B zxiv$7n9{1~XbYH6Np-ctT&g;V=(IoulE%SPu$r!)j;K5SO6G}~%#t(N5`TwjKMk%j zu%7t4ah}~UvDx^*sw*h3IS=Sd0E=X~gr$CpES|vT0P$dSm#uipkZ7csgdWnmONt9k zeERm~+aN9HG(mo-!iS*@6(pqyp<$pfS>+9Xs@8#y9L8CZHE|r(EWaEP3HCA4HVVXa z#a{v_|I0lI;rQ)`VvNv^>75~11yKPz2Vt}V!(xobh8smZD0 zu4EtP`KpGcF+5Y8)Fc*BQ_$8Q?KdJxswUxK1T1w|9)V@WJfruBsog>>%)X$2Ics8n zClLh1j`r*X0!bQSJB>2=qjHYxdlTxBXy1Y&snZWd9H)rJL$?9=pRwd>r4WXig}m>v zr@;i~LY%or+vg~|tPr``!5Ay1WHbI;u&m-LA-FJpY=*u0>j`y?K+d60{$pW^I_hB# zf;tebHMK2B-Z};`;RsD5E{=`u}~JAZXkGokX(;P zwz6oddz%RWy1hIap56_NGUWm=S!gf%HmZE*QbUGy){rxj2Di0q%gT{9U2|;rHIcAd zd$B;z(6#uzu9y#;>+F&*Lt7}w^GJ2>GW25OO9bTh%#Ub( zi~XTE6O7OGV7wsg4Ue8%7l&HBp;pd2EcQRMHxJ(*2MxD{nX^l_g(`oiGE2qd!8XUx z(m~6rTmmQGM`Wp+FGm3i9_x{RF-dHVnV-fEAhnlV+9o{yJi?5}pTkQ9^1)`jxpH0? zgb2$spw35}%*uy7*K;vuoYj`1Xssy>Y#e6lB_^{A^L@1`2Nsiw=BA?7kQVJYf{Eh- zws_Wu>0`&!@<5MA7KdJavOQYso}^Z84&NVBAa<%WGDCNqqb?Y)NL;_a;xn2m&?gKFKcF+B)Yq4BRpcF+%&hQx~Q*Uu1;Zt zu)+McXNSoHpw2=${P=$P{8=xGdyITV9m{z(*G24p5PFk;lvxo85$4L?emrEt zL7!SsjrZHxA6^0VSXaWkTKpI7q>(RR7Zv&X`-S&Iq5tB4fvz=>R4)Cx*3fh=LK>L8 zjvZ>u-pOu@NAghHwGz=KE(=P`Clvw3r%!M0lIp6qCBTU(k4<|Fg#yN1VdXI$9M8Gm z6S()Zu{bQl75RdJ-I0})5kW!L_ZV*#!LIjv=&H#6{8an>dpvS{{~m|GE>j)jghuxi zV9d)By%z9)fh!vG{d*D@(Cr+$q2Ex~*;T>t4S^P~CJNLHIB6u`iay4KO2FxTq%$Rl z*hIWE=k_(8jglHpOFV%F0Xe_6qt?hZq>+<`8(=UFs=a%$%!!fKn}S0L6PuXppkJbU zj241{mN%Qrc8#^P>);~<>2YWZiCA##>A zDW0LhkAmjHe~KRk5$f|1&rTl>U6yrwn04YFx=C~V>~?}JmywXGN@5zGgKeq%^@oCY zZZl-$3+J`x{4ba_{_?}@T{H{D9+MXWfjT7_wNplj}DK%Yz@EUC+KEiTZVsZ z<)w~bbisXOoXt2^nIf>0g`r)iUgyzXcfV_Y6%vTJX*Ya#~#51*kRCK4tUs`--E?PU|Wy3Y=pe)EH*a4Vc z5%Xdne~*Ieps9y!GH@u3)CUmIPe;B-U0Qlc^4m~EdQJbvl(6gqNdzl@#u0oJ&Bb| z9N9>YZJ$oLOe(_BqS-?i&0Y$V!oEQ`$>l?Pe|vPfqZ^K32HE^O$vs8mPg@xU_#+&x z9_7(mw)K9W7)zEt0a(}3>~>)>Co{p6a=KASC#|g;2FC#vL_70r_k8GGdQ8aeSd^Z4 z#pdhsU~|Ug7Qn>hrgBSYhXnzd6HuK;2_v`@csAS2lX{3Fe@vC>5QyMpiPms zJ50hZ6BtKRNn9f|3WNgSd_J;FKA8*412ye?3x<0$WBsVc10< z-}MTv_5N##A#75dpJGW&y^oL|3dVTQnRA55$lI~>NmqE3P8#g;WFiLNO%A&l>T{jx zZp9&h>m9SL_8KbdEcD;R&bG>4Juj$6)>?2bQAQM;0B1Vqg|<=Tcp@YJT!$N3e@;=` zM&78`I@9=pWB;n5W%8+KRaHRLXUX7?r9H0n(H12c`WV4~f`)(SW$LwtC0ol~xAh%f zb0Od&&fGkHQg30-nH48B7`%V8Ap18ZhA^e-!J`GyxF>x>oFyeP;navCzA{Sw)m>oR zoCLWCf?!qivzS$Z^_KIpVq?l?f0`$Fk0kEPku zVSbY=G8Qy&I(A#{_=E9RO8%CWDc&4DV?bGcE1j%Wm3JJ#;It@?EkiJUe~`P)OcRVg zpIGr2+DgvQ1b*&p4TPb0Lz1Sk(9)FJE%t@^$W2M}=V3TEa^R25UkF729jn)r)_e*g z;%Pv|Bvj=lhpoHiRqLKIZ?TL=z?f%1ex1(=k{blHlbFw15#lXf(&opHw=AWO`0sZg4DQB5Wf|yDj z;&>vj3gu%?D8jH#=Tb|fz~jyA^x);e=>b)b938yDN}+Ihk7<7sf4rwP9DMiHZ1y_# zwo_L)@s_V=Umm>p!QWIq44un4opKWT_tf;AtYQ+OB01O7ru+ieAbL^{aa)+z0drUfM=!DQ5AoNtA5K*9e<%KgxJkeuiwu)Cl*xCk z$F-=ngU2B+Zwg1^y-@UrM=xjJ%RwT7t)iYeFBA*}6#G&O^74Yvvspv_F6K8W--t57 zU@6YP3{z^ZiZg3Jq*UCSM;cy``Q_~043Iv0@q?xM2NV46bTzk{>PVuiBd&hMOQ2=`ORy+f40Si-^=vkPxv2lHSn%*7Fpqw zwe?s|f}Tc-9OI;6u>d0LwMK#Ol+&4vXl*qTH9hODGV8)fk+4-6D%qli;C?Tja(Yo; z(u8ke1Zj~ETts;#DCS7YRP+l>AgF^bGnx+|>he5CZi3M~XCtDgC^qx-$5R#&1NNUH z;N3@Af0F?rYFS!blvuiom&<@Veu39uq|7}ywifzl@5Fr4kh--cqThB5uUNsVq$w-e zPbp)!!^alcd@iB7g+s;f5jo>_{*F+Km?YVoDZ?b#$jNe*Ki^g=yDjT-9b~6TP$w+#1e?Z9!Fn7VCrJOlEXb@$1#*?@oQs{ug ztzB_Oz(dYnz((B027tD^F+SF|8<~8H>cHA`+K_Zjs9w$I6q!cZ4jwsGKm=kb(2imV ze}u2@lA;R=&%!9Fb}G4oHSAgDF1aR^pZu}}=a1-b6Jn_ci>Q>)Y3Fj4Pa_(IH)IEQ6=WE}8~hqf?w$zr=u{eu;mHuDAifb`yvg zMwe+nlFi({$)goX4sENFy7(_4Zg(`TOz5U2V>Ges*N!%pS=!Nt+s1^Ob1_I8E&e5l zE=Uw?rAr_>ha!7dzD1H7Z*l!$8+5+bf6f3QYu((^Mzk(h)tvFbA6_hM->*&PSBp$- zW7>B?xzX>VG$?aprW$Wg@g)^UDzg(aLA9*ptgr4hnRIjtjV)rR1kSJPdmDTmT9%s# z;PCgh1kZ2Kc)g)7x$yTC_-X5YQ?_{ZVSdwX8sHD`Cr`ehBMP!6Z;ZrOs)M0Nf6+sZ z{}ogdKRPzaZ#F4mlBX??K+3+QFw)#T()(bfchtz*K5NCUwHrDQ@T|#`RdHpfIzNDv z+q_09$?4QXBvj1a1xS_;@6#$`Qgu;d;5mXSLR6kPn$qPnB90d3Om973@` z7#`P>r-f>fB$Q1T>mUqp2v-x+-s*gMLJo-vT z{3uJFUyCyCm<`bOal}K1`t7NcUCJK#Wg)@Q-J>Yzo&+yLdT_Dd&OQ)b`-Q%BcPhc{ z7S-L-vIWJxlAu%4ILSx6t)U;4-(g+@q3Ns~?A8U@T5ZvwPPnX5I?hi6X`$ie-f(marPRmc_{Nme@|K8?Q{J(8V z5u<>^tv<5IIG^-Jy3X>Oe{)9=;ZIu_{kEpeIzvWF6nVbx!?2_Ld}D*9rA&YuMOfFe zGDgAAA3F`b4eW^Y%rP1K6SBy@nXSMTu8DZdRPZCu(dwjZH+6f*)J*ZfF*i|sYFGBi zj2>NOP*sHwyxZ)-*|+#39R`tt%PXn6EQOx>8V@W=*?V*eubZpAe^%63(&2%duWQ>< z!@o+kq7;DlHXJuup!?<=o*7^r{f{U^ao9DaJi2QS^>7R6taZcdc@OvbEG26L>5FC0 zj0#IMRzM-E^Wd&I+v%)w7x6)Th{&A2y4OtmtHcUXZA8tfL&NTivb?11rJzSJv?*zD zn5LS)Jf$O%s;Ni(f1|gxIPqh}ZQIH;)9k*$Y(HK;jlot7)!Nrn@d9qT(H`?T#K&`G zcf5`xX|nqAo`St#s_{#|K|vYkzx-0o4~-5y?=6!mS#X5+f&&V5A^2K;mu!rYVK7)M zWICh)?15`c29a$W{Pd1E9Y?GTOdJe&GZO_h0Ze)T!r>L9e-}(9n6tVu%dRDq;ub)3 zOy2m255sj7pO*Hm#%BAJsJ6*|Yzap}l6~VV$dPykD4vNMx+eUQEtGK%Dc^RuVm{Tv zW3HjxpDF)vg+U1Ysw)_?Du7YsRlI%$BR)B|Z-33Gn-)C?b}JV;+2Q0GYo;0lTjlrW z((0Gp0hxY;fBTWP0i-HIgx?e74w|(YTk{n?*H4q0rFffhg89R0mybkUfidGwSc1Vd zmd3hwhb+{`tNLRWng;4y-x2Re^37|$_Rd}?3NnM!2uxUYoN(^)z3_Y@e(-^wK+10M zA3Ut^nfHijxc8*qL#>ASj2`ruUOzvI{GI%IOGjj8e>=dhhR;_OCQN`!kmn=%3`5q) zb3h>1A}jE+Ww89_Od#C>3~$xAV03vI{}PNk{OjQ~k_eu-)stEu(r`N1>c4wEWEp_1 z;%wz6IP}quJE}!wowYWCZD8Rs2ui2w{(&ZzS)+#6&+%67C8L^(ohTR@@nJ};b)h@& z7vasflXa%yOpjKvU~6voTmy+;P*s`o^Cypi-Sw&VYra zc*)t`Id&Uj*1k7!!#AO|A1QQ7`fNR~zT0QS1Z6nU&ad=eH)6Z0VrE`_FRwRWA1gGF zwLbJ`l90dl*7u2uJfkEN5&w;f`z*SN>saJ^e|ibzkJr)t3047|NMFy?RZ5#Owy#pt zie2++R_+J3*2Jhqk-gpJXx#*$&V={WDgbHq@cesN>jbTXbzit*liVDqqOes?^(fIR zC@8?#BWTB6_F@n>AU7$0~yjVZch3h_S+!&a3v^|x*dr?GUP z5XZc^)8p|Bp(s*Dah!@z`dFz#o;0c`f2=VPD0VuwQig`M+$}+T7B~Ly*TTd~xoWf# zkUHhfxl3M)hG##AMuw2+^U)=O6=We!mQVDK2 zMGd0VUO(5HR)6tHy=_JB-H^E2Im12m-6Ipa&Scl0CDLzG>+7D@-79Nx5T%Lqe?(U) zQVXmaC4`K!`3HcbtKsGpecusBF$7J1Z|U)%s9?i@HRcbx(ym%rR}WYf`%K9GNEdHN=VpHCm$f78xaYY4$vb*HSX6kZ_^gnF+pM@X8ufbo zmB?CTrmyX^Ld>YXo|<N(XG3Bj2yAwab+Y!lB#$0jZN2W8k zUk+(mJrz(Ff|F`v!E?bgJG2HAjHLq;P()B(1%pboXR(>skPJ;SutoBvzo#k&_4)D7-T34Hs%hFTsW>>lW z&iZyWp+$iPT|N5UMyXM53D)JRVsTQ>vy9kv1mYGCpZ2GH;Tha&l+U&AhK&4JQyrW6wF2Wy z1+sLjry|eB{?T~*e{fg3{ZTiGtUt4#IB+e9eX$}_!gppuSPry%9FpXB$-VQ4kqO6++a;+r-tMcdSGQ|64C)IGEohNfi<@-Rjuij^wnmpxR}vPN;M^YsmwiGE3V*FU?Q+{j zlK=S>V`^0ZViL0KB$ri%&dN4b;hrq1EII2v+s6XIAvqQZV1a=sx~}d~?%w16-jm#$ zTzAg^m;pda&IV4|ATZO@)8F0G$N?LEH)LTl7xD6h6>>5B37_;1dI#)vl5R7xTuJ7> z_So}h$1jHP*AMJB5eHj#9e;cgsSm@>Mabiv&zVe^Tyb`_m8&FX*U3U|f{e4Xq=@H% z6z~jgc*X))FP52@6*7Te%Z&3ik0rvo=A4~RUXL%X$G*ImEQsgq_2tFQyUDBfH<$0O z@ga=sEwW_IM8d>6O)|+|Z6(hqmp%P6N|sC5Px&*+%e#!1ce%`pP=8jxw$%_R)?9)A zD$<3Bc)7;EiF6V#lAe0$hsin(B&z|yo)%&`U~?{cD5pGDL>=J7Gk~M#Wjs%cEaZ7P zbs>-_`fVXaRK9R=)@91G0LV08OAbKq@eRP1*>-?byyNf_@K_CctbM5|JS=1|i?{-j zMuA);*?Pc4JiX)boqyNsA-#Yvqmpnw3_Pc2?sOUlYd)RAsOg*W+3EZ9o9Wxri^Mg!TdNM^@}V%$-@<22l;RfCHC{t4zNe& z(nl5cz^tQ^#4my8KB$jKT@Z=`2Ac_QnOKy1FLD+JQ3Un?eju?HBFjN1MaiqPE004#uJM3E95P<5F?j5@8WL`wvt2Fb_RX3yp z9$1J4E7gIGK=!B8bpT2BiFQN*E_yPnrWE$j8>d;xm(k0O!W&}z57^%Nd}rUQRO%<5Ms zm3cS-CA#G-2ia#E&IlZEDpG=7&%pU%ki$D%_0E_N)&s@`>l6kZ6?t|v6Y&uYVf~}I z$P|zBGys{SH(!W(eFK1qLGXe(Lhf4t9yvb&OfR#I0NggK1Pp8W1~y*f4JUP8CoKT9Wu9xT#W(;Wj<*lge(94 zh09gzr!*nsU@1*$Lbd-_&QlVZB$|`;WI=|Gp1CL=akB9SEXZ*L2pT9n_{xX}UC{^g<;+cH2u$y;-&dk?%G5vzNyz<`nHz3D!f&! z6-LQyM&XG4@_*CP53r4cR?ls2osRtT)Hm00_TJOcgJfCoGO35 z!8m;bXqsW6tJ&=J8uLUxjU`Mow-if4zARy3Vo?Kq!(5kI*#sdV&IyX2EhDoPhZOr3Z|x zoz7!WgILi7LuPH-yKF07G;|R|zz%=v9dg%EQ3!HM$0LqC!BX^cjW3CaUA1yOy2GIA z?II=12;H*Y#2Rn^CW+uc3@|KF)FN=h`j=L$yxu_ClC3dF12oXCYtsjDoEa2=A=ie_ zn(bmn2f+}&K6paGp0{^7NMPFDh+Kb?^4MewdXYui9&8YDkph>3x%=EBc|Cu4;xrf& z@)Yu^%j9cmw!zlP(80QAW?rNx2~g2ileweOF4V_*N8VNzD0IK7bP3;_MXqO9%IA|vNet&D>q33|NRXz?_`tjV&V?0^jkZo1i`T5rrH9|3K7kx+SzxQ zJ#Y{btR`q*YV5((msbb@^-jSc?ef_~WmmbNK%7E#x8BqMExkRZg13KJiEvfQgiI2U zdKiMCPpQNz{PrL|;|N48fi|g#RMHFg6*$5|t>d%HGBzL3WFk<$(vhIGZ&LQM6m-XH zKU?Cg(1d6VwxbpyyMxLI9*=Q>OX-r5&OIrr8mO?chF1t>yfBu;>IS=61@SF~hQ9_` z0JObGviUOOv@eF~sfd5mLi)ArV_gb#Iyqr0Dbtgqqs?aHi+ET>Yk$s<{u9!9%7c&4 zvnNGPqO8az8{8I>t(PCb79FZ&7S zx-(4rP;;yV+j~T)=r)%7dDMY~XM}P{3JZagh9%022!p&C@#v}PsGpj41%Az(PqDLy z;}$HfwdM?C%u|0D)OQ>QS94hZp>K1!`TdeKpult zmJF*b26J>GUlo;o@ct_1RNlmGRxnJ|?4qyh*>H8y*L{B=lx#t@;@KK8swfBOiggC< zc%7B#>e8{Z@|QLobvp$M>N?{OV>1^bdHp94ZlSb$b|l1hn*eyi&g$Cs0Aw7Y zmr*ey9L$F zr^0`3MKa1O|M$Q5!n=NZdftTQ5V&X0-kf=gwsMouzR@}Wwz+_i7@*I#2DpkoIm2_R zy8yxsieYGv7(M2`DIpV81ppn+*j&t!NU9ff3UPuUIw&>4djt5OawuOxuph8fO zOdlIm5~LVs6#JQr=oc}{fR&$Fx~ZM(9^HT3e?(&LP|4E|$0ux_;Qr8FEpiGdU|S%m zAsvxKguZO;iq5^{Dv)Ldgj}3+fI!%&`Zk?D)q(P^lLoc0>(Fq=#MC&7nPf?9j{ngA4^(nOe#q@c^nUWobUqQ8h@Q6p=}Mi6Ipg zw)Ao0{rx@cC%F||sb7gCnlS*4f!)e9T*d(?a4?`!?tp}*4G|a}BROX#fK4W(1oJrK zz&cp;IY#7tqjPM5E zN@HXFY9W~<$3Bo20w2%&$d7)^n# zQ#!9zG1o(y31N8ASd;U9mw z#(!K0F5DIf&--}tf@+|%8{}7!;?92qlmy}&QvVJ;MuW)>S+6AMsUh|yuxcW;jbITQB1tj{Hs+8J zssrgpslaYdQ1+%(HnG(5QSK1JYjZ6!;^<#A8lCcG_uC*fJ1R2vUgFmK`kix_)5#W? zS^cmzxHDQH4j9b?iqq4Xh#@nhXXP#)lphsRjOiap*Sps`VETWQ6xX3F*~||iSH%R8 z+K6YwTwq4~#1XIEhp)5)8z^jD1z0-*j>hF+#0LRX#KG}%TuOu;Rsyg2!eBr-V;>jr zQim`kEBs#MGItf29TI>SjL-NQq^}%W(eoma>fB51egSk~*hkeZObCXYcE!~S-T~Gc zc2E6dqy#U`x;cNJ6~MStWDzA<)H-1@PGwq;V43qcX6@8~iZmvLJ4ZfF%JE9Ep^PC} zbBQH0S zrIo8tGaIwI>C;r+>syhg$ZG@h7uo25S%&T%CuVJ3h7MMpRr*wFvIt0}RFIeB5 z6|#Sf3ow8yGEV1I^K3iB_9f~?9uBSgVIUbm8n6v_Ai4nZupkVJ469TN&gZj0eQ2|x zDzPeI+m&X8@18pEf(!_cD;hc3tX<~S{gIC5?$HO;BTh@Q6+^Rsu&2<2?OAfkZ0k3r+sYqdc*5uPu zw??#TE1o%@vQOAmOdUGy6Mvf6VZ2MVwR%{}%Qn^o!e3@dk-Ep!>5lHEsapzStNpa2 zBtwy4-b(sSMI;+UVOdidoA4h9#{T#~tQ^snIV~3G{#~au3TS5(X|#zLzEnZ1-q?T6 zu%lt+ItAC--A)CnTb!us2pnyEW9rrl(w0%AF28l3wcqUX)17Tqoze8HYKKSj_N}T& z`|EI;)w`V~tPUqyUS^YjR>>0XQKSFfDqAb++=_VK(Qr?n zhWlXhzrG<|ynRQU1x#>WSp0$h%M@!TF=9?ySIbypRp zhe5V>5HIuVZCCZyZ$yl*VNF_xIX1Mq5I|X!E+)FT?E#@MXf9}rblD^EqH2*?1=$>9 zZFH8wEKj0BVk<{@8!S0f=^4a54IuOS(-Qph7F)>gc=>+|fcPfEP81EqnmQM`jKpkO zE-5BxS8lQACe}I-q;1_>KR`W{tMOm8- zk-5N+wTYE79>D{k%5OeB_0>da<~zU{JyknE>9|3yTlQH-i9*oxn?x#8eRfLc&~T6a zQ%RkD(gza2HUz4XQ2lNA+5o3S0O3ReKeJt63E5Oqxl);M*-avi)&!HQm6HQG|5)pl zBKN5E|DkX#4m6sza0-907iFk%97>MJN>y#qsB_gl5u1WyR$+G6Us|<=^5d~`sI3&! zbrDICMxENRyR2gp@971%nmJRkyj0+6?kX>2ZVdBuJI zU)(m*@bCN;E?gdalf{svX?xsldmN<=Pm{n4r0qSxZOyI$A6|Q7dm;48{q663lPt;d z0_}63XFqM&wWZN$G#br}Mx(WrwP2^5-&NV=RTD%zgW$#H^B3zcHeWmsj<3?-;I6qU zi{PldXl|1#4ZbNC#eXzuva*Pw=24mkZ}xU}-yQA7&BrE4ifOR3|L*v3@9*!A_YaTo zA(UImX7jRYf=M||C-urjRnFjho~IK8R0r~UntoWMZP}tpKQ?)GuAkI5T=g<9&sCj_ zek65JH`6iwP{p%Sefw8k7V3LmUS4L!rTSUc>f8KoJSk`MEPvM+RQg+8POj5trK#?= zRs#5_$92Avew?K9CfK7VyH!^#&gI9A^rO6a~`55ffAS`CHyRim=q;27;2C`YY z!ebGudS7QX4u94zwFsjsuaTxnqY6cJQvsZDb2m@xA$5Vi4}FC~PwI51EH1LkMU^xqJh@5o41ZW{nifqDEGXY3S%K9jRCS(I zHU4^k_=W~y82nE*{|3f#7+lmaC16_gfLatE7G=X-BPfHF6=dPG0!|WMjxW>Z4Lys- z<06@*<1v(4gXwt)6Dq6H8K4?qZ5&T*3)bgK-rbOuXo=a?|rkkdkBE5 zG?uv#Re#|>qm$Fy(|G;t+2FK(8V**z-#t9q+kZE{x60FJZKa+4w+GvYyW{9HTn|&HEaHw6~7i`b6P*k3W2iU z#jvbS&-vx{yRSQMVf5AOchJ+LgYBJNw@`F?q<=bh1Oo5fx8t4H@85mbDRy#NBQbvY zEgC$1wzl<`;l@{={QIZB{pra+|7-N?U%xy(IXy!%0hpDQX?j5em5yggbqxc`f5tp* z20Y7GS6Aup0Tv9BfXf72hD30cHjAo&SJR9nY*O8kJO!qtBC1OIabAJ!Az@A+QQ{kQ zZhx~pR~3Wn^sWw8%lYasSk15MRcdLq!fzL41+t`AZ_;X(6-f>fy&!lEz-t=`E~{h) zO%H=opqLX6gc34 zK9C84yGg1nInPs&N{h)ALM&^VKZDq!Gk*?>j004OU_LP&WjOG&7Ni;UwF*cqWEWY= zowO0u#b>}I?d*wXNi(@J;OcT2G`wXA2B733Z=m`tzO2f{yp9GZn`cfDfkT`q-%n<7 zT1=zCR$DgB0Xz~(7jl|PGGMQxJD}i4l3G!?C}1#Q(FS?~w4l5QNK}Ud18AMvV1GVX zXgIh61|J9q7@qJnTn)E6V$g#|R*(!fIBP3-Qis8lz(Yg)l!yeukE?W^CzCY#Fbu+Q z@BqR+-?CAL>Dkm!;^c$<{PqgwdmkVuQP6qnE?4;O#l z!#!S#So7~O#OY4Ne)1rng<*`UOhm1B8}iOl%|cV@sp_Ev!0OQlcQ%NmS%N_C@W(l} zJC6py_4Rc&hn8xP#(7C92nphq76>g?+}^N-v*HS0obF!fYjU-$e>RVYQRow+L#qR_ z;`;kBaK)C@#3#_i;9;`M8XO=gEEj)QX`R*g@ZkNFULt~Fwf1$@SW1fG6;k2pd-P9sd2zKY^gs&mW%X38!3vmt=rMRI%dD+yR`1CoV4yKrzG4As zTYQCws6+@2lsaFaF`$eaG*r+YC>OP8c%a79BKd0;Rh5tTfZCZm673=01em(vMA*)WTgfi{blC zTGiy@8wHChQ{FE@{GLVo#8^=?v*Gw6gLcC+V9Mu~v6KaW4K^QO#TZL4VZCJWt(^ro zJ2QsMN0cmh7Wmg?MW2&1M`YApQPCOp`k|u2)8Sc?gM~hGd+UH?{2qUx-(nx?9#JEB z)ejM2P_|au)9_*1)1;iu63xjt>ly2wE-|Lw(GWzXx`z;byy{mw70>?7>Bm}-H6aS7 z_lJAGSE0iX@`Uz8{oYk%i75@}-J^l>^zB#28k*wlq>P~Oz@Y=0z94$x|E#VTAbL>% zs_g}w|L+gqC@1AGsKI{@zC!0uS~o61k(}olm=o1vn#QyTaXv3`%i{CrL;m{m)#j^M z0iTv>U4$-}B)?7WYF>AOmJDxjO{gm1ulz1phtUh_t8$S~nRpJ2R5`nAa)Gt;4B_|& zC2Hb&as{gi^|*^ zc0W3GjHOCXeDl+F#(8RcYgH#oY*kC{`*l?CCc;?4%5tOZ9U$f0>MxlS%&9$qCks9VF*m*wn@$E6k+cXAcnk_04_P%Iah^)j%ji1=Xb z`KMnziduh!B)@0MJGlIQUIsIwM#>eQi>qsZ&d{;&De@Uuj{Z>jqzHD7(!f^9NLaScmyFt60Q zNBiQk^Ew1IBrk8FoO)Xh5sIfxD=kPJi@v`LGc&Yjoy!$;Wt?_4If|y>9X3b zV2dPcyWD8v0Zs<&(ptFGb7Jgx>XmVtG(L}k>5hNt%Jd3JuY4@*FR^%^-iJ?Wfg7o! z!vI}xyaRL6zMr5Vf%%SqvsUzAWD|G9e})Dd)gwKD{rt#;9vOoH zM&Aewk)b){qpDVpJrn^|$`LyCcnbC$t{m!jRhH-mUw|dhI{UtX)gi!=DAKicr7Hy( z1yz5e+OM6s+(l^EJ3j8GNNORSW z4uC`!g+F=+xvXO>6GIgkp$%g*86Oj8!rS{xqXQG;&**LI8pO8Di9!R4g--Ic;J58G zA%H>+gKVSV7xvF0{mzpb~kyB(DYT3i-jDqZ4_n1sI z>0J~$2mD>$q#W2%G}RqxD@||ez@->*vw9GT7_Bo}E~|IwOfL?L0$h@UOzulu;%K5gAzlN<(oI$;bkQuaX*__ECLD zn-6IMaEQM`Yl`1wRkKK7e%u5Iz}$9|y*M<%J<@lL6tYh@U-i|4hGUr+czcXFSuGvlA2;CYSW^9DaABgHEX0s8rcmg zF7RU^bfpj|Xbj{(jCQ29hjo0cwMit9ROG0X?&mg&Fixi+k;~b<87jSh4D3u}!3-3WIif!?MKDJWyBX_06bdAa)6#$P<@wYXA#(yR zQIb#Ti;u&wHy9m`%3uk)3r2XS$*k=PGQ8-Nz!?`MD&Aj?f|r(R2J9(;p6G%C>I4j? zm#Mr!rm^C<5^dyAt zrUmKT;n_(zr%j7k$caz%S4-m}19V7ANQQ27H6(G?q_aA5v?5{vu=&W?=PLe!)K@V@ zM#>n$njQs(^q-NeW{BgM9{J33QF29Ps%i3jeOZFs$u+Va6?cDiU_)5T@dkb7V9Vhb z&}7o~2(b zT$>N%_y=+O8oiFuC`XBt<`+tq}QW#VFJ;L}w3~mW1 zM!zedK&Q`M!r^K)cNp(v3T(#=6kUJY=BkWL5!}RF&lQ8H0nqTU zJ*rJWudL*ftn}Ms*dNvVq}~#4Giwj6Ry*1Zzr4tkOOG0(*!bj0eMW$5(|2T4b+*80 znl&inxeRlEt;Q~

0Lh%HP_Pd9i$*B}D?(2yr4FQ=4X$B4{%u`N2om;@R~Szx#yR zU6$rkD9(S}fTu`u<1HT#i>n!+kw(pQa4#N{E5u?dXiRRWtf~XA!gn76@KV*Wk@91t zivzd^kcE#Bj`8GN3EDC6Wm!z?(eqadL6~qODTPRi>Z{6o@RhQ4r>ww!P%nCc06y5O zNe;4%kJ?R9v7LilyNk;6f5E&G%&~W4kS19(9!GyD#z4;ko70$3_%Oz2Xtltfc0QA5 z2NqhKifBIa={4lq@px8F7rFj5Ehq5Rk_7}=3~_1}zYeu=jxDKYWXKpgz<7)zT%ily z83vQQHtijmaq!AN_eBU>Vw)G6QQKc6R67hzwRk)htf75sSr?BL0XmD%8We=LcrvH z0eW$6Qg+YY)iBYGQ)TSCtNENIRzQys8h>CbvOeCFFeY?9<`N?^7j#qr!A=$x`aO8? zG7QZrL3oR&wyfeHct>84Ky7&;0*EGQ#pHj>fUeAgdQxSe8mUMV@q5&ZIiSSbVDAeM z^>uTHPC3Ml_QZK56k_2%0Q*Psa+2gcb@5e!%M26*j!uJHD4&4cIYDn!ei!gQTsl+u z7!(SEL)>-Xh3k799Ma5?LU^JMF0A8s>lR zl^wW>TwSA&j~qA~=Ke?PWY)VBVyLTU_ZC*aRY2TEXMd&bWVA|L5#mA!^ul&f=Qyv+ ze9@$6BzkV^|0DlAD29Syt1?6tU)WEa^7NuK*~aa)Hij4U77# z+K*WP1_u;~1Tr7lnq{DgC1QUh5xdZ&f!MpUk@ZLij4G201oj;W;R&AHPq$d=28w0W z(x7A)4>@X1ys)wCS3OyUuB^u9fSNpnjj5^1(liP_{20$rUktv~uLOUle$`HtNjbk0 zPYF#HFh6PY3zSX%LRQ@f8@6W-W+#D_?1B&1U_4DjyYSWBI?60$K3H@ou&SbQ;~yhK zjEzxeSCoM7DCQ$U!XOzZS%}d{jzUBM+k8THF)Sw?^gFaR<*F0jUtjtHxzJgS6!3&j zUFea^>O3p1HM%{aGt_?ont~aJ2hFe&nuJoXQ;QA;JKUk#AOf4*lhrhekHP^}nJT?p zt9iIro2By3SYiGw&3`pccLce$XjP<}=K6E*op~bDG zSekztOq~{!5;Lc`riFNjY`PL>dhz+=tSdeni-R3(AHl=qi{O8r^}9v@to9UPT9!yt zCA>X%hR5$IF(HVr$psV|G*(}1(3a8M!w#T5MHW3=Z!Ug1#&ZYFj{o$*%*6h?^9<8& zm{JmldPr_qSAAN-5~QL$ZZw_A@2E+-qgu1=1{aW4O{2p&(-@=4c+rJ(Axh9UTzB zwyoXS9;>j=QlKveV=uUrcNywuA@wn3&nm?upol=~;URyJC-o}O>``H$SaU?=BmLrn zRSSIjE0JLk{1=VI@4|*;VTm{m>8U@+g*<)mI?|=6SZxJyj0Mv?nVnBz(FK@W0h-yu zJDcUJSFeV_X8AdMhzOd$jG62;QY6&J)$;5qD7LXmrefJ`?h4*N$<1npwPO~U0`dkn zY#?`wxiWuhYQMJEC{)Q=zY4`B_a13m&VGQ=>>8W$*6%g*GyrNqmA|s4LFu#f&hJ2a zsJu?5)G0xWpJhL%Y+Dam8&yBpuP<>GS4oY2REd$Ln5T|GK9%9_q&E|3MFS}<_N@7T z2Ta!)Q%7qRf!AT3d)EinurX~DmSUsV1m+bN5w~t<1Eg1C_4;$k*)Z`hG={F3XKDF@~5R^61#3|6_ zzJ=RiGZpWDM*)DY@ME=N+UupcUvybkk`@CV>xC?+9;TIPG)>PJmr;0#NRh3nz0SD( z6eLYMn|f27+`m@Zds@A~mP#%uqatHFf~@~kL09JWs&+jmdOBul4^gQ#vfD5&n=!J}vR}4iaN- zMNlYu;*rO!ah=tsA8Ch5h<6z@D~Y%r2J9cZP>yFh!_KYfx>DBfpppg6V5#mPcKKr1 zoyE3)PIi^BlM0TngMfX|(Bpr@f;to__Vf;j)V!(b3LC$8uOhxm>IB`Do*u z!^$+9Hy9v&J5-@i^R&83=5&U{sXiXh?^w+mV7Iv$TrJoE;C zpn*=;bJk|}ET^6ZRO(3shT5Qv!$B8{ii7}YL&^1rr%yHw-w<-yTuzlX4x4r0sIc_8 zKh~UgC3h)!YnQ^}?%R~)5mKQ~>Sz)NDLKv?NljGP+coe)pICC@ujr*jZ;b@D{gT?j zkQDsOQt)q1q>DzJ!X{j~*b;!)&Om2>Xf|)fomA<(lKv0+b8#Ec!@n974J1r)ixizN zIm}CuXJ`_n=lI@|kAd;fAdrQ9`k@V)!N`N|B4I?XQ;DI;5S_gyuX@r|2z9~8;Dr&R zz`sDv@9D6`B&v@5zNePr9#uvgfwq5Bgz2h;OlVdzDtwV(P2~4Vg-FL@_ z{}>;3vQLL$^wq&%vF~3-r?y}xP}#f7|()R<&>CpbD}8*viuCVzkCwX0$>6`H%EBZeg3e$ zT$QHB2H8zf`_)lTH(^n{YW8H>1R!tg?Ifbnut=6qh1 z)|5%PC}2(53N0UzDl>93GuZN5fDCO?cjt5q@sm;Tyl>0zf0e%X(RgWphtx`IQbnyG zKveo_P?R(;eCypF`$L@fe@q?KX(QE9cXV~33zZnr*k7Q1dLid99GrEhsi{OPQxd#- zh!Q8P$ez=YJgQ}G!YboSq8xE|L?U46bTftb5$#A1XF9V_wvK~6j^k*S&xe@lL?s^DAL4_8;d1kJy_j*tBb^0k zvE$vQj7_eF!aK<_Zz-bFXVRG@h1kLV(cX_-yVPj7|Ftcx zOQ8C=*Y5aI7C7D*sy4jWgWlKoox1NiAv4POm~&9? zDEf-FN;zN_gtgv|i$`%^-X<014vE6AHQz`y-uXgDu_+hd7P~fo&C|X%$vc4#xFeQar|3Yi z4heTUqff;XPCm*bZA=(O z-hJ)XUt%l0Q=O~=`Z^4#D_oWinVYFBIE#gTueP6mf@e_lS)g!M2eNq^io)e1;~+Nq zJu!)ssyY8Hq*|Ae%Drpj1xAmk(`x2k3>7cUsNezYXtg6zu3 zY5f}SvqMivty7tI6OmX+u~8IcAaVGZHY}eQxolK7xYBU6^yde#nzX$v_-Xe`#1))% zPOCZ{JUHC{@74#4T zPY3JWO+Ejo1s2nNV(dNG8>}4s@26e2M&(K0OPBCod_Dl2uq#!EFKp*cHPnuX99YF9EwIogXHqpF) z>$~8xCflg?+KHha4O)Ror$LoCL|2MUK;=-;HPu8k{3xnr@jXO_j4^OfUr)AX9Gww~ zjh9_mbS7;S<1loS!IuHYWweC`lxR^mGvjeq8L;EDo+R_MQ=^cork8j}zto%D=m9DN3-YO|$*CnYPk|(FPfxa(r z`7DQVio~@Dcz=2F&(nH<6$gI`2j&t=#~guOR5rBo&Qp53r`)+g83G-sFMpMltLs3FUm5A zp2wR5?)4TA!4@fU9USO1B_+YOH6=>*Zc|zqWZvuE^m~KCy*yu+jO5t-hH6?}3UwMj zsZT?Sxnt0NzoJr|luuE)bX3xRoguyg*x{M!%f-}!c!|d%t!b+>xdA(jG9o!kVSBhs zmzJmPZxDfES?N|kyqTAfC=H>ydSM+;DY&nJ0Oxfenx zke#>--ImTW(-#e*DB1<(^#E7@i`Z8_@oiGx7KnI1>MkzL=!65Akx;G^JU30ZU!o|% zdr@iMOBfop%6yFFqD7UvY%EcNmKDCHuA~iSbicB4MPLlc0xv!;Ktfe18-#Y&%{5ar z%S{F<3E9if{`^@Se3N~D&f&UHgSG(*fmgO`)NUkTf5DCV47^Ges#^!YL zpO2w9x)<>_<$7ylrd)? zI?_VQRIb=t#^b)K2I zyBCrjh3`V^&oJmAsk&*#1R^7Blxid8Fl)@)>?6>xM@&-!gPO#2FkhU*xLj@2i*rn5 zbFQRs_pWkF;JI;hV_m(bG(i_?iZi^1ZtM56UufK0k>GE}5htqZ!46G|e z>9Jvd8kZMFVW(^hlq(pG$lml6wfG3lYm9Eey$amQhS{*p{XmVOgb~_;xzcHx`@I$X zaK*`qaGuj6f|~qG8h~qm%?YhKJ+D8gnb9`%kP{}lUY=ewR$a}r zA_RKawue&>IfwiI6|*X7@t+#vPO^mXU1?x}CP0PSDS;VSEz7_v+3F=Z>YWBOllHyz z=F8wPwuI9aX=XR2kv#gxgCejBD{Y`=mT)H8(TP5STbFV@gdD!M7{M08cK8@fhskz=sP| z|49YMtumF{jKGCGmwZ_`In6LZxS{LxjyCIlUn@QB*h4C&oukJX6HcAHa(UL}R{VGs z6`fR1SB`p^;E`%W*LH8M{OJPSvoffEG@|S$@m#{7@avqPRqijAyG}Ym+qWV-L(Ty? z@%jXMrjNfqsfR7C(R<(@F`)~Sg)7@J7L1m?DY3E^9I<{Qo27VR*_tRwN3wr6By@?mx1A<2Mwh zX>PLD$@SSo+T`y3@iqw#w&_uS*AX97dnRVmRdqxj9WtMc=&f&-7^z<)EHmUOFyIUb zmFdAZJ7m<7*4tWyNRNv4XjD5=Si%rcAU@6tPtbGz5^(N(LS z@b*PQt)+F1_AA|HOLt__ZEQq}<$ci;sB(8+nABPqGeP~wuxHg!Sbo@A9+Ogjc_sC*6^3pipNX)xlNd|=PDv|1|p4wA2tF~)_^>zd@a zsc=W7yNmZ4d1Y}+O6g^Pc$ZII(zR9?J}rk`<&H>CeX_OXBr64WGb;>&IF2cj6~{z0 zeou9x3So=)7)fqn@w}Pkp5Nul80*zlAr*-}88LLfbhWoEiJg~~Q#Nd;T#xmd zO2$w>;QN5$$0O@#zsIhtedJVF2_LsLS4e( z=vr&I9kjKv0o}aKuCsYM&62pRE;sPk#&J^pD=D75_?*Jw091abfZUwsyu3vhqNCRl5c`oii}l0HDw$u|D@FUVC4`_J zIVv8}0cX6NAemEtx(95T`JLR?(^OxoHAC+dn0^?LOq;h*)Sle<Tti${r(+Klic4JHfBNmuu3 zS21#msKQ>2t1T-|6h%tEoB$g|SGY=eL*g#QWYr+|ZZfccr&IrlP@8pht9~id8O~W& zME1j>{;6Sk&fJst+a?E&Y+v8l4Wmo9Nz-YjQC1_03s<`tMmF{?Fg4W!J=Fs})r070 zXXp3#oo9yGafdtiE`p!1C`Y05otufR($xy7-LDdD$hTN3Jt|icY8HP$=dfE_J@>1dJ)&r}$kT4O8DxdBQYrk6 zJDbdpy#^Z4EPswNdr5Y5LWtA8tGQ+g%NjS}T9r-r+C3L+} zlZm4a{~m+pg0~x{62R{Q=~6QcFj>I*m+T(d$Cp3T-8cC4{O1?yJN*TSeLgHKrD~q@Uua8(qAmo{G?KsLHhvth zF~yyK+o9YhCmH{&q}H03=xKZJ#?s(^K1}Vq36hwn&1lyfk7S;^areeKgNw%9pE-7J z25zasv|T$t0fA7^P1=0o<~}ov@Wp(&phlQizbdTcBq>n_u)MPtCb%82YS?w)h9Amq~ZCly8Ekn(;a>=yK-tr*FOLJ`Ky=h z5q~t+NNC}mUI|ELyd((a?9c%u#8X$h(kX)^%WL$9NCPk8kL;P5r8C@};)K0sU>1YY zO=0e4c>P`a8!dvg{OHQB8X|Ak{rG(6XiK(%Y z>6YjXZ9yqPqfRBS-mX%5^`DLW>J+<4m)c`^o}?$2psw2_zwUIwtf=N-Px|kRMV`B1 zU)+{G9o45wu{f4E!Jch()5*yd^v;>xj4leuw|O#ecpHhv6}Q{C^O(@v{d~*WPPLhJiN1s$F#V*yO@pr=rRt}g~;zadR7wT>C< zcWIu?YkIe7znCIs>Hw+k?gFzvsEr-K<;HTen;9(;=f94mjK4(k(If$Xm&7{it&I@( z+<^xJgEAunS%LpV))HZL-kX!hArC-XvS>Q=!lu_P2*##KF{voZTHg{fsk(H+r#R#e z<(`bgVIaVZtfrp1hyt;HY!K9!gkkB}N8rlYQDdg}T-? zRLW+HSx<&NZbPP?gB7uV3=UAsDm`t$FT5cux$GqJ(^ngKu6Y!39m3=do;Z51i$`DG z;H$6fx-L82Kq+V--VB}w?O?C#*)s?>0!>}>c~65+UQUB2Pf*#tS?1+Hs<7@fp5i50 z7>B}4s(#u;iqvDAnVXzk+c$mNIXcp)_R;36ueRvFmON`j+qNlx^Z4(YU3q&v6{9ey>O!jN<1IHB=ruEa&yTkD{;CR`81uW z)(rZ0-{xuBxi-;9?;c(UQSy)}(I;!X-J?7;MMj=h(xke_IT`L>QI>6X$Fb{RmI@mr z{Y;!SDM60af8StYD%BT}5Z~dqd3oMFw0XF<^LqU4oBh9kyGPVde~C{1`Paj2e)nf@WpKaL9U-5B!VZ^7IX{vq()BxJz9PGbTyb^ZZvg7 zE6G80SOJ>8Tif`47jD+U(xl_>!*Q0?bX1<=>r+&&t7|Z{!(ZqUrtr7$@#v}JcJ6S= zD0ZI9so-pKHP#OSTg{TjjXCtrOq7GRpIs9(Vm$AED2u*wAPim(opyD-Rtz;pTFaio zl!T_?+lp(v99(B=^n?w{{RTpYQ2hH^?janVLCY8a#@D{nognzrmQ{3$|7n}JNTJ%r zL*v^_dq$+&Xr|6Cb{jTnRwdJHlH}rLCy1fqP4b58D{uRMNO>C;oExMB`+MR+_BopW}YJc)JNl|H=Z zzlNhdw;JI@WGOp@^=4 z7{A-+qW&wW2yk3d3{H(XP_PZ7me+EBz@emlf_{jY+JJ_9Jh@8Lfl*ygXnvjYy^MAz zmR!TdP=uHI8>iWGr*7!O9_{QN9)nW!|K9H%?tZ--X{oGIN!HOMK^#X`+g-tAvI>#@ z_4d*D=-u8DCTTl+62dYM4QoL{SAS`Cwb{euErt1QmCVP?_!0i;JE!8(u(jxa%}MOB z+iyPdkc#k_7JU?29CmKdm|T@5X0{-xsCpPD1!YL$rQD$%8m`u}^pxKHD~QB28B@Wk z&|BV~6`h&l;NI~r;s+;x4dvUR?#rC1tW2Qz@k(OTZ7%ea<4El+WMH-t!GiPs;TsZ| zPPQR~YN4TqvS7ZW&F*x{cNf5-mtvNry6nrkz_zz5qRoWT0+ts-Q|}EPnmCj`A*Vf} z1Yzliz7?bQ3PM9xukpXZF`WhEBfXcXcQ?TdlQ>)w^TB{5VC+tRc+-~HF^JNS3GPSM zm^AQhQmpS4>&I8=x&VBeO{ctB`SDJ6<_Qu;fTRTl5Rm!t>8CF#k2>Y1!4UHq6o8>b z#hS=e3&7XMZ{MgO0#5BCk@_F+ehx4|l22@a;An-3O6>$i219`Zq7%dy<G^BvW7O{blUD;Q`>h(IP6)>0PMI?A&1MV3#A zg;SJ;B#klCguqgm;4o8*Swoy|G-xcc`#>wT(AtKZ(XO-NB4w7(L1tz(ZLDNvgp%YZ z3&@;HOsXd^aFa!K4^M~fQnl6cvUos$eEVko@L)$${jk-4QtKnM$5jG`6mU=Uah6x} z30i>qS^vdc0teHjQ~IkEAB;BLEk-FOdn@owzxK2iJ8hVtjSWo{PNtQ{g=yZlt%Fsc z!v7y%ZT?xwS3DYqr6|}Zvgf&ZEX;t7lL-sbp+o20$)*$M%>^jPWZWjkORqeIj21=# z+n1*GZ5ri&-d$M>kLPE$V?vHb!!qp~TkH99)$#r@e!w`}V{Ntmfbo9Rm>c7+O~QLe z-WYw!P0*QWefFg?#iYxv3Ff20{|1LWn9Cl_X_o(oZ)AG>y>Ok6Uzu9Qzxq5suH^@~ z&Y3LRKJ6Dsiz@S)3V!y4Z(Nd2Pv{Y33bbgi@eK=qcrOc2tF&e})ufzB7}q>c?l@-8 z9rZP|M)ch+rl?U!^oC5V1vO}c6yZjWWDJOlpoasx(=-L`f|A9d{?+FGd>MaXPfP`3 zQRS2)nIO2QzRXG2QiZa0ny-K~oZJ&uBs2_tHb9HjC!b_vkq3Bp|`e z2efABCc|l(XEV$%6mF3Pgd1i<)fY+x)!@y+l}c#YrgNlm#&ZxiZ9rZ~Y5XzlSAko9 zHNe3GZCwLTZ6E9f5k?oYevC#z3kZjYM*uS~DQKrfI0)7hL-CaP%?xEs@tkNk!HPF{ z3`&1Arp!}y@sBI0Ys|GfGs0^%kqs`>tZoWoqiBe`^42X;?LqAuPF0o7;Rya~^oa|u+b z&52y!$dAZ?hE!))g7Cd{C2aO^HYsS+!YwGC8~rjiGaxS+mrgLhT%Mw~g4_F3I=6Tk zkezUK-mktdOq~IqWOV2nb1?SBrh9LD#h%h_ulU8713y%ho$TH@fbyzO74nRKKNb&f z-7%+7YBlEk5RQ;v-h|PBuUuRvS+vjCB|`Zq-=%Xif%~D1RZDPbVVqolpYi4*lNo+K zBmqjNFEU6E@qSOZJ?K4~aM8eXp@8hHL=%V96V;}=ncYa7gproD13dOvhC6DbC*TmX zjBaoPQ_o0wA$|iB)X772bM z1)}PfA&sS5oV2lResy(KU2Li4xlW`C)web_kn&AADf8IeA?u`ndr!{m$c2s{l})lQ zx3`ll%B_bo}CO|SSk+@dHX z+p<(kIm%&@%$tQuP?1%5D19#Oo!(^HbaTTw7%!Ziai|ZNbyh~CnUsa@$v6A8KAbkv zV9ca>S_>ZrN+pwj=#Jhjy9r*sfOfXJ-b(j5lp-EuUk@<4(VD}z>HRIW- zSd%e7a7l2UZLOt273-0+numeH@=X_K)_C_YeOO7?)0gvJ47BjAW+a^}CqYq!#uoeG!zc2K0K&)ZHC| zbc+gJ7!+Bpb*==aEby4IVAQs)4sLdbp%agPjGUniAKHAX;=|;YJpl*w+gW$TM$-L> zyO*6Z9XQowYgMTy-E}zst@!twCTW*4pxoT3Xjq5bA(E#R>GBoF8^h2D!1*w|0+hMMBg!6*vb zS*_xuyEA$4$o+qWn&h)CKoGN!ho!E6V^{u`9-poHWXcT~UnLj@DX}3;Q`_k8`zZev zTk4*nK`=|9^mAB$J2EcI#u@|QKocw%u=>x_60?3CMLJ}{)zMhckBeoAU*pnG4>da$v8Jg7Tehb`eJc&+E@_?akN$Z8#3h1qSqk*z7^r@kS;2#cWNUb= z4tb&D=#}E=fMV6sym?RU60|%l6DAVj;%pjlIlR%uDd)C?`ThBo$r&wKmRB&=KutZ{ zqiXHidc39rRgz&zZqhLwR%4qZBAwB3iIRH|mjN;>6FNz0TbJ0B92Vw(o2Xi2(1K){ zcVxz)6-8~L9Wjvmkp(YI1DyI0GwKgi0wDpS`HO$IbfV2wGPd)iLHQO9Hgx!B`waRu z&(uY;I)3i?W}IvWd~N5DNnK;0-z+Q23g9-kX>whwC@K$FO;B~A8T!N6gN%oS)ecc@ z=E)9J^|(F5MDai9Sjq2y)Ge-4z7%kQ_b{m%>*8{qa16XoGna`6+h4BH@RVI%W79zY z37ufdib=kh3X=Or;zt2+DmP%l7a9^6N{H7$s~Dpm34i1nvquOP=YpIz1GIRP9O%5b zyy80~J|>gKbPE$WX?u!6j+i1eC<{U3FF|@4<>wsMBm!CD`zcG6VlhJ@il9D8s*r?diLsz&+I2jKEFzW=qo)T>k=Bt>h%}# zXY2K%_;kT-`~ZAe-qw6Qh6*La)JN@1z0HdCWH$Zm(;)in)AOv+b)YBPZ@0rRAN=F^_5Qo@>;0qS@xhzz<8Ss4->yo2gtWNHD)R~i#bNr@ zNe=)?IByINTK%X@e53>@xE`tl;bo1h7b`X9>iy%7Kk_M+F|rsj zEW+HzIWshW0K82mC|97&+t0qZ#v%s?JH*lPLr8ecP6bmS-oP9z7qAZI$qh(vn%eJ+ zOcK38Pk6E5`1dN!Q{JrP;l-Q`m=Go%ulI0;z$4;vzx9ePFbGM+h2~IiQyy79m_%}SgGQCS{?r^@zfFlB zcyk51wZ3j@dN05D%o*7Z12KODM+e)7%mrV$To9~2sn?&>tC-?Rjinkh?u^{$Y;_03 zaar4cQb&eff;Pifp!>ETyu_n`5q^cWk65k;c0L0=HlfJ<&=Cm)9^XHi#**L*1~+Qk z9e`+lsd@0^#g-E&vljdyq2GMpyH*a&DHdTAf2ae569>Y1SvIh^CvzN?^E?I3;s?Gy zKA{)}<&wjzRPj8TQyo2nsP)u~8dL(BS638&_Ey_RY+=nRc#HOz7tcTa{L?R9e)j3- zTj9$W@B%pP&o5rQeEIo{&6l5j@#@phKY#VbCcLDTF0_qT#lsj$E<_X1Cpi6Q$;UeT z*|-e`@3M!LuDPmMnJ6*EWid^vsf^FMP{>{Vz%HTEt4EhHQ$MGVzu-cw=}uCgk{5MtYs{DWdP2{Rca*-3oz-}>6G`J;4x)s zZrNx?g|Svl@$icKEW>B!E@p~zXYnP_b-o07ptOy=&}CfKnpQ)@G=M>5E5hlmA&FZt zW&(*#Jsw{~4|XSdS|@1ybqwo89X-N-JK2Y@NS`*X-#Yylnu5wxXJvf6efaI}@%VV3 zmS*jB2tnHmgDp}jKsg!8LsXQuO#Me*fZEZ%Aa!QA^4m&low$aHv+P?sne@S9)KC%9 zSH{eMG>gW(am`DnXdS!*^8L}y+pova!SV68$78&LBh>lJdcjBnFNZJ>Mo;AdSEr>i<9-9iNlLa_H@|&n1^@|=lx+8L+p}(JlXwgU zgTcHo;6Cd<>9QaVqhvm0t76vu3`;uuoqhH;U2d{yepN90t-}Vr{-6uLp0kT9&dxT) zRhqE#bXHvZ8E0Rnt0eS`C`~-*dCob1`}*D6lhgAPued3gpM>n~x2G5H-+l4j#kcRz zu@KsI_V)HV?-t9LFL+W=Z zr5QUrIqM!B_1sR*i`BA7(>U)2>0${m5e$x>^M#)jQJ}%}2!T$tAUJV4pF^R4dd+yJ zGt1Hi^8_F!%kv_GR+D10Yr*(`@0# z(a${mUZ7#QOe_4xFJPLP<#t&0V|~r%ez4Ixh=TUU=W?D}b5+#d;k!gqvc%~m%hC)x z&UrBrbhpNx4iboGFbzp5530X^rZRgnN&E$$Oq@=q6U2U=vn^2V@BMhi>CqVy8n6Tx zS5eO3pP#T*)lDswhl_+QmjJhfFM-+5#dR);!9iBrp6V;5M~)88Bgg%p2`uo`?nx zd&PR45@iXufp6wVIcKM7QSK2Q3MyLg?n7OqDp-`jzR6cpqK@TMz$dVN!G}q;8{|M~ z0j!`67R?y)G}Sun(Xn`|x2n*(fNF_M;3r91Fd716!Q+fJ+~dq*kC`!=j@E?#R4!6| z6tM;k#6`1;Jh0cZ#9Xj{V*yLP>%%2{>u?ef&OrbZxXIx(7;*8(qx^C!#`Eo?X&BoQ zWx`FgV;~Wm6ESCUCpGR1*1-6_Q0Mo9Dm2MeQ7nf~pN46WdrQ(gUYgCHW_-po4x8>N zC?0>2hCJRE(f~kR`T5mkqM;@V1a~*E!b)3P6k}2uUuIi-?mf5E*c};)2L$DX>XK#+s?>bn~c9?Fsg8X=-eLovmsfG#PCjlSyGZ$fa$n ztg=bUjgc>T5Y09~0SSdE#j3jA%b3Uv)1f{Y4Plhz*uTJk--20 zgp(pSC$V3D+Qs4YKk%0a7WxF5g018jEfI%w2`h=BXa_{K!X8h;{2D}zZFx^Dr`bq0 zOqWDl0BYkdb!i`LY2HruOBmqNA}AopfNminYi$M5__4qw(k6sUmoA;w{^)kC;*d?j zYa#11^5c>RZSKuIG57!{&91Ma;A#t;YcT$$KLQ4SXvN7u;*@>he959hR7e%m24)S- zLBY(T8|0qRusayL>>^w7Erb5o3ityA1sOshN5F4dCqk4E=PD#xyEk{Oy-u2B;&IN~ z*AMK4E27?(SziNJgOd?t+%M28+yX>d^F(P>Sk+dz2a%eS$Q_q`=>yh{-n5@Qf4Kx^ zwrym8{|c6~%_kw}!ltg8KwO}nmeNoTuW`BZq44J|tqt1ySIVERye$ET=W^a9&w8D* z{}2%I7plXM;sL5REIk2W{@h10N>w5WTIsGKdKVRlb0J27+(RPS@L$ru`&Ua}eJ;^V z_r9vN)|~X(URRj5u9PBN*+WPrVVJlYJ<0`tj|^+x9BQTpscakcnQirEvbH&u+0IEQ z=m5Z)~wlek)z78Q7n;ctjxphQq4kAJSN#?R}|S|@jA_2yWJQCY}yg8 z*0V|Y7J^8-!Q5%GkVMuN8=BwvK{1hIHEr=6%rIr*Y8aw3ue%IrcJ*bXsVp7!#_&&n zS3YP0*8OQUM6F|gT%Uz#`N#V9rT<07!z1ND{#>~I`M=TaC#y!Gj4w6%|9Js{ zf4^%A({tFt@AOq4XMet@+BrKpJ38u3zCU??{_fk;$@>$uNjb$)BUsPO`eFUrz6=i@ zIrPWA^x(Ji#IbGvc6uA!W`Tp{j`R9|P8%z;ptrqDK^4j__#X20gCHE(BftCeo9_Q! zhGRrWdvjg`kWa`TCORzna)OhC)v%RRZrc6}C}~i^lPX#?kwR`!ch|QCPRaVOSy4l| z+a$<&madkF%)%3o5}RbTsO$!iq4wG##kNMlBwB*7@$zLH6<|$UQhI}N2~H<}$~gpp zF-sxe@NLxXk8yMLD)i+jR6B&~jy_E}N^e}X=gSoA1OP!LrctNr5ZSUTK^3Th4nXZE zYL14V3Q37(a zQ3byNTbGc>XN5EZCJeVi7WlV+gBEr8rvi>I8g!cIHsFE^t*}KE{4OEmvj$jDs^LK^ z0=6S8tyRrcM4rQ9WIO7sv0UA41Va)$(G?JsoCx45o<)IDHaXh%uNWQ^1?fEVm*5Av z%wMNbSc4-?cQ7tNcrRE8?srhc8<$O21&k1YY=&J$TSItLa@f29C&Qk9;6;E-R&$mj zifa^Jl!wtA=F?)E(6oV4eYtY*TCR-OG`B_A5ZQV@QBwp^zgRzV)KLGej_LY_fA zsAz6mYa+(pH?W2|>0J%l$USKhfuXZBEtVPbhy?~!_f=_6xtdg$tRuBA2}_p*FImSf zVdNroS151S zK!4%u*lMh_&lXV>ueh&;ndTuzwh^mvWTJ_(5zCFd$P5Ngsgoh5n!( z{kA`XC*>V^&%B;fh9kmgMmBXJ0?}FoAtz!*?HiYE<%yT1OH>J+GL1x)B&?zH{Qaav% z6^)}(TzAudM8ERwF@S@n>BbO+H=~5iQXqMYNK;2y^6%EOteOb?lMc4%^v04Tt=wHp zKeN(W#D!Hm@lrK&qvoX!)&%!TubLZG$9fh2$!Z*0sX9NKMj%+Sja5HcQY{h%_*cz+ z^ur%v&rL`hnL)}sf;++*hcZ*$le0BZR*rRGsUUxU1&lPe(oiz0($!)rO&bEt6mapk zfM8&D)>=0>r3_Z)Uajf7nGQBYaf}E{T_NUyJOK7JkfGMO6u?!S6(J-R5KQo*w}Ut$ zMx(~oC~+5o@RX&3RHHutF1rfHUrD0QneKsycE&i^K~efj^8wq=<1ub{2DzfAfzx!`Yv>8qWX@}K@%ew99TLr<0V zyIl%EeI6BzrZ%cf|90MLgRm8k_^zW+A1wJRdFMeZ^60@U zvSY_Td{r8!H-E9nJ-$=q8t4DIu)d$H-rurH`*#iXTZFqjsWWRSmR-lN2HPwU5pC7@ z_iBut+5#Nbv#;O0J^AM3^aA}sn|j;Y0g5&94!Yw{EC*ad{MGh@p@~Hb)@2z5Sgw+P zpvW7*GV6ztH?}WB2SH_4&%5l`f$lT!6k}06_~T;=JlKj&tN>1Tyc4MkE1*xf8>vg% z_MSMG&L;w`Hl!ph3}wqMR!6G&YCh+nuG9^kDixy&I@8~aOeUdHdrVwYcX~kbE=c@V`I`7vrN@RGp(Zfcvn8wxjlFy| zwXwY`i;aUCQPk2C1U39;so>P9I>bN})M=SeFs{ssz_hJ`W7c1~Di~f}l6^%~T)hQU zRZrA6eCh7KmoDjU1PKA@?w0Ou@DdWzAzVRHq*J83ySp0%q>+$(`OAI2=X+n*a;?qG z&fng%XE^IHM}WOs;Kvrq5)-pLly7#zu_fql@3Ite8bJy_wzJG@;Sg2TG=i6fQ~ zu~N|PDEhC2=v8B@u(}f##hNC^Y)3ybN_?GEB>MI%Z@qNU=I;@s0-&3@y!*A@#o%Si znTU9c7k90!Hj}FjACA>q9BKLzNeSWe`Z-)p856GPfz3TQRC**NW#q?Tw#@g0JiT); zWzQe5axVQ4Z*4X!^qw^iU|Wz#yV0GxhVJ3xp(1;Y!HD>KXiG#RL@-Z0wM}RY)9XIpJ7|Ps3UOrRrd$ znPLe5BIOT#DhXFNr$w?uDnh?jBrL8d1n1A260i(i=xXoG4xaG)+f4iM%AHXR!M#yp zo)Ln(Fohhjf#?tSsC_6?-w?d~wv|IT>78QPnjrXU0?ys`YH{c1bN>a=u(Vnf}hc$flbEFTfr>0!yaKzKsn1;Sz zt_+EHLg(%nl4NZ|yeaxBdhj#k!6!B8TFmnvSf=H7T&%F{?{;n*YHMoKn)wf~`ViA6 zacX=kQ7I8Ds3UnMrSyiFV3>)tfPcKnLz{=JxE0j8G>JKu+sSPlb$B#O%uLWTBv`Qc9r*DBJtB?Xa!bfp*(G zO6T{VKhy6+-w<6VIWu?3gD{%s_&n-E*C0k==-J%FDYF7Bl!@yqhIw43F?$lYmc^m3 zV+mF7NE@lq78e@8{`A%4)?nGs1n=*{zkIBg(N1r7#yt@2_V4TF)hr=3|O`bn<=u5d1>nSJrqss|qN?&Y? z9AtnyBdH&;koHE(D7+G!(C!7p=7C;?#QOYkmCsyos>3$ee=Z4EvIkY{`2cb-A3eG& z5DaNAgFPetN&lp-T!^l)UI)PfF0?vZj)1U?fDR#V%_SZ2`#+m-sEz4ItWHO(~O^->l9hU3b3@$c*~qaGi|)-j<-g>gMs=ibYG=`W48a*zc&Q zT4r^t-Yxy=Q}kT25m=Q~nLLEqLv1`@AaBUFE{~JB^iofNSpLgYB`L<8nSZ5`&XIPg zOJ&|Q_b$RxmdJK2XJ}xi&S4-c=rS1JLb`RzrlK+vncw^uic3Z*o$Qh}4C8y^)EMEj z`QR3F+tb~{w_+NxQ3tAFL_3-k3qP7dvt1*H+;yAg!9??!_h6f#CDfnE{fU9pRNA3A znuvvG52bn%cgNdyE_!zM;cH(4n2Dx_wK{oM0z!!iM`j%n)}|d1@I;&re#hov=&f4Y zt@-+By`T4O0H?V;b@4g!7W%i5>YGWyOU3XkaG;_hNHmEYP3y&SeDaJ2Ri#QZXAdUD z%l3l2ut5c?wqQE2u~Bc=1(n9ew|g;}Pt}74{B90FA2u|+#v7HdUPo3p$-+y%`i9d8 zWqDv#>Fz%aZibup0&5SZXr=;og0JG-N|Je$mOf(aa=9H{ew>KFq_Z*OnNo6NXC4bU zNX>7$V0OMhz5K9xPfW>pdXeNL22-=5LpQZOIrU^;fCsj|V=KNhx|Z_E!q03nGp`}j zR@-MgxQfmCOc*jgHPaB3sAv1Q^SW5L;NZI$S=DT^a4+R6i4VJMI^}}Os7YmY0g?p@ zg}52ZhKw3J*MB%xCpu0@2C8OO2rQjYT)w_SAiwH0S)&WBmkkA&vBuzhyy&cOg}2Rub^Bdg zrotzEmEZab6lM8*B6%;F)n#(EwVaTp%}_+U;0^Ax`o)yLR>l^CHF)@rk1wb;UB5Uq zJ-zLrZ-D>RFU_0m$b`T+C)9Ag`)&uLq$S@-t;fT6!tqwlDb5*bx!P>Wc0!otw-PzD zr`Xmkri?zzAM@pH>)7N^()woaxx=ZcBa3O|KO`oQ#ujVjp6LK}XRMMOwrK`v3WpO) zwxu|D5pv3xF4@P*60u}`GYXxIr}%xg3!acGZ7yV^D=nA*{$HPtc>Z#PK?s(9^~;wd zn)tEnn)q?p*j~OIab$rL(u48eHzm5Q>I6uc003V|05h(z$((GuuC)bJn8)w zO4ix7Y%<1u9Dv-h;4;9r(Lv}~ak;>J-i*fREs$3yu~}qo!m*iItpYwC_vhw&4_8A2 z15t$!rhRU2*p)trez=|U3=Og;+b`1ZJ#HB_m2US3ZEnNaYT{t_jQjas{np3ns{Z~4 z%XF4Zi{RVwGQcf%LtB;1zS95cH5=9ji_%SWEoKUVH|L_tpR zbR+q?J6Q4FHd;Qsfsz$?j3oq5Mm`mPTKuNDljeVgBM}KZJ)(ww%C=kc1Di}Q!yNui zn!qS&A3a+tXlwU!8$<}H#6C5nh6QhTVav3h(SLTzK1iA}f=zD;!(FyxiDUsi*7SNM zPGxcgbLJ~?zhlW;nvx28`zWrn+unoov*Yh-D5sh_=LNM+#XwBNrVH-7_?zu{YJjK= zvSjWPQ6utLT5M*suFRNHCb;=&f#1Zo-ZcFebq3-i{;h2ww-u%`S<|^<=d@j1fi5aQ zyyJ~uM{drwS+0-2*57Yl*dK%guI2yiR1}$?C{)~3 zvM{Y%51PyH+ukD;9jdAWbMTxPXNU$o9MTF2KP-L9#aY1a6g(&QqXg^1pVl36jL4CG zl)BeNMbWW8xp-W4^A>Wpy>_(WF+j!^RU5nRQr1mG)NnRYaI#ArEE48lJ3cHlWcKxg zB|sJb%44r3zH#@cbb8|SnErgr;nUsTW`~K@$2U%sS)vLQ>tF9eG6IcaVzfiRzuy17 zEx;;4Iu*LXKBow|!|enMbSR(87_4KleWVlpSW@yg%QM?$xvz67%edu(-}#@L!|pq$ zdknOLf#2NoW?slPH$I-Xw=*Z<_k65b53c9iH#1{p(tV*%In8Z%BY)T4;8RRS-EpWC z?{Q<}DjCsOQUa&qbngdJyKORq?s*ME+LIJu z@%_Tc<$Q6Q3{Q%S&(BXcx@`Dh_JgFEha-o=`yyjL5U3ux(e^rYI}b4rauL61@VjlDL@gzWAt0bbNVBNUCYZ%mKkL;o*G8B?t_g zh7p}Xx@)f{rK%G7ci5!shWn#vwl7jJV>}ASZN<}%Hp!E1I}G+rB^3OrP)7JcbcRB) zA60chZklky#^5;{eiAmfX%aX%#~3jxLdqpxXO6`(=8X??64b*#UyskYvl{TvNuD4= zlrTD0YfMm$w!C7j{M5TJ-hoBiS_>yK>Gm~Z7`8<9M}J+S3rl#Ky2An05quX}-ZrFb zSLO1elnOc}Pbmz1k-h&RojjX_H$#4Z@OLFN=Lf9DNEDd-^9Z8K{K+eSoLAYrS(9nB z9vE*w@sM}Pm2rIw5Gm%FEk)S-(4bnYYbauLiTpdZp7Nt=_mJT86|NuSaPtYGE8}qm zZ4vK6=s9;KK8dX=ueOH37LUBnG{{v%0Og@Fta_pQxF=i8sVM!x(y>a+xeqJpv3#}m z;g0p;?lUR?Y}hwsE=o7RZYmrqBgCgE)fC3ivOY2ZIyvjW3Q-Bkeq+ta)PjkPeC3ff z@dwXvE54)L$fyTtE#PD>X=>BTTmJDQ#42EL?*1{|eG2W4CZhg(bl$jE+uyP;1`~Y(hWu?Ey>deb$UCpFap_BJOo|MO zyBs~jOx^(=-5YdDAFi%_tsh#P*HkGdW8U$VeYie_*T@1Ua=v4k*=ABn)*tH4QP05+ zUvl!+H3wHt(c+x)<3$|3E>lcce>{?b|K~m+S|M>;vuSn;( zL4V0^n=B$>7%&~0#%Wi7F5r<}M_0D;r&mTP#kc6Jxd~_SoA$bR@^CA{#7{gC#7B&i~=4M(S;3AKfFUpPek% z1~b9U9XVvpW7l)Ey&}^o($1xUlvt(kx)#$t6(ZX{z(??l_2g)#0R0+8PR|6>QWw$+ zC=C2fNF|V!{!(X}$6RPhYCS_WaDR~jhW$5nQ>MAs?LmX3QcG<@ zwFOM0cI>#bu-cO(Giv#a*w~*OSkdY3eRqdyifBdgEQ*xwy|D9ed_f!MwKcZ(1?HU z?AGK#ZIZ#m_-evYz=h{(&}!$KNr;1^vXpB}f06Q3t|0I5f@Qy8yC8Mo$V_%}6)<59 z!In9`@w8YBjV{GvjXqKlp`k`>Lad;i)6PcrU4gNR-N1(pEawdW)CG78RUN;J?M*T8 zQp^M04cAZIjRQo~C5zDj+*X-M7YnYQ6eaQ6SYKJKA<}UXS@h&(vf<)x0m#*uPd zY>$;U^7}0!%APGGMH{~iS7pKrs_bTtJsWA+fj131Uxe4+!>wur2>)456X-xn98*E- zNLjqm?pbWXo|*rO`_VJ>f=f-E>|=d3xFus#((P)9<>O@Idcxd0 zj?9Lo%EpTH8Cs0sG@t5&qU2%o9!K<3lCH>R$7F0;M&BpKS##pO^B6^Mj9OnB>Ivkb4qQ58NKT7 z{)s$sW`*_1KI-eIOXV!wbtm)fz1sO46w&70J zVIPtrD5kwmL_N@?e#RVo0to_$96*mVNCrWSEAQ=ZMi<|VwUGJF&mWE@$AO4=hJ!DT>r!Ik;R`u@QzVUwP~`IESg$wy<%sXzTl0{9HX zH!gy*iM7(DXC$>Zm#8#{-(U}j2G#rC$X$k`4@*9O5sWSx(i<@-v`32s_C+}V1rYd6 z-Aai6KCL3WexD`9`YxT%t~frneFF1Phhg+4q<1tQ4jvAV(f*_F&bW1yeduew+I{5T zIlfd+NoBA%Pwk2&YPe|Ehg9yq3g;0Llu2CS6u=4bzQqRW)1NSr~f$78&|y^+Y&MI6wKm0)^Hu z-_SpI^NX*#NAT{#Qx3#npmd61qKf*ca}^I9w2AoK-X3wAiFE7eNx8#o@k$nI%%Fo` zdk*O_`6d8te+0Ekxs|~EZT})??h)DA4(sUK*OadUVW|twqw0$9Y6EAq28lfWjoR{h zHI|OMS~~?t5o?Sv%VlJQ_~<01g)+`Mp5PTHA^nc;k3PK07?EtH*oV3%M|V)J>(-E3 z<2H-3vD=z6u~7r;SG|Ss2reBq`T-W0M;4IS-C>pae)(g>$n2jU=OxBLuP9onaB{hT zLz*uWYtt$PD}<&EbzI`-_Ys#D4=^=QfSYljJQFMk9JQqcO9gSKje0JAm-`l%^X$=;)f1y> zF30UGVEbWh z9(Vcd#)H&f=!qU;rxdaKvu1h9|8_e&wrW@(cokp!ZaQugZ0mts{QE?+*0!v5 zcM#;O>mgMeE6{T^T38Oxgs6HF=sLiWYb#r$`1R5-1rg|)gNiBg!9#aHj(IV?gynj7 z6OlHEC8LXnWecR58|=_k&ah}o&_w#_Lq_0R4b=u7eL;u^Y{b+7{=RFF6$HL+SB(^JkZ8mopUJE4l0FB5xFNOmg=W3la+gbi zb3W$TY|Rj7gvFJ3!e8jhz*}L$$`}JjqLyvzfQu@NoxDxAo#dhK-};*y+D$_re7_aM z4P}1Y$4sxxXNxCdN;G_J3>PHKaJWo%YQqRjTdIvD1S@$iY}X$7IzH-r8H7th)~Y6t z8W(1h|B~pw?#9wgGVHFxD2YSe$Y8q3hbeFLec}AP*r-jRlP34`Y=(Vkm0NTCY|)|v zTpmA6sIqZJi|~iD&2834fxDfXBb1hu*;~Girn+k1UctJWGJGMgk&#HCD67}+28036 zY;xc0eDFpKqwIUne(K(ZButxDviVi{C#!_>oPJ55fl29Ps#)f%nv&*FK>;CF87CcC zfzJfrtqqA$RwDZ#T8{UW+yv$rc2g!r^)c15>8F%fL)i)L5oPTIcw$0+LV}dNbOKi_lf( zB(~`~)BwA0^W_)6c{})Maw$d|`W}^W7=6Az)>KPdx*{fSze~(THyr{>@{XI^OtJOQ z-SG#Snf#6$u2FF1(Q^{PC@;dY7Z{m?l)LsSH?>iPSs&{;b20 zdlcM-(o2No{=N4e^{{uDdLS&JE>-qGMBx1DdfkRNxt|dDUF7-C-4^>RK{^$(wIZ9D z)pX2ze_u-@g!eJ577F0DI&jPXo5h>c~_~0AHe5LIiouRVBtWrXM!Wr}<&5cE>%NRNGJqdIt z?jSRpgrlY`?VYZ`7DX2v3){WbMcE@wPGgCJ9Z##+Ik5>_4zhxC5swnSM^v{mvScX+ z7w@EHFOx$e@pzW_ilg8eao1-3k*62un4X2QEOod8_wKI8F%@i;-%!D*i%eToCV&VGqc!`=3 zozd~=FD`V!B#z=m(%Bb1IBkVG~=KbbH0Tcl)aBt-*<@ zUORVCj!9H>9c~ft=$406B9owCH;`HjV3-E(OxvxK`)?PJ=Y6s>0L|Rxi(#B!FQ_~ffmvFF@@>_v zwY;Q>MLwjAx8j({YsM?B#avbsRXX}aof_!VG)VcElLYPVQTJt+kzTzPW||~euXi{k z5pODrdVt&XH@!wKEnXvS;4w-GvW^i#7CQ;?tjP(TF)3K6I<}M~yJAcUYmvu9DmXHo zh^=+lOx5$qn>y<3ExWn{fvxh2N_JT|>0Pb%N>RPnx8I3>y6|w}$y7ziY+7+dAiEkj zM5oXg$hKBzbaUT(-L_uk>1C7n>*v_fj*cHn+N*f$9HHOD^7X3WUgt5aj7~6cm6Ut+ zpEXJk9?Bx@Kmy^V*>9zq;*2pt0FL3e{mz8yTCcvDedbD>Qt%+?#{eI`dt5T|(k15# z5*fYg#0Z*h!=<$(SnwB(eKm*g$igj|%F+9!43J0oS_DH+ir~j;Ap%zLHH-eH>@N+2 zPEQXSv9N%Im59H$Adn7Xx{4n17<(bL5}i%BSbZS}ueHQq+K7XDAX~ZmxkbUZIVPYZxKuSBeQ&4`sJSxhEcL48O)6*|HD{!lA>_$h@%d zC{k6HlV>;gkyJ9Sdab2Z=~*hrlH?4F+7K|TL`8?fc{Ohvf2@Vj^r2N%exQ|SZrCVf<^K{_)5Q3ij|{a#W^uj`v{E`z z87penmyRJK%rrUy_R|IRM*7ajY0WvyQX2D{-1Li2NzU?G>ZRrc((`s(I@XCD6-c&# zynGr@e}pvS-$>TR<-}}|J7$6C@kCpgSr};=m`Qzt@Q!?CPP}5La?_u9zguF9@groE z*~xj}F?}1ahQ*WHY;_FWAPBN73~^lEv0R*f(($EjC-S5R4`*}7f6Mw2Y(lg7*>E8x z;O7KTExz= z$!k!tk$c?Vaxb~s%9V${H>AFTzyf)-m|j^aE#~UE-ShPU{0v^jjs7si`mRTV?xe_T zQj0SR2A3UFaLX3M$Lzmo5Asvys1EK~_R^_x*13naHK^h|#Z{!Qlt}Ww`6A2HrVjUX zosd7=?450egj9Bu8i)YKxY*GpvHd13UL#58-Oe3@_YH&p$V&IKYfZadY^*aA5^}WS z>^#IK;qa1YrL=#MegF2FD9^#++c+AGUb+Eml?`RM4|s1Nh8z!$z~*%v2j$Y;{wt@a zyP)ef4v&qCU!b|RD>_F`pYLBV&l!;K4_$Isq(gJ7TqZo11>S|1Na{{9D0YN7P-HEl zl=xMc;J|7`{xxyo$+iP z>v@6X(+Ke5$6g~s-nt?G7Dn^(3)&xlP2P ziAB-#fW3mF!rEP$yx05jDEF_}+`FgSE-7JL7zTF0IC{*-)aAo!lBi<8kaqNc&;~v} zP*5zN8_aqX#d%Sf6%4lh)X9$D#}+?J{U$zjC@>TcBC6_2;c!4|Prad{&hyM(2ZxC2 z^|N)x4j;X8C(L(^5{Y&Fr8vS=CKSfDmG269-ziEvtuP)vX-X$X5jHd) ztbFYcUcNL3q^OijTw@>mp3HlMrxg0f#Dscp1)3I0{*b#-?YOB@C z1v9}**mF@p4rZYFYx~g|Cxw{_aP{M^Sw<$nQqR&YNb7XSqROVO?^l{(P(o~NTljcw zLJPwNqnDF#s{G~tvP_@0yE1Rsap?YTY#Lc>(bDt7TI7LJbx&P+L*;=L(a)H(U$NaG zVBK?{y_JvYgg$6fAN@JHdDM8c<$kUE zON>TwO)_{J{b+gkPj9EglW zSsA5LU|U}+d1Flb`56&I67UymS1{NSy{Gxj+dfT|zAg7n&*LHFoLv;@652}u{%g$d z3>9LjUk{im2F1egg=vJQ;YvDOOAnHim@dYlA>>18(l0Kr7z&=JnSr;n$oSdyhkC^`;dCcsWPWgcbw9LeEhVKGX(s- z44*T_6a~S0AfG$>;e-D>OGJ{!D!ni$xJs%fz6 zV;+amEh{VH}`L^~QOtmbA35N5gKh z(93(@01l|J+!rtou(F1qBrp{Q_loxBopiImM6qcE-);N#X6a|EsLuu7s;?}xo_+SX zD{_2G-9L)aqUc6M;j<5p7E&HkPYoL?|H+9|kqoY*!Lw15_V07#%Dm1$t-!*h=MGqA z-mrf#&?oQhq+uEQY`5=g|6WhQ?pbTufI+;cN1IhB8rHe&Y7DD`w=Ocvsxl+ z_E<8Gr_?a{yc0AdlbwHxh^@U~v% zyM=YuDBO$isx27xB-661ahMSuHB^_O*>J_Oh5f51xO=721J30@e4e%lP7WlbXf{?= z-ZmhGqNh)Vmaux{kvyFJreGFqieRGumL-qjgijA)T(hK-Q3(u0F50c>=$&QBL2w|J zo6x+QspO2lb`38Wp=UPXb9vLkwpHtx9No80P#-)ZtdRN$gN6srj5h4#uFoH#?zhId=l(uF?|QoH%XnJ4Ty6PqrI*D5F0hENOg?=2P2*B0*!%Mm zCsUYwZDDs$scz5%LL=Pt#aSXBetu=`>3E#^XXvoBifgkg@!&mddyx4#396B2JJ%!u zHaW4iLIS61bwmQc|8q!auhu?d zy!&}Iet$;<#xw;6?<=mEMObZ&RS=^QWvX|HH<=nP26*PnYrmWz-6BJCSoG1zeqBxa zcPaIS>?DG;$q#y^M{nu5TqYv4+uXS)RvJ{&%)Sa_P1g_a4n;Ol>(kX&Gg=bFte(Yv z!?wuGQlMPk_cj~M!m>?_frse{F zA4woDMmbln&aXsSMtwAkZ>Dt?Vw?-Qy7XIr^^Tarkd3hTs|QV={I}DSKAC;_)fZ=5 z>w1n)V~R~?h{NngyKtL3`oYuh(!=~XpT%eUFj)o>V964x=B{2l9mI#_B%m2$B= zFncGfm&399FlZJoF)-g$|CFbZcF5G>|FioBOrFu|`DMvvSO|M`IPH0T zscEAF-iTlslM}Q@-b{~?$(wIa&sd8m@bjF-5InZ|eXAt8S4 zZ88Vk8DQD#S9xNSuyL(#dKA9qyIa>Wg4ZS=;;I5CBDGG^?m~)p<+#8pIfaqMSj_C| z!#&LAxE?+=Dy)Tdfd1{W1UkHxL`>WvM21P;;9Yqg9>q?t(ksIgZ=s%erv|vCx>Cs# z4hsh^{h<$D+o9GGA4ZQGhXcmMd{R**e@*lJVdK^|vo?#rjT0tU68XuPfdg^p11Cx) ze`bkP-Xs0%K6jUa33Bru!>QQA!838^SF!fpGhF;)Xp)&s{Y6lLedYB$iN*K+xvqz% z8;V`}I6Jq3_h!IvcqSsqo=RT2Me0T>%G?`#4so_+h1mI?HRby3JTiy6<_2XMJWZOD z33f~Gr!!%EwP zhsG4E`B7jYj;99o(sa|_xqbkP=Ak1OZ`lNhE~gh6VD~0* zgJvPqrg0pu;-j8v-Ba~Cbi2IGXs%BEzmw43+*JBT;>fCxg_9Rc zi~m{gqtJ*4yubL{canQT;e>LnN?`&(4s=ArMRSz)^ozHy&s>A0z3~y2wYE#8 zum7-R=~u$60O{F!no1aImr@8JWeH4zU-}W!-?ef8{$A5WPb0oR{Y%aOBG88=GH6ao zGuThP!We#9H8tFB%9sOYiyfzyUh`~$knFm=|9S&|V_3^Foq)s|O$`w%BI&Rr51Zru z_8U8+;_X)NLZ<0qyz$Tce(HAMEMrZ z9DiDWCrO-0FFPPO8&CPYnSAUl-@Bw=y+e9JkDxd_I$43arg)Tf1~-#jzroG`5`3-u zkr#0Cp26YxuI|l+rRZ`)(57;9u_GI$e7{AQ`;8#a2qLXwAkdQRd-P@#SmEix|L6%vq;CD{ zQrDIwudw?3$IpvDmqYx0CrVk(0-sjNp8R`}ZXHJ82oilRE-_0OJ;$5en-9KLCC}zh z8r%M?WO)Yz-o4x~4-wqFHn48bC73!2GE)0XoMS?gU9+rE{?=$F`>xo|XT&3S%J=gU z(ddHL$dB{F69R}A*Hrl^NU*J!!nTBewUd1=qH&aH=30NTc;o-Q@1t%{6IUPR-y5M2 z8Estmmv=+kv~lHFUj{Kkars{c--Y6;y>QlLhT&?!{d;#*ssIVI9RL7`Lpp9r@F3Qk z6qpdoNZi2}k>f~QJoFb50fMVR_d*&rkiC$QP`qzY29a<)b|~o_f!Bli!XOC2bAXB!XX0f- z85FYdYEb_%Kuo)d$RH*qcqkC&598 zEB*k&%V@ecehHL89*oZj10d0861ql-$Z#KE0ghAp{h30 z@M)n2P}1>XiC-A7s__S);4atV3%nSpBW}cR{U5*D@rP(%c#C%Mfl%JQU--#TUX$PW z;qWgEzfbTRpk(16{2?gLUibKOi2v#&@k=wg9})n-013RuC#~~>BZz_WAfpk$D!wSe z)FCLscp;lC2u>+p$cj(`A}H@*G=T*)ChkOnR;aijzq$wp2{8Xl zOxd2c&mmqnnx4S^F0p%ZBCx{|^;n%w+D2I-sKN845L)3;Ld;>L}hD->L z`Y+SQ$R|q*&k7}Q0RU!*SmN`q6OES?Xmu;Ngj!G){3L|D(8_nFBMgQ{b;U(ECG=u$ z#DUO(`GpisCHw@9YABPi8p<0|N?7`m-#YFZLOo~&C3F);_P>Zx#1NIEy^s@Mh@xMV z{a3_L3t8Pnk-(RE)-|FAsM>==q6(-~#tl)~OX=4s!4daBd5Or0Szd|-B11u(_oCpG zg18*Y`i+U$6k1G3EX1x*T><>Wl~9~G-w=yI89c;@`=MncE=kOX_oB>Ci#P%b6Otiu z6;wluHE}#tOx2b+2`aW{Pke><5A+o=F1cUu0Kf?*06+~1j3y?AEImDADR9YKYCKUYLt!iT`I|*sTyl;QuLa)wB@NWds1KgCP@DKs?B^a^yPZ zO=3I77ojvX5?p9dmFOg1F9<=fsmMqntZNr0ivSk&A>6`JW>W0mC;>XaE2?6$HnS7!Q&y1cZk;Av}j5CQO0? zwV^0O;__0#V7B8x78d|uhz9mKUMgV{0*F!<2_gg&krKJ?T$O~+<;4I?7YQ!xKLe7# zWqCN@0016j$l4tVF(e<661&d5heQbO-?Z#>-O|_ReEF+~+Yr!yz!KHTtde|%rgnFe1Ru)( zxJ7~ttvb}-Bq^BxTFtI1-sJMLE5`qANhFZoza+;mp43182o;>UBO$|oiOX(du>}?Y z2t)e+0f&hPM6RR21`a|qa)b*cg?fuY2<(H7&JzP$q59H*z$NHn^`QZ7LVYr321Y}j zK4AyOqy95kuH{a(ga80MpW#n8Nr>vc3jvQ1{>|*a?OhpqZYdlx|7IX!7|+RQ6$8%T zzW5JO2aZ7PS!)6ZphkENfw7t|41HBVg8!+ZYTzRR)_>iP3`dyi^ttoyk^mrLhCq@! z#3mpN)K|1FpgdHK-XQSL3-s$4NK!Y?neIV(anNlThzgA&XdFoO!eqPZgdg(^TN2`b z`6hzIPXpoWh9-d7Q2S2PKyRqf?|GmvH0w6oKtpJ!8{7xBLm6U^fi%!Py5=7E3rc3A zfoz}*7}y{M=%^t%h#lI9;u%0WP-VPqAYy1oQRM;ULqWRZ1)V}QoCtwvp<+Z*AYF=o zcz>NT|6s}n00`~>Z|YMBo|jCvImnLf1yZaekQ8)7)kz1Dp#2ln`EoZU_#C_w!v6|F z*8h{tDF8{nAOLwj(2zpn%|VC|)MC&}=YvocgNk1CjuwNYq0SRmg1lY|04wy8+5Nfb zL1-_?SJ!~TpaFYl&5JE;wiCSkg0eb(UFP(wY z?dn;dEDnT93Pe=5GYdj_nQ0Yxom)x>0Cd>Alv+9QbE$!rLA8Yc0z5;_SDAqU01n_^ z1h39PdoOuE)~it1rvLyfKK+}4h>%dC)S+L3E?ywDq^l1xf1ZZ_`Vs*x0jVc+8_(n+ z6@mt{EI_LG>K_gTtR|!{FhDphNc~>0sk9*d1l^280!cqX^EMbsS`6)q-r1y7Q1CMH zNb#UrtBXj%&_&8$Mk)&>KUR{`K^e-bNpW7f)pK_MJm>HEAEdR26a>j8qeOlkGtM@~s(6eI0Ia_S00jOsP61hGpd_tZ zVkE!8ehF(%h`jU#O-Q%``P-MlF$Hqy4iDjTBv*PFjBq6X4E2lBg?#Phe7_r+nl}HO z=8)$VMf-vUMKC!+9g8>l5j1sVzT}J0etH)~o(fg*#4z$2Xv*56$TOj&X#%+@(ZA@vC*JiHJg-+0$^XtL|MKupxPp}uscx!} z{0FqkBHG9~p|#V}PcHs)Hh3WX!oB-^HmHB~zg8>Qo~`muke@<3Gvf-m3iNmua7z9c z8iel+xiggE7>+_5niOtSiePAH4d@hqpw9llrPzlj=X7``0Nw8i3&cTiNYcTSXWr`EVuZSX?myl@wtd)( z4wR}2Cw;IO&p)KcU8k31k!|H743i{1@^^PF@;NR?v{b~LOWcjAjsjk{d0XhAGR~r-d zhZ5P0rLxA!AM7N-toM8(yoNhnl;H*7GF0PoUvJBw%b0bBzQ&N+-!M~E4f{JbW`v<@ zLO-MDHBvG5tF0T?`TZ0t_Y*3D2flTB?#CD-{nYK1@xMFHg-Kx}DKoeooQZm$S5vGo zlj{E7U<)2-?72V87TK#E%YWeDA;ed6Nkz1+ncM8Ks0O1BE`T`T`NtXf+K#*jI}9x^ zxw0!q#S$&TcgZ;zbU?}%+TC2w3w3BpA-GY)Ux_~siYQV ztaKV^>SM=S@W%{gnVsIs?Mw&scYmM!d^Y1Z~tV`I_l8fprcW|fnz&(m1+XlWFsmlnS<{>9lu4Z_s z>YR^?p)+KEJI~>t|DbWTP@vvx@~Jddxe|7rqYGiU*?S2*SK2P`1zMsKrB9w`Om#IeGfZIvp+lM z0shr#s|gnV6eo@5ZU#cv$z8BJR`96$LAAP-IuP@dih~7|qHu;d$Jd}@AyNCJV3l$2 zBPJ^1pHuf#U(-@P&YDED-|{oHr~k4x(7`kf!_4CUaCJ`6fd$*vj*|{LwrzH7+qP{x z*|BZgww>Ekh8k91h!L;Tf2H=NOZm;0f%`OF%riq4V0|Vf6hPBXvPsLjL{HHm$wfft$ahMYK#B~=N!0hYtWfvC04Cae{d9X1Jtpv; z)>NO@Um#`UMq42@`t)9G27?7M-Ntiw>^FGgl*dDbntR`(l{r-??`og0MJAGdmFH7P zV2$cdt^>Osdx;f83QA<`F`1QI)Al zG{|GbM-%!#4$q=&rzhbNk^x!^_jzjr1YjYrx=2o9;xhH;oruEz(;Jaq5BhzVk4#9* zb`QI@nGYxY9X*DdgB`s1cRgXO1G#UR3XOi`k@|&~I1od3ivm7S+r~sCP&=;UMWlL> z>sl8_gE>8|#wUWRfF&;cpmlz_U*^)@8mf z9a@?5e2*|H)eHGOLq9CN3?a-$7T3eW#i@2s^w0=@5RPH;uy9Yx!Q^_f>%`mMq2O@P z8di?}No8}?L;Z(3%VI;7%fQ!1ovz;Dl6q0ly!$pUyc9|T`8q+HLzBouG?0$ZD6JTyi1 zm?m>lhbFK<-n4mw&S|M26dqtobvE(_L~q#rrmJ{4qY{I??J(HA4m%)iG+)>K-Ykq4 zluQ<7?tpt4-fMKUw2S7XW8sqOXYQ!vjK3z^vw45$H}W<*w;>ZX*R(~}WG>iM3)xd$ z*RVGsgSpw}AjO8+Ilp39VzKiUQDhY&`DnzYGo|A))upy2ln)bC&It)b-^){{oAi;L zWxmf1lk==;Q*%T_P!8Hnl;$Z@)#Y`Cm&KSq&I6n(WStwezT58kWG^gt(Gco(gh3i1 zG!;k(`sMzynQUU*Qu6f{t26`^UP(C!9C5HD3b(B~EY7e@>~j`!jN7!|a!`=qLbXC| zM3~ZorlO3kBhzB4?at~3{fim%+VE%Bkj+!5Le1%gc*Z>xdlmRU=mrxAj4n*tg~@1` zWPvnY7N_GljS0lL)^quZwn6*IgPTVT0&&<%9QI#>w#h$qjMyPjhx9z#9Vx#GX{t%S zH!k#gHOw{eCQ`b=a-)&amQMYcZ*Cvgx{TSAX0X|BOM7;gQl}J55c=6s95p8YI%0_s zh=QPs6&<9?HjW)=T*;9Rk2cAZ-Z*Gv#sVb$0Y&4YXPTN$n>M}`DzF=6#ml!SKt?Vh^5hiksM>&WgEO#*0a zOew*cml?cRWrTb8#zM8)HrE;4_4q*23e;0~io5InF(nBEok|U?1j+xBIJbaCBdURW z9y<02@sr1}Zh=5y_Cy5h8OJIZz$L)_29-F2fONkc`FBnSi6Q!C$}8)MlATbFZ$bFC z)h_{*{$DTOz`SS$NjuEt+-?GMSO6yXUmDQu`kjA*bPM>DS|V>73r|dCNIE<+xlu9K z$aRwxwYysr|o;DP`;2K@XC)w0;lo59_!jbw#GvpkMaGGA=Nc`uG`+0xYF5OcV zxu?=F{Ti7MjYe-4o0E@QGfCF8T5DHMON^^9UPrW7;ZPU_wHNCj{ zuDID$s!p5Cgs!*%q-#5~Vl$+Y8)pJbVJ~f;7ZuM5|=i zLu1+%qEUvZBx%?5i71`d6iNSn9qn!LX=Lv{xIM*J0bbp5e5!y>fnK=rgTu+QTU52e zpU+}+0qSVKF6@5(khIni>#Pm`3{DcFBc!OR9OX~*QHq;}PE`=z1jIXH8zo}lFV5C1 zwkiEIim$uAuLf8g^?#D2v4Zz8XDj!@I?5HzjV3h|H?lq|rR3$DxnhU)$uXvkRrkcL z{Z{X$#%K*U@mvAY;FsdVDqJlwN`C6|hpyi*{G@y0K*}}xiFGYakJBBi-Fx;^EtG1C zpueduUeQO)bgW3y=NDIr`k-mNMG^7ZUx_Gpwsi0-bnWqV#2q5Xazbr!Ctmw$@|ecc z-a~Z+s2t8-OdAqc64bT75q&ne#FYc>x$8c(i@(z%kuh|Di5Ru8LNeMQ1-r?At*`x6 z2kWS$509VOx2%|O_*OOh0-cg^2{Tl|8Y0+UcY@^!#+%LsXKq_OW3x&lvN!zmwH-*x zvme;H(w z#F?{|!zl9i3^9qV#US?jqQ0_xS&!*h$5ZP(aHX{McJqq8YP-I0PkuzQ@WTJjfq<(*oD8Qeh0^;4ArhLZ#YbNISLl8DTYXjS=>-h z{St}BHBeB+OMD^FbM7rl@QlS*jjVTscv~~?{CI~RZzXxj)b?3@2x@6@Xrx^2zK`Nl zyzOLGy=jyw1xLG_c8Y#*olT%>Q>C?wXPgGq8zHpFe-{R&x#C+u_edHuwA3u#IV z@KqB=lyQ;gv+&||blkDUz4u)o+sxCX0AA-CoFAka{D!uctZOFO(D9=bHY9hk-ug1= z^?uzkTve{AU7i=dD%Ax!ZGVvWP)Pwy2x3yqU%1-nI_AAs{RwWhmc|tO-^Ams9_=CR zmrRW^xsz+KSHRj1vw}mvH92=%YBsb9>YegTxA8Ri_GIg&(x3 zxn)M)GVa#W(f<@?=EMMlu3^;i-S`y@TAiFyBk`nPo*;EX1F4l;K&}E5VVgzWPA#S2 z(sUMBCv)wRQ&ftbUS{FspFK4m<#}oX<(1VM`6n4d;Y_rLKeh2ue92F3#I1wM4BDwn zrIqilk)8PQ;`J-&mHkRGqND~`%GkpL`lICXs9SjRz3W|!L0Sz*H*7TAO_M64GWaMv zSsN)Lx#d_t6-fqXT@?ZMCJM!d3>B{Y%5{jv!DgCUUT*XWH>aE1LqyQhYe25x`d`BL zM^b@InImJ`*UYcr-<2nR-Vjz5&@W*|Eob5=SWJcC1vXd{-0LL)ll~9Tsw1# zirldhV-%TS_dnw9tA6O^`;@16@$yhu_~Kksc8kCegcZ^73MK*GvWHbmmJq8=Gs#TX zho4xPe8y)svRx_OCX3g(I8AzYAFKoxtHF;z;JzlujW{&wW^iS3PjswM zC^?K}T!9JKW2e_^=*V#LpBuZEFSOGqaf!wA>f~#{)l7Fp&RXpxa;ZZ&P~#h{S%yia z$Yzdxg}$%e*($)PR|Wg-sfkhSfb)^+DW58=<8+QoN<9dVFF(`wCHO zXFA8aG$#ON?`gc(c2f6Wb;7%6g5*OMsCODWVSBZ7ChN-`H)>BFZC43uQqSU|(lp)w zK^j%lX3lONX6SJqG?b{TY)Lk2+>FOt$?qxn6d^N*`v(4Q-BCfvGtj zReFUG6EQ9sVVyvA`;`w@e_t2VZOhE-!AL~)6AS~eJYK2cD);JGGj){i1Qp%F+`ohm z55)0}#Ed7ZI~0BS1r3>2dJHMUt7!SgZz3+h^K_FIZJw{1&C~QH*jq=V!VCR86NKq! zBNf`#keX{0%wo*ySb{o+kK?K3;JU2YwZ7f((;wHS|=Jy@&H0|@R{CXtid z5&ePuuOdw;pTemWrae_qY*d`-U9?|kXJz3ot3?+||;b@#8d_WOKQU;E!~8TdbG z?0npR^!I*o7h1x*cY3~_(beJ+8x_&q0wDh{%;-NtG*qxU?LYV@h}b{H{=bFj_Cf~2 zLNMSzMH@8j^0WU6mJt3qIRB+qGniVrxYAqMn>#SdiKz;S3aJX!s@o~-iz9tr889mg zs9HDbaX!>pM7FU8qC|p=7N`k?#_}~jY5MqWy9s~#S-9gHqjEB+krF3ud3haOW`2aI zn+`?YFxti}sewt%8v%~g(y|3J4)UV-uQ%DK*Y0O`&xK7^lHw^P+>D49qpBK477(tx|g#ykZYs7>P?xjtfb``+Red zrX8ZCHed^Sp_;IjC}Sm!wW$*!;z#|fGYTcyyd4SD>R}f^7O)Am8v7YjiEwStfP!`2 zLSCb;3469n{w4BKX`hYO9@N<)#uHDqmvN}&RKY|enu@ylF1F9C&P;Az$5iKNwr5xp z!t6|(xQGA7iA^B;&B%sGYS#iLkk{01B4NLBk>Es*=DZnLFh{9I)3WQ4(>7?EgqP8k zqjXeWjnz-G2KJm=I|(W_&$P?vn3mzXQ4qcdEW8lbs$xf4vEBb0_7P7Z=NN=ED=kfG z?s16V6Mfm}_B+&zNY%cs#`Ig$*-!6f6GFM4s(4V80zKca*wf-xOGXfO+D*^& zH0Vots8T@{VnC7Jw{~RFRWXj7y*OV6F6)v5+KX~^=`c-2Q3`e6i^}?)dtaha z%gCjtq?>rOzvB9K9&TEuO_yLvyL|9i8-KeQf-7^xr&dGFJ@5K=xy$p}!oDMyr>Q2Lv7-n(U$6zzwMAla`tKReC(a?g#Bj^Ey68J~b4z1?voM8O z`E-15>Bhly3h#8NTuT7fptS6&mcplLJ288$eJSU_aAJF5SHehjO&LM8+sZds5ZKr6 z9>I?e$*l@suxUG}X4J;;Z$*9z_=C!abyCkAr?-lI{q-{Cz;?Qo-!^j3L%PK-t3jxM zpi>Innbahe+Yd`4HBom!WYv*;_jc{Uz@y#u`O23(r%e=*}K=lRZFeIGlQ zih38~)$k@*gjfH2V(rV_&7B=v$HFk`QM^$x6$JdB6uAHNM2FNSR^5NS@IULHnfreo zJb!jV_y2YIz$2Y*c>nGB{afV!U4z6ys7xOQp$hu{_2W^(^r3&x=0N^+TM&}}{v?)z zkm`Sb%SPWEq@e`@!r$@l9mIdv%yST;0^?c5V+-`${j(%9r4CRQ0SO@Ul3;-lvd<@P zeW<)2Vwu>T=t)J7Ut1~`is+eKnnxKr%~PA3#qwugt8K|Fr*?0^@?BXpKGyJ;N5exE z9C7jrWP9CiZdlY9%+#;sJ9cr5gpC4rT{S;L0ps zLI<@dYCn-??t8T@#AwN4MP_H{S+1R7+9*Tm}SZ%S3;99s$~oUuyC0vSsvV0L0D7P{;01hSQB#(j-v?JtCp4mLWm3o$~j@2-_qqE zFHz}=j(t5fP=?B^_66bTPjk+jby(kN@=u}K$DaMZ2NYB|5Jiao(SRFERw$b_e`l|{ z_P}f)C3GNWr;m4{%E!>=uqb8`1@+h@L*R1{72^-&7BTQrQ#u}uw)<^wV={W;+z-Fc zm8zwf_Iw!R_T1J7n8McH7}G|Qxw%1k1@A9qkJqi$EkZuR>T{NU*|rWpjBq)YvWd3n zeW1Z>{{-_938*&rF?1x~`m5g=EjGNF0C9VyOWUOJyqx_f%r(eq(k`J=cqv%EK^}|2 z%i@UU`V~xqufxJtr5;gn(GCeINFU(|^X7WFu3G==;nUU)pdrMcQ30GyWMd9jBxGeK zot>TP@dEOjNGN5~+2;K40&#-`1q}N+!}>OTHa3O+8f^;SBhX&)`FD6b#XCVjEcR|b zqeGoK>r&a^h3JF-!7S3_v3r_cakkL#7WSfb<)wTh3)7L$~aA!a2F?G)sCWa&8OB035I%t~=t@q)slLnxt6Y`nb0k z=h~vy3(jpl#DJkbRZFKjhRQ_j@lb^pGb<>9PW|Ka83q;7{mJ5gNMMPDTtsyeOw|qz)w_fhnGScJ_hi!-$Y0xjp6h?ILjE@R!@1qU zYik~|9eX^)o;;-7$KljLeK1!OJj9s(gu$hMV{{jXe4B2s9jr?s5UhF$)lJwJo1l{z zO3xh-epz&Ldv&+Rj5$6m;@qJqJf!vuPB_phc@FZQwpI2l8$Ue}Q_rV>rgH^LGgDow z3M6(`9%2Fsp#S-X-#U*VWF)ZP7h<#=iUdhz=TE>vz|H= z*%f^cMe=FXn=g!8U-@&QfSU0l*#Gw?K^+o@L;$k-H>>1ByB1l;F7*XUqfFZ@zLTA zt=~vql_gglkQZzwkZp5oa|Tchhfr1#Zul>UGH5Egdj|Dwzbp zX$(HsBH_Ih#K~q#cB-nDw^ZIPH@~!)u!#RQg!z}PtKKCuPkr?uo6bKY~Ypn+WOezW9hdrofN+^9R-#U4z^w{_KQw6Rl^t87jM} z&3Zu!*UzOl0u`Lii3*q-`tbKqgxgo(8~ZJw9lo24zs zKHh^ce-y{7!TTte7}rYfgWp`p_EOG6M|`_Tc_j+FAg6CP@p8efmvt8e+cP3_M2zql z@1e*m2-CAu^geRo2Nw@FRb19c=m|jaeFw?jd8>Md3G17qtwjze)Aa?Z9JC(*nLfy3 z%7g9kJ4#cfeKuzWgIkvqg6nF+`)y6bvORb;$#wYo6;Y zEd_fTl3+i(%BqD!m90Vh_7q?@AoDGoL-)XTIz= zDFBjrH)}LCaFP>h2Pisu1J@>f3Jd-`!LKhlILR>S?JZ zcM#04_tRLcvxr&8emGvwG5A8vExSZ$ynUjl@Y@|}J_R5Fmg-0&CEyM4@H&H! z#tj-CYu+QFGT)VJG=p4fQd2nr(T6IvaeV{7YA^XvD`GyCN{g$dt5TVgO->L|(*ZS4 zXs9~)*a~;*xf$)8U99JQUot&;t!%m00ptZMFYTx3y)j16hnDLN>LA zE26O7dauWC??yD$xd*c{JJ={Qq))vxjSziue2diemaqjt`Zvp-W*{hgAgYuUY&!+v zdtiOpN67Z{mV^6UNZ!n-O?~(+F+{XKJ7{qjthM@>>H3dl=T80KB-3#z;IoTi1LGPZ zFNm+v!`0Hx@1Loe!j z8y6ib-$fE18Ss-)Nr|N}J?%5C8QMnO{5&+%Wqa-S4K^|54#wywpziY|=zkZo5$J=I zC@G5ZE?YcNRH_8MsH$CPefJv(a;Qyb+~khFXkGFKnlG#5DeoJ4S>H1tJS||_j;*P5 zAzWHmsQGx$s+el1Gf$dYW59Pjw+%q0lr-$}DX%DN%e(TPmwOL-ZwmhQi0p7i1f$a3 zx0|QMKN5LbLGDCWzgWtAD46nE_T1rFaB(-BKO(XCu+AU%(CgqnLbA;^U8*f_sq9@> z562|{Gs`r4y?HNW`+pQ?yB21-SWiVJ*vC^2dT9iEr;2Xm`0x}IJu2fzH&u6sK%#9$ zh8%47k|PT6^2xEXh6$#6y~7|eR9$U2cmDLI!6!DR#pQ{ymykm_#mls|6VG`J8&r?J zn`8*N_grmE_wsAVbf}6fbE=9y;QyqfU*Yrx#??(wl(CA|5h_3_pzT=?cPs6mt)LqZYtc?76t-7O7wn&^0mxX+7T{o zyaj4UPPjHAbtyh&aT&A;z6XAfW7WOm~ffv=Mng6fqoSntOww#{;Euw;OCs9~#{`)EX`z=H8$tu_NTV6qA& zV|^z{muvjnSagDv)uU4kJ|QosH4l;y&@0j?dyo*%OPO6}^Ix}!*eITpqeQEgJ}T_W z>y+m`4KQ@r+G41Kn&-oUw6r%&@GWiu6uVok8S^f|e>Y3p5oQct854lD*r6U52qWf> z<#=3B$9uAK7KyXfF2#D<@cI>g7Ck&>0cRGrugoyss&X~H-M8y5;4dH-r*iwp+l2c z#RL(WBP86XbYrkO{KP?ax2$F`6Z%V;K!qlhx-DLz3b${kF)zaFU<9t*5f1fnk0VO9 zA%9P61PY)AuQWvaM1Ihb#a)!{4co5o5G-7Q@WJLm6Phu-aX6!`orQ#~MK3zXeC-G5uF zMsfx16%#z&1{l|T65Cs!F4m$^oTxDMh~V3L%XYQjS_W_I4)1`8mp)eR*&G3+tIf2Id6bJUx^hrF-n z9TY?6pn)QEhPa;CXg;TV%El2Gjj`t>rPjcBd*C~DF>}zO`m@DQ9<+!3Zb$-RzdL=J z>YJgjkZP00la=WJ=uIG|w~3A` zQ8ObeH&a0@)Cb=gi4T2uPiu4dlD<8j(J1Wp$8~%%TEBCAUJw87)3X_HXx#z3S-VO} zP3w0<5(ukD@ZXxCSdlyuqPs<_a|&w~mAzHhA=`O%b#U$j#@1a<9YL}EB+eohGy|2u zS2mO1{T8U1c8aBSvbrnmYPOo_dl5p0zD$tacPV@Kk7nPTQ^|yJCiORyr?=wW0LGvC z%gxc-xeU;^o;?9n&a33intB+1Ji4!1>I9;390Hgif(64!TS5>R*H}Zd(Acn$gXY;Z zi{H~d`<5$#6FlqfEOsW*Uh!NGsd}Z_MWT!?>3hG?-NntTDt3zI`R0O@;VhByigq(D zaBm8-_+6Ml)G#V{*$QLoWaFk(Qrwp^l^wMJhT23tMuBGfb`x|L64Y>f&!i5DH_Okn3WnKb2$m#ylO z6-@P1sud{aKX6FLPURuETPXa-Z=!=+i*uYh4KTa2cnnFCEB*6fpCDf=NA&{!y}vMiZw=LOF?KVIj@#(-AQuS?&%koSd1 zt6LIr!;7ZgFw*czP;{@g#^}bG{O8M-n++(BM{!1Xl-|KHjk>##w++ZIMuzwJ0D~_U zf0-mdc!>2ErmjFt*tqSN+DVb`^)Wy!Pt$qs}N1sr|RuO#Iz5MF~WPoSH7=> zblz`Xzhha4GE@d-oErHeDA5JG*D>8CxzCeM1$Fvuk}g5Ag{cc{0(^_}^3C4u9C;;z z!7s75*&)fSkjtnyap*WkANZ`4G7{T4@M^IT^&S&V)ouJmx49wn#X@ID&v*f7{PhEbj_PM>6V5)MNC#GbzH8}kshiyP(#AhBCB<0ru(A+D z>wu%!FwA=kihD7r^Hm>|(4GK+36dwYexW=2W0YL|-6T5)8MZ>dCOQgu(wtOi4cQ=v zP3(j$5jEkqlV*d8z46WTSvX+s1(tSj2E$4aq6*$uzV&D_i;Y|zp51=ypDt?YmF(SV zTfxxAc_`qhaaj6*bgZM@0Iu)e$(D4UTUqJ1-?vL^7*O|V%dR?dC7$kF5!!N)|iSds`+ z5f2}hk~)>~rdrVx-0qkpyy)@fHwRJH=f1Ry^{9c|Xd+Ni$BbOhc4Z7GMMk4qR#J;7 zEAB`#y0P=#<0w;E^#^Y0XFXI7toAAeeI;PwFT>*3)cXgt!K(NB4pe^~TzXlUa_QL- zy@J2G#T?@daI2CwrFSLJes!aK>a-cc#V370gS^~S$n@h8A`)NC6}>=5qXPtIE; zl<#}KjLu|Ag1SXZkU;Uw=Ji3wE>F*PP4OP_Pgx3BFUv@i`p*>k?%n9y|6LRg)9$fnd|S zXjoGWO~2eeJ|EZ=G0YF=i9vf^E&=tFkb^(3oxiJn|D-35AbBfgv~K;e|Er3R7PIV* zhs)%wJE<(GdQ*WR)~Q>6Pf+a_?2JzFmrnBoqW!7bc^+T3>!RyOodU&60?sWzmoDQB zb*|?WT~eBp=zstn!*?uU%8#sbZ@YH?KaZEX8skrErbj?yNhO!=Umb5tV?<5Z$T>#L zoVl5HT7YUHK>eA$p(P%2!r=tkc+ z9m;PC%TK2=Cod_2xB=3EMs22u?VUqS0b-gj$9<)AE4-5^A8z1KK>qbZT(4N?ehW{y zpO6l;;8#tiJC5IGY)<>usvc#cki4a$wmkOF6m=jj1JT7ZTmLmyhit1Eiptl64|ak$ z0oAdmbri>R0J*aqdlMz?cxtT&V}H1?A@pi>?a_ktZOhWX&ZJ{vi5aE8#X~Q3RL`nh zM~kxt+gvsThR;aQc>(ktWShXoFI)FD_Vo?^s~e?3Cvd}q1aqUOv+Nk0!XdtmyCrWz zK?7)3hH13nL3sc-)?w?MDFA(gx-ly4ML>MKu|KuqO zF+ZvEl8DEOPirdNZT~!TI9Oh__Cau-4F^=Y`37$W+Jg6@sgedz=!{{&nYvZYW z#0m)l(lq7}LIv~j?WqVSKI_gVS3;9%4_XqA4P)sqD_narJDZrSwv(DX-;U z{6&&(j_G>E_bkZg8c|)j)4^32_J_4eL-Bq1TbFd3*p4lo!yYpVu|v!Rpl%vwR{(Yj zI|0s@r%6mqUb3E<8tqnj_YRIUN$(ELvT(ey=79p3cybn<>U;lkhlD4U`JJ(PyU0yW zv6Y&`aPGmP{N?U-oWeV>PGzz5l9L1yOIkWu?^A`J-p@*wmVI6~uTD@7~ z^Kz7-ig;qn6T2tE2(dYDk!;RcoLbjYG)Ax*N>GqJepU2Lh_#$>Owi+#-+-=|$*>Z} zkNj=~C}8R2Opg}SpQ{hcq?(jmkViamek|d9glk~s$}isX(kR+S$%}Frt8>6+DwGK9 z6XG5E;R8=|Nr3=~keQ0AqQ&lNucSIc(R|(vag(uJTpnexn-isvoP$YL7)W7;Dm7>& zqz4I(J08EWGGvke=EqA_3Rslo>F$5Q&^m%ktgHVSi0q`4)tmpZ7qotC%<5FVX#eK1MmT%O}-^KRuAdbe|Kaop#SBeABVs zU}&@?R5*Jlz>sL?24>>JHdkxQ6b9n1mv*9+vj5r_`V$ zW^C3Q`H@r&Y&kd{RNKFWe0aBcEu^Fb`0$ZoTdvhpkIW*^kdD$lG0K$Vvo`KH75PeF zI)i`Y)_+C3zgc|R{m~j|U^T8Ko9(nhy{`Z1ZDrpW9e3y118lrnBA}Zy)l&XwwaiVD7ZSICMC zW&?Bc+w<$b-EX!R-x?DkYPBN7!{9-iCkcJYwL_U2H#FKJZKYZ+K+k(W`*)iIdP|?b zicLQuHX!30fJ|SWKj41+3AtOW9vWE;oi+rMQqrSVfUW(d`|3#eq0!a6axE`zjkitpr{KRJpGfse+ zHcEsw;?L-Xo#n4{V`dRtr>m59^VF4mmKgq`FGYAS@j(@775njUWO#ha*8RtwoQ*-` z0)N9n0|6rbTXDfN?zEd@>BHDXvJL_L7(-7PRr)9w-IaEHr>J0izm=dLn&j=OSc^vW z3s_xWE}M>u^O<Si3lE*s4$UHkvy9u4zZ=+C6#*zeie^EvmT&HT~oG zqW1=#=$KXDR#wdj^b85U3*?4j+d2#<%kymFDvgtLS37wK;+6D9JGf(~{yF#1(HP!0 z1h6{Bi?y}&NzXnMTbSu3ryG_@(^IJuMtDjkL*~3iep#I@54^Jw5os$abg?wMfEwo* znd94}h(u5w@WvzLSclZ+{crFuGrxh!W28$!>gh9HTV7N+!3I} zHPKt59AvoL03VXZL{$FHUau4q)Bq&i08k9Xd{zqKDr`wYpfM|#2c4NatttT|5}R>Z zCNayrPCRcXP$GY3%Wk`4?>ee5(QMWvCoJwTBH_!szDdd1YFLW9A*a}sKV1kRPd7XB z=|K>0f8Vs6eVf*{`zk2l_~w6m>5e#-36noCJ&5CRc}hm)y0g>@UzzLWV28I;4V>gD zKyxMbj(YfFD63FClo2zbFViAlW&UvwxOvnx$G5!1P7FhtH2v;#EW41vR`z;$VZ+MV2er(~QlFlSzB53$B$xQZRC}9!2zYYVGcUMKe72wOy;R zZedBF$rIn2*F_HDyP%}m+QX(2J|Mva<_h|^NLu#?j4-l&4S1Ii0EQsWka_`Ri|u1w3#6l z=s)Jsq!CzBiZ%66q3P!*XI??VY+b*w#ifj*5UjtV1nC8i&fk>I4eA;hb|8I_u(f33 zTf`tD0k4rL<3#*#>-SMHi_49o{gCAwsW6xn9@(?Ci>_df8p!1Sa~x03=%$ky4U~YG z(J{Edj|RWsRRzZAu-tc|OJeGgAPOT$TD>J%^%xofSQ-c8W%a*-jSaGCdNQ~1xGGl@GCI z&^O{gxJ*_`(5;Z?*NjYkxe3zsWM^+bJ*P%SQ|JPHzbo|@?$E#X?0gS&No3e>GY=kC zA{f}x-nz|`4g_^~N3)O~3KgThsRV9=@S*K-d#Xc**mR^X7qjq15&@)jID=AiZWqZl zr^Ig4RQD-xxbdOUcfP3J6>eZ)vBXD7QYpc2OXWFeV&wYZxMMVV4Z%u=jyp>e&+usnmDX}JLF2UkQ{tH$H( z@+;C^t=DA9+qS*dMatj3LOMbH>vdKXug|I&zxb1F&4+s^iUAFlM`(7Bi81`!F|F#5 zTaD|7PE_TN;_S^MNCnPbmKdxQfd*&qSY!0-@$_aqI^A#`W*(`9Yidc0ox%}M3kQl{MJ ztr)xsSzI6WevvUbFJ0n*NJ7ay#^=K6BnJOf!wkcJ{>!?NICv-viDXwE{iqA5AMTwF z`VG#FVt&0Z8=t#TETjOoQhv%@w!<<~+YV-p4%O>H6pF|J<)4YaJ~p?UXtMVl_+UwXo&B@h0-v455)W8;SzgN0(Oz*+hwKp(CppOVNfjploEDJ&XIB zxzBhbu)q^#lBbQ(y*qEgh4tI&n?L+IDfA5!1~NF&wY#zZ1!$lQsLz}R>=QV+-k{(hBeTw%cDG;y7pSV_$51+hOQzvaM zmTUbliA!#cJe5X)R2h{=*61%{1!odw-e@~Z7Qh3sc8l!WvOZyQACgqd4UN z$3gSzRWG$+5~<$NH>h-T*VRq<#CTf-j+HlL*@UcOa=UJaufxAx?j-;xS%6!sBGq$h z3@rHv3k#6V+fNrcjL8?n7xq-3M(MC+*Hc_&1VVuyDn~FNVd~4Qy3r?a=J2guSR53} z64=>O8hqV)-#yyfZ@}~h_bF^i$J+MrmUyhn08(d2P%aoGz2=4DJ`>Y$dIUTQNRV>reWp#h?5~D z<j#iQ>y(88S!4X7E=fjLHAGNW*XrlqJ0*6Q}c$&$dk060lsWaND`bN~&6lBhzy$ zZqe#J>7y86RKnrR)6`(p5riVMC&w^v!{D-C$8mS(%Y{3@=V#M!QpYXZ(2{p6@Xbr1 zR_gbGqD&Ygu_T_Cf)*XjO5h6Go^|km02=V+%Jul=dkM@FzF0UGIfNhE^4cTz{n}Q8 zylJI&v1@SjRg0<98JRaTEBwCJEA_Nyg63PRsxPYQwaoo%G*n?wt569a%7>Z7%B@e* z2TC+@kOxOlbfro)dxQ9o%Q!g)aAN~`A9|jmcdOf_&enza7+n0kk-Y<5)brGlj1d6} zrv&R*ZM$i%Ovgh%u^&eC{=?EhPAYO>R`kl375~7r^Jxix?RTeof%?y1@QoNL(YLYG zY(=-RuXA7AfR~*L5GZheV@Uzv#zO3ga3ymlIakiNJ3w;!I^B^rM z0~fWDGlq%r3-i}&tjzf-wNjS1(UlwdiZYVD&S^E6ne|=z-0=2QuFqhn);?H-?4Hz` zux0l5q~VHjw!-W;`Maa}_A=}XE2JY(VsWWLsOLl}4T+ThVe2a3s%n}(-Q7rBKu{V{ z>FzE;Q92BeMncL9lG2E9Xb?e48tLu^=?*~&Y3Y#fa4-12_}HqOn7BA2|o@i7YTB8ofVC=TLtp zb(#`5I~NvG0)e{oF3-iS>73aLKQ^dp{d&&>;`l)|1l7LMLsE&Rh0R8Y|werbrjZ9 z9XMXOM0uwX8k>ybPMGsdU3I}u>q~l-=BGNr9E%%FgwDD>lXED?O=Ra00|IBJ_UlzX zuTU1=>x9jHSu3SjN1PU^yfGE1ASL(8;U#aX1>1dcHrJAvH(P_VLcSvm#8H< zDCW3u<+Jv0cr~85mu_fmK&JOOXB@4+H=iveb%<@WK%nwpvN1Tc+p@IE91kh6)x|Z?my>D7*@NAKR6Id?yGNWa;ICYRNK|A)Fk(|u*tl( zq!-1~3=^Fjz{y(=;-4$6C|n1^zenypDv=7{5U-Hq92FYEiGPKh{xC!D-$B~QTWt3 zwAFbU+Nl1vELy-&$V;%2YaFu5JmwWvo~ac{+;=`pn{X&tzpZP!+lIObh;R8G|B`vP zStjs#p%JmmK%cX;;RlVnb>HYO_N;1T=h&ndOc+K`rm?b}5CcF-BYC)r?54uu^bN&l zka!ubuU^Gpqhs}N72n%H%Egm^{PDz+c`u4R_nav#sq@!jJ=Ak@?S%Q$qkP4vRLfYN z#>HtC)H#%7q+xT0@>H`!xtqS1HN3saGQ|bhwyB@pG~Q2_7yv0HX=P)K-|m)p){w~i(Wxc8(Fy-pmZc^IHT4tmw3!M<`=f;GSAG6mkt=g@v;j8eV3}2b-Bzdn`xw z^w8v@dZyrBQ$Yv^^Sr5>Vtjo5#B<+7r_-n0MyytS+xbaTFNVrqnLDSrODi=h?h*y< z-Eb7@{zf{_=}iWVChFIt6Yh~=8P?!Hoqb4m55krfBz~bNtk7>fk==jA_k@5|F=C_w z$$^joSTC_vk{^B7trkXjb5W%8OXj&j{7vX~S6F%gGqW7CdMQUNwe%W8DU#x1>+7ZZ zTyc3+$(eo`WVv`f{UCSB@nhek*GRiA!Q_1}zU;IVm@gR&jby9YyyEOSy6fXaPH4@7 zcEEXeLf}rt&Jo}=2Wcj^Mwpm3&+od?sdu|G->IEHr%>W8nsj1@U+%7zoOD@e)WI@T zM_w|Spe}Jus&P8#wq3`@q>@6WQ_C8C`2?Q4EzQQ9S>-U7Y4YPgRA1L7zY?59=XP5K z`DF`Cy*5$dA}{B&=Z!KRGWl36=Bj`V<^Qd9%fHAaTz#i$6e=RVUu4j#>SD}-v*Rwl zi5oMbG;h9B<5cKA%46oMzf@JUI69(}#KfuTz8Q=6sjnZ%*I!ex75N(nPo3Jvk+h(DWfBOz9ceTo=~ z!p?~{VdA?Bc3pi3Lcj1v6X>;FX`q`tx5ziLKCCTjuBNo!?^!7H{A7q6KkKo#seGDk z*p}DPa-ibWJ`pcbmcC8saX_MEvy|&A8i)D$gSh$;> zMiXq>vCGWl$?r~v(;#-N*sPtcLHse4b6#~D7V+c}i6Q3Wxb#NazrMBSw{#2IN@iB= zAgz}lXmKhZ5vP~jo0-Uf8lGTQv>_97;`k83qr<0fP70`dJIO#E>$E^<%Kpl6*nuWE z$~Hm1TSM!_?jzRc8Ul@x?wL4(caTD;AtGeLMk4iz)M%lt4N}`UxouhY+S`88apoQq z(-)fe9_vi$Ao7Z-PN*;5cC0Igy6KE12}cU^7(I8TKn!fM9VxOidmtF*-#^|&JIr0F zJGUH1+nzjhw%HPRZuG}?bbD-b=XYuTK&20!pp?nGgru-U0~})=!<{VQ0nho=91>UW z+TPhe=x5u?Rz$aEztU%6#T3%a{(MaAx@K2LK7nlE^utTrq2W%}R=+^(2(+~4&nWV` z7{}QUKRp8nCTC@o_Y%(g0%^T@IJ^-SAwsNdrCJ8Mx-wu$~!hT~+~zT?oG5iG1TH}Y-lqa&-ju!bj}ki7)rIOnnTZO8P5G^GQJ ziH4lC+E^yoxaXX{N>o~OBC{;|MhsUBiqSrBn@T=Kfp&baaY>|%A9X<^$4!-fMs<+= zB02}znii#)!wQGWw>z((s%IM{>n3Ns z-)U5G+0mYTXwzgq?3+_vDSNmhj3hdFQp2wL91nTJ#M*f{#u0eWj#14j(c#=~L{_ws zy~g4pRnNtA>b!Pb;hZqzirlQJ6XRCg<1?K#zCHIEWq6PJVP2q>s72#$dwk4Pj<)T<%rClv8R_DxvQHlE(Swoby={ zz72fvw!I@M7PH?g!}jhhSH$ndFS5*s%Sg?N&DM`G@=J)%{dv?nj%}cW#c>+B&V720 z3vPji~k zNVd5fK_8Wryk1RT{|S#eG<6I;Be%kfWk+s~j}KGOo~!dygh}xu8cEblsi%ATlJhC=Y?5<5=#F^W`SEiX4gTxQI1QvM&RB#-ZfBv9Gv2yKW>9n)Uhwx;Q0c*6 zrQ5Sybbjh3sGwyj|JLl8w8lyV|L{u4_b__bE>zwkHmZWPplOSrXubv_o7e*Q8?);3 zR@2}cUp6-vRz47z#s)sFkQu+he24!ave>kJn1<@}yac7)GWwX|J=$4kPNVs4AH}_Q zIlT)KB=-)eqks2D7W%D173Or7CQwUnWgLbX)1Kb5PQ?FKHmmVo(lS^)Wz}FlQ8LQ( z(bJxo3=GPn-$sEhoKaKLd+n;>5c~njWaCLXtc{0f-5rA%sp+gc%BmT*Di!JqWj%Ju z=53hq+z4YyR)iE|-M1ihIX|8;|KPG+5(qQw-L|ZE5-@TK*iv@bhFYwd2+29-i0}Ba zsIyJ0c%dg_si;)1annki`RKMOxSSivDC>@}(-B!B`4cq{_v}4$4FBXBT=S#a)LFG@ z-6->wf8N9#)G)zAYGcXfO+!kL9%gRdGhEwBh7L@+eC*T%zGAY^K|kAKM1E2?9mzfO zZW_aX^G*B7R<)JB?HUxTFDPp;iLW~?q(d``nAl~uWnSY|I*El#93n$s9&MZR@{1v! zQZc`#I(?>RG$M<1yXB<&scBlbhSSQ8&}4Pvle7Y)Xj}fAH5c}p=PD6U{Gs2ezR$dJ zHjEOVov>6x9kQJF_N>V+-Ahnph0-zx@B{2{sH5k$*||>#)?A>N_{jnhi4UKDE+(xn zIu=>KLrwZR(I8+@M`3t$#nb;gVMLEFG9UAy>$e4w2ks;$vo|MxKPg0w`XtceBpFen z+G6@z7Uy-U_RNRkr0k*q1Ch^Pq3S2a!HrqJHmMM}i6slX-$Q8ft8+}gExkbIc#(CN zxoWc*tN3%T&}y`=DD?XP^c-*0qa-DXu_Rncxl4sO+iPY$jiP{#S%dh##)gnO0cz&_ zt7`t(gU}f|jNREfhL<^a+&6Z+(?}U=?6Pf-Ms9F(Cs$0;bmX5zjc=F`KiiNgd)3h7 z_>frs%o)+nP*`{HsG$GVdkB@BE+=qr>W2_s?M9l&0CnUlZxhsN$dGe52FIU=?|c5U zR&+##?P^p%GZI2estnVdRGHa&^YT#z?dCuuq+?$GT8!jL8@-Qgmy7mPyOw)Wd1jz3;B&ufZG|?ue?T zo6Py?D4vg}1luUAgdRc^&xPqf+hO(>!)>uGA8Ys0n}z~3Hm}w>=gV!o^A0SeOT*sY(-$`WFt6WO z<;;xy`CR}n%G=ZWuSs)|j4_3y^=RHMM61MX9$o5RK9i|!KkmFI%p#R4JJJmV5KKV95?3q#YgrvGee}es?5GB{&2f_U4e5m&@brMqug(8 z>FdcDD_oVk+$Eo5%GC-YJs#fKc&j0-_yYk2{GUfVt-p&Tm(Q^-O<_j=ShLe!$iUfV zniI*}@$fG#O%H!ZzMr5hJ-$!9=KNUHkn85E4?Pv-PudI%0)423)Zy*?lbdtvXD`C! zyCk1FzPvrnGmo~q@pQLbrciPrkMS$`W6OaD2iR6>R5(Z6e5a}S$;5i%TUqwE1<`ir z*@yBTWILxI7|Y~8d>h;qKB?;e775`8ckWhpavPWX$wyOp((t(rV~NO94)jjWTGZb) zrs)Kj(;G2-3Ai~MP`x)cvM0EE2W9VT=!Ir1a>$#}mTW~i(rq6FSfm}JwvkXztSg>P zseKFJx&6DpoajqD6?KzgMIZUrg7cjFpd&6F?YlK@Bj6`xkP-FkR8RJYLzP$q_Yfwr zDP}q7GIxe42p7Np+DAEEA2X#z=K)?WG`^SlfT)--6+Zazr4#f6TB*L`p7r-u*08wV z5;Q6j8AF;uzTDstgdG*lsrs_r!e%#?B0KM^(7l;R@P{zI&-a}TT)_C#};mZ|cO z8{a_L%q=j5r6K|B$MFijo(vggv^)(V?)K6{UpN@{WoJ0PGEaV~Mn5w@|I>ojXxKd~ z)zp`hep;d7i5USMEGVDVE4|%v_M{E}BVl*8;q=QxlH7>eVbb5+69=+$b>Wa=;aM7C z0!1z)3!*1j0mHouI=pytxcLd&cW$VDCu6O`{`fhj=qr-UOywXnLi^FFWQ^qTnzN*2 z&X@Sa6~@-E*zw*J!wfT5>$eHIQiHUK)@$qB1lz@ahVt8)(2k&=YQVHRlgDJ8bWe)K zAC8G4Qma{l0-Q}Z<59=LY)kosLxr|C-=%Xk-FMb@4AxYmIv&WGhEw+@NMw?a-xtbm zP-)i-S+&69^PF{|QtF4L%u8n+9TwG;4C0OLbO|WLWHVIr^S`KyR!3A=qIgyg zo=164crkoGBtCJUcBd8$7_?V;sZP*YUN`rF$q4uQ6@hLZ3&sIgqPq@3(Gg6<75~bLYKjJ^1ze z_k;64Cl<80PJ~0B=p@UHNo~K{^^hD^M`h{_|9*9s@9pQ6>Y8Ax@!cB?VmWQOmRp)9 z&v^FDf26+gGl9Om`zc|(A~YosTbht3@gBPFKaI)LR_OfdOGi?m8-Tu0NqsQhvC{-t zs~sdCM&VXKvz?4sP3@lB9cw(3MPpRQ@!G4&skbNJOY!6|Z76|IY&W&OiS(e4&Xg0I zm5^DnnHUeUg^=O1dVHHEHt0sxo7@r+d1+c6BI$;?R9FA#$&MCg_hUw(SG18xEsIX{ zWP!P>;0@-~ti4~JEaKgLsl_Ew_>w)q-AV_%!f~W|6KY=H8*KNY!Q9>1wdGf@)14hZ z6jM%u&vZ52*lF9^>J#kSLGR9y&+Zo58xA-`<1enLkKvP#L?+b8vL<;a%{XEf1G^4L z08wr7s97T8n{uq=$^{D@)|DmRd2^q;cSLq$raicn85!mBxvd+{>FN`Tusyzu_E3Bs)wyv6q3QQZ1Da^h3;181q$ z$ivSj#*81|31*M(@kvK>Tj$@=>TQiqRgN8l^Sm$neoio8@9!7|Yi(QY&%Wps~l|dZ>5g9_1QrnqZ^bMpqg>NFU{G zyf=!XvHa%PGYe=x#NW+{?&h?|6jdfmCb6=+b@1`%c`DYA-tVud>6vvbU(oAxH|=NB zNYp8`L1*RDOmWigC;xs)j;yZrMNv-fE#`8Q+*- zuAVfQ#iaZy%uHOQ3AF7@@FO44Kq58Y*RFm3NqTvT?5tiM>6q}O?k7^+Jnx&ASdaA6 z%Q@oE7j9C>PaSgS z69KJw?M(+Yf{)DUx93^OCTJh>v*G8>@%o}46P}LNxM3|@w$~cAw>%HEBj^aw@c%&1 z5VY*uh9qqG`UeVQN-T%`*Gjj;oPyJ??z61*^D4FI+NN{bClw0S>%tN5_U{R-kl8-3 zh?Muze)`X|AObOK7}Q-;1_;F~=|ZH`B@^ z@8x}rX?~%9v@4OyC6jHKVi3NxA9JXGy2m(A^n(b>EwQ0>LO?r*+IVle2%sG8i40Rd z34iyBg&ll(jia&GP?ZQqAgfC4N_Dw^@Xd#neukqardkRwzYr>KuqYbg2PE&eXKl?t zDmvxCk!rBf*~H#u6{uM72x(TN`~5cW$1Y~+E<-J^v8|w+I5~=c`Nl9?>1|w>(OzU- z4_T8_Y38g$s)PV(l%ST;SS)tCKIQ^dpB%Ey>Ez}z$3!;^aL-KZ~ zkIv?Qp2R6_sDEF59eh7dr7q19Ng9~;_SDe89Q$B`^>Toi-4fv`Zo`(dTVdggC_|wa zNAWxz6v#p=9Y5k-Qt}^B`BV@Z~O`Rd@`%Xq6I#pvP%SbV;CyN$PL6mG_{=&509QgIaH z>!KAf*>$nh9JeMHe2qk(zQw~r` z}zi1NCrQXXwzkTq8{^Bo=F@V|Yt(M)yYrrH%c% z#FGs45;O|h8~bi*g`uNOg+iE+{HLyU1kjqTlNo$^?HMtvR4f3o#{d%kE+c{1%B zLpQ6R7gDfg!F1=oWj69KhD~(Ze_irDR)gc#7-O;z?aHmm5$3OSc zFgq43egC7eSUh|Jw&LbQnhj zD$30RcuL*Y1<#RB?ha`8yjH2B&AFu|;2X_fHDIPXi~jMU4$rEA{;mXXHCxC!dgx6X zpJ{x_j6R_gZH@ID`f+p&>F2kl3VgpQF)G&%>8$CCdzz>a-o76sx?pLr*s}V_dy$HA z?ES{Gz1{E;mhIZrw#V;R+{;^^dx(xg{n1AG`g12t<%(d!%jY9i&CgKORK zQ;RfNfm|tI9WycPmM>bM%27mWChCXZu2oaU;l9r!$0@K4yqndUKfAmU2^zl3;1UyN zATx=a?jgi8Po44362%9D1MshOKG^+E>3QT;7kQ?}I?98RT-z%+@F>1H`7w65Hq=`y zJQqR6zkP(8cVp7T#H$9?ukzQ*9PVi^)**VS$E|PalI!waI3hbO8yjrM^iKq(KW5!X zq-trgA^wOl%;}0UAnS`&Tajf))RI#fmVEN(rH>cG?n};wBEa33f0KnXdiqBvUhS7Q zbfyPOOXORs(c#!f`GqUG(YrPufeUztJhO2L&4%R4d+Uhk2 z8Z+?M_9T|L>T8pd#dZX>AGD08&E2yeWMVbc)XB+Oda|Hm3vFnPxj7K@Q&X^v)ng6! z`9}A{^Jc*UzA*mHdneKOS@93tq}~RLKh8jKX*i9PnPHyVN-y5T($zz&jrb-^39U`) zH{$r&PdsnhjlS65A|T9kv)Ogu7bWC$jvKAr;4mU~e2`cCH;?l^{`Z3vW#G`;x1}CdQNPlB=|n~ zNfJvqgaWA+Gv;L*G*&gz{6y*(1gYTVyNx&OE?KlZUP!S*eD@6q9;1H_!M1CShOTEZ zZOcZEsP1+jdlU*-l>t*2ELMV*><37`Lx>GME2@1+CTyM#+{RVfHDTJ1HfBAO3kS&C z^_bC7D+|7$`3G1hHr^!R!EfYSkK1E3#)-bMoNY>$HQFhUHw1CsGLcHZnq1{5x>%D*S?mFrwohBWDZqPz41szW4wv&)SjFm z#e86Lu-^H7iHTFx!PE7^n58HC-EOhT5gj3IWW6e$>Et+$VJ&%h8Irz4SP>Swxqz$b z+Ml3~N!&cl)FoxrS0kAnFL9LaL4B)QJYN(`)5}(e{v6lOcbn?~6oT@aLZ<|$W~nuZ zhtyQ_WFAeY^CM0RM-@LhYVuIh?&OaNQ%#^HdSo&6{QX0YiJ7L_qZXC(#k+6k$2F|{ zHL0b=SZGs?%QQVoCu^6-SRAs^k|J1r8m$436#m1XFG~#`LS=?jD^*2V1E9;_kL;c; z%5~EAxbmzEelW&wLbo<$z)LsdUq@F?wNb6yi<`@OHU0&OX--Qd3Bw`EhMZk%IDLmX zbZP(5n#(=w=}0@3O@L?4)r$WdmC}7*(W9r3Mk!(vKgp{+%alE%nDdr|*N3N~I7sR5 zV!rHo+IpTi-ZmzYouvq#r3{AVC*6&Hs9cCXZc+bU94)e~vT1Xl!C=pQ{(EMT-Hpu` zAKJ?f0@~vCJ@|k*69Mc29 zaa-q<`<}M*no1)aUd#fVH6a zhrJofeI-kr+?&J|X(?#R@}fu1J;54PvEwwsp;cBsclKo~%6{Kqa1Rj}3{b(5ZLHBj z>}%P0pzGU@Tp5Oz<4m$6#i~R3>+{!)0p0IEr(e{D`lDGZ_0u9sebBjW?3k8ZlTM~~ z8cY@Z32mX5r0t!SEA(q*&R6K`rM9!d6*FhMt@{G_irgvqEd|u}m5q5;CWFCIQ{yJW z(}0}Tn)C0LVP+#TKF!@;gIZ;c5(PUTM-|_7OVWNR$WbxnF{5g@;~kCgMRmH`j8kDb zf*RTOv8qVunJi!Xfe9(c?yA=BS8k4a9rIkYsZ+1{bHcY2gX|p9mTRDf9&{+%KRcle zq7R)v%L_eHS}ympa7r306!q3G7P>_txP;T;JuJg5t73XSo_3B_XjeV=19z{RI>c|~ z=S%3%UeSk7QH4>_rCDiXd3T1iHo3@C{haZ`|9G-cyF07qU>!|tI@vq^PRQ0WJbEEO zEjXBWDv6$j9HLLYxoE%*RV(=}T!%#kZSNvUOmV1Aa}&xZ??5{aP*VOwhkt?Dmt zWI{PYYo8UNW^(bP%z$<%acSfDud#S&MB?5bH#L?Ki??ClzKZYR`tE0! zfR2d6FRx-90u5eTwEN)8$VZ{USEeROlL8diX~hLM2M@mSZ~KHTJe|R9QJ3rYJYOxrOz4O~hff-Tz_P$*!tx ztGvbB+P(d89wPt1U?26h?b_|1sbbV4%fc!WQu{NiUnqFvurW%{?uq&mRmdK9wxApl ziR2(nMGks;i5y70<)VZ(<+08bLjwy%Z}9hSq+tB;#~a8Gw%d_Z#KDFD-oe&>;~03KhmxX#K2WY{r!QKV{gPEr^jy_ z_!&Q&*_Zmm`ggIZk~d+;N3y^lTnGJ|Lprp3{b8yHcbWPC)?_a`=y2h(Zv7}_QoV#w zz2BeqRdZpH=*IFCHxnnOS#rI~HS<5TWMw%SOzqL`u4Re&e90dM$KO(asvHUAc0keE zl{&Adr4E1T#un+>6wzlQW{bVKkZ%8t$73>=yaaQGX2A4YD63j0a$>Cd*xV?aFooxR z`~7#)vgb2$`W%8qD$pt_OzxeVJFl>3KJ4q+@Ck&qCUL#&lwmGEY7{vo9E+sk)ia`< zF^|Gz9Y&X_z2VJOkgrzjydthdnmA)>7=Dt)OHc7b#&|aL3-$>9dzB@7Lax@sF~2)= zTz#Kv8S;Bw$4d=AWiDuxVf>n7Bn>xu!=aGXoar^;FZ0ggX`(t*;MaPWgnraWHo9T@ z9QH2O$&;bg1oC~1L>Vcmorh#T@jeLdIG?Q7wI3 z($?xAVckCS{8qJqK?$o{8yi@+QrpKVNv+BoB0TuSSnN{{=4K7Ygp?c^RGU>Zz_-3R zZFi{KKEa!psy0Q%Vn<@$?UbSNuyIe{K1O$}A^DNd_2))sBPDeBXg|19FBNm80-ti) ztGCPCKcF3hRsd>1s_(#Mv$!fiKX;=4hrBW`$sSqqMS*HpbP+?>2g%B%4n{#2;2uhF zG{eK6k%ZIurLGRX53x0e+z!h);^(s1*`&XJeN~QY$zbcF2VU0jqB4m5Knal=!s4mA zB|iXRJbi%p2VDTF{B{cZ@)K1kJMp+lgVYiCuw!q@fn3y(X=H#iGTQ-KM#ZfshdnFa z%?8xPP>tUyc}e`N+@o)V8GQM6ZhnIZCG$FWaiZb5e>8PqzLAKV+)x$R?p3j^S2yc# z^$I(~y<^!6bLE|d_{?aKH*uqC=~|NFrc{3#-XmUql#qcli#}lXCXH|t; zIgpRj`%8Z1SfE7{_>a8|+rk9$LRGHRxMkQITy3 z+!YlfP_G+ROySYu@be|CCY?EZDSB61A@VhabC&9x(3Us&r%xPRXY&rv^LhSw+T1(s zWM)AYV)jo1`wtD^sGUPJYa}ZeII}0Av^!;cN@-hEop@BUTkkJozCOt?8N>3YvOn3e zb}pYt6|JN}0wY3A=flQW1PhI_np3n>1T{gbCRM!?Ua=+qK|Sy$c9gV}lgq&8cY^KtudKVB)^LupT*=Bu0xeL4@v8i>LyEK^u2pEh2x!Y zwI0+SC~vM(X#3J^HD!&_98>XR3{s=4n19924>rzcEAbk&!7I@$)rE|W%JY<-Hp;8$ zk=b&NRq<@!;o`x=;YoXn>@K*Bsx*IPRo9vP$f9ds*)E!3WFwAh3uZXxum^ z@ySG$>V}GPbq)O>s!TmpqSDI1JEId{-9)#lI}JSFKJ(D;(YHF_9a;PJ@&HE;B6(|5 zFg&#oJq5$9=EXv>9O(fgUqU6Fb@~&|&O?Fxjhf>_yO!!3>%tUC11Ca{r`C;5zO>T` zEAV&mhp(wiit+65bF7(EbU5_rNoJHvJRv!K(*cFL_MG$S9-^PQ5EWEqi`!03qrbg5 z)cWi}rFh#mPBSh(_>M zjEITyyiddBwS}TuLt~QylT_EJTD_)(bvlgn z)n7h@eqk-fF5)&s#!zsU>@5jY-uNtHUyJl(NUwLG_0!6v~_31XbOp@6@OCxYK9no1%U317DSU0fc4^A;sQx4u*9GEmX zsTmDRuAiMoL91S-nQ{?)qxC*VKIZ3>&*1AfGNn}6-xXjNv3W)v^>*@-Z=S6mg`D+h z^9Mj3eQY%(MX0y)f~zQ~(B~XBqT)48gg(kOC}L)>+_L$QL$Pas^~PH)!+`y?)t5pV zZQ=)~skyiQFdM0eG~!d-VyO*|MuqehGnv`ELSc-vA6V9eqoZ+XSp8vCr~;p|X8Hb*cv6R8CB=4bY53!?81dn+O?9cMQ06-o(aTeS!v%ImpTi za%}PO(6?^b(-S6guOwosxsg@=+;7cLHG&EZImS9a-%~~w8A&Mdn=W?qtL6+$do{3v zV8Tyg_;|N)@J6%bFT^EL+xN#^j#F`b$!<5Qx4n)tf*G+Qw4I;amXI+CM0iJoAT9Ml z66)RHrGB8SZ@oT8@CV2@JU`S4er^`ZZ``6BN&RcK{?Xdfcwh(((>ROd&lQfJEB2dH z*($LOLvHyi#D`33qy`%)G=jtSp3fM#vv+mu)aQHuP$azQVe>rf^*xdO721ftAD2r3 z{sIZKkHjM$vtmv9Bk+Q1y60BdtmOgqJ2&W@v4L^v0HWc`aoYGOs#js6Y%@cB%M}Zv zb?cHVK^!V^n__tSuhKfB+syf4V5-e%;ETRr-{>#Y)7z**8-E$)p;LtMintvm5tVezZvds8%$B7s)e zw`L3wE{=vbOo&j%`74N3OIriad0 z>Lw7BW`2CKCU>D)7cdNbaNhcyXhnz!`jwbL`r~@LDDC$U*VBWW?VIg#Uh}=I2c+XD zY7Y7zT)*+PSP9bJGJf>+j9yprNnu+#mBgp`u-{VU24a+qv&hN(AlYMr zF5;e`byMlr^NkqVZPyFp^p;Yzi?sgE{oRCq0U{tZbc1LvQaS^7bkI}c5U*c_y z4;j}&rzrxA#25xb$%2pko+B`;sz)YPZs;ikO;lyst@Du*7NM0iYH@WZG;i1?$zPb`35(zR1_=;!@go|5?UBaQS z4#9st14JSqcVPGU0(KFQ8;DFma0G-FPRP3;-~k;G5Jos*I|4$1oaRLc;DEpH11GV) z2Qepr?0X0^N5ZQskcF z@B;56#^(huL%tFLzn6H40F;ps4!R4~9Y8T^HTah63h+hS;J3e@60c+K$QO5MfSyGN z4h(r4;Zw#k$Oqr4jX?SrccE@m1;~$t+=LBk9{6&y0KBUC2vm06R4iaS^2$`&50D#3 zJC6au50JYsu@$Tnqo<&UlHg_N*KL&of<8bv;2u_Ah%MMgMvRgGYabxwFuOFwb6=og zfUolghr4;rEfE0ILio# zq+U)FMhPj_Bsi%AVC1g{KV|_$Qbw*VU;rzi4w&&CKNn_HKsWb6Tdt!E)-KQhXDoyS zmS;=7adw7a)a$^yxIR^afN?D39!#ByTB86NI4#<@5D;!(`2>D1@tWL)4Sr{j0GN)w z96aS)k?d@GoL*9YfC00seR>JO3`Fg6uL|2m>d3CE|$LrCCxSrZRhYYu^vcj6&ru)yuLG9qeFBOn~w z{##u8H{no;1PJ_|a6mT!)Zix$Cx<6Mh+!JQSAcPufXONWUfxZ2E%Y=h7tkBPbi(CS zKBSXwX#kU8z zAtvC=^(9`--0X!eOLO335`-4WH%G+&Prg1KuH?%Hr>GB{qU%j)?Ij$~WdX)|{UZbi zmWR=R*z4Ee+$e%A18nMlKP6sMKuQvX4<6;oByhku8@PgL8_*b<TrE8|MM8bU7hDyKkbU|2xLWN`z`nS}qDgqT7Y76Pz+x{UW*2KgdRFt<>_I~%UY zsId&_{s_+PX3Awxk4bcQCk1P2g#2Fc zyh2C!o`6Q_fceSxSI0#QG9zf?f9Sr^GAd{-r=oI)nyp z#2cAq+4p+or=GS5hD#XlfuJ zfL-eEr^Ks9^b$KKj)V?WgUaC}cYg*)F4Vqco_~gr!W11Yxi^?yR63Z=*H@7zPcE@a z8CRRRml>cAWTQ)ZV#d`*u^gblm_H*IhazFaWxSYI;dG9kpUQPhUN6}f<;7~=oiJP*7t zv20lo5*Rj>jduAA^tK-?#_QSe<=rLLIqR~R_Og2rM=uH&%)Og`1ALLU%i)*U^Y=)& z9RKbll5?Lf27>zY<^SzZ2=SM4foZ@$4Z(+1z2|NAPD{}HMsQZ|UDL3?`xlQ180KDWI9zi< zUBw4~c|<@*?q#PY_|x+2V&`xVEUfE2?EVQH?|BA}O`CTWP0l<}m+9GG9x7m)2cdx5 z9DKpsJpV7AI1(}zY%o}Q%}>!B+~yl zS@mC73;+`y8SV~D>QCa5XbT;ZG`>w&0#nSTqoLmaL!TpJlBS_&B*=qtDk_-}d{ zMRBl`2)_F_{f!>}mB9mO3L!YKJe@*#IR|hTf_XaQ@|TZt_ti58PFt6MYYVek!lVmq z%ukK}ZO%l{{|Ey)g;z6nQ5(oK@yLK$9r6v}PvK>4|Dfv1ItM364x9imntwkfUdC5g z^`guEa=`>)u+R0joRn~>mn#{Jz^^1^Y@nd%vYDgx-M)Jl+(wHV{M*b|{!5Aoz%0HL zxX^z!%=NN)S_T`23D7ORG+%abhvGh%H$33nTsNus3R_-$X}&>@I8*EFisz0y<3~kExCB3@@ z0)ZFF<^{d*@RHtn3`Rxx>s56re+8L-s3;fn!2~3uqhJHEAQP6`3~HmadZ1UKVDr3Q z_LZ2I0>8dqEk#(RprRM}mvmJ^P|-ywVQG6|_f;sbcTaf;KwkzS2k7Wgu>P~-J-GGW zVhkLZ9K5vfdZ+il#2eD1{O^%b@wI^12-sQx{Gl= z%dVmq2U3yVvI2+xI+LIzlu zU)FSgX-lXw=ms0O+%o)~yNd;jn->nP0_9*4x)r*ozYd!12Ohnzk5eNAhhkSi=wVQ{ zV?_WDgvx?P*z3XE7K1}gDz5slM+In?uoRq}|Cii(LH3t{lTX2az!T+0B}k4@gp-vk zFP}hs8dl?Y3`VsZoI$#4UNk;{L*pwU6fo0BbUgY|L5EpDFRpKb9&5p&E0tGm5U~mz z40r-3->ZU;hfi>xdd*d= zEiTCK^5Nvfn#+*9`4~zr0M6Ddm_*leGQ9#0ovlLo-}ALf>Cbl%Fp{2N1<+p$I(ZFT z?0)U#{A>_0XDWf(TL}LRx?>|8n%|6q0R+`v*&kmE8hYFgMAU%`5N8)ysDB@goMGX3 zrh^M}9XRZDYoB()@nm&Z0p+R#)kyZi$%b_hB3KHnP8*w^frfj5o$&g}ndQd?lpQ|J z4Hv@T_5)_acHN~bvQ=Y6KHw&r>dC)#k9-V=iq>Ck+zsntM;o_#2or4JfxX2(L@-o) ze&E%W*CJ+03Dnm^=wPUZh=Tgs7vST=BE)}^`Ga6|1B4R>B2p>-&WnhEunztKpB4Q5 zq0;&xVMi>g=`PbWGAR-N{3vhY;`vISBegf>8!L46z1B4uQB0sWGQ>g%99pE(4 z{RLh$0yiL{0YVeqco{u<(>`Zi@T_wP2I1y4pnWD>r%K~xNzjThrA&f4Q$RTVH7H&I z9GcX4d1z}yO|8xXSDb#ie-A{=#c-(6S5#c!xbZ4Ou$sWxA#J-Hu>%zkP;0v48D8)d zd*Qt3rmK@O&M&Z{(!6+v;S8%$R16@Kh7R8UokaExP{Ex$Dp<1X(cVIqUk4Ejx#W38k;4<~Ao)&{jxj^LgwRaJ)Z3dh9pI@lxz+&@Not`&? z4$RHN?S%0li=g+4Emt1uw19xtmA?Q|7!Nk*P37qG-~kW80Q_^k_dZ?&AgvGzAY=m- z^FQ^(MVC9D1Y*zs2mcd>zkGV24oZT-YgoU~K?b}9zrf2Rp%pa6Oa?$~1IfLumk+W) zWq+5`|8BEsUKWZMP*%7wR~xt@XDDI-gvA)7z=SdeywKrH_X}pO`XzJj0m!UqyIl9( z>AjC7!Jf4Mrt9_8S_=G+019y4cKIlnony%9BRIczZvVTdHwy*k+QD6RaySM)px=HK zVk?k_q#AR+9uc`UQ#{Na=tO0y-TKe7L_>9pH#dIe&TZ8ury_MX~`sl?IE5;UcV;pAs+WTsZWk z140Sg4AGB*@7xCKEfNgMe+Rw9>vsVxC^Y|b@Ejw?*tZ6a{0tt1>8@0R-%Gp*N?;;n zKvd^dS{8JI6H;AqN#Cl%KnGSkui|xl!F*AV0noQ&Pyk$AS3-(iARW0CMyCe?z!<`8 zO?adyCJMSW4%&L%t-Ki+_6E?`b@{x3H0-zWr~tSX4gc3j_V1VD(R5$Vv$E$LRP6uN zD?trxcY`@iM;`KvJU=#QJacz10MHW{)pul;{*cz9R!5tr~fWQiUx3~hY=4q*>GQvF$OwhwC&DptV0d^&5%z)^yml{I3*a~RGuzThD@!+DXtS4-xX z3-ax87&-a~+(R2oViE!|{g4DPi{JQ4qClRf)aGXDkF}Vv)iIhTDtS53;Bv;H(S7`1&uyXlnaKg%;cj zI7J}-Q;uV1|AFIMVB!474;-ye9AltNumj>hM|^&t|H#<*Vc`Sopzm-K&Mr)Nm;&Pi zT;Hya6{_DrvPs4TnH-4D!Xkim3b@F}3tn#i1&hW?aJ8$Q z0VR=!F3ALgSE1(^1j&c(!1f^Mh0);E9>(i}9P$lLE&<7~@lJv>MIV7}BLi$3*W0hj z=mix1C_s_TT3`f3APD~Zl>cA~ZWZe+776fj=qkXjL*QV<>u}zeAqX`*h}{?D&wFt4 zpP?&@sfIza^f8>QGJLt|xQM}3D6UtjzzG~`c?Qnv-~D9fSH2HN;C?b2JP+yKyB8^nPK8{p!{CIfz5J&=Dep6eF~CdUN0TK)H2mUz7;zQo#6Vxs^eqgM-u z`Y1TEF!_I&cm)4G1OYx?U@C52V%C|kasL;yeSr~UzQiz&U1f~$7)XD_c}ce!gOI^m z_*ttOp$h1X68PtO7JKr*u+%^$ANGH*=+hU92zg;lW?+2$vZ;{0Jec7Fy)6Zo$?K00 zWCQ@!afmQHz@g)ybi3rG>b7wREzFEDa!a#cU|bc!1@ihjdnA8}Wtg}+KZ=8YLuOOD zq`OR9xfpRlUsJxMcTQXus;4Z4uK}oA2F$4In<+_kz-tPuE2_!Mlk~@1E&Q_J=8o;- zztuXe0f(ARUanD{e6J^pz`noT@vl|`4>+{=N-OJo$oMvRPB8(ubk~zXB@YITp1RyY zx6To$aDb0M$h-bk`nn0Obgcy&`+qjDum7*E>i~=DTK=mjy)G=U%a#iWA|1r?UNqth z#+cY*4OR#$!3viApRutTBsOBO9D6h(8WrnCqOo9$iLu5m5fD3~hy@i3|KGXi+?BiQ zyWh8;X3or8?-|V}F%vSYAWP*fj|f5T9TR`yRr^CO+r*SB4sWO{xt(yM_p!7RSKfw{&)X_qJ@#^6}?$P+#r( z*mA~E@eF^;f1Dky)cN+)iOPz-aLB0*WT(SCW2-)tjQ3X}OANk^^NjsGT}XpoPAZaA z!nAwI<|DB<;h%R1G-pE{!1-%yTgGH%zCGR!5q=lXTAH>TqC z;FbQCip(A6#yGYsjh*hxmTEakj(1_6>;i=^tQiDn)Or}&F{U~SY4Uq2Ab;t&*9+DKxeh5VW&1f zdB!V7%7HIs0VVdDPX4@Z2o()JG`gm_KO~Aog8+6nKe#P4LrDr|Dm5gsT$1R+a!?@;&Z)PjiWUra}1f@Q^fZQ$Tb8EGkJ?Y$u zh!wm7GCw9`v)xKEa<5WvopqCMpx2j0Vs4<-G5>~CRBXK=UW>ZQ;88_Nc2*T-R4v@Q zZp8|P;;&#Ei&;GPDM_EA_s!D&CPb}BB<*h@SjXLzOrJx+eghb|=%%!_UZY^UK@9A6 ziy!@;e{yr_5yfw3Oe2gX)DMw7 z-uy5p$hjO_pJNMitT$8!7-_ zK1PH$AxRYypL7cUYJv#&BO59V9*oaE3ip}J`8=(Vj7pn6$n*)*_y|7kpO z1kb(C6JYw3U;1QV)mGyt_oAEGoJZMxsrgY$c`W{p!(%EX_-BDLp1*0b!^oB-9h->f?XnoRu}eGSn_CVW^QSysWoBLn*!whriKx zsq)>tcpD>2eIUtbd;l3Y>}24wp(fYI*3>sZU-V-F1@TbW*p`4+fy5(hEc%-P;{4fwC2EaOb%&n4KWCa}?U(Lo&S4q;}r{IrXGO+#;e`}t*WUqb_l12!U zy*y*<6)KW!qk2!qHa^0tpSKf-y-9?V%9#{Bl4d_c2e0^CO_q^0gC&`?^MACqzMEKX267X*LRaDuBZ zRFfy+F!R{z9Zg*hCrEnCyDAyeK1tHSPi~{83o)~%>vnJf$1Qv;1pt zj!*eAwVv>N52tJSapH0<$8GagMKmRV#;;t@OlWI&!zZ^e2y{4#cV8Pskc&0<>F*t&#JmS5w+C{WJiD5 zYLeyT$LEG9u|}CPaZ2;CSb+5?!2}srx1YVq>LZ8&+ZR$Q5?)}@>$Zz;OkMpFio7i5!Ufez zinpr;eAhh=cYomHNT$?E>oboIraj|>2W$BT^^+p`(R55n23ekWH40y*z4I&SC1KPn z@VKGzCEG)N^9qD;KqDWpD?bV7L z4MZ>a+7iucN#xMim~M1aaWGEou`vDTQ24nJ5gtn7!+l*yshOw>gAF^ykslfeKJ_Yt zwr>D_^8o{=<3AXy913pVmVuYW`zoypx}V$G>tEyjT6Jg3HF1e&WZrKjKaY6}ZXJ6v z@ajHLX82o4nQ!RWxkNTr@Rp~%6>p0gBx1X32N#iV7_){l)aP%dtm#$<4!TqZ{!g9M zW9?7DrZfi5sgu?uKK9c)$lXI5;t)CQrzA4ckUl5>wDaS9_PVs$7{{{kU8tfQ zxu;DyM^V`umCu!(clU?dNr-*9g<4&uSZeYbE+i(Y{k?~_O++`yG~IHQ{w`s%e%erA z_eH;)=H_-0>ZqZXoa-=qVz2>MdWS~j+RbNg#lKN3RC!w_p2-drRYUGJ4O@D!d9rK-eraqC1#k9b;Lf`Y_N2r{a2I9h^CUVy8#O@+b}1Ow z{FsclLl}P3Mgo5~*S-;D6Uo5cW7T%VHCA2kUAo_;$kY^YSb-nsYlTiEb?LohH698N%k ze}F{Pa$4lW%`8D@{JS z-zhE{MQ9wfk(0R|Vr2QYf>wNo+v$8^F~NM*m7rnaPY8qHn0p} zT)%N)GWPzRG2Qg1+JSs#Cz+?eouI*O_3O5Rip;U&T)a2k_A3O3r6}dU&D)d2^>pb+9H#-V1Q7mubR;+GJn%Q%^{_?XfWG(PVz=PykcwS+$rP&MYri{;; zz7bhqOQ3^1(LKIO*4PVSEFYh-$0F`1r4UtYTFQv`R5^-!WXO3$cM>W^Y+UBYWISHR zCKYa~?MXKW$smIr!1LlAHuk-Pz`qgMNWtkf41CprFMZNg<$zn@xdv*%BD&2LNdWhwT-AhYB&>EUA) z3E#`gvBJXV>K1~G_9Nu$az)9=BE2!qASX%X(M}K{PsPSoItlEm%6IEVAKn1p%nY$) zGt7sfmODwh)lv=}1O{#fP1yRxI|CdRLcv}n-C1BSjH0!5-3LRZvDp0)#pcIk{4JcK z1~KB}l(<_f#`7gOFtCRUz{zbHINpUXL|TGN*IX=u9!}$L=15JI(%p>OnC$DRu|5s1 z>fEDxA#7C)XOqWFTn|Qj(M3udkLc_T`Z2Jnp}uQ=n1$+i?SaGf;S#m7fV+#qf)B2%6>E*)T~;fFOI zB+-qB-M>0+U9}&=oj^d#GiLBHhCk`}d#qCCV%OmXNRHyTA@?HvpNy>BO_>k}+QM;D_`|fLztFrx@z|^O{EFud^BlGSyvj#vFI>`rxb?!HN8VF)=ZB zd>Rnb9{X=Pf{o5?8ZNPBY72WcQfDe#K(d;G286=w$CujKx={G%@iy~4WK3YLO2^JAz}^?nY--BS_- zGvfkg5F6{}$=Te?E_J#A!wiREjm}WlSS}im6X!`RDc$L&yb@R__>ip6=&Wk{Z8U7q^PFh zmdu+hW%x@}67%hpP5V3sE;DndO>|sZGUc;@P;YLYfrqwSnt%+IkDq+Yc)(FJyd~DN zy}^3fdd8t@BferP@|KqL3>~|ufk=~bw|B8^9aWxR7lZU0E z^HD@lQBr-S1TxJR9QI#k;H|z~nQF)U?ib*672qN_)tV}XT4Uzmss@KG)eQWhnj3pq z(62Lwz)2b{w=~CT4>DFQG-Z}p31XY!Ft1(#WC#hXU z2h)Dyg8^E}9Y4?lo|(_#qqPG2NU1|ge6R=dg2pP(+ic{x0}8YbR-a)f9L?Hu2XqOD z`X;hH8(X$kz;~Y8wAM*Df8>sH|6o^1MdFgDmxNt=svU)mRzatNnI zTrZMhkXC83fzEe}!wU?8hsa}Rl`{1xto#-~x!smkaNH*bu6I~7#S5x04Z8Y)hbukz zMO;tv@S(QeTfqhE{^djuCkybC*Cdr7NOsey$t*!&S2uLaQlBPc$=3y2mIW;yaNH|` zz?+y=0+ji?hQlLkF=>Rqh*u(I&xC z)@H7pl{$dS3jP1bN%|k1i0ezf3XqamW&o!3)9Z-;Tpj!Vmt~ie6n-d>!|MVB{!dNl z0|9Rw!{OZnrG04xg-@5@gFEXS$@)NnU)0<~2kkm>A`E(vH-VBtT$*4oaXcSv*F%HZ6s zWl9XTq~ia~g>y5oT-(ZuW#48}LrA=I*0YnIcm&~0Uocv4PqsAU^9@+2-W=?Y%#>}} zm0B(%XcQ_%v?dhuH5|dYbqSRc_BRyXOM(}e;a4fVaummR2@_&O7q~rp>9Wgkff-28 zO=OCm9uM5JdJPHxufATtsdD2@w`Djs1)Me&1h@ZY-^(dBI7GkcZ7D-U4#!Q3;PU3>zB;xZv8(>b zvPu}Uj^l2P;HjZqM&X`&h~TNfM+e^gn2f#la@;o&g1@*FJKUe|s)J>#5bfv{m>-jI z)=`d|7%BLPxNp3dG{247^jAcf+zzKsinvY4?nu5D{Nr7!u$#YAl+ZW1TI>Z5z!OEVXs|`rW`=i;7Y1 zG+7QD_xotRV8yntFVfGA&LN;fWm-*fq?? z;4uZiApE2!&zRZ#fAArGtqkt1Eg2m%kV9Bi1+df!Ba d;=^Ap>!uEI^`|EHV+Eb#?KQZPHji$m{}1{+T@3&L diff --git a/Misc/NEWS.d/next/Library/2024-02-03-17-54-17.gh-issue-114965.gHksCK.rst b/Misc/NEWS.d/next/Library/2024-02-03-17-54-17.gh-issue-114965.gHksCK.rst new file mode 100644 index 00000000000000..d59ff991993792 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-02-03-17-54-17.gh-issue-114965.gHksCK.rst @@ -0,0 +1 @@ +Update bundled pip to 24.0 diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index 94566772338b10..e94dcb83dd4e40 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -1570,18 +1570,18 @@ "fileName": "Modules/_decimal/libmpdec/vcdiv64.asm" }, { - "SPDXID": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-23.3.2-py3-none-any.whl", + "SPDXID": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-24.0-py3-none-any.whl", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "8e48f55ab2965ee64bd55cc91a8077d184a33e30" + "checksumValue": "e44313ae1e6af3c2bd3b60ab2fa8c34308d00555" }, { "algorithm": "SHA256", - "checksumValue": "5052d7889c1f9d05224cd41741acb7c5d6fa735ab34e339624a614eaaa7e7d76" + "checksumValue": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc" } ], - "fileName": "Lib/ensurepip/_bundled/pip-23.3.2-py3-none-any.whl" + "fileName": "Lib/ensurepip/_bundled/pip-24.0-py3-none-any.whl" } ], "packages": [ @@ -1742,21 +1742,21 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e" + "checksumValue": "034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784" } ], - "downloadLocation": "https://files.pythonhosted.org/packages/76/cb/6bbd2b10170ed991cf64e8c8b85e01f2fb38f95d1bc77617569e0b0b26ac/distlib-0.3.6-py2.py3-none-any.whl", + "downloadLocation": "https://files.pythonhosted.org/packages/8e/41/9307e4f5f9976bc8b7fea0b66367734e8faf3ec84bc0d412d8cfabbb66cd/distlib-0.3.8-py2.py3-none-any.whl", "externalRefs": [ { "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "pkg:pypi/distlib@0.3.6", + "referenceLocator": "pkg:pypi/distlib@0.3.8", "referenceType": "purl" } ], "licenseConcluded": "MIT", "name": "distlib", "primaryPackagePurpose": "SOURCE", - "versionInfo": "0.3.6" + "versionInfo": "0.3.8" }, { "SPDXID": "SPDXRef-PACKAGE-distro", @@ -2204,19 +2204,19 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "5052d7889c1f9d05224cd41741acb7c5d6fa735ab34e339624a614eaaa7e7d76" + "checksumValue": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc" } ], - "downloadLocation": "https://files.pythonhosted.org/packages/15/aa/3f4c7bcee2057a76562a5b33ecbd199be08cdb4443a02e26bd2c3cf6fc39/pip-23.3.2-py3-none-any.whl", + "downloadLocation": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", "externalRefs": [ { "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:a:pypa:pip:23.3.2:*:*:*:*:*:*:*", + "referenceLocator": "cpe:2.3:a:pypa:pip:24.0:*:*:*:*:*:*:*", "referenceType": "cpe23Type" }, { "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "pkg:pypi/pip@23.3.2", + "referenceLocator": "pkg:pypi/pip@24.0", "referenceType": "purl" } ], @@ -2224,7 +2224,7 @@ "name": "pip", "originator": "Organization: Python Packaging Authority", "primaryPackagePurpose": "SOURCE", - "versionInfo": "23.3.2" + "versionInfo": "24.0" } ], "relationships": [ @@ -2909,7 +2909,7 @@ "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" }, { - "relatedSpdxElement": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-23.3.2-py3-none-any.whl", + "relatedSpdxElement": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-24.0-py3-none-any.whl", "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-pip" } From ab76d37948fd506af44762dc1c3e32f27d1327a8 Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Sat, 3 Feb 2024 12:45:49 -0600 Subject: [PATCH 31/62] gh-101100: Fix Sphinx reference warnings in the glossary (#114729) Co-authored-by: Alex Waygood --- Doc/glossary.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 098bfffb104ef6..f656e32514c717 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -341,7 +341,7 @@ Glossary docstring A string literal which appears as the first expression in a class, function or module. While ignored when the suite is executed, it is - recognized by the compiler and put into the :attr:`__doc__` attribute + recognized by the compiler and put into the :attr:`!__doc__` attribute of the enclosing class, function or module. Since it is available via introspection, it is the canonical place for documentation of the object. @@ -1104,10 +1104,12 @@ Glossary The :class:`collections.abc.Sequence` abstract base class defines a much richer interface that goes beyond just :meth:`~object.__getitem__` and :meth:`~object.__len__`, adding - :meth:`count`, :meth:`index`, :meth:`~object.__contains__`, and + :meth:`!count`, :meth:`!index`, :meth:`~object.__contains__`, and :meth:`~object.__reversed__`. Types that implement this expanded interface can be registered explicitly using - :func:`~abc.ABCMeta.register`. + :func:`~abc.ABCMeta.register`. For more documentation on sequence + methods generally, see + :ref:`Common Sequence Operations `. set comprehension A compact way to process all or part of the elements in an iterable and From 72d2d0f10d5623bceb98a2014926ea0b87594ecb Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Sun, 4 Feb 2024 00:55:38 +0300 Subject: [PATCH 32/62] gh-114803: Mention that `@dataclass` should not be applied on enums (GH-114891) Co-authored-by: Kirill Podoprigora Co-authored-by: Ethan Furman --- Doc/howto/enum.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index 1e9ac9b6761b64..30be15230fc088 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -497,13 +497,30 @@ the :meth:`~Enum.__repr__` omits the inherited class' name. For example:: >>> Creature.DOG -Use the :func:`!dataclass` argument ``repr=False`` +Use the :func:`~dataclasses.dataclass` argument ``repr=False`` to use the standard :func:`repr`. .. versionchanged:: 3.12 Only the dataclass fields are shown in the value area, not the dataclass' name. +.. note:: + + Adding :func:`~dataclasses.dataclass` decorator to :class:`Enum` + and its subclasses is not supported. It will not raise any errors, + but it will produce very strange results at runtime, such as members + being equal to each other:: + + >>> @dataclass # don't do this: it does not make any sense + ... class Color(Enum): + ... RED = 1 + ... BLUE = 2 + ... + >>> Color.RED is Color.BLUE + False + >>> Color.RED == Color.BLUE # problem is here: they should not be equal + True + Pickling -------- From 1032326fe46afaef57c3e01160a4f889dadfee95 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 3 Feb 2024 17:16:03 -0600 Subject: [PATCH 33/62] gh-114883: Fix Makefile dependency tree for non-jit builds (GH-114884) --- Makefile.pre.in | 13 ++++++++++++- configure | 3 +++ configure.ac | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index fff3d3c4914e7a..aad637876ead80 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2643,7 +2643,18 @@ config.status: $(srcdir)/configure Python/asm_trampoline.o: $(srcdir)/Python/asm_trampoline.S $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< -Python/jit.o: regen-jit + +JIT_DEPS = \ + $(srcdir)/Tools/jit/*.c \ + $(srcdir)/Tools/jit/*.py \ + $(srcdir)/Python/executor_cases.c.h \ + pyconfig.h + +jit_stencils.h: $(JIT_DEPS) + @REGEN_JIT_COMMAND@ + +Python/jit.o: $(srcdir)/Python/jit.c @JIT_STENCILS_H@ + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< .PHONY: regen-jit regen-jit: diff --git a/configure b/configure index 1d41d7ba66470d..0375565c294552 100755 --- a/configure +++ b/configure @@ -920,6 +920,7 @@ LLVM_AR PROFILE_TASK DEF_MAKE_RULE DEF_MAKE_ALL_RULE +JIT_STENCILS_H REGEN_JIT_COMMAND ABIFLAGS LN @@ -8019,12 +8020,14 @@ then : else $as_nop as_fn_append CFLAGS_NODIST " -D_Py_JIT" REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host" + JIT_STENCILS_H="jit_stencils.h" if test "x$Py_DEBUG" = xtrue then : as_fn_append REGEN_JIT_COMMAND " --debug" fi fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_experimental_jit" >&5 printf "%s\n" "$enable_experimental_jit" >&6; } diff --git a/configure.ac b/configure.ac index b29cd028f8f200..e121e893a1d0d9 100644 --- a/configure.ac +++ b/configure.ac @@ -1592,11 +1592,13 @@ AS_VAR_IF([enable_experimental_jit], [AS_VAR_APPEND([CFLAGS_NODIST], [" -D_Py_JIT"]) AS_VAR_SET([REGEN_JIT_COMMAND], ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"]) + AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) AS_VAR_IF([Py_DEBUG], [true], [AS_VAR_APPEND([REGEN_JIT_COMMAND], [" --debug"])], [])]) AC_SUBST([REGEN_JIT_COMMAND]) +AC_SUBST([JIT_STENCILS_H]) AC_MSG_RESULT([$enable_experimental_jit]) # Enable optimization flags From 80734a6872105de874a424478cd0001e23286098 Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Sat, 3 Feb 2024 18:16:30 -0600 Subject: [PATCH 34/62] Update README.md (#114974) Trivial edit Co-authored-by: Carol Willing --- Tools/wasm/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index beb857f69e40da..23b38c8e93638a 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -83,7 +83,7 @@ embuilder --pic build zlib bzip2 MINIMAL_PIC ``` -#### Compile a build Python interpreter +### Compile and build Python interpreter From within the container, run the following command: From 848c86786be588312bff948441929816cdd19e28 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 11:45:35 +0200 Subject: [PATCH 35/62] gh-101100: Fix Sphinx warnings from PEP 3108 stdlib re-organisation (#114327) * Fix Sphinx warnings from PEP 3108 stdblib re-organisation * Apply suggestions from code review Co-authored-by: Alex Waygood * Update Doc/whatsnew/2.2.rst Co-authored-by: Alex Waygood * Apply suggestions from code review Co-authored-by: Alex Waygood --------- Co-authored-by: Alex Waygood --- Doc/whatsnew/2.0.rst | 12 ++++++------ Doc/whatsnew/2.2.rst | 10 +++++----- Doc/whatsnew/2.4.rst | 16 ++++++++-------- Doc/whatsnew/2.5.rst | 18 +++++++++--------- Doc/whatsnew/2.6.rst | 42 +++++++++++++++++++++--------------------- Doc/whatsnew/2.7.rst | 44 ++++++++++++++++++++++---------------------- Doc/whatsnew/3.0.rst | 36 ++++++++++++++++++------------------ Doc/whatsnew/3.5.rst | 2 +- 8 files changed, 90 insertions(+), 90 deletions(-) diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index f4a9d23699de53..af8171487fbcfa 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -1039,12 +1039,12 @@ is an implementation of the Secure Socket Layer, which encrypts the data being sent over a socket. When compiling Python, you can edit :file:`Modules/Setup` to include SSL support, which adds an additional function to the :mod:`socket` module: ``socket.ssl(socket, keyfile, certfile)``, which takes a socket -object and returns an SSL socket. The :mod:`httplib` and :mod:`urllib` modules +object and returns an SSL socket. The :mod:`httplib ` and :mod:`urllib` modules were also changed to support ``https://`` URLs, though no one has implemented FTP or SMTP over SSL. -The :mod:`httplib` module has been rewritten by Greg Stein to support HTTP/1.1. -Backward compatibility with the 1.5 version of :mod:`httplib` is provided, +The :mod:`httplib ` module has been rewritten by Greg Stein to support HTTP/1.1. +Backward compatibility with the 1.5 version of :mod:`!httplib` is provided, though using HTTP/1.1 features such as pipelining will require rewriting code to use a different set of interfaces. @@ -1108,7 +1108,7 @@ module. * :mod:`pyexpat`: An interface to the Expat XML parser. (Contributed by Paul Prescod.) -* :mod:`robotparser`: Parse a :file:`robots.txt` file, which is used for writing +* :mod:`robotparser `: Parse a :file:`robots.txt` file, which is used for writing web spiders that politely avoid certain areas of a web site. The parser accepts the contents of a :file:`robots.txt` file, builds a set of rules from it, and can then answer questions about the fetchability of a given URL. (Contributed @@ -1129,10 +1129,10 @@ module. :file:`Tools/idle/BrowserControl.py`, and adapted for the standard library by Fred.) -* :mod:`_winreg`: An interface to the Windows registry. :mod:`_winreg` is an +* :mod:`_winreg `: An interface to the Windows registry. :mod:`!_winreg` is an adaptation of functions that have been part of PythonWin since 1995, but has now been added to the core distribution, and enhanced to support Unicode. - :mod:`_winreg` was written by Bill Tutt and Mark Hammond. + :mod:`!_winreg` was written by Bill Tutt and Mark Hammond. * :mod:`zipfile`: A module for reading and writing ZIP-format archives. These are archives produced by :program:`PKZIP` on DOS/Windows or :program:`zip` on diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 968bd7a126bdf0..e6c13f957b8d54 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -55,7 +55,7 @@ implemented in C. In particular, it's not possible to subclass built-in types, so you can't just subclass, say, lists in order to add a single useful method to them. The :mod:`!UserList` module provides a class that supports all of the methods of lists and that can be subclassed further, but there's lots of C code -that expects a regular Python list and won't accept a :class:`!UserList` +that expects a regular Python list and won't accept a :class:`~collections.UserList` instance. Python 2.2 fixes this, and in the process adds some exciting new capabilities. @@ -69,7 +69,7 @@ A brief summary: * It's also possible to automatically call methods on accessing or setting an instance attribute by using a new mechanism called :dfn:`properties`. Many uses - of :meth:`!__getattr__` can be rewritten to use properties instead, making the + of :meth:`~object.__getattr__` can be rewritten to use properties instead, making the resulting code simpler and faster. As a small side benefit, attributes can now have docstrings, too. @@ -933,7 +933,7 @@ anyway). New and Improved Modules ======================== -* The :mod:`!xmlrpclib` module was contributed to the standard library by Fredrik +* The :mod:`xmlrpclib ` module was contributed to the standard library by Fredrik Lundh, providing support for writing XML-RPC clients. XML-RPC is a simple remote procedure call protocol built on top of HTTP and XML. For example, the following snippet retrieves a list of RSS channels from the O'Reilly Network, @@ -956,7 +956,7 @@ New and Improved Modules # 'description': 'A utility which converts HTML to XSL FO.', # 'title': 'html2fo 0.3 (Default)'}, ... ] - The :mod:`!SimpleXMLRPCServer` module makes it easy to create straightforward + The :mod:`SimpleXMLRPCServer ` module makes it easy to create straightforward XML-RPC servers. See http://xmlrpc.scripting.com/ for more information about XML-RPC. * The new :mod:`hmac` module implements the HMAC algorithm described by @@ -964,7 +964,7 @@ New and Improved Modules * Several functions that originally returned lengthy tuples now return pseudo-sequences that still behave like tuples but also have mnemonic attributes such - as :attr:`!memberst_mtime` or :attr:`!tm_year`. The enhanced functions include + as :attr:`!memberst_mtime` or :attr:`~time.struct_time.tm_year`. The enhanced functions include :func:`~os.stat`, :func:`~os.fstat`, :func:`~os.statvfs`, and :func:`~os.fstatvfs` in the :mod:`os` module, and :func:`~time.localtime`, :func:`~time.gmtime`, and :func:`~time.strptime` in the :mod:`time` module. diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 15d4003622c506..7e235d4370edaa 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -1081,7 +1081,7 @@ complete list of changes, or look through the CVS logs for all the details. :func:`nsmallest` that use heaps to find the N largest or smallest values in a dataset without the expense of a full sort. (Contributed by Raymond Hettinger.) -* The :mod:`httplib` module now contains constants for HTTP status codes defined +* The :mod:`httplib ` module now contains constants for HTTP status codes defined in various HTTP-related RFC documents. Constants have names such as :const:`OK`, :const:`CREATED`, :const:`CONTINUE`, and :const:`MOVED_PERMANENTLY`; use pydoc to get a full list. (Contributed by @@ -1218,10 +1218,10 @@ complete list of changes, or look through the CVS logs for all the details. now include the string ``'%default'``, which will be replaced by the option's default value. (Contributed by Greg Ward.) -* The long-term plan is to deprecate the :mod:`rfc822` module in some future +* The long-term plan is to deprecate the :mod:`!rfc822` module in some future Python release in favor of the :mod:`email` package. To this end, the - :func:`email.Utils.formatdate` function has been changed to make it usable as a - replacement for :func:`rfc822.formatdate`. You may want to write new e-mail + :func:`email.Utils.formatdate ` function has been changed to make it usable as a + replacement for :func:`!rfc822.formatdate`. You may want to write new e-mail processing code with this in mind. (Change implemented by Anthony Baxter.) * A new ``urandom(n)`` function was added to the :mod:`os` module, returning @@ -1308,7 +1308,7 @@ complete list of changes, or look through the CVS logs for all the details. sockets, and regular expression pattern objects. (Contributed by Raymond Hettinger.) -* The :mod:`xmlrpclib` module now supports a multi-call extension for +* The :mod:`xmlrpclib ` module now supports a multi-call extension for transmitting multiple XML-RPC calls in a single HTTP operation. (Contributed by Brian Quinlan.) @@ -1323,8 +1323,8 @@ complete list of changes, or look through the CVS logs for all the details. cookielib --------- -The :mod:`cookielib` library supports client-side handling for HTTP cookies, -mirroring the :mod:`Cookie` module's server-side cookie support. Cookies are +The :mod:`cookielib ` library supports client-side handling for HTTP cookies, +mirroring the :mod:`Cookie ` module's server-side cookie support. Cookies are stored in cookie jars; the library transparently stores cookies offered by the web server in the cookie jar, and fetches the cookie from the jar when connecting to the server. As in web browsers, policy objects control whether @@ -1335,7 +1335,7 @@ are provided: one that stores cookies in the Netscape format so applications can use the Mozilla or Lynx cookie files, and one that stores cookies in the same format as the Perl libwww library. -:mod:`urllib2` has been changed to interact with :mod:`cookielib`: +:mod:`urllib2 ` has been changed to interact with :mod:`cookielib `: :class:`HTTPCookieProcessor` manages a cookie jar that is used when accessing URLs. diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index f45d70ea5a19a0..2ae26e7a106a0b 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1478,8 +1478,8 @@ complete list of changes, or look through the SVN logs for all the details. .. Patch 790710 -* The :mod:`pickle` and :mod:`cPickle` modules no longer accept a return value - of ``None`` from the :meth:`__reduce__` method; the method must return a tuple +* The :mod:`pickle` and :mod:`!cPickle` modules no longer accept a return value + of ``None`` from the :meth:`~object.__reduce__` method; the method must return a tuple of arguments instead. The ability to return ``None`` was deprecated in Python 2.4, so this completes the removal of the feature. @@ -1519,7 +1519,7 @@ complete list of changes, or look through the SVN logs for all the details. .. Patch #1472854 -* The :mod:`SimpleXMLRPCServer` and :mod:`DocXMLRPCServer` classes now have a +* The :mod:`SimpleXMLRPCServer ` and :mod:`DocXMLRPCServer ` classes now have a :attr:`rpc_paths` attribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only ``'/'`` and ``'/RPC2'``. Setting :attr:`rpc_paths` to ``None`` or an empty tuple disables this path checking. @@ -1650,9 +1650,9 @@ complete list of changes, or look through the SVN logs for all the details. .. Patch #754022 -* The :mod:`xmlrpclib` module now supports returning :class:`~datetime.datetime` objects - for the XML-RPC date type. Supply ``use_datetime=True`` to the :func:`loads` - function or the :class:`Unmarshaller` class to enable this feature. (Contributed +* The :mod:`xmlrpclib ` module now supports returning :class:`~datetime.datetime` objects + for the XML-RPC date type. Supply ``use_datetime=True`` to the :func:`~xmlrpc.client.loads` + function or the :class:`!Unmarshaller` class to enable this feature. (Contributed by Skip Montanaro.) .. Patch 1120353 @@ -2253,12 +2253,12 @@ code: appeared. In Python 2.5, the argument must be exactly one %char specifier with no surrounding text. -* Library: The :mod:`pickle` and :mod:`cPickle` modules no longer accept a - return value of ``None`` from the :meth:`__reduce__` method; the method must +* Library: The :mod:`pickle` and :mod:`!cPickle` modules no longer accept a + return value of ``None`` from the :meth:`~object.__reduce__` method; the method must return a tuple of arguments instead. The modules also no longer accept the deprecated *bin* keyword parameter. -* Library: The :mod:`SimpleXMLRPCServer` and :mod:`DocXMLRPCServer` classes now +* Library: The :mod:`SimpleXMLRPCServer ` and :mod:`DocXMLRPCServer ` classes now have a :attr:`rpc_paths` attribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only ``'/'`` and ``'/RPC2'``. Setting :attr:`rpc_paths` to ``None`` or an empty tuple disables this path diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index c6bab93b7efdda..7d3769a22286e2 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -1082,7 +1082,7 @@ the :mod:`io` module: (In Python 2.6, :class:`io.StringIO` is implemented in pure Python, so it's pretty slow. You should therefore stick with the - existing :mod:`StringIO` module or :mod:`cStringIO` for now. At some + existing :mod:`!StringIO` module or :mod:`!cStringIO` for now. At some point Python 3.0's :mod:`io` module will be rewritten into C for speed, and perhaps the C implementation will be backported to the 2.x releases.) @@ -1807,7 +1807,7 @@ changes, or look through the Subversion logs for all the details. Nubis; :issue:`1817`.) The :func:`parse_qs` and :func:`parse_qsl` functions have been - relocated from the :mod:`!cgi` module to the :mod:`urlparse` module. + relocated from the :mod:`!cgi` module to the :mod:`urlparse ` module. The versions still available in the :mod:`!cgi` module will trigger :exc:`PendingDeprecationWarning` messages in 2.6 (:issue:`600362`). @@ -1895,8 +1895,8 @@ changes, or look through the Subversion logs for all the details. (Contributed by Raymond Hettinger.) -* The :mod:`Cookie` module's :class:`Morsel` objects now support an - :attr:`httponly` attribute. In some browsers. cookies with this attribute +* The :mod:`Cookie ` module's :class:`~http.cookies.Morsel` objects now support an + :attr:`~http.cookies.Morsel.httponly` attribute. In some browsers. cookies with this attribute set cannot be accessed or manipulated by JavaScript code. (Contributed by Arvin Schnell; :issue:`1638033`.) @@ -1987,8 +1987,8 @@ changes, or look through the Subversion logs for all the details. (Contributed by Raymond Hettinger.) * An optional ``timeout`` parameter, specifying a timeout measured in - seconds, was added to the :class:`httplib.HTTPConnection` and - :class:`HTTPSConnection` class constructors. (Added by Facundo + seconds, was added to the :class:`httplib.HTTPConnection ` and + :class:`HTTPSConnection ` class constructors. (Added by Facundo Batista.) * Most of the :mod:`inspect` module's functions, such as @@ -2371,10 +2371,10 @@ changes, or look through the Subversion logs for all the details. ``socket(socket.AF_INET, ...)`` may be all that's required to make your code work with IPv6. -* The base classes in the :mod:`SocketServer` module now support - calling a :meth:`handle_timeout` method after a span of inactivity - specified by the server's :attr:`timeout` attribute. (Contributed - by Michael Pomraning.) The :meth:`serve_forever` method +* The base classes in the :mod:`SocketServer ` module now support + calling a :meth:`~socketserver.BaseServer.handle_timeout` method after a span of inactivity + specified by the server's :attr:`~socketserver.BaseServer.timeout` attribute. (Contributed + by Michael Pomraning.) The :meth:`~socketserver.BaseServer.serve_forever` method now takes an optional poll interval measured in seconds, controlling how often the server will check for a shutdown request. (Contributed by Pedro Werneck and Jeffrey Yasskin; @@ -2478,9 +2478,9 @@ changes, or look through the Subversion logs for all the details. ``with tempfile.NamedTemporaryFile() as tmp: ...``. (Contributed by Alexander Belopolsky; :issue:`2021`.) -* The :mod:`test.test_support` module gained a number +* The :mod:`test.test_support ` module gained a number of context managers useful for writing tests. - :func:`EnvironmentVarGuard` is a + :func:`~test.support.os_helper.EnvironmentVarGuard` is a context manager that temporarily changes environment variables and automatically restores them to their old values. @@ -2577,9 +2577,9 @@ changes, or look through the Subversion logs for all the details. (:issue:`1513695`) * An optional ``timeout`` parameter was added to the - :func:`urllib.urlopen` function and the + :func:`urllib.urlopen ` function and the :class:`urllib.ftpwrapper` class constructor, as well as the - :func:`urllib2.urlopen` function. The parameter specifies a timeout + :func:`urllib2.urlopen ` function. The parameter specifies a timeout measured in seconds. For example:: >>> u = urllib2.urlopen("http://slow.example.com", @@ -2604,7 +2604,7 @@ changes, or look through the Subversion logs for all the details. intended for testing purposes that lets you temporarily modify the warning filters and then restore their original values (:issue:`3781`). -* The XML-RPC :class:`SimpleXMLRPCServer` and :class:`DocXMLRPCServer` +* The XML-RPC :class:`SimpleXMLRPCServer ` and :class:`DocXMLRPCServer ` classes can now be prevented from immediately opening and binding to their socket by passing ``False`` as the *bind_and_activate* constructor parameter. This can be used to modify the instance's @@ -2621,11 +2621,11 @@ changes, or look through the Subversion logs for all the details. information. (Contributed by Alan McIntyre as part of his project for Google's Summer of Code 2007.) -* The :mod:`xmlrpclib` module no longer automatically converts +* The :mod:`xmlrpclib ` module no longer automatically converts :class:`datetime.date` and :class:`datetime.time` to the - :class:`xmlrpclib.DateTime` type; the conversion semantics were + :class:`xmlrpclib.DateTime ` type; the conversion semantics were not necessarily correct for all applications. Code using - :mod:`xmlrpclib` should convert :class:`date` and :class:`~datetime.time` + :mod:`!xmlrpclib` should convert :class:`date` and :class:`~datetime.time` instances. (:issue:`1330538`) The code can also handle dates before 1900 (contributed by Ralf Schmitt; :issue:`2014`) and 64-bit integers represented by using ```` in XML-RPC responses @@ -3274,11 +3274,11 @@ that may require changes to your code: :exc:`StandardError` but now it is, through :exc:`IOError`. (Implemented by Gregory P. Smith; :issue:`1706815`.) -* The :mod:`xmlrpclib` module no longer automatically converts +* The :mod:`xmlrpclib ` module no longer automatically converts :class:`datetime.date` and :class:`datetime.time` to the - :class:`xmlrpclib.DateTime` type; the conversion semantics were + :class:`xmlrpclib.DateTime ` type; the conversion semantics were not necessarily correct for all applications. Code using - :mod:`xmlrpclib` should convert :class:`date` and :class:`~datetime.time` + :mod:`!xmlrpclib` should convert :class:`date` and :class:`~datetime.time` instances. (:issue:`1330538`) * (3.0-warning mode) The :class:`Exception` class now warns diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index 524967b4524234..ada05aa22b46f6 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -915,7 +915,7 @@ used with the :option:`-W` switch, separated by commas. (Contributed by Brian Curtin; :issue:`7301`.) For example, the following setting will print warnings every time -they occur, but turn warnings from the :mod:`Cookie` module into an +they occur, but turn warnings from the :mod:`Cookie ` module into an error. (The exact syntax for setting an environment variable varies across operating systems and shells.) @@ -1012,12 +1012,12 @@ Several performance enhancements have been added: scan. This is sometimes faster by a factor of 10. (Added by Florent Xicluna; :issue:`7462` and :issue:`7622`.) -* The :mod:`pickle` and :mod:`cPickle` modules now automatically +* The :mod:`pickle` and :mod:`!cPickle` modules now automatically intern the strings used for attribute names, reducing memory usage of the objects resulting from unpickling. (Contributed by Jake McGuire; :issue:`5084`.) -* The :mod:`cPickle` module now special-cases dictionaries, +* The :mod:`!cPickle` module now special-cases dictionaries, nearly halving the time required to pickle them. (Contributed by Collin Winter; :issue:`5670`.) @@ -1163,7 +1163,7 @@ changes, or look through the Subversion logs for all the details. statement, has been deprecated, because the :keyword:`!with` statement now supports multiple context managers. -* The :mod:`cookielib` module now ignores cookies that have an invalid +* The :mod:`cookielib ` module now ignores cookies that have an invalid version field, one that doesn't contain an integer value. (Fixed by John J. Lee; :issue:`3924`.) @@ -1306,11 +1306,11 @@ changes, or look through the Subversion logs for all the details. ``('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')``. (Contributed by Carl Chenet; :issue:`7418`.) -* The default :class:`~httplib.HTTPResponse` class used by the :mod:`httplib` module now +* The default :class:`~http.client.HTTPResponse` class used by the :mod:`httplib ` module now supports buffering, resulting in much faster reading of HTTP responses. (Contributed by Kristján Valur Jónsson; :issue:`4879`.) - The :class:`~httplib.HTTPConnection` and :class:`~httplib.HTTPSConnection` classes + The :class:`~http.client.HTTPConnection` and :class:`~http.client.HTTPSConnection` classes now support a *source_address* parameter, a ``(host, port)`` 2-tuple giving the source address that will be used for the connection. (Contributed by Eldon Ziegler; :issue:`3972`.) @@ -1518,16 +1518,16 @@ changes, or look through the Subversion logs for all the details. the :class:`bytearray` and :class:`memoryview` objects. (Implemented by Antoine Pitrou; :issue:`8104`.) -* The :mod:`SocketServer` module's :class:`~SocketServer.TCPServer` class now +* The :mod:`SocketServer ` module's :class:`~socketserver.TCPServer` class now supports socket timeouts and disabling the Nagle algorithm. - The :attr:`~SocketServer.TCPServer.disable_nagle_algorithm` class attribute + The :attr:`!disable_nagle_algorithm` class attribute defaults to ``False``; if overridden to be true, new request connections will have the TCP_NODELAY option set to prevent buffering many small sends into a single TCP packet. - The :attr:`~SocketServer.BaseServer.timeout` class attribute can hold + The :attr:`~socketserver.BaseServer.timeout` class attribute can hold a timeout in seconds that will be applied to the request socket; if - no request is received within that time, :meth:`~SocketServer.BaseServer.handle_timeout` - will be called and :meth:`~SocketServer.BaseServer.handle_request` will return. + no request is received within that time, :meth:`~socketserver.BaseServer.handle_timeout` + will be called and :meth:`~socketserver.BaseServer.handle_request` will return. (Contributed by Kristján Valur Jónsson; :issue:`6192` and :issue:`6267`.) * Updated module: the :mod:`sqlite3` module has been updated to @@ -1648,7 +1648,7 @@ changes, or look through the Subversion logs for all the details. and has been updated to version 5.2.0 (updated by Florent Xicluna; :issue:`8024`). -* The :mod:`urlparse` module's :func:`~urlparse.urlsplit` now handles +* The :mod:`urlparse ` module's :func:`~urllib.parse.urlsplit` now handles unknown URL schemes in a fashion compliant with :rfc:`3986`: if the URL is of the form ``"://..."``, the text before the ``://`` is treated as the scheme, even if it's a made-up scheme that @@ -1675,7 +1675,7 @@ changes, or look through the Subversion logs for all the details. (Python 2.7 actually produces slightly different output, since it returns a named tuple instead of a standard tuple.) - The :mod:`urlparse` module also supports IPv6 literal addresses as defined by + The :mod:`urlparse ` module also supports IPv6 literal addresses as defined by :rfc:`2732` (contributed by Senthil Kumaran; :issue:`2987`). .. doctest:: @@ -1697,8 +1697,8 @@ changes, or look through the Subversion logs for all the details. or comment (which looks like ````). (Patch by Neil Muller; :issue:`2746`.) -* The XML-RPC client and server, provided by the :mod:`xmlrpclib` and - :mod:`SimpleXMLRPCServer` modules, have improved performance by +* The XML-RPC client and server, provided by the :mod:`xmlrpclib ` and + :mod:`SimpleXMLRPCServer ` modules, have improved performance by supporting HTTP/1.1 keep-alive and by optionally using gzip encoding to compress the XML being exchanged. The gzip compression is controlled by the :attr:`encode_threshold` attribute of @@ -2334,11 +2334,11 @@ Port-Specific Changes: Windows and :data:`LIBRARIES_ASSEMBLY_NAME_PREFIX`. (Contributed by David Cournapeau; :issue:`4365`.) -* The :mod:`_winreg` module for accessing the registry now implements - the :func:`~_winreg.CreateKeyEx` and :func:`~_winreg.DeleteKeyEx` +* The :mod:`_winreg ` module for accessing the registry now implements + the :func:`~winreg.CreateKeyEx` and :func:`~winreg.DeleteKeyEx` functions, extended versions of previously supported functions that - take several extra arguments. The :func:`~_winreg.DisableReflectionKey`, - :func:`~_winreg.EnableReflectionKey`, and :func:`~_winreg.QueryReflectionKey` + take several extra arguments. The :func:`~winreg.DisableReflectionKey`, + :func:`~winreg.EnableReflectionKey`, and :func:`~winreg.QueryReflectionKey` were also tested and documented. (Implemented by Brian Curtin: :issue:`7347`.) @@ -2508,7 +2508,7 @@ In the standard library: which raises an exception if there's an error. (Changed by Lars Gustäbel; :issue:`7357`.) -* The :mod:`urlparse` module's :func:`~urlparse.urlsplit` now handles +* The :mod:`urlparse ` module's :func:`~urllib.parse.urlsplit` now handles unknown URL schemes in a fashion compliant with :rfc:`3986`: if the URL is of the form ``"://..."``, the text before the ``://`` is treated as the scheme, even if it's a made-up scheme that @@ -2711,8 +2711,8 @@ and :ref:`setuptools-index`. PEP 476: Enabling certificate verification by default for stdlib http clients ----------------------------------------------------------------------------- -:pep:`476` updated :mod:`httplib` and modules which use it, such as -:mod:`urllib2` and :mod:`xmlrpclib`, to now verify that the server +:pep:`476` updated :mod:`httplib ` and modules which use it, such as +:mod:`urllib2 ` and :mod:`xmlrpclib`, to now verify that the server presents a certificate which is signed by a Certificate Authority in the platform trust store and whose hostname matches the hostname being requested by default, significantly improving security for many applications. This diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 1df5209f22c6a5..888e6279754fc2 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -337,7 +337,7 @@ changed. (However, the standard library remains ASCII-only with the exception of contributor names in comments.) -* The :mod:`StringIO` and :mod:`cStringIO` modules are gone. Instead, +* The :mod:`!StringIO` and :mod:`!cStringIO` modules are gone. Instead, import the :mod:`io` module and use :class:`io.StringIO` or :class:`io.BytesIO` for text and data respectively. @@ -563,7 +563,7 @@ review: removal in Python 3.0 due to lack of use or because a better replacement exists. See :pep:`3108` for an exhaustive list. -* The :mod:`bsddb3` package was removed because its presence in the +* The :mod:`!bsddb3` package was removed because its presence in the core standard library has proved over time to be a particular burden for the core developers due to testing instability and Berkeley DB's release schedule. However, the package is alive and well, @@ -588,40 +588,40 @@ review: * A common pattern in Python 2.x is to have one version of a module implemented in pure Python, with an optional accelerated version implemented as a C extension; for example, :mod:`pickle` and - :mod:`cPickle`. This places the burden of importing the accelerated + :mod:`!cPickle`. This places the burden of importing the accelerated version and falling back on the pure Python version on each user of these modules. In Python 3.0, the accelerated versions are considered implementation details of the pure Python versions. Users should always import the standard version, which attempts to import the accelerated version and falls back to the pure Python - version. The :mod:`pickle` / :mod:`cPickle` pair received this + version. The :mod:`pickle` / :mod:`!cPickle` pair received this treatment. The :mod:`profile` module is on the list for 3.1. The - :mod:`StringIO` module has been turned into a class in the :mod:`io` + :mod:`!StringIO` module has been turned into a class in the :mod:`io` module. * Some related modules have been grouped into packages, and usually the submodule names have been simplified. The resulting new packages are: - * :mod:`dbm` (:mod:`anydbm`, :mod:`dbhash`, :mod:`dbm`, - :mod:`dumbdbm`, :mod:`gdbm`, :mod:`whichdb`). + * :mod:`dbm` (:mod:`!anydbm`, :mod:`!dbhash`, :mod:`!dbm`, + :mod:`!dumbdbm`, :mod:`!gdbm`, :mod:`!whichdb`). - * :mod:`html` (:mod:`HTMLParser`, :mod:`htmlentitydefs`). + * :mod:`html` (:mod:`!HTMLParser`, :mod:`!htmlentitydefs`). - * :mod:`http` (:mod:`httplib`, :mod:`BaseHTTPServer`, - :mod:`CGIHTTPServer`, :mod:`SimpleHTTPServer`, :mod:`Cookie`, - :mod:`cookielib`). + * :mod:`http` (:mod:`!httplib`, :mod:`!BaseHTTPServer`, + :mod:`!CGIHTTPServer`, :mod:`!SimpleHTTPServer`, :mod:`!Cookie`, + :mod:`!cookielib`). * :mod:`tkinter` (all :mod:`Tkinter`-related modules except :mod:`turtle`). The target audience of :mod:`turtle` doesn't really care about :mod:`tkinter`. Also note that as of Python 2.6, the functionality of :mod:`turtle` has been greatly enhanced. - * :mod:`urllib` (:mod:`urllib`, :mod:`urllib2`, :mod:`urlparse`, - :mod:`robotparse`). + * :mod:`urllib` (:mod:`!urllib`, :mod:`!urllib2`, :mod:`!urlparse`, + :mod:`!robotparse`). - * :mod:`xmlrpc` (:mod:`xmlrpclib`, :mod:`DocXMLRPCServer`, - :mod:`SimpleXMLRPCServer`). + * :mod:`xmlrpc` (:mod:`!xmlrpclib`, :mod:`!DocXMLRPCServer`, + :mod:`!SimpleXMLRPCServer`). Some other changes to standard library modules, not covered by :pep:`3108`: @@ -642,9 +642,9 @@ Some other changes to standard library modules, not covered by * Cleanup of the :mod:`operator` module: removed :func:`sequenceIncludes` and :func:`isCallable`. -* Cleanup of the :mod:`thread` module: :func:`acquire_lock` and - :func:`release_lock` are gone; use :func:`acquire` and - :func:`release` instead. +* Cleanup of the :mod:`!thread` module: :func:`!acquire_lock` and + :func:`!release_lock` are gone; use :meth:`~threading.Lock.acquire` and + :meth:`~threading.Lock.release` instead. * Cleanup of the :mod:`random` module: removed the :func:`jumpahead` API. diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 1c7a9270af0aab..5c2ec230441b42 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2418,7 +2418,7 @@ Changes in the Python API (Contributed by Victor Stinner in :issue:`21205`.) * The deprecated "strict" mode and argument of :class:`~html.parser.HTMLParser`, - :meth:`HTMLParser.error`, and the :exc:`HTMLParserError` exception have been + :meth:`!HTMLParser.error`, and the :exc:`!HTMLParserError` exception have been removed. (Contributed by Ezio Melotti in :issue:`15114`.) The *convert_charrefs* argument of :class:`~html.parser.HTMLParser` is now ``True`` by default. (Contributed by Berker Peksag in :issue:`21047`.) From ec69e1d0ddc9906e0fb755a5234aeabdc96450ab Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Sun, 4 Feb 2024 08:24:24 -0600 Subject: [PATCH 36/62] gh-101100: Fix dangling references in pickle.rst (#114972) Co-authored-by: Alex Waygood --- Doc/library/pickle.rst | 51 +++++++++++++++++++++--------------------- Doc/tools/.nitignore | 1 - 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 1b718abfa481a0..acada092afb679 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -356,7 +356,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`, :func:`copyreg.pickle`. It is a mapping whose keys are classes and whose values are reduction functions. A reduction function takes a single argument of the associated class and should - conform to the same interface as a :meth:`__reduce__` + conform to the same interface as a :meth:`~object.__reduce__` method. By default, a pickler object will not have a @@ -376,7 +376,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`, Special reducer that can be defined in :class:`Pickler` subclasses. This method has priority over any reducer in the :attr:`dispatch_table`. It - should conform to the same interface as a :meth:`__reduce__` method, and + should conform to the same interface as a :meth:`~object.__reduce__` method, and can optionally return ``NotImplemented`` to fallback on :attr:`dispatch_table`-registered reducers to pickle ``obj``. @@ -516,7 +516,7 @@ The following types can be pickled: * classes accessible from the top level of a module; -* instances of such classes whose the result of calling :meth:`__getstate__` +* instances of such classes whose the result of calling :meth:`~object.__getstate__` is picklable (see section :ref:`pickle-inst` for details). Attempts to pickle unpicklable objects will raise the :exc:`PicklingError` @@ -552,7 +552,7 @@ purpose, so you can fix bugs in a class or add methods to the class and still load objects that were created with an earlier version of the class. If you plan to have long-lived objects that will see many versions of a class, it may be worthwhile to put a version number in the objects so that suitable -conversions can be made by the class's :meth:`__setstate__` method. +conversions can be made by the class's :meth:`~object.__setstate__` method. .. _pickle-inst: @@ -567,7 +567,7 @@ customize, and control how class instances are pickled and unpickled. In most cases, no additional code is needed to make instances picklable. By default, pickle will retrieve the class and the attributes of an instance via -introspection. When a class instance is unpickled, its :meth:`__init__` method +introspection. When a class instance is unpickled, its :meth:`~object.__init__` method is usually *not* invoked. The default behaviour first creates an uninitialized instance and then restores the saved attributes. The following code shows an implementation of this behaviour:: @@ -658,30 +658,30 @@ methods: Refer to the section :ref:`pickle-state` for more information about how to use -the methods :meth:`__getstate__` and :meth:`__setstate__`. +the methods :meth:`~object.__getstate__` and :meth:`~object.__setstate__`. .. note:: - At unpickling time, some methods like :meth:`__getattr__`, - :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the + At unpickling time, some methods like :meth:`~object.__getattr__`, + :meth:`~object.__getattribute__`, or :meth:`~object.__setattr__` may be called upon the instance. In case those methods rely on some internal invariant being - true, the type should implement :meth:`__new__` to establish such an - invariant, as :meth:`__init__` is not called when unpickling an + true, the type should implement :meth:`~object.__new__` to establish such an + invariant, as :meth:`~object.__init__` is not called when unpickling an instance. .. index:: pair: copy; protocol As we shall see, pickle does not use directly the methods described above. In fact, these methods are part of the copy protocol which implements the -:meth:`__reduce__` special method. The copy protocol provides a unified +:meth:`~object.__reduce__` special method. The copy protocol provides a unified interface for retrieving the data necessary for pickling and copying objects. [#]_ -Although powerful, implementing :meth:`__reduce__` directly in your classes is +Although powerful, implementing :meth:`~object.__reduce__` directly in your classes is error prone. For this reason, class designers should use the high-level -interface (i.e., :meth:`__getnewargs_ex__`, :meth:`__getstate__` and -:meth:`__setstate__`) whenever possible. We will show, however, cases where -using :meth:`__reduce__` is the only option or leads to more efficient pickling +interface (i.e., :meth:`~object.__getnewargs_ex__`, :meth:`~object.__getstate__` and +:meth:`~object.__setstate__`) whenever possible. We will show, however, cases where +using :meth:`!__reduce__` is the only option or leads to more efficient pickling or both. .. method:: object.__reduce__() @@ -716,8 +716,9 @@ or both. These items will be appended to the object either using ``obj.append(item)`` or, in batch, using ``obj.extend(list_of_items)``. This is primarily used for list subclasses, but may be used by other - classes as long as they have :meth:`append` and :meth:`extend` methods with - the appropriate signature. (Whether :meth:`append` or :meth:`extend` is + classes as long as they have + :ref:`append and extend methods ` with + the appropriate signature. (Whether :meth:`!append` or :meth:`!extend` is used depends on which pickle protocol version is used as well as the number of items to append, so both must be supported.) @@ -793,8 +794,8 @@ any other code which depends on pickling, then one can create a pickler with a private dispatch table. The global dispatch table managed by the :mod:`copyreg` module is -available as :data:`copyreg.dispatch_table`. Therefore, one may -choose to use a modified copy of :data:`copyreg.dispatch_table` as a +available as :data:`!copyreg.dispatch_table`. Therefore, one may +choose to use a modified copy of :data:`!copyreg.dispatch_table` as a private dispatch table. For example :: @@ -833,12 +834,12 @@ Handling Stateful Objects single: __setstate__() (copy protocol) Here's an example that shows how to modify pickling behavior for a class. -The :class:`TextReader` class opens a text file, and returns the line number and +The :class:`!TextReader` class below opens a text file, and returns the line number and line contents each time its :meth:`!readline` method is called. If a -:class:`TextReader` instance is pickled, all attributes *except* the file object +:class:`!TextReader` instance is pickled, all attributes *except* the file object member are saved. When the instance is unpickled, the file is reopened, and -reading resumes from the last location. The :meth:`__setstate__` and -:meth:`__getstate__` methods are used to implement this behavior. :: +reading resumes from the last location. The :meth:`!__setstate__` and +:meth:`!__getstate__` methods are used to implement this behavior. :: class TextReader: """Print and number lines in a text file.""" @@ -903,7 +904,7 @@ functions and classes. For those cases, it is possible to subclass from the :class:`Pickler` class and implement a :meth:`~Pickler.reducer_override` method. This method can return an -arbitrary reduction tuple (see :meth:`__reduce__`). It can alternatively return +arbitrary reduction tuple (see :meth:`~object.__reduce__`). It can alternatively return ``NotImplemented`` to fallback to the traditional behavior. If both the :attr:`~Pickler.dispatch_table` and @@ -971,7 +972,7 @@ provided by pickle protocol 5 and higher. Provider API ^^^^^^^^^^^^ -The large data objects to be pickled must implement a :meth:`__reduce_ex__` +The large data objects to be pickled must implement a :meth:`~object.__reduce_ex__` method specialized for protocol 5 and higher, which returns a :class:`PickleBuffer` instance (instead of e.g. a :class:`bytes` object) for any large data. diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore index 7127f30f240ce7..f96478b45e44c0 100644 --- a/Doc/tools/.nitignore +++ b/Doc/tools/.nitignore @@ -46,7 +46,6 @@ Doc/library/mmap.rst Doc/library/multiprocessing.rst Doc/library/optparse.rst Doc/library/os.rst -Doc/library/pickle.rst Doc/library/pickletools.rst Doc/library/platform.rst Doc/library/plistlib.rst From ff7588b729a2a414ea189a2012904da3fbd1401c Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Sun, 4 Feb 2024 07:22:55 -0800 Subject: [PATCH 37/62] gh-114071: [Enum] update docs and code for tuples/subclasses (GH-114871) Update documentation with `__new__` and `__init__` entries. Support use of `auto()` in tuple subclasses on member assignment lines. Previously, auto() was only supported on the member definition line either solo or as part of a tuple: RED = auto() BLUE = auto(), 'azul' However, since Python itself supports using tuple subclasses where tuples are expected, e.g.: from collections import namedtuple T = namedtuple('T', 'first second third') def test(one, two, three): print(one, two, three) test(*T(4, 5, 6)) # 4 5 6 it made sense to also support tuple subclasses in enum definitions. --- Doc/library/enum.rst | 29 ++++++++++++++-- Lib/enum.py | 10 ++++-- Lib/test/test_enum.py | 34 +++++++++++++++++++ ...-02-01-10-19-11.gh-issue-114071.vkm2G_.rst | 1 + 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-02-01-10-19-11.gh-issue-114071.vkm2G_.rst diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 07b15e23b2c10a..f31e6ea848f3b2 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -337,6 +337,17 @@ Data Types >>> PowersOfThree.SECOND.value 9 + .. method:: Enum.__init__(self, \*args, \**kwds) + + By default, does nothing. If multiple values are given in the member + assignment, those values become separate arguments to ``__init__``; e.g. + + >>> from enum import Enum + >>> class Weekday(Enum): + ... MONDAY = 1, 'Mon' + + ``Weekday.__init__()`` would be called as ``Weekday.__init__(self, 1, 'Mon')`` + .. method:: Enum.__init_subclass__(cls, \**kwds) A *classmethod* that is used to further configure subsequent subclasses. @@ -364,6 +375,18 @@ Data Types >>> Build('deBUG') + .. method:: Enum.__new__(cls, \*args, \**kwds) + + By default, doesn't exist. If specified, either in the enum class + definition or in a mixin class (such as ``int``), all values given + in the member assignment will be passed; e.g. + + >>> from enum import Enum + >>> class MyIntEnum(Enum): + ... SEVENTEEN = '1a', 16 + + results in the call ``int('1a', 16)`` and a value of ``17`` for the member. + .. method:: Enum.__repr__(self) Returns the string used for *repr()* calls. By default, returns the @@ -477,9 +500,9 @@ Data Types .. class:: Flag - *Flag* members support the bitwise operators ``&`` (*AND*), ``|`` (*OR*), - ``^`` (*XOR*), and ``~`` (*INVERT*); the results of those operators are members - of the enumeration. + ``Flag`` is the same as :class:`Enum`, but its members support the bitwise + operators ``&`` (*AND*), ``|`` (*OR*), ``^`` (*XOR*), and ``~`` (*INVERT*); + the results of those operators are members of the enumeration. .. method:: __contains__(self, value) diff --git a/Lib/enum.py b/Lib/enum.py index a8a50a58380375..98a8966f5eb159 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -409,10 +409,11 @@ def __setitem__(self, key, value): if isinstance(value, auto): single = True value = (value, ) - if type(value) is tuple and any(isinstance(v, auto) for v in value): + if isinstance(value, tuple) and any(isinstance(v, auto) for v in value): # insist on an actual tuple, no subclasses, in keeping with only supporting # top-level auto() usage (not contained in any other data structure) auto_valued = [] + t = type(value) for v in value: if isinstance(v, auto): non_auto_store = False @@ -427,7 +428,12 @@ def __setitem__(self, key, value): if single: value = auto_valued[0] else: - value = tuple(auto_valued) + try: + # accepts iterable as multiple arguments? + value = t(auto_valued) + except TypeError: + # then pass them in singlely + value = t(*auto_valued) self._member_names[key] = None if non_auto_store: self._last_values.append(value) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index d045739efa46b8..39c1ae0ad5a078 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2344,6 +2344,40 @@ class SomeTuple(tuple, Enum): globals()['SomeTuple'] = SomeTuple test_pickle_dump_load(self.assertIs, SomeTuple.first) + def test_tuple_subclass_with_auto_1(self): + from collections import namedtuple + T = namedtuple('T', 'index desc') + class SomeEnum(T, Enum): + __qualname__ = 'SomeEnum' # needed for pickle protocol 4 + first = auto(), 'for the money' + second = auto(), 'for the show' + third = auto(), 'for the music' + self.assertIs(type(SomeEnum.first), SomeEnum) + self.assertEqual(SomeEnum.third.value, (3, 'for the music')) + self.assertIsInstance(SomeEnum.third.value, T) + self.assertEqual(SomeEnum.first.index, 1) + self.assertEqual(SomeEnum.second.desc, 'for the show') + globals()['SomeEnum'] = SomeEnum + globals()['T'] = T + test_pickle_dump_load(self.assertIs, SomeEnum.first) + + def test_tuple_subclass_with_auto_2(self): + from collections import namedtuple + T = namedtuple('T', 'index desc') + class SomeEnum(Enum): + __qualname__ = 'SomeEnum' # needed for pickle protocol 4 + first = T(auto(), 'for the money') + second = T(auto(), 'for the show') + third = T(auto(), 'for the music') + self.assertIs(type(SomeEnum.first), SomeEnum) + self.assertEqual(SomeEnum.third.value, (3, 'for the music')) + self.assertIsInstance(SomeEnum.third.value, T) + self.assertEqual(SomeEnum.first.value.index, 1) + self.assertEqual(SomeEnum.second.value.desc, 'for the show') + globals()['SomeEnum'] = SomeEnum + globals()['T'] = T + test_pickle_dump_load(self.assertIs, SomeEnum.first) + def test_duplicate_values_give_unique_enum_items(self): class AutoNumber(Enum): first = () diff --git a/Misc/NEWS.d/next/Library/2024-02-01-10-19-11.gh-issue-114071.vkm2G_.rst b/Misc/NEWS.d/next/Library/2024-02-01-10-19-11.gh-issue-114071.vkm2G_.rst new file mode 100644 index 00000000000000..587ce4d2157637 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-02-01-10-19-11.gh-issue-114071.vkm2G_.rst @@ -0,0 +1 @@ +Support tuple subclasses using auto() for enum member value. From fc060969117f5a5dc96c220eb91b1e2f863d71cf Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:23:26 +0200 Subject: [PATCH 38/62] gh-83383: Always mark the dbm.dumb database as unmodified after open() and sync() (GH-114560) The directory file for a newly created database is now created immediately after opening instead of deferring this until synchronizing or closing. --- Lib/dbm/dumb.py | 4 +- Lib/test/test_dbm_dumb.py | 72 +++++++++++++++++++ ...4-01-25-19-22-17.gh-issue-83383.3GwO9v.rst | 5 ++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-25-19-22-17.gh-issue-83383.3GwO9v.rst diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index 754624ccc8f500..def120ffc3778b 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -98,7 +98,8 @@ def _update(self, flag): except OSError: if flag not in ('c', 'n'): raise - self._modified = True + with self._io.open(self._dirfile, 'w', encoding="Latin-1") as f: + self._chmod(self._dirfile) else: with f: for line in f: @@ -134,6 +135,7 @@ def _commit(self): # position; UTF-8, though, does care sometimes. entry = "%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair) f.write(entry) + self._modified = False sync = _commit diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index a481175b3bfdbd..672f9092207cf6 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -246,9 +246,27 @@ def test_missing_data(self): _delete_files() with self.assertRaises(FileNotFoundError): dumbdbm.open(_fname, value) + self.assertFalse(os.path.exists(_fname + '.dat')) self.assertFalse(os.path.exists(_fname + '.dir')) self.assertFalse(os.path.exists(_fname + '.bak')) + for value in ('c', 'n'): + _delete_files() + with dumbdbm.open(_fname, value) as f: + self.assertTrue(os.path.exists(_fname + '.dat')) + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertFalse(os.path.exists(_fname + '.bak')) + + for value in ('c', 'n'): + _delete_files() + with dumbdbm.open(_fname, value) as f: + f['key'] = 'value' + self.assertTrue(os.path.exists(_fname + '.dat')) + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertTrue(os.path.exists(_fname + '.bak')) + def test_missing_index(self): with dumbdbm.open(_fname, 'n') as f: pass @@ -259,6 +277,60 @@ def test_missing_index(self): self.assertFalse(os.path.exists(_fname + '.dir')) self.assertFalse(os.path.exists(_fname + '.bak')) + for value in ('c', 'n'): + with dumbdbm.open(_fname, value) as f: + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertFalse(os.path.exists(_fname + '.bak')) + os.unlink(_fname + '.dir') + + for value in ('c', 'n'): + with dumbdbm.open(_fname, value) as f: + f['key'] = 'value' + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertTrue(os.path.exists(_fname + '.bak')) + os.unlink(_fname + '.dir') + os.unlink(_fname + '.bak') + + def test_sync_empty_unmodified(self): + with dumbdbm.open(_fname, 'n') as f: + pass + os.unlink(_fname + '.dir') + for value in ('c', 'n'): + with dumbdbm.open(_fname, value) as f: + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + f.sync() + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + os.unlink(_fname + '.dir') + f.sync() + self.assertFalse(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertFalse(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + + def test_sync_nonempty_unmodified(self): + with dumbdbm.open(_fname, 'n') as f: + pass + os.unlink(_fname + '.dir') + for value in ('c', 'n'): + with dumbdbm.open(_fname, value) as f: + f['key'] = 'value' + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + f.sync() + self.assertTrue(os.path.exists(_fname + '.dir')) + self.assertTrue(os.path.exists(_fname + '.bak')) + os.unlink(_fname + '.dir') + os.unlink(_fname + '.bak') + f.sync() + self.assertFalse(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + self.assertFalse(os.path.exists(_fname + '.dir')) + self.assertFalse(os.path.exists(_fname + '.bak')) + def test_invalid_flag(self): for flag in ('x', 'rf', None): with self.assertRaisesRegex(ValueError, diff --git a/Misc/NEWS.d/next/Library/2024-01-25-19-22-17.gh-issue-83383.3GwO9v.rst b/Misc/NEWS.d/next/Library/2024-01-25-19-22-17.gh-issue-83383.3GwO9v.rst new file mode 100644 index 00000000000000..e6336204dfa236 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-25-19-22-17.gh-issue-83383.3GwO9v.rst @@ -0,0 +1,5 @@ +Synchronization of the :mod:`dbm.dumb` database is now no-op if there was no +modification since opening or last synchronization. +The directory file for a newly created empty :mod:`dbm.dumb` database is now +created immediately after opening instead of deferring this until +synchronizing or closing. From ca715e56a13feabc15c368898df6511613d18987 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:25:21 +0200 Subject: [PATCH 39/62] gh-69893: Add the close() method for xml.etree.ElementTree.iterparse() iterator (GH-114534) --- Doc/library/xml.etree.elementtree.rst | 5 ++ Doc/whatsnew/3.13.rst | 8 ++ Lib/test/test_xml_etree.py | 85 ++++++++++++++++++- Lib/xml/etree/ElementTree.py | 9 +- ...4-01-24-17-25-18.gh-issue-69893.PQq5fR.rst | 2 + 5 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-24-17-25-18.gh-issue-69893.PQq5fR.rst diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index bb6773c361a9b4..75a7915c15240d 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -625,6 +625,8 @@ Functions target. Returns an :term:`iterator` providing ``(event, elem)`` pairs; it has a ``root`` attribute that references the root element of the resulting XML tree once *source* is fully read. + The iterator has the :meth:`!close` method that closes the internal + file object if *source* is a filename. Note that while :func:`iterparse` builds the tree incrementally, it issues blocking reads on *source* (or the file it names). As such, it's unsuitable @@ -647,6 +649,9 @@ Functions .. versionchanged:: 3.8 The ``comment`` and ``pi`` events were added. + .. versionchanged:: 3.13 + Added the :meth:`!close` method. + .. function:: parse(source, parser=None) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index f17c6ec0775bef..77f4fce6c321fe 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -472,6 +472,14 @@ warnings warning may also be emitted when a decorated function or class is used at runtime. See :pep:`702`. (Contributed by Jelle Zijlstra in :gh:`104003`.) +xml.etree.ElementTree +--------------------- + +* Add the :meth:`!close` method for the iterator returned by + :func:`~xml.etree.ElementTree.iterparse` for explicit cleaning up. + (Contributed by Serhiy Storchaka in :gh:`69893`.) + + Optimizations ============= diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 221545b315fa44..a435ec7822ea0c 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -555,6 +555,17 @@ def test_iterparse(self): ('end', '{namespace}root'), ]) + with open(SIMPLE_XMLFILE, 'rb') as source: + context = iterparse(source) + action, elem = next(context) + self.assertEqual((action, elem.tag), ('end', 'element')) + self.assertEqual([(action, elem.tag) for action, elem in context], [ + ('end', 'element'), + ('end', 'empty-element'), + ('end', 'root'), + ]) + self.assertEqual(context.root.tag, 'root') + events = () context = iterparse(SIMPLE_XMLFILE, events) self.assertEqual([(action, elem.tag) for action, elem in context], []) @@ -646,12 +657,81 @@ def test_iterparse(self): # Not exhausting the iterator still closes the resource (bpo-43292) with warnings_helper.check_no_resource_warning(self): - it = iterparse(TESTFN) + it = iterparse(SIMPLE_XMLFILE) del it + with warnings_helper.check_no_resource_warning(self): + it = iterparse(SIMPLE_XMLFILE) + it.close() + del it + + with warnings_helper.check_no_resource_warning(self): + it = iterparse(SIMPLE_XMLFILE) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'element')) + del it, elem + + with warnings_helper.check_no_resource_warning(self): + it = iterparse(SIMPLE_XMLFILE) + action, elem = next(it) + it.close() + self.assertEqual((action, elem.tag), ('end', 'element')) + del it, elem + with self.assertRaises(FileNotFoundError): iterparse("nonexistent") + def test_iterparse_close(self): + iterparse = ET.iterparse + + it = iterparse(SIMPLE_XMLFILE) + it.close() + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + + with open(SIMPLE_XMLFILE, 'rb') as source: + it = iterparse(source) + it.close() + self.assertFalse(source.closed) + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + + it = iterparse(SIMPLE_XMLFILE) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'element')) + it.close() + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + + with open(SIMPLE_XMLFILE, 'rb') as source: + it = iterparse(source) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'element')) + it.close() + self.assertFalse(source.closed) + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + + it = iterparse(SIMPLE_XMLFILE) + list(it) + it.close() + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + + with open(SIMPLE_XMLFILE, 'rb') as source: + it = iterparse(source) + list(it) + it.close() + self.assertFalse(source.closed) + with self.assertRaises(StopIteration): + next(it) + it.close() # idempotent + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" @@ -3044,8 +3124,7 @@ def test_basic(self): # With an explicit parser too (issue #9708) sourcefile = serialize(doc, to_string=False) parser = ET.XMLParser(target=ET.TreeBuilder()) - self.assertEqual(next(ET.iterparse(sourcefile, parser=parser))[0], - 'end') + self.assertEqual(next(ET.iterparse(sourcefile, parser=parser))[0], 'end') tree = ET.ElementTree(None) self.assertRaises(AttributeError, tree.iter) diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index bb7362d1634a72..a37fead41b750e 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1248,10 +1248,17 @@ def iterator(source): if close_source: source.close() + gen = iterator(source) class IterParseIterator(collections.abc.Iterator): - __next__ = iterator(source).__next__ + __next__ = gen.__next__ + def close(self): + if close_source: + source.close() + gen.close() def __del__(self): + # TODO: Emit a ResourceWarning if it was not explicitly closed. + # (When the close() method will be supported in all maintained Python versions.) if close_source: source.close() diff --git a/Misc/NEWS.d/next/Library/2024-01-24-17-25-18.gh-issue-69893.PQq5fR.rst b/Misc/NEWS.d/next/Library/2024-01-24-17-25-18.gh-issue-69893.PQq5fR.rst new file mode 100644 index 00000000000000..1ebf434c33187b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-24-17-25-18.gh-issue-69893.PQq5fR.rst @@ -0,0 +1,2 @@ +Add the :meth:`!close` method for the iterator returned by +:func:`xml.etree.ElementTree.iterparse`. From ecabff98c41453f15ecd26ac255d531b571b9bc1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:27:42 +0200 Subject: [PATCH 40/62] gh-113267: Revert "gh-106584: Fix exit code for unittest in Python 3.12 (#106588)" (GH-114470) This reverts commit 8fc071345b50dd3de61ebeeaa287ccef21d061b2. --- Lib/test/test_unittest/test_discovery.py | 2 +- Lib/test/test_unittest/test_skipping.py | 12 ++++++------ Lib/unittest/case.py | 4 +--- Lib/unittest/result.py | 10 ++++------ .../2024-01-23-11-04-21.gh-issue-113267.xe_Pxe.rst | 2 ++ 5 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-23-11-04-21.gh-issue-113267.xe_Pxe.rst diff --git a/Lib/test/test_unittest/test_discovery.py b/Lib/test/test_unittest/test_discovery.py index dcb72d73efceab..004898ed431834 100644 --- a/Lib/test/test_unittest/test_discovery.py +++ b/Lib/test/test_unittest/test_discovery.py @@ -571,7 +571,7 @@ def _get_module_from_name(name): result = unittest.TestResult() suite.run(result) self.assertEqual(len(result.skipped), 1) - self.assertEqual(result.testsRun, 0) + self.assertEqual(result.testsRun, 1) self.assertEqual(import_calls, ['my_package']) # Check picklability diff --git a/Lib/test/test_unittest/test_skipping.py b/Lib/test/test_unittest/test_skipping.py index 1a6af06d32b433..f146dcac18ecc0 100644 --- a/Lib/test/test_unittest/test_skipping.py +++ b/Lib/test/test_unittest/test_skipping.py @@ -103,16 +103,16 @@ def test_dont_skip(self): pass result = LoggingResult(events) self.assertIs(suite.run(result), result) self.assertEqual(len(result.skipped), 1) - expected = ['addSkip', 'stopTest', 'startTest', - 'addSuccess', 'stopTest'] + expected = ['startTest', 'addSkip', 'stopTest', + 'startTest', 'addSuccess', 'stopTest'] self.assertEqual(events, expected) - self.assertEqual(result.testsRun, 1) + self.assertEqual(result.testsRun, 2) self.assertEqual(result.skipped, [(test_do_skip, "testing")]) self.assertTrue(result.wasSuccessful()) events = [] result = test_do_skip.run() - self.assertEqual(events, ['startTestRun', 'addSkip', + self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', 'stopTest', 'stopTestRun']) self.assertEqual(result.skipped, [(test_do_skip, "testing")]) @@ -135,13 +135,13 @@ def test_1(self): test = Foo("test_1") suite = unittest.TestSuite([test]) self.assertIs(suite.run(result), result) - self.assertEqual(events, ['addSkip', 'stopTest']) + self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(record, []) events = [] result = test.run() - self.assertEqual(events, ['startTestRun', 'addSkip', + self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', 'stopTest', 'stopTestRun']) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(record, []) diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 811557498bb30e..001b640dc43ad6 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -606,6 +606,7 @@ def run(self, result=None): else: stopTestRun = None + result.startTest(self) try: testMethod = getattr(self, self._testMethodName) if (getattr(self.__class__, "__unittest_skip__", False) or @@ -616,9 +617,6 @@ def run(self, result=None): _addSkip(result, self, skip_why) return result - # Increase the number of tests only if it hasn't been skipped - result.startTest(self) - expecting_failure = ( getattr(self, "__unittest_expecting_failure__", False) or getattr(testMethod, "__unittest_expecting_failure__", False) diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index 9e56f658027f4d..3ace0a5b7bf2ef 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -97,12 +97,10 @@ def _restoreStdout(self): sys.stdout = self._original_stdout sys.stderr = self._original_stderr - if self._stdout_buffer is not None: - self._stdout_buffer.seek(0) - self._stdout_buffer.truncate() - if self._stderr_buffer is not None: - self._stderr_buffer.seek(0) - self._stderr_buffer.truncate() + self._stdout_buffer.seek(0) + self._stdout_buffer.truncate() + self._stderr_buffer.seek(0) + self._stderr_buffer.truncate() def stopTestRun(self): """Called once after all tests are executed. diff --git a/Misc/NEWS.d/next/Library/2024-01-23-11-04-21.gh-issue-113267.xe_Pxe.rst b/Misc/NEWS.d/next/Library/2024-01-23-11-04-21.gh-issue-113267.xe_Pxe.rst new file mode 100644 index 00000000000000..ad8aaf9250f6d8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-23-11-04-21.gh-issue-113267.xe_Pxe.rst @@ -0,0 +1,2 @@ +Revert changes in :gh:`106584` which made calls of ``TestResult`` methods +``startTest()`` and ``stopTest()`` unbalanced. From 0ea366240b75380ed7568acbe95d72e481a734f7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:28:07 +0200 Subject: [PATCH 41/62] gh-113280: Always close socket if SSLSocket creation failed (GH-114659) Co-authored-by: Thomas Grainger --- Lib/ssl.py | 107 +++++++++--------- Lib/test/test_ssl.py | 33 ++++-- ...-01-27-20-11-24.gh-issue-113280.CZPQMf.rst | 2 + 3 files changed, 78 insertions(+), 64 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-27-20-11-24.gh-issue-113280.CZPQMf.rst diff --git a/Lib/ssl.py b/Lib/ssl.py index 74a9d2d8fd4fb0..03d0121891ff4c 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -994,71 +994,67 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True, if context.check_hostname and not server_hostname: raise ValueError("check_hostname requires server_hostname") + sock_timeout = sock.gettimeout() kwargs = dict( family=sock.family, type=sock.type, proto=sock.proto, fileno=sock.fileno() ) self = cls.__new__(cls, **kwargs) super(SSLSocket, self).__init__(**kwargs) - sock_timeout = sock.gettimeout() sock.detach() - - self._context = context - self._session = session - self._closed = False - self._sslobj = None - self.server_side = server_side - self.server_hostname = context._encode_hostname(server_hostname) - self.do_handshake_on_connect = do_handshake_on_connect - self.suppress_ragged_eofs = suppress_ragged_eofs - - # See if we are connected + # Now SSLSocket is responsible for closing the file descriptor. try: - self.getpeername() - except OSError as e: - if e.errno != errno.ENOTCONN: - raise - connected = False - blocking = self.getblocking() - self.setblocking(False) + self._context = context + self._session = session + self._closed = False + self._sslobj = None + self.server_side = server_side + self.server_hostname = context._encode_hostname(server_hostname) + self.do_handshake_on_connect = do_handshake_on_connect + self.suppress_ragged_eofs = suppress_ragged_eofs + + # See if we are connected try: - # We are not connected so this is not supposed to block, but - # testing revealed otherwise on macOS and Windows so we do - # the non-blocking dance regardless. Our raise when any data - # is found means consuming the data is harmless. - notconn_pre_handshake_data = self.recv(1) + self.getpeername() except OSError as e: - # EINVAL occurs for recv(1) on non-connected on unix sockets. - if e.errno not in (errno.ENOTCONN, errno.EINVAL): + if e.errno != errno.ENOTCONN: raise - notconn_pre_handshake_data = b'' - self.setblocking(blocking) - if notconn_pre_handshake_data: - # This prevents pending data sent to the socket before it was - # closed from escaping to the caller who could otherwise - # presume it came through a successful TLS connection. - reason = "Closed before TLS handshake with data in recv buffer." - notconn_pre_handshake_data_error = SSLError(e.errno, reason) - # Add the SSLError attributes that _ssl.c always adds. - notconn_pre_handshake_data_error.reason = reason - notconn_pre_handshake_data_error.library = None - try: - self.close() - except OSError: - pass + connected = False + blocking = self.getblocking() + self.setblocking(False) try: - raise notconn_pre_handshake_data_error - finally: - # Explicitly break the reference cycle. - notconn_pre_handshake_data_error = None - else: - connected = True + # We are not connected so this is not supposed to block, but + # testing revealed otherwise on macOS and Windows so we do + # the non-blocking dance regardless. Our raise when any data + # is found means consuming the data is harmless. + notconn_pre_handshake_data = self.recv(1) + except OSError as e: + # EINVAL occurs for recv(1) on non-connected on unix sockets. + if e.errno not in (errno.ENOTCONN, errno.EINVAL): + raise + notconn_pre_handshake_data = b'' + self.setblocking(blocking) + if notconn_pre_handshake_data: + # This prevents pending data sent to the socket before it was + # closed from escaping to the caller who could otherwise + # presume it came through a successful TLS connection. + reason = "Closed before TLS handshake with data in recv buffer." + notconn_pre_handshake_data_error = SSLError(e.errno, reason) + # Add the SSLError attributes that _ssl.c always adds. + notconn_pre_handshake_data_error.reason = reason + notconn_pre_handshake_data_error.library = None + try: + raise notconn_pre_handshake_data_error + finally: + # Explicitly break the reference cycle. + notconn_pre_handshake_data_error = None + else: + connected = True - self.settimeout(sock_timeout) # Must come after setblocking() calls. - self._connected = connected - if connected: - # create the SSL object - try: + self.settimeout(sock_timeout) # Must come after setblocking() calls. + self._connected = connected + if connected: + # create the SSL object self._sslobj = self._context._wrap_socket( self, server_side, self.server_hostname, owner=self, session=self._session, @@ -1069,9 +1065,12 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True, # non-blocking raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets") self.do_handshake() - except (OSError, ValueError): + except: + try: self.close() - raise + except OSError: + pass + raise return self @property diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 3fdfa2960503b8..1b18230d83577d 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2206,14 +2206,15 @@ def _test_get_server_certificate(test, host, port, cert=None): sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem)) def _test_get_server_certificate_fail(test, host, port): - try: - pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE) - except ssl.SSLError as x: - #should fail - if support.verbose: - sys.stdout.write("%s\n" % x) - else: - test.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) + with warnings_helper.check_no_resource_warning(test): + try: + pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE) + except ssl.SSLError as x: + #should fail + if support.verbose: + sys.stdout.write("%s\n" % x) + else: + test.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) from test.ssl_servers import make_https_server @@ -3026,6 +3027,16 @@ def test_check_hostname_idn(self): server_hostname="python.example.org") as s: with self.assertRaises(ssl.CertificateError): s.connect((HOST, server.port)) + with ThreadedEchoServer(context=server_context, chatty=True) as server: + with warnings_helper.check_no_resource_warning(self): + with self.assertRaises(UnicodeError): + context.wrap_socket(socket.socket(), + server_hostname='.pythontest.net') + with ThreadedEchoServer(context=server_context, chatty=True) as server: + with warnings_helper.check_no_resource_warning(self): + with self.assertRaises(UnicodeDecodeError): + context.wrap_socket(socket.socket(), + server_hostname=b'k\xf6nig.idn.pythontest.net') def test_wrong_cert_tls12(self): """Connecting when the server rejects the client's certificate @@ -4983,7 +4994,8 @@ def call_after_accept(conn_to_client): self.assertIsNone(wrap_error.library, msg="attr must exist") finally: # gh-108342: Explicitly break the reference cycle - wrap_error = None + with warnings_helper.check_no_resource_warning(self): + wrap_error = None server = None def test_https_client_non_tls_response_ignored(self): @@ -5032,7 +5044,8 @@ def call_after_accept(conn_to_client): # socket; that fails if the connection is broken. It may seem pointless # to test this. It serves as an illustration of something that we never # want to happen... properly not happening. - with self.assertRaises(OSError): + with warnings_helper.check_no_resource_warning(self), \ + self.assertRaises(OSError): connection.request("HEAD", "/test", headers={"Host": "localhost"}) response = connection.getresponse() diff --git a/Misc/NEWS.d/next/Library/2024-01-27-20-11-24.gh-issue-113280.CZPQMf.rst b/Misc/NEWS.d/next/Library/2024-01-27-20-11-24.gh-issue-113280.CZPQMf.rst new file mode 100644 index 00000000000000..3dcdbcf0995616 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-27-20-11-24.gh-issue-113280.CZPQMf.rst @@ -0,0 +1,2 @@ +Fix a leak of open socket in rare cases when error occurred in +:class:`ssl.SSLSocket` creation. From 3ddc5152550ea62280124c37d0b4339030ff7df4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:32:25 +0200 Subject: [PATCH 42/62] gh-114388: Fix warnings when assign an unsigned integer member (GH-114391) * Fix a RuntimeWarning emitted when assign an integer-like value that is not an instance of int to an attribute that corresponds to a C struct member of type T_UINT and T_ULONG. * Fix a double RuntimeWarning emitted when assign a negative integer value to an attribute that corresponds to a C struct member of type T_UINT. --- Lib/test/test_capi/test_structmembers.py | 37 +++++++++ ...-01-21-17-29-32.gh-issue-114388.UVGO4K.rst | 5 ++ Python/structmember.c | 83 ++++++++++++------- 3 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-01-21-17-29-32.gh-issue-114388.UVGO4K.rst diff --git a/Lib/test/test_capi/test_structmembers.py b/Lib/test/test_capi/test_structmembers.py index 2cf46b203478dc..415b8033bd16b3 100644 --- a/Lib/test/test_capi/test_structmembers.py +++ b/Lib/test/test_capi/test_structmembers.py @@ -14,6 +14,13 @@ PY_SSIZE_T_MAX, PY_SSIZE_T_MIN, ) + +class Index: + def __init__(self, value): + self.value = value + def __index__(self): + return self.value + # There are two classes: one using and another using # `Py_`-prefixed API. They should behave the same in Python @@ -72,6 +79,10 @@ def test_int(self): self.assertEqual(ts.T_INT, INT_MIN) ts.T_UINT = UINT_MAX self.assertEqual(ts.T_UINT, UINT_MAX) + ts.T_UINT = Index(0) + self.assertEqual(ts.T_UINT, 0) + ts.T_UINT = Index(INT_MAX) + self.assertEqual(ts.T_UINT, INT_MAX) def test_long(self): ts = self.ts @@ -81,6 +92,10 @@ def test_long(self): self.assertEqual(ts.T_LONG, LONG_MIN) ts.T_ULONG = ULONG_MAX self.assertEqual(ts.T_ULONG, ULONG_MAX) + ts.T_ULONG = Index(0) + self.assertEqual(ts.T_ULONG, 0) + ts.T_ULONG = Index(LONG_MAX) + self.assertEqual(ts.T_ULONG, LONG_MAX) def test_py_ssize_t(self): ts = self.ts @@ -173,6 +188,28 @@ def test_ushort_max(self): with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_USHORT = USHRT_MAX+1 + def test_int(self): + ts = self.ts + if LONG_MIN < INT_MIN: + with self.assertWarns(RuntimeWarning): + ts.T_INT = INT_MIN-1 + if LONG_MAX > INT_MAX: + with self.assertWarns(RuntimeWarning): + ts.T_INT = INT_MAX+1 + + def test_uint(self): + ts = self.ts + with self.assertWarns(RuntimeWarning): + ts.T_UINT = -1 + if ULONG_MAX > UINT_MAX: + with self.assertWarns(RuntimeWarning): + ts.T_UINT = UINT_MAX+1 + + def test_ulong(self): + ts = self.ts + with self.assertWarns(RuntimeWarning): + ts.T_ULONG = -1 + class TestWarnings_OldAPI(TestWarnings, unittest.TestCase): cls = _test_structmembersType_OldAPI diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-01-21-17-29-32.gh-issue-114388.UVGO4K.rst b/Misc/NEWS.d/next/Core and Builtins/2024-01-21-17-29-32.gh-issue-114388.UVGO4K.rst new file mode 100644 index 00000000000000..52c2742001d9ca --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-01-21-17-29-32.gh-issue-114388.UVGO4K.rst @@ -0,0 +1,5 @@ +Fix a :exc:`RuntimeWarning` emitted when assign an integer-like value that +is not an instance of :class:`int` to an attribute that corresponds to a C +struct member of :ref:`type ` T_UINT and T_ULONG. Fix a +double :exc:`RuntimeWarning` emitted when assign a negative integer value to +an attribute that corresponds to a C struct member of type T_UINT. diff --git a/Python/structmember.c b/Python/structmember.c index 7a5a6a49d23116..18bd486952419b 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -197,45 +197,72 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) WARN("Truncation of value to int"); break; } - case Py_T_UINT:{ - unsigned long ulong_val = PyLong_AsUnsignedLong(v); - if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { - /* XXX: For compatibility, accept negative int values - as well. */ - PyErr_Clear(); - ulong_val = PyLong_AsLong(v); - if ((ulong_val == (unsigned long)-1) && - PyErr_Occurred()) + case Py_T_UINT: { + /* XXX: For compatibility, accept negative int values + as well. */ + int overflow; + long long_val = PyLong_AsLongAndOverflow(v, &overflow); + if (long_val == -1 && PyErr_Occurred()) { + return -1; + } + if (overflow < 0) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + else if (!overflow) { + *(unsigned int *)addr = (unsigned int)(unsigned long)long_val; + if (long_val < 0) { + WARN("Writing negative value into unsigned field"); + } + else if ((unsigned long)long_val > UINT_MAX) { + WARN("Truncation of value to unsigned short"); + } + } + else { + unsigned long ulong_val = PyLong_AsUnsignedLong(v); + if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) { return -1; - *(unsigned int *)addr = (unsigned int)ulong_val; - WARN("Writing negative value into unsigned field"); - } else - *(unsigned int *)addr = (unsigned int)ulong_val; - if (ulong_val > UINT_MAX) - WARN("Truncation of value to unsigned int"); - break; + } + *(unsigned int*)addr = (unsigned int)ulong_val; + if (ulong_val > UINT_MAX) { + WARN("Truncation of value to unsigned int"); + } } + break; + } case Py_T_LONG:{ *(long*)addr = PyLong_AsLong(v); if ((*(long*)addr == -1) && PyErr_Occurred()) return -1; break; } - case Py_T_ULONG:{ - *(unsigned long*)addr = PyLong_AsUnsignedLong(v); - if ((*(unsigned long*)addr == (unsigned long)-1) - && PyErr_Occurred()) { - /* XXX: For compatibility, accept negative int values - as well. */ - PyErr_Clear(); - *(unsigned long*)addr = PyLong_AsLong(v); - if ((*(unsigned long*)addr == (unsigned long)-1) - && PyErr_Occurred()) + case Py_T_ULONG: { + /* XXX: For compatibility, accept negative int values + as well. */ + int overflow; + long long_val = PyLong_AsLongAndOverflow(v, &overflow); + if (long_val == -1 && PyErr_Occurred()) { + return -1; + } + if (overflow < 0) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + else if (!overflow) { + *(unsigned long *)addr = (unsigned long)long_val; + if (long_val < 0) { + WARN("Writing negative value into unsigned field"); + } + } + else { + unsigned long ulong_val = PyLong_AsUnsignedLong(v); + if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) { return -1; - WARN("Writing negative value into unsigned field"); + } + *(unsigned long*)addr = ulong_val; } break; - } + } case Py_T_PYSSIZET:{ *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) From 7e42fddf608337e83b30401910d76fd75d5cf20a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 17:49:42 +0200 Subject: [PATCH 43/62] gh-113951: Tkinter: "tag_unbind(tag, sequence, funcid)" now only unbinds "funcid" (GH-113955) Previously, "tag_unbind(tag, sequence, funcid)" methods of Text and Canvas widgets destroyed the current binding for "sequence", leaving "sequence" unbound, and deleted the "funcid" command. Now they remove only "funcid" from the binding for "sequence", keeping other commands, and delete the "funcid" command. They leave "sequence" unbound only if "funcid" was the last bound command. --- Lib/test/test_tkinter/test_misc.py | 95 +++++++++++++++++++ Lib/tkinter/__init__.py | 26 ++--- ...-01-11-20-47-49.gh-issue-113951.AzlqFK.rst | 7 ++ 3 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-11-20-47-49.gh-issue-113951.AzlqFK.rst diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index dc8a810235fc9b..71553503005c48 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -706,6 +706,101 @@ def test3(e): pass self.assertCommandExist(funcid2) self.assertCommandExist(funcid3) + def _test_tag_bind(self, w): + tag = 'sel' + event = '' + w.pack() + self.assertRaises(TypeError, w.tag_bind) + tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind + if isinstance(w, tkinter.Text): + self.assertRaises(TypeError, w.tag_bind, tag) + self.assertRaises(TypeError, w.tag_bind, tag, event) + self.assertEqual(tag_bind(tag), ()) + self.assertEqual(tag_bind(tag, event), '') + def test1(e): pass + def test2(e): pass + + funcid = w.tag_bind(tag, event, test1) + self.assertEqual(tag_bind(tag), (event,)) + script = tag_bind(tag, event) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + + funcid2 = w.tag_bind(tag, event, test2, add=True) + script = tag_bind(tag, event) + self.assertIn(funcid, script) + self.assertIn(funcid2, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + def _test_tag_unbind(self, w): + tag = 'sel' + event = '' + w.pack() + tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind + self.assertEqual(tag_bind(tag), ()) + self.assertEqual(tag_bind(tag, event), '') + def test1(e): pass + def test2(e): pass + + funcid = w.tag_bind(tag, event, test1) + funcid2 = w.tag_bind(tag, event, test2, add=True) + + self.assertRaises(TypeError, w.tag_unbind, tag) + w.tag_unbind(tag, event) + self.assertEqual(tag_bind(tag, event), '') + self.assertEqual(tag_bind(tag), ()) + + def _test_tag_bind_rebind(self, w): + tag = 'sel' + event = '' + w.pack() + tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind + self.assertEqual(tag_bind(tag), ()) + self.assertEqual(tag_bind(tag, event), '') + def test1(e): pass + def test2(e): pass + def test3(e): pass + + funcid = w.tag_bind(tag, event, test1) + funcid2 = w.tag_bind(tag, event, test2, add=True) + script = tag_bind(tag, event) + self.assertIn(funcid2, script) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + funcid3 = w.tag_bind(tag, event, test3) + script = tag_bind(tag, event) + self.assertNotIn(funcid, script) + self.assertNotIn(funcid2, script) + self.assertIn(funcid3, script) + self.assertCommandExist(funcid3) + + def test_canvas_tag_bind(self): + c = tkinter.Canvas(self.frame) + self._test_tag_bind(c) + + def test_canvas_tag_unbind(self): + c = tkinter.Canvas(self.frame) + self._test_tag_unbind(c) + + def test_canvas_tag_bind_rebind(self): + c = tkinter.Canvas(self.frame) + self._test_tag_bind_rebind(c) + + def test_text_tag_bind(self): + t = tkinter.Text(self.frame) + self._test_tag_bind(t) + + def test_text_tag_unbind(self): + t = tkinter.Text(self.frame) + self._test_tag_unbind(t) + + def test_text_tag_bind_rebind(self): + t = tkinter.Text(self.frame) + self._test_tag_bind_rebind(t) + def test_bindtags(self): f = self.frame self.assertEqual(self.root.bindtags(), ('.', 'Tk', 'all')) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index e0db41dd915ece..a1567d332ae6ef 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1537,16 +1537,19 @@ def unbind(self, sequence, funcid=None): Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. """ + self._unbind(('bind', self._w, sequence), funcid) + + def _unbind(self, what, funcid=None): if funcid is None: - self.tk.call('bind', self._w, sequence, '') + self.tk.call(*what, '') else: - lines = self.tk.call('bind', self._w, sequence).split('\n') + lines = self.tk.call(what).split('\n') prefix = f'if {{"[{funcid} ' keep = '\n'.join(line for line in lines if not line.startswith(prefix)) if not keep.strip(): keep = '' - self.tk.call('bind', self._w, sequence, keep) + self.tk.call(*what, keep) self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): @@ -1558,7 +1561,7 @@ def bind_all(self, sequence=None, func=None, add=None): def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" - self.tk.call('bind', 'all' , sequence, '') + self._root()._unbind(('bind', 'all', sequence)) def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event @@ -1573,7 +1576,7 @@ def bind_class(self, className, sequence=None, func=None, add=None): def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" - self.tk.call('bind', className , sequence, '') + self._root()._unbind(('bind', className, sequence)) def mainloop(self, n=0): """Call the mainloop of Tk.""" @@ -2885,9 +2888,7 @@ def bbox(self, *args): def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" - self.tk.call(self._w, 'bind', tagOrId, sequence, '') - if funcid: - self.deletecommand(funcid) + self._unbind((self._w, 'bind', tagOrId, sequence), funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. @@ -3997,9 +3998,7 @@ def tag_add(self, tagName, index1, *args): def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" - self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') - if funcid: - self.deletecommand(funcid) + return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. @@ -4010,6 +4009,11 @@ def tag_bind(self, tagName, sequence, func, add=None): return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) + def _tag_bind(self, tagName, sequence=None, func=None, add=None): + # For tests only + return self._bind((self._w, 'tag', 'bind', tagName), + sequence, func, add) + def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': diff --git a/Misc/NEWS.d/next/Library/2024-01-11-20-47-49.gh-issue-113951.AzlqFK.rst b/Misc/NEWS.d/next/Library/2024-01-11-20-47-49.gh-issue-113951.AzlqFK.rst new file mode 100644 index 00000000000000..e683472e59b8a4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-11-20-47-49.gh-issue-113951.AzlqFK.rst @@ -0,0 +1,7 @@ +Fix the behavior of ``tag_unbind()`` methods of :class:`tkinter.Text` and +:class:`tkinter.Canvas` classes with three arguments. Previously, +``widget.tag_unbind(tag, sequence, funcid)`` destroyed the current binding +for *sequence*, leaving *sequence* unbound, and deleted the *funcid* +command. Now it removes only *funcid* from the binding for *sequence*, +keeping other commands, and deletes the *funcid* command. It leaves +*sequence* unbound only if *funcid* was the last bound command. From d466052ad48091a00a50c5298f33238aff591028 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 19:06:22 +0200 Subject: [PATCH 44/62] gh-114388: Fix an error in GH-114391 (GH-115000) --- Python/structmember.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Python/structmember.c b/Python/structmember.c index 18bd486952419b..c9f03a464078d0 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -208,6 +208,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) if (overflow < 0) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C long"); + return -1; } else if (!overflow) { *(unsigned int *)addr = (unsigned int)(unsigned long)long_val; @@ -247,6 +248,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) if (overflow < 0) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C long"); + return -1; } else if (!overflow) { *(unsigned long *)addr = (unsigned long)long_val; From da8f9fb2ea65cc2784c2400fc39ad8c800a67a42 Mon Sep 17 00:00:00 2001 From: Dai Wentao Date: Mon, 5 Feb 2024 02:42:58 +0800 Subject: [PATCH 45/62] gh-113803: Fix inaccurate documentation for shutil.move when dst is an existing directory (#113837) * fix the usage of dst and destination in shutil.move doc * update shutil.move doc --- Doc/library/shutil.rst | 25 ++++++++++++++----------- Lib/shutil.py | 10 +++++----- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 7a7dd23177e672..ff8c9a189ab3de 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -360,21 +360,24 @@ Directory and files operations .. function:: move(src, dst, copy_function=copy2) - Recursively move a file or directory (*src*) to another location (*dst*) - and return the destination. + Recursively move a file or directory (*src*) to another location and return + the destination. - If the destination is an existing directory, then *src* is moved inside that - directory. If the destination already exists but is not a directory, it may - be overwritten depending on :func:`os.rename` semantics. + If *dst* is an existing directory or a symlink to a directory, then *src* + is moved inside that directory. The destination path in that directory must + not already exist. + + If *dst* already exists but is not a directory, it may be overwritten + depending on :func:`os.rename` semantics. If the destination is on the current filesystem, then :func:`os.rename` is - used. Otherwise, *src* is copied to *dst* using *copy_function* and then - removed. In case of symlinks, a new symlink pointing to the target of *src* - will be created in or as *dst* and *src* will be removed. + used. Otherwise, *src* is copied to the destination using *copy_function* + and then removed. In case of symlinks, a new symlink pointing to the target + of *src* will be created as the destination and *src* will be removed. - If *copy_function* is given, it must be a callable that takes two arguments - *src* and *dst*, and will be used to copy *src* to *dst* if - :func:`os.rename` cannot be used. If the source is a directory, + If *copy_function* is given, it must be a callable that takes two arguments, + *src* and the destination, and will be used to copy *src* to the destination + if :func:`os.rename` cannot be used. If the source is a directory, :func:`copytree` is called, passing it the *copy_function*. The default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the *copy_function* allows the move to succeed when it is not possible to also diff --git a/Lib/shutil.py b/Lib/shutil.py index acc9419be4dfca..c19ea0607208af 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -861,12 +861,12 @@ def move(src, dst, copy_function=copy2): similar to the Unix "mv" command. Return the file or directory's destination. - If the destination is a directory or a symlink to a directory, the source - is moved inside the directory. The destination path must not already - exist. + If dst is an existing directory or a symlink to a directory, then src is + moved inside that directory. The destination path in that directory must + not already exist. - If the destination already exists but is not a directory, it may be - overwritten depending on os.rename() semantics. + If dst already exists but is not a directory, it may be overwritten + depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. Symlinks are From 929d44e15a5667151beadb2d3a2528cd641639d6 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Sun, 4 Feb 2024 22:16:43 +0300 Subject: [PATCH 46/62] gh-114685: PyBuffer_FillInfo() now raises on PyBUF_{READ,WRITE} (GH-114802) --- Lib/test/test_buffer.py | 21 +++++++++++++++++++ ...-01-31-15-43-35.gh-issue-114685.n7aRmX.rst | 3 +++ Modules/_testcapimodule.c | 21 +++++++++++++++++++ Objects/abstract.c | 16 +++++++++----- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2024-01-31-15-43-35.gh-issue-114685.n7aRmX.rst diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 535b795f508a24..5b1b95b9c82064 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -4591,6 +4591,27 @@ def test_c_buffer_invalid_flags(self): self.assertRaises(SystemError, buf.__buffer__, PyBUF_READ) self.assertRaises(SystemError, buf.__buffer__, PyBUF_WRITE) + @unittest.skipIf(_testcapi is None, "requires _testcapi") + def test_c_fill_buffer_invalid_flags(self): + # PyBuffer_FillInfo + source = b"abc" + self.assertRaises(SystemError, _testcapi.buffer_fill_info, + source, 0, PyBUF_READ) + self.assertRaises(SystemError, _testcapi.buffer_fill_info, + source, 0, PyBUF_WRITE) + + @unittest.skipIf(_testcapi is None, "requires _testcapi") + def test_c_fill_buffer_readonly_and_writable(self): + source = b"abc" + with _testcapi.buffer_fill_info(source, 1, PyBUF_SIMPLE) as m: + self.assertEqual(bytes(m), b"abc") + self.assertTrue(m.readonly) + with _testcapi.buffer_fill_info(source, 0, PyBUF_WRITABLE) as m: + self.assertEqual(bytes(m), b"abc") + self.assertFalse(m.readonly) + self.assertRaises(BufferError, _testcapi.buffer_fill_info, + source, 1, PyBUF_WRITABLE) + def test_inheritance(self): class A(bytearray): def __buffer__(self, flags): diff --git a/Misc/NEWS.d/next/C API/2024-01-31-15-43-35.gh-issue-114685.n7aRmX.rst b/Misc/NEWS.d/next/C API/2024-01-31-15-43-35.gh-issue-114685.n7aRmX.rst new file mode 100644 index 00000000000000..76ff00645fe57d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2024-01-31-15-43-35.gh-issue-114685.n7aRmX.rst @@ -0,0 +1,3 @@ +:c:func:`PyBuffer_FillInfo` now raises a :exc:`SystemError` if called with +:c:macro:`PyBUF_READ` or :c:macro:`PyBUF_WRITE` as flags. These flags should +only be used with the ``PyMemoryView_*`` C API. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 6def680190b1a6..e67de3eeb6e17e 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1261,6 +1261,26 @@ make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored)) return PyMemoryView_FromBuffer(&info); } +static PyObject * +buffer_fill_info(PyObject *self, PyObject *args) +{ + Py_buffer info; + const char *data; + Py_ssize_t size; + int readonly; + int flags; + + if (!PyArg_ParseTuple(args, "s#ii:buffer_fill_info", + &data, &size, &readonly, &flags)) { + return NULL; + } + + if (PyBuffer_FillInfo(&info, NULL, (void *)data, size, readonly, flags) < 0) { + return NULL; + } + return PyMemoryView_FromBuffer(&info); +} + static PyObject * test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored)) { @@ -3314,6 +3334,7 @@ static PyMethodDef TestMethods[] = { {"eval_code_ex", eval_eval_code_ex, METH_VARARGS}, {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, METH_NOARGS}, + {"buffer_fill_info", buffer_fill_info, METH_VARARGS}, {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, {"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS}, {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, diff --git a/Objects/abstract.c b/Objects/abstract.c index daf04eb4ab2cda..07d4b89fe188c8 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -767,11 +767,17 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, return -1; } - if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && - (readonly == 1)) { - PyErr_SetString(PyExc_BufferError, - "Object is not writable."); - return -1; + if (flags != PyBUF_SIMPLE) { /* fast path */ + if (flags == PyBUF_READ || flags == PyBUF_WRITE) { + PyErr_BadInternalCall(); + return -1; + } + if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && + (readonly == 1)) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } } view->obj = Py_XNewRef(obj); From 15f6f048a6ecdf0f6f4fc076d013be3d110f8ed6 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 4 Feb 2024 22:19:06 +0200 Subject: [PATCH 47/62] gh-114392: Improve test_capi.test_structmembers (GH-114393) Test all integer member types with extreme values and values outside of the valid range. Test support of integer-like objects. Test warnings for wrapped out values. --- Lib/test/test_capi/test_structmembers.py | 217 ++++++++++------------- 1 file changed, 93 insertions(+), 124 deletions(-) diff --git a/Lib/test/test_capi/test_structmembers.py b/Lib/test/test_capi/test_structmembers.py index 415b8033bd16b3..a294c3b13a5c30 100644 --- a/Lib/test/test_capi/test_structmembers.py +++ b/Lib/test/test_capi/test_structmembers.py @@ -45,83 +45,115 @@ class ReadWriteTests: def setUp(self): self.ts = _make_test_object(self.cls) + def _test_write(self, name, value, expected=None): + if expected is None: + expected = value + ts = self.ts + setattr(ts, name, value) + self.assertEqual(getattr(ts, name), expected) + + def _test_warn(self, name, value, expected=None): + ts = self.ts + self.assertWarns(RuntimeWarning, setattr, ts, name, value) + if expected is not None: + self.assertEqual(getattr(ts, name), expected) + + def _test_overflow(self, name, value): + ts = self.ts + self.assertRaises(OverflowError, setattr, ts, name, value) + + def _test_int_range(self, name, minval, maxval, *, hardlimit=None, + indexlimit=None): + if hardlimit is None: + hardlimit = (minval, maxval) + ts = self.ts + self._test_write(name, minval) + self._test_write(name, maxval) + hardminval, hardmaxval = hardlimit + self._test_overflow(name, hardminval-1) + self._test_overflow(name, hardmaxval+1) + self._test_overflow(name, 2**1000) + self._test_overflow(name, -2**1000) + if hardminval < minval: + self._test_warn(name, hardminval) + self._test_warn(name, minval-1, maxval) + if maxval < hardmaxval: + self._test_warn(name, maxval+1, minval) + self._test_warn(name, hardmaxval) + + if indexlimit is None: + indexlimit = hardlimit + if not indexlimit: + self.assertRaises(TypeError, setattr, ts, name, Index(minval)) + self.assertRaises(TypeError, setattr, ts, name, Index(maxval)) + else: + hardminindexval, hardmaxindexval = indexlimit + self._test_write(name, Index(minval), minval) + if minval < hardminindexval: + self._test_write(name, Index(hardminindexval), hardminindexval) + if maxval < hardmaxindexval: + self._test_write(name, Index(maxval), maxval) + else: + self._test_write(name, Index(hardmaxindexval), hardmaxindexval) + self._test_overflow(name, Index(hardminindexval-1)) + if name in ('T_UINT', 'T_ULONG'): + self.assertRaises(TypeError, setattr, self.ts, name, + Index(hardmaxindexval+1)) + self.assertRaises(TypeError, setattr, self.ts, name, + Index(2**1000)) + else: + self._test_overflow(name, Index(hardmaxindexval+1)) + self._test_overflow(name, Index(2**1000)) + self._test_overflow(name, Index(-2**1000)) + if hardminindexval < minval and name != 'T_ULONGLONG': + self._test_warn(name, Index(hardminindexval)) + self._test_warn(name, Index(minval-1)) + if maxval < hardmaxindexval: + self._test_warn(name, Index(maxval+1)) + self._test_warn(name, Index(hardmaxindexval)) + def test_bool(self): ts = self.ts ts.T_BOOL = True - self.assertEqual(ts.T_BOOL, True) + self.assertIs(ts.T_BOOL, True) ts.T_BOOL = False - self.assertEqual(ts.T_BOOL, False) + self.assertIs(ts.T_BOOL, False) self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1) + self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 0) + self.assertRaises(TypeError, setattr, ts, 'T_BOOL', None) def test_byte(self): - ts = self.ts - ts.T_BYTE = CHAR_MAX - self.assertEqual(ts.T_BYTE, CHAR_MAX) - ts.T_BYTE = CHAR_MIN - self.assertEqual(ts.T_BYTE, CHAR_MIN) - ts.T_UBYTE = UCHAR_MAX - self.assertEqual(ts.T_UBYTE, UCHAR_MAX) + self._test_int_range('T_BYTE', CHAR_MIN, CHAR_MAX, + hardlimit=(LONG_MIN, LONG_MAX)) + self._test_int_range('T_UBYTE', 0, UCHAR_MAX, + hardlimit=(LONG_MIN, LONG_MAX)) def test_short(self): - ts = self.ts - ts.T_SHORT = SHRT_MAX - self.assertEqual(ts.T_SHORT, SHRT_MAX) - ts.T_SHORT = SHRT_MIN - self.assertEqual(ts.T_SHORT, SHRT_MIN) - ts.T_USHORT = USHRT_MAX - self.assertEqual(ts.T_USHORT, USHRT_MAX) + self._test_int_range('T_SHORT', SHRT_MIN, SHRT_MAX, + hardlimit=(LONG_MIN, LONG_MAX)) + self._test_int_range('T_USHORT', 0, USHRT_MAX, + hardlimit=(LONG_MIN, LONG_MAX)) def test_int(self): - ts = self.ts - ts.T_INT = INT_MAX - self.assertEqual(ts.T_INT, INT_MAX) - ts.T_INT = INT_MIN - self.assertEqual(ts.T_INT, INT_MIN) - ts.T_UINT = UINT_MAX - self.assertEqual(ts.T_UINT, UINT_MAX) - ts.T_UINT = Index(0) - self.assertEqual(ts.T_UINT, 0) - ts.T_UINT = Index(INT_MAX) - self.assertEqual(ts.T_UINT, INT_MAX) + self._test_int_range('T_INT', INT_MIN, INT_MAX, + hardlimit=(LONG_MIN, LONG_MAX)) + self._test_int_range('T_UINT', 0, UINT_MAX, + hardlimit=(LONG_MIN, ULONG_MAX), + indexlimit=(LONG_MIN, LONG_MAX)) def test_long(self): - ts = self.ts - ts.T_LONG = LONG_MAX - self.assertEqual(ts.T_LONG, LONG_MAX) - ts.T_LONG = LONG_MIN - self.assertEqual(ts.T_LONG, LONG_MIN) - ts.T_ULONG = ULONG_MAX - self.assertEqual(ts.T_ULONG, ULONG_MAX) - ts.T_ULONG = Index(0) - self.assertEqual(ts.T_ULONG, 0) - ts.T_ULONG = Index(LONG_MAX) - self.assertEqual(ts.T_ULONG, LONG_MAX) + self._test_int_range('T_LONG', LONG_MIN, LONG_MAX) + self._test_int_range('T_ULONG', 0, ULONG_MAX, + hardlimit=(LONG_MIN, ULONG_MAX), + indexlimit=(LONG_MIN, LONG_MAX)) def test_py_ssize_t(self): - ts = self.ts - ts.T_PYSSIZET = PY_SSIZE_T_MAX - self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MAX) - ts.T_PYSSIZET = PY_SSIZE_T_MIN - self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MIN) + self._test_int_range('T_PYSSIZET', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, indexlimit=False) def test_longlong(self): - ts = self.ts - if not hasattr(ts, "T_LONGLONG"): - self.skipTest("long long not present") - - ts.T_LONGLONG = LLONG_MAX - self.assertEqual(ts.T_LONGLONG, LLONG_MAX) - ts.T_LONGLONG = LLONG_MIN - self.assertEqual(ts.T_LONGLONG, LLONG_MIN) - - ts.T_ULONGLONG = ULLONG_MAX - self.assertEqual(ts.T_ULONGLONG, ULLONG_MAX) - - ## make sure these will accept a plain int as well as a long - ts.T_LONGLONG = 3 - self.assertEqual(ts.T_LONGLONG, 3) - ts.T_ULONGLONG = 4 - self.assertEqual(ts.T_ULONGLONG, 4) + self._test_int_range('T_LONGLONG', LLONG_MIN, LLONG_MAX) + self._test_int_range('T_ULONGLONG', 0, ULLONG_MAX, + indexlimit=(LONG_MIN, LONG_MAX)) def test_bad_assignments(self): ts = self.ts @@ -131,10 +163,9 @@ def test_bad_assignments(self): 'T_SHORT', 'T_USHORT', 'T_INT', 'T_UINT', 'T_LONG', 'T_ULONG', + 'T_LONGLONG', 'T_ULONGLONG', 'T_PYSSIZET' ] - if hasattr(ts, 'T_LONGLONG'): - integer_attributes.extend(['T_LONGLONG', 'T_ULONGLONG']) # issue8014: this produced 'bad argument to internal function' # internal error @@ -154,68 +185,6 @@ class ReadWriteTests_OldAPI(ReadWriteTests, unittest.TestCase): class ReadWriteTests_NewAPI(ReadWriteTests, unittest.TestCase): cls = _test_structmembersType_NewAPI -class TestWarnings: - def setUp(self): - self.ts = _make_test_object(self.cls) - - def test_byte_max(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_BYTE = CHAR_MAX+1 - - def test_byte_min(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_BYTE = CHAR_MIN-1 - - def test_ubyte_max(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_UBYTE = UCHAR_MAX+1 - - def test_short_max(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_SHORT = SHRT_MAX+1 - - def test_short_min(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_SHORT = SHRT_MIN-1 - - def test_ushort_max(self): - ts = self.ts - with warnings_helper.check_warnings(('', RuntimeWarning)): - ts.T_USHORT = USHRT_MAX+1 - - def test_int(self): - ts = self.ts - if LONG_MIN < INT_MIN: - with self.assertWarns(RuntimeWarning): - ts.T_INT = INT_MIN-1 - if LONG_MAX > INT_MAX: - with self.assertWarns(RuntimeWarning): - ts.T_INT = INT_MAX+1 - - def test_uint(self): - ts = self.ts - with self.assertWarns(RuntimeWarning): - ts.T_UINT = -1 - if ULONG_MAX > UINT_MAX: - with self.assertWarns(RuntimeWarning): - ts.T_UINT = UINT_MAX+1 - - def test_ulong(self): - ts = self.ts - with self.assertWarns(RuntimeWarning): - ts.T_ULONG = -1 - -class TestWarnings_OldAPI(TestWarnings, unittest.TestCase): - cls = _test_structmembersType_OldAPI - -class TestWarnings_NewAPI(TestWarnings, unittest.TestCase): - cls = _test_structmembersType_NewAPI - if __name__ == "__main__": unittest.main() From 391659b3da570bfa28fed5fbdb6f2d9c26ab3dd0 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 5 Feb 2024 08:04:57 +0800 Subject: [PATCH 48/62] gh-114099: Add test exclusions to support running the test suite on iOS (#114889) Add test annotations required to run the test suite on iOS (PEP 730). The majority of the change involve annotating tests that use subprocess, but are skipped on Emscripten/WASI for other reasons, and including iOS/tvOS/watchOS under the same umbrella as macOS/darwin checks. `is_apple` and `is_apple_mobile` test helpers have been added to identify *any* Apple platform, and "any Apple platform except macOS", respectively. --- Lib/test/support/__init__.py | 26 ++++- Lib/test/support/os_helper.py | 8 +- Lib/test/test_asyncio/test_events.py | 14 +++ Lib/test/test_asyncio/test_streams.py | 3 +- Lib/test/test_asyncio/test_subprocess.py | 2 + Lib/test/test_asyncio/test_unix_events.py | 2 +- Lib/test/test_cmd_line_script.py | 16 +-- Lib/test/test_code_module.py | 1 + Lib/test/test_fcntl.py | 12 ++- Lib/test/test_ftplib.py | 3 + Lib/test/test_genericpath.py | 22 ++-- Lib/test/test_httpservers.py | 18 ++-- Lib/test/test_io.py | 16 ++- Lib/test/test_marshal.py | 4 +- Lib/test/test_mmap.py | 4 +- Lib/test/test_os.py | 4 +- Lib/test/test_pdb.py | 102 +++++++++--------- Lib/test/test_platform.py | 3 +- Lib/test/test_posix.py | 15 +-- Lib/test/test_pty.py | 18 ++-- Lib/test/test_selectors.py | 5 +- Lib/test/test_shutil.py | 2 + Lib/test/test_signal.py | 9 +- Lib/test/test_socket.py | 24 +++-- Lib/test/test_sqlite3/test_dbapi.py | 6 +- Lib/test/test_stat.py | 5 +- Lib/test/test_sys_settrace.py | 3 +- Lib/test/test_unicode_file_functions.py | 14 +-- Lib/test/test_urllib2.py | 2 + Lib/test/test_venv.py | 10 +- ...-02-02-13-18-55.gh-issue-114099.C_ycWg.rst | 1 + 31 files changed, 224 insertions(+), 150 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index f2e6af078a5f29..5b091fb2fd32dc 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -43,7 +43,7 @@ "requires_limited_api", "requires_specialization", # sys "MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi", - "check_impl_detail", "unix_shell", "setswitchinterval", + "is_apple_mobile", "check_impl_detail", "unix_shell", "setswitchinterval", # os "get_pagesize", # network @@ -522,7 +522,7 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'): is_android = hasattr(sys, 'getandroidapilevel') -if sys.platform not in ('win32', 'vxworks'): +if sys.platform not in {"win32", "vxworks", "ios", "tvos", "watchos"}: unix_shell = '/system/bin/sh' if is_android else '/bin/sh' else: unix_shell = None @@ -532,19 +532,35 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'): is_emscripten = sys.platform == "emscripten" is_wasi = sys.platform == "wasi" -has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi +# Apple mobile platforms (iOS/tvOS/watchOS) are POSIX-like but do not +# have subprocess or fork support. +is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"} +is_apple = is_apple_mobile or sys.platform == "darwin" + +has_fork_support = hasattr(os, "fork") and not ( + is_emscripten + or is_wasi + or is_apple_mobile +) def requires_fork(): return unittest.skipUnless(has_fork_support, "requires working os.fork()") -has_subprocess_support = not is_emscripten and not is_wasi +has_subprocess_support = not ( + is_emscripten + or is_wasi + or is_apple_mobile +) def requires_subprocess(): """Used for subprocess, os.spawn calls, fd inheritance""" return unittest.skipUnless(has_subprocess_support, "requires subprocess support") # Emscripten's socket emulation and WASI sockets have limitations. -has_socket_support = not is_emscripten and not is_wasi +has_socket_support = not ( + is_emscripten + or is_wasi +) def requires_working_socket(*, module=False): """Skip tests or modules that require working sockets diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index 20f38fd36a8876..22787e32b5f3ab 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -22,8 +22,8 @@ # TESTFN_UNICODE is a non-ascii filename TESTFN_UNICODE = TESTFN_ASCII + "-\xe0\xf2\u0258\u0141\u011f" -if sys.platform == 'darwin': - # In Mac OS X's VFS API file names are, by definition, canonically +if support.is_apple: + # On Apple's VFS API file names are, by definition, canonically # decomposed Unicode, encoded using UTF-8. See QA1173: # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html import unicodedata @@ -48,8 +48,8 @@ 'encoding (%s). Unicode filename tests may not be effective' % (TESTFN_UNENCODABLE, sys.getfilesystemencoding())) TESTFN_UNENCODABLE = None -# macOS and Emscripten deny unencodable filenames (invalid utf-8) -elif sys.platform not in {'darwin', 'emscripten', 'wasi'}: +# Apple and Emscripten deny unencodable filenames (invalid utf-8) +elif not support.is_apple and sys.platform not in {"emscripten", "wasi"}: try: # ascii and utf-8 cannot encode the byte 0xff b'\xff'.decode(sys.getfilesystemencoding()) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index b25c0975736e20..c92c88bd5b2429 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1815,6 +1815,7 @@ def check_killed(self, returncode): else: self.assertEqual(-signal.SIGKILL, returncode) + @support.requires_subprocess() def test_subprocess_exec(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') @@ -1836,6 +1837,7 @@ def test_subprocess_exec(self): self.check_killed(proto.returncode) self.assertEqual(b'Python The Winner', proto.data[1]) + @support.requires_subprocess() def test_subprocess_interactive(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') @@ -1863,6 +1865,7 @@ def test_subprocess_interactive(self): self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) + @support.requires_subprocess() def test_subprocess_shell(self): connect = self.loop.subprocess_shell( functools.partial(MySubprocessProtocol, self.loop), @@ -1879,6 +1882,7 @@ def test_subprocess_shell(self): self.assertEqual(proto.data[2], b'') transp.close() + @support.requires_subprocess() def test_subprocess_exitcode(self): connect = self.loop.subprocess_shell( functools.partial(MySubprocessProtocol, self.loop), @@ -1890,6 +1894,7 @@ def test_subprocess_exitcode(self): self.assertEqual(7, proto.returncode) transp.close() + @support.requires_subprocess() def test_subprocess_close_after_finish(self): connect = self.loop.subprocess_shell( functools.partial(MySubprocessProtocol, self.loop), @@ -1904,6 +1909,7 @@ def test_subprocess_close_after_finish(self): self.assertEqual(7, proto.returncode) self.assertIsNone(transp.close()) + @support.requires_subprocess() def test_subprocess_kill(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') @@ -1920,6 +1926,7 @@ def test_subprocess_kill(self): self.check_killed(proto.returncode) transp.close() + @support.requires_subprocess() def test_subprocess_terminate(self): prog = os.path.join(os.path.dirname(__file__), 'echo.py') @@ -1937,6 +1944,7 @@ def test_subprocess_terminate(self): transp.close() @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") + @support.requires_subprocess() def test_subprocess_send_signal(self): # bpo-31034: Make sure that we get the default signal handler (killing # the process). The parent process may have decided to ignore SIGHUP, @@ -1961,6 +1969,7 @@ def test_subprocess_send_signal(self): finally: signal.signal(signal.SIGHUP, old_handler) + @support.requires_subprocess() def test_subprocess_stderr(self): prog = os.path.join(os.path.dirname(__file__), 'echo2.py') @@ -1982,6 +1991,7 @@ def test_subprocess_stderr(self): self.assertTrue(proto.data[2].startswith(b'ERR:test'), proto.data[2]) self.assertEqual(0, proto.returncode) + @support.requires_subprocess() def test_subprocess_stderr_redirect_to_stdout(self): prog = os.path.join(os.path.dirname(__file__), 'echo2.py') @@ -2007,6 +2017,7 @@ def test_subprocess_stderr_redirect_to_stdout(self): transp.close() self.assertEqual(0, proto.returncode) + @support.requires_subprocess() def test_subprocess_close_client_stream(self): prog = os.path.join(os.path.dirname(__file__), 'echo3.py') @@ -2041,6 +2052,7 @@ def test_subprocess_close_client_stream(self): self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) + @support.requires_subprocess() def test_subprocess_wait_no_same_group(self): # start the new process in a new session connect = self.loop.subprocess_shell( @@ -2053,6 +2065,7 @@ def test_subprocess_wait_no_same_group(self): self.assertEqual(7, proto.returncode) transp.close() + @support.requires_subprocess() def test_subprocess_exec_invalid_args(self): async def connect(**kwds): await self.loop.subprocess_exec( @@ -2066,6 +2079,7 @@ async def connect(**kwds): with self.assertRaises(ValueError): self.loop.run_until_complete(connect(shell=True)) + @support.requires_subprocess() def test_subprocess_shell_invalid_args(self): async def connect(cmd=None, **kwds): diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 3c8cc5f3649180..210990593adfa9 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -10,7 +10,6 @@ import unittest from unittest import mock import warnings -from test.support import socket_helper try: import ssl except ImportError: @@ -18,6 +17,7 @@ import asyncio from test.test_asyncio import utils as test_utils +from test.support import requires_subprocess, socket_helper def tearDownModule(): @@ -770,6 +770,7 @@ async def client(addr): self.assertEqual(msg2, b"hello world 2!\n") @unittest.skipIf(sys.platform == 'win32', "Don't have pipes") + @requires_subprocess() def test_read_all_from_pipe_reader(self): # See asyncio issue 168. This test is derived from the example # subprocess_attach_read_pipe.py, but we configure the diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 808b21c6617551..f50a9ebc031ba8 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -47,6 +47,7 @@ def _start(self, *args, **kwargs): self._proc.pid = -1 +@support.requires_subprocess() class SubprocessTransportTests(test_utils.TestCase): def setUp(self): super().setUp() @@ -110,6 +111,7 @@ def test_subprocess_repr(self): transport.close() +@support.requires_subprocess() class SubprocessMixin: def test_stdin_stdout(self): diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index d2c8cba6acfa31..59ef9f5f58cabc 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1874,7 +1874,7 @@ async def runner(): wsock.close() -@unittest.skipUnless(hasattr(os, 'fork'), 'requires os.fork()') +@support.requires_fork() class TestFork(unittest.IsolatedAsyncioTestCase): async def test_fork_not_share_event_loop(self): diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 48754d5a63da3b..3a5a8abf81e43d 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -14,8 +14,7 @@ import textwrap from test import support -from test.support import import_helper -from test.support import os_helper +from test.support import import_helper, is_apple, os_helper from test.support.script_helper import ( make_pkg, make_script, make_zip_pkg, make_zip_script, assert_python_ok, assert_python_failure, spawn_python, kill_python) @@ -557,12 +556,17 @@ def test_pep_409_verbiage(self): self.assertTrue(text[3].startswith('NameError')) def test_non_ascii(self): - # Mac OS X denies the creation of a file with an invalid UTF-8 name. + # Apple platforms deny the creation of a file with an invalid UTF-8 name. # Windows allows creating a name with an arbitrary bytes name, but # Python cannot a undecodable bytes argument to a subprocess. - # WASI does not permit invalid UTF-8 names. - if (os_helper.TESTFN_UNDECODABLE - and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')): + # Emscripten/WASI does not permit invalid UTF-8 names. + if ( + os_helper.TESTFN_UNDECODABLE + and sys.platform not in { + "win32", "emscripten", "wasi" + } + and not is_apple + ): name = os.fsdecode(os_helper.TESTFN_UNDECODABLE) elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 747c0f9683c19c..259778a5cade98 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -160,6 +160,7 @@ def setUp(self): self.console = code.InteractiveConsole(local_exit=True) self.mock_sys() + @unittest.skipIf(sys.flags.no_site, "exit() isn't defined unless there's a site module") def test_exit(self): # default exit message self.infunc.side_effect = ["exit()"] diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 203dd6fe57dcd9..6d734d052454d3 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -6,7 +6,9 @@ import struct import sys import unittest -from test.support import verbose, cpython_only, get_pagesize +from test.support import ( + cpython_only, get_pagesize, is_apple, requires_subprocess, verbose +) from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink @@ -56,8 +58,10 @@ def get_lockdata(): else: start_len = "qq" - if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) - or sys.platform == 'darwin'): + if ( + sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) + or is_apple + ): if struct.calcsize('l') == 8: off_t = 'l' pid_t = 'i' @@ -157,6 +161,7 @@ def test_flock(self): self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + @requires_subprocess() def test_lockf_exclusive(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_EX | fcntl.LOCK_NB @@ -169,6 +174,7 @@ def test_lockf_exclusive(self): self.assertEqual(p.exitcode, 0) @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") + @requires_subprocess() def test_lockf_share(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_SH | fcntl.LOCK_NB diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 2f191ea7a44c16..81115e9db888cf 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -18,6 +18,7 @@ from unittest import TestCase, skipUnless from test import support +from test.support import requires_subprocess from test.support import threading_helper from test.support import socket_helper from test.support import warnings_helper @@ -900,6 +901,7 @@ def retr(): @skipUnless(ssl, "SSL not available") +@requires_subprocess() class TestTLS_FTPClassMixin(TestFTPClass): """Repeat TestFTPClass tests starting the TLS layer for both control and data connections first. @@ -916,6 +918,7 @@ def setUp(self, encoding=DEFAULT_ENCODING): @skipUnless(ssl, "SSL not available") +@requires_subprocess() class TestTLS_FTPClass(TestCase): """Specific TLS_FTP class tests.""" diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 4f311c2d498e9f..b77cd4c67d6b2a 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -7,9 +7,9 @@ import sys import unittest import warnings -from test.support import is_emscripten -from test.support import os_helper -from test.support import warnings_helper +from test.support import ( + is_apple, is_emscripten, os_helper, warnings_helper +) from test.support.script_helper import assert_python_ok from test.support.os_helper import FakePath @@ -483,12 +483,16 @@ def test_abspath_issue3426(self): self.assertIsInstance(abspath(path), str) def test_nonascii_abspath(self): - if (os_helper.TESTFN_UNDECODABLE - # macOS and Emscripten deny the creation of a directory with an - # invalid UTF-8 name. Windows allows creating a directory with an - # arbitrary bytes name, but fails to enter this directory - # (when the bytes name is used). - and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')): + if ( + os_helper.TESTFN_UNDECODABLE + # Apple platforms and Emscripten/WASI deny the creation of a + # directory with an invalid UTF-8 name. Windows allows creating a + # directory with an arbitrary bytes name, but fails to enter this + # directory (when the bytes name is used). + and sys.platform not in { + "win32", "emscripten", "wasi" + } and not is_apple + ): name = os_helper.TESTFN_UNDECODABLE elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 9fa6ecf9c08e27..d762ec6102ab8a 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -30,8 +30,9 @@ import unittest from test import support -from test.support import os_helper -from test.support import threading_helper +from test.support import ( + is_apple, os_helper, requires_subprocess, threading_helper +) support.requires_working_socket(module=True) @@ -410,8 +411,8 @@ def close_conn(): reader.close() return body - @unittest.skipIf(sys.platform == 'darwin', - 'undecodable name cannot always be decoded on macOS') + @unittest.skipIf(is_apple, + 'undecodable name cannot always be decoded on Apple platforms') @unittest.skipIf(sys.platform == 'win32', 'undecodable name cannot be decoded on win32') @unittest.skipUnless(os_helper.TESTFN_UNDECODABLE, @@ -422,11 +423,11 @@ def test_undecodable_filename(self): with open(os.path.join(self.tempdir, filename), 'wb') as f: f.write(os_helper.TESTFN_UNDECODABLE) response = self.request(self.base_url + '/') - if sys.platform == 'darwin': - # On Mac OS the HFS+ filesystem replaces bytes that aren't valid - # UTF-8 into a percent-encoded value. + if is_apple: + # On Apple platforms the HFS+ filesystem replaces bytes that + # aren't valid UTF-8 into a percent-encoded value. for name in os.listdir(self.tempdir): - if name != 'test': # Ignore a filename created in setUp(). + if name != 'test': # Ignore a filename created in setUp(). filename = name break body = self.check_status_and_reason(response, HTTPStatus.OK) @@ -697,6 +698,7 @@ def test_html_escape_filename(self): @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, "This test can't be run reliably as root (issue #13308).") +@requires_subprocess() class CGIHTTPServerTestCase(BaseTestCase): class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler): _test_case_self = None # populated by each setUp() method call. diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 9e28b936e00bd5..73669ecc792776 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -39,11 +39,9 @@ from test import support from test.support.script_helper import ( assert_python_ok, assert_python_failure, run_python_until_end) -from test.support import import_helper -from test.support import os_helper -from test.support import threading_helper -from test.support import warnings_helper -from test.support import skip_if_sanitizer +from test.support import ( + import_helper, is_apple, os_helper, skip_if_sanitizer, threading_helper, warnings_helper +) from test.support.os_helper import FakePath import codecs @@ -606,10 +604,10 @@ def test_raw_bytes_io(self): self.read_ops(f, True) def test_large_file_ops(self): - # On Windows and Mac OSX this test consumes large resources; It takes - # a long time to build the >2 GiB file and takes >2 GiB of disk space - # therefore the resource must be enabled to run this test. - if sys.platform[:3] == 'win' or sys.platform == 'darwin': + # On Windows and Apple platforms this test consumes large resources; It + # takes a long time to build the >2 GiB file and takes >2 GiB of disk + # space therefore the resource must be enabled to run this test. + if sys.platform[:3] == 'win' or is_apple: support.requires( 'largefile', 'test requires %s bytes and a long time to run' % self.LARGE) diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 6e17e010e7f355..615568e6af2102 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -1,5 +1,5 @@ from test import support -from test.support import os_helper, requires_debug_ranges +from test.support import is_apple_mobile, os_helper, requires_debug_ranges from test.support.script_helper import assert_python_ok import array import io @@ -286,7 +286,7 @@ def test_recursion_limit(self): #if os.name == 'nt' and support.Py_DEBUG: if os.name == 'nt': MAX_MARSHAL_STACK_DEPTH = 1000 - elif sys.platform == 'wasi': + elif sys.platform == 'wasi' or is_apple_mobile: MAX_MARSHAL_STACK_DEPTH = 1500 else: MAX_MARSHAL_STACK_DEPTH = 2000 diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index b89621e08577be..ac759757d24659 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,5 +1,5 @@ from test.support import ( - requires, _2G, _4G, gc_collect, cpython_only, is_emscripten + requires, _2G, _4G, gc_collect, cpython_only, is_emscripten, is_apple, ) from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink @@ -1067,7 +1067,7 @@ def tearDown(self): unlink(TESTFN) def _make_test_file(self, num_zeroes, tail): - if sys.platform[:3] == 'win' or sys.platform == 'darwin': + if sys.platform[:3] == 'win' or is_apple: requires('largefile', 'test requires %s bytes and a long time to run' % str(0x180000000)) f = open(TESTFN, 'w+b') diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index ed79a2c24ef30b..86af1a8ed8ee15 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3848,6 +3848,7 @@ def test_does_not_crash(self): self.assertGreaterEqual(size.columns, 0) self.assertGreaterEqual(size.lines, 0) + @support.requires_subprocess() def test_stty_match(self): """Check if stty returns the same results @@ -4577,7 +4578,8 @@ def test_posix_pty_functions(self): self.addCleanup(os.close, son_fd) self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd)) - @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()") + @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()") + @support.requires_subprocess() def test_pipe_spawnl(self): # gh-77046: On Windows, os.pipe() file descriptors must be created with # _O_NOINHERIT to make them non-inheritable. UCRT has no public API to diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index b2283cff6cb462..2b0795cdad707e 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -779,58 +779,62 @@ def test_pdb_where_command(): (Pdb) continue """ -def test_pdb_interact_command(): - """Test interact command - >>> g = 0 - >>> dict_g = {} +# skip this test if sys.flags.no_site = True; +# exit() isn't defined unless there's a site module. +if not sys.flags.no_site: + def test_pdb_interact_command(): + """Test interact command - >>> def test_function(): - ... x = 1 - ... lst_local = [] - ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + >>> g = 0 + >>> dict_g = {} - >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE - ... 'interact', - ... 'x', - ... 'g', - ... 'x = 2', - ... 'g = 3', - ... 'dict_g["a"] = True', - ... 'lst_local.append(x)', - ... 'exit()', - ... 'p x', - ... 'p g', - ... 'p dict_g', - ... 'p lst_local', - ... 'continue', - ... ]): - ... test_function() - --Return-- - > (4)test_function()->None - -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - (Pdb) interact - *pdb interact start* - ... x - 1 - ... g - 0 - ... x = 2 - ... g = 3 - ... dict_g["a"] = True - ... lst_local.append(x) - ... exit() - *exit from pdb interact command* - (Pdb) p x - 1 - (Pdb) p g - 0 - (Pdb) p dict_g - {'a': True} - (Pdb) p lst_local - [2] - (Pdb) continue - """ + >>> def test_function(): + ... x = 1 + ... lst_local = [] + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'interact', + ... 'x', + ... 'g', + ... 'x = 2', + ... 'g = 3', + ... 'dict_g["a"] = True', + ... 'lst_local.append(x)', + ... 'exit()', + ... 'p x', + ... 'p g', + ... 'p dict_g', + ... 'p lst_local', + ... 'continue', + ... ]): + ... test_function() + --Return-- + > (4)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) interact + *pdb interact start* + ... x + 1 + ... g + 0 + ... x = 2 + ... g = 3 + ... dict_g["a"] = True + ... lst_local.append(x) + ... exit() + *exit from pdb interact command* + (Pdb) p x + 1 + (Pdb) p g + 0 + (Pdb) p dict_g + {'a': True} + (Pdb) p lst_local + [2] + (Pdb) continue + """ def test_convenience_variables(): """Test convenience variables diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 216973350319fe..648e18d0150ef0 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -472,7 +472,8 @@ def test_macos(self): 'root:xnu-4570.71.2~1/RELEASE_X86_64'), 'x86_64', 'i386') arch = ('64bit', '') - with mock.patch.object(platform, 'uname', return_value=uname), \ + with mock.patch.object(sys, "platform", "darwin"), \ + mock.patch.object(platform, 'uname', return_value=uname), \ mock.patch.object(platform, 'architecture', return_value=arch): for mac_ver, expected_terse, expected in [ # darwin: mac_ver() returns empty strings diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 9c382ace806e0f..72e348fbbdcbc1 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1,7 +1,7 @@ "Test posix functions" from test import support -from test.support import import_helper +from test.support import is_apple from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok @@ -781,9 +781,10 @@ def check_stat(uid, gid): check_stat(uid, gid) self.assertRaises(OSError, chown_func, first_param, 0, -1) check_stat(uid, gid) - if 0 not in os.getgroups(): - self.assertRaises(OSError, chown_func, first_param, -1, 0) - check_stat(uid, gid) + if hasattr(os, 'getgroups'): + if 0 not in os.getgroups(): + self.assertRaises(OSError, chown_func, first_param, -1, 0) + check_stat(uid, gid) # test illegal types for t in str, float: self.assertRaises(TypeError, chown_func, first_param, t(uid), gid) @@ -1256,8 +1257,8 @@ def test_sched_priority(self): self.assertIsInstance(lo, int) self.assertIsInstance(hi, int) self.assertGreaterEqual(hi, lo) - # OSX evidently just returns 15 without checking the argument. - if sys.platform != "darwin": + # Apple plaforms return 15 without checking the argument. + if not is_apple: self.assertRaises(OSError, posix.sched_get_priority_min, -23) self.assertRaises(OSError, posix.sched_get_priority_max, -23) @@ -2028,11 +2029,13 @@ def test_dup2(self): @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") +@support.requires_subprocess() class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin): spawn_func = getattr(posix, 'posix_spawn', None) @unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp") +@support.requires_subprocess() class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin): spawn_func = getattr(posix, 'posix_spawnp', None) diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 51e3a46d0df178..3f2bac0155fd9e 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -1,12 +1,17 @@ -from test.support import verbose, reap_children -from test.support.os_helper import TESTFN, unlink +import sys +import unittest +from test.support import ( + is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose +) from test.support.import_helper import import_module +from test.support.os_helper import TESTFN, unlink -# Skip these tests if termios or fcntl are not available +# Skip these tests if termios is not available import_module('termios') -# fcntl is a proxy for not being one of the wasm32 platforms even though we -# don't use this module... a proper check for what crashes those is needed. -import_module("fcntl") + +# Skip tests on WASM platforms, plus iOS/tvOS/watchOS +if is_apple_mobile or is_emscripten or is_wasi: + raise unittest.SkipTest(f"pty tests not required on {sys.platform}") import errno import os @@ -17,7 +22,6 @@ import signal import socket import io # readline -import unittest import warnings TEST_STRING_1 = b"I wish to buy a fish license.\n" diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index 677349c2bfca93..643775597c56c6 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -6,8 +6,7 @@ import socket import sys from test import support -from test.support import os_helper -from test.support import socket_helper +from test.support import is_apple, os_helper, socket_helper from time import sleep import unittest import unittest.mock @@ -526,7 +525,7 @@ def test_above_fd_setsize(self): try: fds = s.select() except OSError as e: - if e.errno == errno.EINVAL and sys.platform == 'darwin': + if e.errno == errno.EINVAL and is_apple: # unexplainable errors on macOS don't need to fail the test self.skipTest("Invalid argument error calling poll()") raise diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 8edd75e9907ec0..d96dad4eb9475d 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2148,6 +2148,7 @@ def check_chown(path, uid=None, gid=None): check_chown(dirname, uid, gid) +@support.requires_subprocess() class TestWhich(BaseTest, unittest.TestCase): def setUp(self): @@ -3181,6 +3182,7 @@ def test_bad_environ(self): self.assertGreaterEqual(size.lines, 0) @unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty") + @support.requires_subprocess() @unittest.skipUnless(hasattr(os, 'get_terminal_size'), 'need os.get_terminal_size()') def test_stty_match(self): diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 637a0ca3b36972..61fb047caf6dab 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -13,9 +13,10 @@ import time import unittest from test import support -from test.support import os_helper +from test.support import ( + is_apple, is_apple_mobile, os_helper, threading_helper +) from test.support.script_helper import assert_python_ok, spawn_python -from test.support import threading_helper try: import _testcapi except ImportError: @@ -832,7 +833,7 @@ def test_itimer_real(self): self.assertEqual(self.hndl_called, True) # Issue 3864, unknown if this affects earlier versions of freebsd also - @unittest.skipIf(sys.platform in ('netbsd5',), + @unittest.skipIf(sys.platform in ('netbsd5',) or is_apple_mobile, 'itimer not reliable (does not mix well with threading) on some BSDs.') def test_itimer_virtual(self): self.itimer = signal.ITIMER_VIRTUAL @@ -1344,7 +1345,7 @@ def handler(signum, frame): # Python handler self.assertEqual(len(sigs), N, "Some signals were lost") - @unittest.skipIf(sys.platform == "darwin", "crashes due to system bug (FB13453490)") + @unittest.skipIf(is_apple, "crashes due to system bug (FB13453490)") @unittest.skipUnless(hasattr(signal, "SIGUSR1"), "test needs SIGUSR1") @threading_helper.requires_working_threading() diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 231448c75f01db..17964234992062 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1,9 +1,8 @@ import unittest from test import support -from test.support import os_helper -from test.support import socket_helper -from test.support import threading_helper -from test.support import refleak_helper +from test.support import ( + is_apple, os_helper, refleak_helper, socket_helper, threading_helper +) import _thread as thread import array @@ -1196,8 +1195,11 @@ def testGetServBy(self): # Find one service that exists, then check all the related interfaces. # I've ordered this by protocols that have both a tcp and udp # protocol, at least for modern Linuxes. - if (sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd')) - or sys.platform in ('linux', 'darwin')): + if ( + sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd')) + or sys.platform == 'linux' + or is_apple + ): # avoid the 'echo' service on this platform, as there is an # assumption breaking non-standard port/protocol entry services = ('daytime', 'qotd', 'domain') @@ -3708,7 +3710,7 @@ def testFDPassCMSG_LEN(self): def _testFDPassCMSG_LEN(self): self.createAndSendFDs(1) - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") @requireAttrs(socket, "CMSG_SPACE") def testFDPassSeparate(self): @@ -3719,7 +3721,7 @@ def testFDPassSeparate(self): maxcmsgs=2) @testFDPassSeparate.client_skip - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") def _testFDPassSeparate(self): fd0, fd1 = self.newFDs(2) @@ -3732,7 +3734,7 @@ def _testFDPassSeparate(self): array.array("i", [fd1]))]), len(MSG)) - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") @requireAttrs(socket, "CMSG_SPACE") def testFDPassSeparateMinSpace(self): @@ -3746,7 +3748,7 @@ def testFDPassSeparateMinSpace(self): maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC) @testFDPassSeparateMinSpace.client_skip - @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958") + @unittest.skipIf(is_apple, "skipping, see issue #12958") @unittest.skipIf(AIX, "skipping, see issue #22397") def _testFDPassSeparateMinSpace(self): fd0, fd1 = self.newFDs(2) @@ -3770,7 +3772,7 @@ def sendAncillaryIfPossible(self, msg, ancdata): nbytes = self.sendmsgToServer([msg]) self.assertEqual(nbytes, len(msg)) - @unittest.skipIf(sys.platform == "darwin", "see issue #24725") + @unittest.skipIf(is_apple, "skipping, see issue #12958") def testFDPassEmpty(self): # Try to pass an empty FD array. Can receive either no array # or an empty array. diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index f3efe0f52f4fd7..588272448bbfda 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -31,7 +31,7 @@ from test.support import ( SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess, - is_emscripten, is_wasi + is_apple, is_emscripten, is_wasi ) from test.support import gc_collect from test.support import threading_helper @@ -667,7 +667,7 @@ def test_open_with_path_like_object(self): cx.execute(self._sql) @unittest.skipIf(sys.platform == "win32", "skipped on Windows") - @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_apple, "skipped on Apple platforms") @unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI") @unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths") def test_open_with_undecodable_path(self): @@ -713,7 +713,7 @@ def test_open_uri_readonly(self): cx.execute(self._sql) @unittest.skipIf(sys.platform == "win32", "skipped on Windows") - @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_apple, "skipped on Apple platforms") @unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI") @unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths") def test_open_undecodable_uri(self): diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index d6b6dd6e741700..49013a4bcd8af6 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -2,8 +2,7 @@ import os import socket import sys -from test.support import os_helper -from test.support import socket_helper +from test.support import is_apple, os_helper, socket_helper from test.support.import_helper import import_fresh_module from test.support.os_helper import TESTFN @@ -247,7 +246,7 @@ def test_flags_consistent(self): for flag in self.file_flags: if flag.startswith("UF"): self.assertTrue(getattr(self.statmod, flag) & self.statmod.UF_SETTABLE, f"{flag} not in UF_SETTABLE") - elif sys.platform == 'darwin' and self.statmod is c_stat and flag == 'SF_DATALESS': + elif is_apple and self.statmod is c_stat and flag == 'SF_DATALESS': self.assertTrue(self.statmod.SF_DATALESS & self.statmod.SF_SYNTHETIC, "SF_DATALESS not in SF_SYNTHETIC") self.assertFalse(self.statmod.SF_DATALESS & self.statmod.SF_SETTABLE, "SF_DATALESS in SF_SETTABLE") else: diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index ae6e192a7ab6ef..125f40227118f6 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -7,7 +7,7 @@ import gc from functools import wraps import asyncio -from test.support import import_helper +from test.support import import_helper, requires_subprocess import contextlib import os import tempfile @@ -1810,6 +1810,7 @@ def compare_events(self, line_offset, events, expected_events): def make_tracer(): return Tracer(trace_opcode_events=True) + @requires_subprocess() def test_trace_opcodes_after_settrace(self): """Make sure setting f_trace_opcodes after starting trace works even if it's the first time f_trace_opcodes is being set. GH-103615""" diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py index 47619c8807bafe..25c16e3a0b7e43 100644 --- a/Lib/test/test_unicode_file_functions.py +++ b/Lib/test/test_unicode_file_functions.py @@ -5,7 +5,7 @@ import unittest import warnings from unicodedata import normalize -from test.support import os_helper +from test.support import is_apple, os_helper from test import support @@ -23,13 +23,13 @@ '10_\u1fee\u1ffd', ] -# Mac OS X decomposes Unicode names, using Normal Form D. +# Apple platforms decompose Unicode names, using Normal Form D. # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html # "However, most volume formats do not follow the exact specification for # these normal forms. For example, HFS Plus uses a variant of Normal Form D # in which U+2000 through U+2FFF, U+F900 through U+FAFF, and U+2F800 through # U+2FAFF are not decomposed." -if sys.platform != 'darwin': +if not is_apple: filenames.extend([ # Specific code points: NFC(fn), NFD(fn), NFKC(fn) and NFKD(fn) all different '11_\u0385\u03d3\u03d4', @@ -119,11 +119,11 @@ def test_open(self): os.stat(name) self._apply_failure(os.listdir, name, self._listdir_failure) - # Skip the test on darwin, because darwin does normalize the filename to + # Skip the test on Apple platforms, because they don't normalize the filename to # NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC, # NFKD in Python is useless, because darwin will normalize it later and so # open(), os.stat(), etc. don't raise any exception. - @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X') + @unittest.skipIf(is_apple, 'irrelevant test on Apple platforms') @unittest.skipIf( support.is_emscripten or support.is_wasi, "test fails on Emscripten/WASI when host platform is macOS." @@ -142,10 +142,10 @@ def test_normalize(self): self._apply_failure(os.remove, name) self._apply_failure(os.listdir, name) - # Skip the test on darwin, because darwin uses a normalization different + # Skip the test on Apple platforms, because they use a normalization different # than Python NFD normalization: filenames are different even if we use # Python NFD normalization. - @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X') + @unittest.skipIf(is_apple, 'irrelevant test on Apple platforms') def test_listdir(self): sf0 = set(self.files) with warnings.catch_warnings(): diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 99c9e24994732f..fa528a675892b5 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1,6 +1,7 @@ import unittest from test import support from test.support import os_helper +from test.support import requires_subprocess from test.support import warnings_helper from test import test_urllib from unittest import mock @@ -998,6 +999,7 @@ def test_http_body_fileobj(self): file_obj.close() + @requires_subprocess() def test_http_body_pipe(self): # A file reading from a pipe. # A pipe cannot be seek'ed. There is no way to determine the diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 6dda00efd7bbb6..ba31beb81e80b0 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -19,8 +19,8 @@ import tempfile from test.support import (captured_stdout, captured_stderr, skip_if_broken_multiprocessing_synchronize, verbose, - requires_subprocess, is_emscripten, is_wasi, - requires_venv_with_pip, TEST_HOME_DIR, + requires_subprocess, is_apple_mobile, is_emscripten, + is_wasi, requires_venv_with_pip, TEST_HOME_DIR, requires_resource, copy_python_src_ignore) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest @@ -39,8 +39,10 @@ or sys._base_executable != sys.executable, 'cannot run venv.create from within a venv on this platform') -if is_emscripten or is_wasi: - raise unittest.SkipTest("venv is not available on Emscripten/WASI.") +# Skip tests on WASM platforms, plus iOS/tvOS/watchOS +if is_apple_mobile or is_emscripten or is_wasi: + raise unittest.SkipTest(f"venv tests not required on {sys.platform}") + @requires_subprocess() def check_output(cmd, encoding=None): diff --git a/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst b/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst new file mode 100644 index 00000000000000..487cd5062fc75b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst @@ -0,0 +1 @@ +Added test exclusions required to run the test suite on iOS. From e207cc181fbb0ceb30542fd0d68140c916305f57 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 4 Feb 2024 20:57:54 -0500 Subject: [PATCH 49/62] gh-114628: Display csv.Error without context (#115005) When cvs.Error is raised when TypeError is caught, the TypeError display and 'During handling' note is just noise with duplicate information. Suppress with 'from None'. --- Lib/csv.py | 4 ++-- .../Library/2024-02-04-13-17-33.gh-issue-114628.WJpqqS.rst | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-02-04-13-17-33.gh-issue-114628.WJpqqS.rst diff --git a/Lib/csv.py b/Lib/csv.py index a079279b8b8cbc..75e35b23236795 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -113,8 +113,8 @@ def _validate(self): try: _Dialect(self) except TypeError as e: - # We do this for compatibility with py2.3 - raise Error(str(e)) + # Re-raise to get a traceback showing more user code. + raise Error(str(e)) from None class excel(Dialect): """Describe the usual properties of Excel-generated CSV files.""" diff --git a/Misc/NEWS.d/next/Library/2024-02-04-13-17-33.gh-issue-114628.WJpqqS.rst b/Misc/NEWS.d/next/Library/2024-02-04-13-17-33.gh-issue-114628.WJpqqS.rst new file mode 100644 index 00000000000000..8138adc62c95f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-02-04-13-17-33.gh-issue-114628.WJpqqS.rst @@ -0,0 +1,2 @@ +When csv.Error is raised when handling TypeError, do not print the TypeError +traceback. From 39ec7fbba84663ab760853da2ac422c2e988d189 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 4 Feb 2024 23:11:31 -0500 Subject: [PATCH 50/62] Remove bogus syntax error marker in csv doc (#115017) --- Doc/library/csv.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index fd62b225fcebb8..4ee7820585d3a2 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -244,7 +244,6 @@ The :mod:`csv` module defines the following classes: with open('students.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile, dialect='unix') - ^^^^^^^^^^^^^^ .. class:: excel() From f71bdd34085d31a826148b2e5da57e0302655056 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Mon, 5 Feb 2024 13:20:34 +0300 Subject: [PATCH 51/62] gh-115020: Remove a debugging print in test_frame (GH-115021) --- Lib/test/test_frame.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 244ce8af7cdf08..baed03d92b9e56 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -72,7 +72,6 @@ def inner(): except ZeroDivisionError as exc: support.gc_collect() self.assertIsNotNone(wr()) - print(exc.__traceback__.tb_next.tb_frame.f_locals) exc.__traceback__.tb_next.tb_frame.clear() support.gc_collect() self.assertIsNone(wr()) From 87cd20a567aca56369010689e22a524bc1f1ac03 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 5 Feb 2024 13:45:09 +0300 Subject: [PATCH 52/62] gh-115026: Argument Clinic: handle PyBuffer_FillInfo errors in generated code (#115027) --- Modules/_sqlite/clinic/connection.c.h | 6 ++++-- Modules/clinic/_codecsmodule.c.h | 18 +++++++++++++----- Modules/clinic/_ssl.c.h | 6 ++++-- Tools/clinic/clinic.py | 4 +++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index db5eb77891e52e..f2cff6a7b421f3 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -1551,7 +1551,9 @@ deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { @@ -1818,4 +1820,4 @@ getconfig(pysqlite_Connection *self, PyObject *arg) #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=90b5b9c14261b8d7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=99299d3ee2c247ab input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 12fea806ab5209..1c0f37442ab350 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -297,7 +297,9 @@ _codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { @@ -1099,7 +1101,9 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { @@ -1175,7 +1179,9 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { @@ -1644,7 +1650,9 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t na if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { @@ -2738,4 +2746,4 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=d8d9e372f7ccba35 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e50d5fdf65bd45fa input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 19c0f619b92f45..2940f16a2cb7f6 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -1297,7 +1297,9 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (ptr == NULL) { goto exit; } - PyBuffer_FillInfo(&view, args[0], (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&view, args[0], (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) { + goto exit; + } } else { /* any bytes-like object */ if (PyObject_GetBuffer(args[0], &view, PyBUF_SIMPLE) != 0) { @@ -1662,4 +1664,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=6342ea0062ab16c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fd1c3378fbba5240 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 770878a3f8d2c7..c1df83a72bd8ce 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4368,7 +4368,9 @@ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> st if (ptr == NULL) {{{{ goto exit; }}}} - PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, 0); + if (PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, PyBUF_SIMPLE) < 0) {{{{ + goto exit; + }}}} }}}} else {{{{ /* any bytes-like object */ if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ From 992446dd5bd3fff92ea0f8064fb19eebfe105cef Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 5 Feb 2024 16:20:54 +0000 Subject: [PATCH 53/62] GH-113462: Limit the number of versions that a single class can use. (GH-114900) --- Include/cpython/object.h | 1 + Lib/test/test_type_cache.py | 13 +++++++++++++ .../2024-02-02-05-27-48.gh-issue-113462.VMml8q.rst | 2 ++ Objects/typeobject.c | 7 ++++++- 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-02-05-27-48.gh-issue-113462.VMml8q.rst diff --git a/Include/cpython/object.h b/Include/cpython/object.h index c93931634fee05..7512bb70c760fd 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -229,6 +229,7 @@ struct _typeobject { /* bitset of which type-watchers care about this type */ unsigned char tp_watched; + uint16_t tp_versions_used; }; /* This struct is used by the specializer diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py index 295df78a17374a..58572c6f4d3157 100644 --- a/Lib/test/test_type_cache.py +++ b/Lib/test/test_type_cache.py @@ -79,6 +79,19 @@ class C: _clear_type_cache() + def test_per_class_limit(self): + class C: + x = 0 + + type_assign_version(C) + orig_version = type_get_version(C) + for i in range(1001): + C.x = i + type_assign_version(C) + + new_version = type_get_version(C) + self.assertEqual(new_version, 0) + @support.cpython_only class TypeCacheWithSpecializationTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-02-05-27-48.gh-issue-113462.VMml8q.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-02-05-27-48.gh-issue-113462.VMml8q.rst new file mode 100644 index 00000000000000..1a401ecebf019a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-02-05-27-48.gh-issue-113462.VMml8q.rst @@ -0,0 +1,2 @@ +Limit the number of versions that a single class can use. Prevents a few +wayward classes using up all the version numbers. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a850473cad813d..e220d10ce563c2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -908,6 +908,8 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } } +#define MAX_VERSIONS_PER_CLASS 1000 + static int assign_version_tag(PyInterpreterState *interp, PyTypeObject *type) { @@ -922,7 +924,10 @@ assign_version_tag(PyInterpreterState *interp, PyTypeObject *type) if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) { return 0; } - + if (type->tp_versions_used >= MAX_VERSIONS_PER_CLASS) { + return 0; + } + type->tp_versions_used++; if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { /* static types */ if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) { From b4ba0f73d6eef3da321bb96aafd09dfbc572e95d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Feb 2024 18:24:54 +0200 Subject: [PATCH 54/62] gh-43457: Tkinter: fix design flaws in wm_attributes() (GH-111404) * When called with a single argument to get a value, it allow to omit the minus prefix. * It can be called with keyword arguments to set attributes. * w.wm_attributes(return_python_dict=True) returns a dict instead of a tuple (it will be the default in future). * Setting wantobjects to 0 no longer affects the result. --- Doc/whatsnew/3.13.rst | 9 +++ Lib/test/test_tkinter/support.py | 2 +- Lib/test/test_tkinter/test_misc.py | 55 +++++++++++++++++++ Lib/tkinter/__init__.py | 51 ++++++++++------- Lib/tkinter/simpledialog.py | 2 +- ...3-10-27-19-24-58.gh-issue-43457.84lx9H.rst | 8 +++ 6 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-10-27-19-24-58.gh-issue-43457.84lx9H.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 77f4fce6c321fe..c25d41351c2f3c 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -421,6 +421,15 @@ tkinter :meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. (Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.) +* The :mod:`tkinter` widget method :meth:`!wm_attributes` now accepts + the attribute name without the minus prefix to get window attributes, + e.g. ``w.wm_attributes('alpha')`` and allows to specify attributes and + values to set as keyword arguments, e.g. ``w.wm_attributes(alpha=0.5)``. + Add new optional keyword-only parameter *return_python_dict*: calling + ``w.wm_attributes(return_python_dict=True)`` returns the attributes as + a dict instead of a tuple. + (Contributed by Serhiy Storchaka in :gh:`43457`.) + * Add support of the "vsapi" element type in the :meth:`~tkinter.ttk.Style.element_create` method of :class:`tkinter.ttk.Style`. diff --git a/Lib/test/test_tkinter/support.py b/Lib/test/test_tkinter/support.py index a37705f0ae6feb..ebb9e00ff91bf0 100644 --- a/Lib/test/test_tkinter/support.py +++ b/Lib/test/test_tkinter/support.py @@ -14,7 +14,7 @@ def setUpClass(cls): # Some window managers can maximize new windows. cls.root.wm_state('normal') try: - cls.root.wm_attributes('-zoomed', False) + cls.root.wm_attributes(zoomed=False) except tkinter.TclError: pass diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index 71553503005c48..81a20b698a72eb 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -437,6 +437,61 @@ def test_info_patchlevel(self): self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) +class WmTest(AbstractTkTest, unittest.TestCase): + + def test_wm_attribute(self): + w = self.root + attributes = w.wm_attributes(return_python_dict=True) + self.assertIsInstance(attributes, dict) + attributes2 = w.wm_attributes() + self.assertIsInstance(attributes2, tuple) + self.assertEqual(attributes2[::2], + tuple('-' + k for k in attributes)) + self.assertEqual(attributes2[1::2], tuple(attributes.values())) + # silently deprecated + attributes3 = w.wm_attributes(None) + if self.wantobjects: + self.assertEqual(attributes3, attributes2) + else: + self.assertIsInstance(attributes3, str) + + for name in attributes: + self.assertEqual(w.wm_attributes(name), attributes[name]) + # silently deprecated + for name in attributes: + self.assertEqual(w.wm_attributes('-' + name), attributes[name]) + + self.assertIn('alpha', attributes) + self.assertIn('fullscreen', attributes) + self.assertIn('topmost', attributes) + if w._windowingsystem == "win32": + self.assertIn('disabled', attributes) + self.assertIn('toolwindow', attributes) + self.assertIn('transparentcolor', attributes) + if w._windowingsystem == "aqua": + self.assertIn('modified', attributes) + self.assertIn('notify', attributes) + self.assertIn('titlepath', attributes) + self.assertIn('transparent', attributes) + if w._windowingsystem == "x11": + self.assertIn('type', attributes) + self.assertIn('zoomed', attributes) + + w.wm_attributes(alpha=0.5) + self.assertEqual(w.wm_attributes('alpha'), + 0.5 if self.wantobjects else '0.5') + w.wm_attributes(alpha=1.0) + self.assertEqual(w.wm_attributes('alpha'), + 1.0 if self.wantobjects else '1.0') + # silently deprecated + w.wm_attributes('-alpha', 0.5) + self.assertEqual(w.wm_attributes('alpha'), + 0.5 if self.wantobjects else '0.5') + w.wm_attributes(alpha=1.0) + self.assertEqual(w.wm_attributes('alpha'), + 1.0 if self.wantobjects else '1.0') + + class BindTest(AbstractTkTest, unittest.TestCase): def setUp(self): diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index a1567d332ae6ef..2be9da2cfb9299 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -2108,26 +2108,39 @@ def wm_aspect(self, aspect = wm_aspect - def wm_attributes(self, *args): - """This subcommand returns or sets platform specific attributes - - The first form returns a list of the platform specific flags and - their values. The second form returns the value for the specific - option. The third form sets one or more of the values. The values - are as follows: - - On Windows, -disabled gets or sets whether the window is in a - disabled state. -toolwindow gets or sets the style of the window - to toolwindow (as defined in the MSDN). -topmost gets or sets - whether this is a topmost window (displays above all other - windows). - - On Macintosh, XXXXX - - On Unix, there are currently no special attribute values. + def wm_attributes(self, *args, return_python_dict=False, **kwargs): + """Return or sets platform specific attributes. + + When called with a single argument return_python_dict=True, + return a dict of the platform specific attributes and their values. + When called without arguments or with a single argument + return_python_dict=False, return a tuple containing intermixed + attribute names with the minus prefix and their values. + + When called with a single string value, return the value for the + specific option. When called with keyword arguments, set the + corresponding attributes. """ - args = ('wm', 'attributes', self._w) + args - return self.tk.call(args) + if not kwargs: + if not args: + res = self.tk.call('wm', 'attributes', self._w) + if return_python_dict: + return _splitdict(self.tk, res) + else: + return self.tk.splitlist(res) + if len(args) == 1 and args[0] is not None: + option = args[0] + if option[0] == '-': + # TODO: deprecate + option = option[1:] + return self.tk.call('wm', 'attributes', self._w, '-' + option) + # TODO: deprecate + return self.tk.call('wm', 'attributes', self._w, *args) + elif args: + raise TypeError('wm_attribute() options have been specified as ' + 'positional and keyword arguments') + else: + self.tk.call('wm', 'attributes', self._w, *self._options(kwargs)) attributes = wm_attributes diff --git a/Lib/tkinter/simpledialog.py b/Lib/tkinter/simpledialog.py index 538bbfc318d704..0f0dc66460f798 100644 --- a/Lib/tkinter/simpledialog.py +++ b/Lib/tkinter/simpledialog.py @@ -262,7 +262,7 @@ def _setup_dialog(w): w.tk.call("::tk::unsupported::MacWindowStyle", "style", w, "moveableModal", "") elif w._windowingsystem == "x11": - w.wm_attributes("-type", "dialog") + w.wm_attributes(type="dialog") # -------------------------------------------------------------------- # convenience dialogues diff --git a/Misc/NEWS.d/next/Library/2023-10-27-19-24-58.gh-issue-43457.84lx9H.rst b/Misc/NEWS.d/next/Library/2023-10-27-19-24-58.gh-issue-43457.84lx9H.rst new file mode 100644 index 00000000000000..401a532ce03e77 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-27-19-24-58.gh-issue-43457.84lx9H.rst @@ -0,0 +1,8 @@ +Fix the :mod:`tkinter` widget method :meth:`!wm_attributes`. It now +accepts the attribute name without the minus prefix to get window attributes +and allows to specify attributes and values to set as keyword arguments. +Add new optional keyword argument *return_python_dict*: calling +``w.wm_attributes(return_python_dict=True)`` returns the attributes as +a dict instead of a tuple. +Calling ``w.wm_attributes()`` now returns a tuple instead of string if +*wantobjects* was set to 0. From 36518e69d74607e5f094ce55286188e4545a947d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 5 Feb 2024 18:28:51 +0000 Subject: [PATCH 55/62] GH-108362: Incremental GC implementation (GH-108038) --- Doc/whatsnew/3.13.rst | 34 + Include/internal/pycore_gc.h | 42 +- Include/internal/pycore_object.h | 17 +- Include/internal/pycore_runtime_init.h | 8 +- Lib/test/test_gc.py | 22 +- ...-01-07-04-22-51.gh-issue-108362.oB9Gcf.rst | 13 + Modules/gcmodule.c | 23 +- Objects/object.c | 15 + Objects/structseq.c | 5 +- Python/gc.c | 824 +++++++++++------- Python/gc_free_threading.c | 27 +- Python/import.c | 2 +- Tools/gdb/libpython.py | 7 +- 13 files changed, 647 insertions(+), 392 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-01-07-04-22-51.gh-issue-108362.oB9Gcf.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index c25d41351c2f3c..0770e28d230b4b 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -92,6 +92,10 @@ Interpreter improvements: New Features ============ +* The cyclic garbage collector is now incremental. + This means that maximum pause times are reduced, + by an order of magnitude or more for larger heaps. + Improved Error Messages ----------------------- @@ -101,6 +105,13 @@ Improved Error Messages variables. See also :ref:`using-on-controlling-color`. (Contributed by Pablo Galindo Salgado in :gh:`112730`.) +Incremental Garbage Collection +------------------------------ + +* The cycle garbage collector is now incremental. + This means that maximum pause times are reduced + by an order of magnitude or more for larger heaps. + Other Language Changes ====================== @@ -232,6 +243,29 @@ fractions sign handling, minimum width and grouping. (Contributed by Mark Dickinson in :gh:`111320`.) +gc +-- +* The cyclic garbage collector is now incremental, which changes the meanings + of the results of :meth:`gc.get_threshold` and :meth:`gc.get_threshold` as + well as :meth:`gc.get_count` and :meth:`gc.get_stats`. +* :meth:`gc.get_threshold` returns a three-tuple for backwards compatibility, + the first value is the threshold for young collections, as before, the second + value determines the rate at which the old collection is scanned; the + default is 10 and higher values mean that the old collection is scanned more slowly. + The third value is meangless and is always zero. +* :meth:`gc.set_threshold` ignores any items after the second. +* :meth:`gc.get_count` and :meth:`gc.get_stats`. + These functions return the same format of results as before. + The only difference is that instead of the results refering to + the young, aging and old generations, the results refer to the + young generation and the aging and collecting spaces of the old generation. + +In summary, code that attempted to manipulate the behavior of the cycle GC may +not work as well as intended, but it is very unlikely to harmful. +All other code will work just fine. +Uses should avoid calling :meth:`gc.collect` unless their workload is episodic, +but that has always been the case to some extent. + glob ---- diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index ca1d9fdf5253b8..d2f5c69b45ee39 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -71,11 +71,15 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) { /* Bit flags for _gc_prev */ /* Bit 0 is set when tp_finalize is called */ -#define _PyGC_PREV_MASK_FINALIZED (1) +#define _PyGC_PREV_MASK_FINALIZED 1 /* Bit 1 is set when the object is in generation which is GCed currently. */ -#define _PyGC_PREV_MASK_COLLECTING (2) +#define _PyGC_PREV_MASK_COLLECTING 2 + +/* Bit 0 is set if the object belongs to old space 1 */ +#define _PyGC_NEXT_MASK_OLD_SPACE_1 1 + /* The (N-2) most significant bits contain the real address. */ -#define _PyGC_PREV_SHIFT (2) +#define _PyGC_PREV_SHIFT 2 #define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT) /* set for debugging information */ @@ -101,11 +105,13 @@ typedef enum { // Lowest bit of _gc_next is used for flags only in GC. // But it is always 0 for normal code. static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) { - uintptr_t next = gc->_gc_next; + uintptr_t next = gc->_gc_next & _PyGC_PREV_MASK; return (PyGC_Head*)next; } static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) { - gc->_gc_next = (uintptr_t)next; + uintptr_t unext = (uintptr_t)next; + assert((unext & ~_PyGC_PREV_MASK) == 0); + gc->_gc_next = (gc->_gc_next & ~_PyGC_PREV_MASK) | unext; } // Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. @@ -113,6 +119,7 @@ static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) { uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK); return (PyGC_Head*)prev; } + static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) { uintptr_t uprev = (uintptr_t)prev; assert((uprev & ~_PyGC_PREV_MASK) == 0); @@ -198,6 +205,13 @@ struct gc_generation { generations */ }; +struct gc_collection_stats { + /* number of collected objects */ + Py_ssize_t collected; + /* total number of uncollectable objects (put into gc.garbage) */ + Py_ssize_t uncollectable; +}; + /* Running stats per generation */ struct gc_generation_stats { /* total number of collections */ @@ -219,8 +233,8 @@ struct _gc_runtime_state { int enabled; int debug; /* linked lists of container objects */ - struct gc_generation generations[NUM_GENERATIONS]; - PyGC_Head *generation0; + struct gc_generation young; + struct gc_generation old[2]; /* a permanent generation which won't be collected */ struct gc_generation permanent_generation; struct gc_generation_stats generation_stats[NUM_GENERATIONS]; @@ -233,22 +247,20 @@ struct _gc_runtime_state { /* This is the number of objects that survived the last full collection. It approximates the number of long lived objects tracked by the GC. - (by "full collection", we mean a collection of the oldest generation). */ Py_ssize_t long_lived_total; - /* This is the number of objects that survived all "non-full" - collections, and are awaiting to undergo a full collection for - the first time. */ - Py_ssize_t long_lived_pending; + + Py_ssize_t work_to_do; + /* Which of the old spaces is the visited space */ + int visited_space; }; extern void _PyGC_InitState(struct _gc_runtime_state *); -extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation, - _PyGC_Reason reason); -extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); +extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason); +extern void _PyGC_CollectNoFail(PyThreadState *tstate); /* Freeze objects tracked by the GC and ignore them in future collections. */ extern void _PyGC_Freeze(PyInterpreterState *interp); diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 34a83ea228e8b1..efa712c4a0b458 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -125,19 +125,7 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) } #define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) -static inline void _Py_SetImmortal(PyObject *op) -{ - if (op) { -#ifdef Py_GIL_DISABLED - op->ob_tid = _Py_UNOWNED_TID; - op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; - op->ob_ref_shared = 0; -#else - op->ob_refcnt = _Py_IMMORTAL_REFCNT; -#endif - } -} -#define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op)) +extern void _Py_SetImmortal(PyObject *op); // Makes an immortal object mortal again with the specified refcnt. Should only // be used during runtime finalization. @@ -325,11 +313,12 @@ static inline void _PyObject_GC_TRACK( filename, lineno, __func__); PyInterpreterState *interp = _PyInterpreterState_GET(); - PyGC_Head *generation0 = interp->gc.generation0; + PyGC_Head *generation0 = &interp->gc.young.head; PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT(last, gc); _PyGCHead_SET_PREV(gc, last); _PyGCHead_SET_NEXT(gc, generation0); + assert((gc->_gc_next & _PyGC_NEXT_MASK_OLD_SPACE_1) == 0); generation0->_gc_prev = (uintptr_t)gc; #endif } diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 0a5c92bb84b524..4370ad05bdc058 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -160,12 +160,12 @@ extern PyTypeObject _PyExc_MemoryError; }, \ .gc = { \ .enabled = 1, \ - .generations = { \ - /* .head is set in _PyGC_InitState(). */ \ - { .threshold = 700, }, \ - { .threshold = 10, }, \ + .young = { .threshold = 2000, }, \ + .old = { \ { .threshold = 10, }, \ + { .threshold = 0, }, \ }, \ + .work_to_do = -5000, \ }, \ .object_state = _py_object_state_INIT(INTERP), \ .dtoa = _dtoa_state_INIT(&(INTERP)), \ diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index b01f344cb14a1a..0002852fce9643 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -383,19 +383,11 @@ def test_collect_generations(self): # each call to collect(N) x = [] gc.collect(0) - # x is now in gen 1 + # x is now in the old gen a, b, c = gc.get_count() - gc.collect(1) - # x is now in gen 2 - d, e, f = gc.get_count() - gc.collect(2) - # x is now in gen 3 - g, h, i = gc.get_count() - # We don't check a, d, g since their exact values depends on + # We don't check a since its exact values depends on # internal implementation details of the interpreter. self.assertEqual((b, c), (1, 0)) - self.assertEqual((e, f), (0, 1)) - self.assertEqual((h, i), (0, 0)) def test_trashcan(self): class Ouch: @@ -846,16 +838,6 @@ def test_get_objects_generations(self): self.assertFalse( any(l is element for element in gc.get_objects(generation=2)) ) - gc.collect(generation=1) - self.assertFalse( - any(l is element for element in gc.get_objects(generation=0)) - ) - self.assertFalse( - any(l is element for element in gc.get_objects(generation=1)) - ) - self.assertTrue( - any(l is element for element in gc.get_objects(generation=2)) - ) gc.collect(generation=2) self.assertFalse( any(l is element for element in gc.get_objects(generation=0)) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-01-07-04-22-51.gh-issue-108362.oB9Gcf.rst b/Misc/NEWS.d/next/Core and Builtins/2024-01-07-04-22-51.gh-issue-108362.oB9Gcf.rst new file mode 100644 index 00000000000000..1fe4e0f41e1295 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-01-07-04-22-51.gh-issue-108362.oB9Gcf.rst @@ -0,0 +1,13 @@ +Implements an incremental cyclic garbage collector. By collecting the old +generation in increments, there is no need for a full heap scan. This can +hugely reduce maximum pause time for programs with large heaps. + +Reduces the number of generations from three to two. The old generation is +split into two spaces, "aging" and "collecting". + +Collection happens in two steps:: * First, the young generation is scanned +and the survivors moved to the end of the aging space. * Then objects are +taken from the collecting space, at such a rate that all cycles are +collected eventually. Those objects are then scanned and the survivors +moved to the end of the aging space. When the collecting space becomes +empty, the two spaces are swapped. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index ffddef34ecce7a..3b63dd7a9a8353 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -158,17 +158,12 @@ gc_set_threshold_impl(PyObject *module, int threshold0, int group_right_1, { GCState *gcstate = get_gc_state(); - gcstate->generations[0].threshold = threshold0; + gcstate->young.threshold = threshold0; if (group_right_1) { - gcstate->generations[1].threshold = threshold1; + gcstate->old[0].threshold = threshold1; } if (group_right_2) { - gcstate->generations[2].threshold = threshold2; - - /* generations higher than 2 get the same threshold */ - for (int i = 3; i < NUM_GENERATIONS; i++) { - gcstate->generations[i].threshold = gcstate->generations[2].threshold; - } + gcstate->old[1].threshold = threshold2; } Py_RETURN_NONE; } @@ -185,9 +180,9 @@ gc_get_threshold_impl(PyObject *module) { GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", - gcstate->generations[0].threshold, - gcstate->generations[1].threshold, - gcstate->generations[2].threshold); + gcstate->young.threshold, + gcstate->old[0].threshold, + 0); } /*[clinic input] @@ -202,9 +197,9 @@ gc_get_count_impl(PyObject *module) { GCState *gcstate = get_gc_state(); return Py_BuildValue("(iii)", - gcstate->generations[0].count, - gcstate->generations[1].count, - gcstate->generations[2].count); + gcstate->young.count, + gcstate->old[gcstate->visited_space].count, + gcstate->old[gcstate->visited_space^1].count); } /*[clinic input] diff --git a/Objects/object.c b/Objects/object.c index bbf7f98ae3daf9..7247eb21df6b6e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2387,6 +2387,21 @@ _Py_NewReferenceNoTotal(PyObject *op) new_reference(op); } +void +_Py_SetImmortal(PyObject *op) +{ + if (PyObject_IS_GC(op) && _PyObject_GC_IS_TRACKED(op)) { + _PyObject_GC_UNTRACK(op); + } +#ifdef Py_GIL_DISABLED + op->ob_tid = _Py_UNOWNED_TID; + op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; + op->ob_ref_shared = 0; +#else + op->ob_refcnt = _Py_IMMORTAL_REFCNT; +#endif +} + void _Py_ResurrectReference(PyObject *op) { diff --git a/Objects/structseq.c b/Objects/structseq.c index 581d6ad240885a..661d96a968fb80 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -603,6 +603,9 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, PyStructSequence_Desc *desc, unsigned long tp_flags) { + if (Py_TYPE(type) == NULL) { + Py_SET_TYPE(type, &PyType_Type); + } Py_ssize_t n_unnamed_members; Py_ssize_t n_members = count_members(desc, &n_unnamed_members); PyMemberDef *members = NULL; @@ -618,7 +621,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, } initialize_static_fields(type, desc, members, tp_flags); - _Py_SetImmortal(type); + _Py_SetImmortal((PyObject *)type); } #ifndef NDEBUG else { diff --git a/Python/gc.c b/Python/gc.c index 46646760291526..cda12ff7fbc982 100644 --- a/Python/gc.c +++ b/Python/gc.c @@ -45,7 +45,7 @@ typedef struct _gc_runtime_state GCState; // move_legacy_finalizers() removes this flag instead. // Between them, unreachable list is not normal list and we can not use // most gc_list_* functions for it. -#define NEXT_MASK_UNREACHABLE (1) +#define NEXT_MASK_UNREACHABLE 2 #define AS_GC(op) _Py_AS_GC(op) #define FROM_GC(gc) _Py_FROM_GC(gc) @@ -95,9 +95,48 @@ gc_decref(PyGC_Head *g) g->_gc_prev -= 1 << _PyGC_PREV_SHIFT; } +static inline int +gc_old_space(PyGC_Head *g) +{ + return g->_gc_next & _PyGC_NEXT_MASK_OLD_SPACE_1; +} -#define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) +static inline int +flip_old_space(int space) +{ + assert(space == 0 || space == 1); + return space ^ _PyGC_NEXT_MASK_OLD_SPACE_1; +} +static inline void +gc_flip_old_space(PyGC_Head *g) +{ + g->_gc_next ^= _PyGC_NEXT_MASK_OLD_SPACE_1; +} + +static inline void +gc_set_old_space(PyGC_Head *g, int space) +{ + assert(space == 0 || space == _PyGC_NEXT_MASK_OLD_SPACE_1); + g->_gc_next &= ~_PyGC_NEXT_MASK_OLD_SPACE_1; + g->_gc_next |= space; +} + +static PyGC_Head * +GEN_HEAD(GCState *gcstate, int n) +{ + assert((gcstate->visited_space & (~1)) == 0); + switch(n) { + case 0: + return &gcstate->young.head; + case 1: + return &gcstate->old[gcstate->visited_space].head; + case 2: + return &gcstate->old[gcstate->visited_space^1].head; + default: + Py_UNREACHABLE(); + } +} static GCState * get_gc_state(void) @@ -116,11 +155,12 @@ _PyGC_InitState(GCState *gcstate) GEN.head._gc_prev = (uintptr_t)&GEN.head; \ } while (0) - for (int i = 0; i < NUM_GENERATIONS; i++) { - assert(gcstate->generations[i].count == 0); - INIT_HEAD(gcstate->generations[i]); - }; - gcstate->generation0 = GEN_HEAD(gcstate, 0); + assert(gcstate->young.count == 0); + assert(gcstate->old[0].count == 0); + assert(gcstate->old[1].count == 0); + INIT_HEAD(gcstate->young); + INIT_HEAD(gcstate->old[0]); + INIT_HEAD(gcstate->old[1]); INIT_HEAD(gcstate->permanent_generation); #undef INIT_HEAD @@ -218,6 +258,7 @@ gc_list_is_empty(PyGC_Head *list) static inline void gc_list_append(PyGC_Head *node, PyGC_Head *list) { + assert((list->_gc_prev & ~_PyGC_PREV_MASK) == 0); PyGC_Head *last = (PyGC_Head *)list->_gc_prev; // last <-> node @@ -275,6 +316,8 @@ gc_list_merge(PyGC_Head *from, PyGC_Head *to) PyGC_Head *from_tail = GC_PREV(from); assert(from_head != from); assert(from_tail != from); + assert(gc_list_is_empty(to) || + gc_old_space(to_tail) == gc_old_space(from_tail)); _PyGCHead_SET_NEXT(to_tail, from_head); _PyGCHead_SET_PREV(from_head, to_tail); @@ -343,8 +386,8 @@ enum flagstates {collecting_clear_unreachable_clear, static void validate_list(PyGC_Head *head, enum flagstates flags) { - assert((head->_gc_prev & PREV_MASK_COLLECTING) == 0); - assert((head->_gc_next & NEXT_MASK_UNREACHABLE) == 0); + assert((head->_gc_prev & ~_PyGC_PREV_MASK) == 0); + assert((head->_gc_next & ~_PyGC_PREV_MASK) == 0); uintptr_t prev_value = 0, next_value = 0; switch (flags) { case collecting_clear_unreachable_clear: @@ -366,7 +409,7 @@ validate_list(PyGC_Head *head, enum flagstates flags) PyGC_Head *gc = GC_NEXT(head); while (gc != head) { PyGC_Head *trueprev = GC_PREV(gc); - PyGC_Head *truenext = (PyGC_Head *)(gc->_gc_next & ~NEXT_MASK_UNREACHABLE); + PyGC_Head *truenext = GC_NEXT(gc); assert(truenext != NULL); assert(trueprev == prev); assert((gc->_gc_prev & PREV_MASK_COLLECTING) == prev_value); @@ -376,8 +419,44 @@ validate_list(PyGC_Head *head, enum flagstates flags) } assert(prev == GC_PREV(head)); } + +static void +validate_old(GCState *gcstate) +{ + for (int space = 0; space < 2; space++) { + PyGC_Head *head = &gcstate->old[space].head; + PyGC_Head *gc = GC_NEXT(head); + while (gc != head) { + PyGC_Head *next = GC_NEXT(gc); + assert(gc_old_space(gc) == space); + gc = next; + } + } +} + +static void +validate_consistent_old_space(PyGC_Head *head) +{ + PyGC_Head *prev = head; + PyGC_Head *gc = GC_NEXT(head); + if (gc == head) { + return; + } + int old_space = gc_old_space(gc); + while (gc != head) { + PyGC_Head *truenext = GC_NEXT(gc); + assert(truenext != NULL); + assert(gc_old_space(gc) == old_space); + prev = gc; + gc = truenext; + } + assert(prev == GC_PREV(head)); +} + #else #define validate_list(x, y) do{}while(0) +#define validate_old(g) do{}while(0) +#define validate_consistent_old_space(l) do{}while(0) #endif /*** end of list stuff ***/ @@ -394,15 +473,7 @@ update_refs(PyGC_Head *containers) while (gc != containers) { next = GC_NEXT(gc); - /* Move any object that might have become immortal to the - * permanent generation as the reference count is not accurately - * reflecting the actual number of live references to this object - */ - if (_Py_IsImmortal(FROM_GC(gc))) { - gc_list_move(gc, &get_gc_state()->permanent_generation.head); - gc = next; - continue; - } + assert(!_Py_IsImmortal(FROM_GC(gc))); gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc))); /* Python's cyclic gc should never see an incoming refcount * of 0: if something decref'ed to 0, it should have been @@ -500,12 +571,13 @@ visit_reachable(PyObject *op, void *arg) // Manually unlink gc from unreachable list because the list functions // don't work right in the presence of NEXT_MASK_UNREACHABLE flags. PyGC_Head *prev = GC_PREV(gc); - PyGC_Head *next = (PyGC_Head*)(gc->_gc_next & ~NEXT_MASK_UNREACHABLE); + PyGC_Head *next = GC_NEXT(gc); _PyObject_ASSERT(FROM_GC(prev), prev->_gc_next & NEXT_MASK_UNREACHABLE); _PyObject_ASSERT(FROM_GC(next), next->_gc_next & NEXT_MASK_UNREACHABLE); - prev->_gc_next = gc->_gc_next; // copy NEXT_MASK_UNREACHABLE + prev->_gc_next = gc->_gc_next; // copy flag bits + gc->_gc_next &= ~NEXT_MASK_UNREACHABLE; _PyGCHead_SET_PREV(next, prev); gc_list_append(gc, reachable); @@ -557,6 +629,9 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) * or to the right have been scanned yet. */ + validate_consistent_old_space(young); + /* Record which old space we are in, and set NEXT_MASK_UNREACHABLE bit for convenience */ + uintptr_t flags = NEXT_MASK_UNREACHABLE | (gc->_gc_next & _PyGC_NEXT_MASK_OLD_SPACE_1); while (gc != young) { if (gc_get_refs(gc)) { /* gc is definitely reachable from outside the @@ -602,17 +677,18 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) // But this may pollute the unreachable list head's 'next' pointer // too. That's semantically senseless but expedient here - the // damage is repaired when this function ends. - last->_gc_next = (NEXT_MASK_UNREACHABLE | (uintptr_t)gc); + last->_gc_next = flags | (uintptr_t)gc; _PyGCHead_SET_PREV(gc, last); - gc->_gc_next = (NEXT_MASK_UNREACHABLE | (uintptr_t)unreachable); + gc->_gc_next = flags | (uintptr_t)unreachable; unreachable->_gc_prev = (uintptr_t)gc; } - gc = (PyGC_Head*)prev->_gc_next; + gc = _PyGCHead_NEXT(prev); } // young->_gc_prev must be last element remained in the list. young->_gc_prev = (uintptr_t)prev; + young->_gc_next &= _PyGC_PREV_MASK; // don't let the pollution of the list head's next pointer leak - unreachable->_gc_next &= ~NEXT_MASK_UNREACHABLE; + unreachable->_gc_next &= _PyGC_PREV_MASK; } static void @@ -669,8 +745,8 @@ move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) PyObject *op = FROM_GC(gc); _PyObject_ASSERT(op, gc->_gc_next & NEXT_MASK_UNREACHABLE); + next = GC_NEXT(gc); gc->_gc_next &= ~NEXT_MASK_UNREACHABLE; - next = (PyGC_Head*)gc->_gc_next; if (has_legacy_finalizer(op)) { gc_clear_collecting(gc); @@ -689,8 +765,8 @@ clear_unreachable_mask(PyGC_Head *unreachable) assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0); for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) { _PyObject_ASSERT((PyObject*)FROM_GC(gc), gc->_gc_next & NEXT_MASK_UNREACHABLE); + next = GC_NEXT(gc); gc->_gc_next &= ~NEXT_MASK_UNREACHABLE; - next = (PyGC_Head*)gc->_gc_next; } validate_list(unreachable, collecting_set_unreachable_clear); } @@ -1023,25 +1099,6 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, } -// Show stats for objects in each generations -static void -show_stats_each_generations(GCState *gcstate) -{ - char buf[100]; - size_t pos = 0; - - for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { - pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, - " %zd", - gc_list_size(GEN_HEAD(gcstate, i))); - } - - PySys_FormatStderr( - "gc: objects in each generation:%s\n" - "gc: objects in permanent generation: %zd\n", - buf, gc_list_size(&gcstate->permanent_generation.head)); -} - /* Deduce which objects among "base" are unreachable from outside the list and move them to 'unreachable'. The process consist in the following steps: @@ -1115,7 +1172,6 @@ deduce_unreachable(PyGC_Head *base, PyGC_Head *unreachable) { * the reachable objects instead. But this is a one-time cost, probably not * worth complicating the code to speed just a little. */ - gc_list_init(unreachable); move_unreachable(base, unreachable); // gc_prev is pointer again validate_list(base, collecting_clear_unreachable_clear); validate_list(unreachable, collecting_set_unreachable_set); @@ -1154,219 +1210,272 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, } -/* Invoke progress callbacks to notify clients that garbage collection - * is starting or stopping - */ +#define UNTRACK_TUPLES 1 +#define UNTRACK_DICTS 2 + static void -invoke_gc_callback(PyThreadState *tstate, const char *phase, - int generation, Py_ssize_t collected, - Py_ssize_t uncollectable) -{ - assert(!_PyErr_Occurred(tstate)); +gc_collect_region(PyThreadState *tstate, + PyGC_Head *from, + PyGC_Head *to, + int untrack, + struct gc_collection_stats *stats); - /* we may get called very early */ - GCState *gcstate = &tstate->interp->gc; - if (gcstate->callbacks == NULL) { - return; +static inline Py_ssize_t +gc_list_set_space(PyGC_Head *list, int space) +{ + Py_ssize_t size = 0; + PyGC_Head *gc; + for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(gc)) { + gc_set_old_space(gc, space); + size++; } + return size; +} - /* The local variable cannot be rebound, check it for sanity */ - assert(PyList_CheckExact(gcstate->callbacks)); - PyObject *info = NULL; - if (PyList_GET_SIZE(gcstate->callbacks) != 0) { - info = Py_BuildValue("{sisnsn}", - "generation", generation, - "collected", collected, - "uncollectable", uncollectable); - if (info == NULL) { - PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); - return; + +static void +add_stats(GCState *gcstate, int gen, struct gc_collection_stats *stats) +{ + gcstate->generation_stats[gen].collected += stats->collected; + gcstate->generation_stats[gen].uncollectable += stats->uncollectable; + gcstate->generation_stats[gen].collections += 1; +} + + +/* Multiply by 4 so that the default incremental threshold of 10 + * scans objects at 40% the rate that the young gen tenures them. */ +#define SCAN_RATE_MULTIPLIER 4 + + +static void +gc_collect_young(PyThreadState *tstate, + struct gc_collection_stats *stats) +{ + GCState *gcstate = &tstate->interp->gc; + PyGC_Head *young = &gcstate->young.head; + PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head; +#ifdef Py_STATS + { + Py_ssize_t count = 0; + PyGC_Head *gc; + for (gc = GC_NEXT(young); gc != young; gc = GC_NEXT(gc)) { + count++; } } +#endif - PyObject *phase_obj = PyUnicode_FromString(phase); - if (phase_obj == NULL) { - Py_XDECREF(info); - PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); - return; + PyGC_Head survivors; + gc_list_init(&survivors); + gc_collect_region(tstate, young, &survivors, UNTRACK_TUPLES, stats); + Py_ssize_t survivor_count = 0; + if (gcstate->visited_space) { + /* objects in visited space have bit set, so we set it here */ + survivor_count = gc_list_set_space(&survivors, 1); } - - PyObject *stack[] = {phase_obj, info}; - for (Py_ssize_t i=0; icallbacks); i++) { - PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); - Py_INCREF(cb); /* make sure cb doesn't go away */ - r = PyObject_Vectorcall(cb, stack, 2, NULL); - if (r == NULL) { - PyErr_WriteUnraisable(cb); - } - else { - Py_DECREF(r); + else { + PyGC_Head *gc; + for (gc = GC_NEXT(&survivors); gc != &survivors; gc = GC_NEXT(gc)) { +#ifdef GC_DEBUG + assert(gc_old_space(gc) == 0); +#endif + survivor_count++; } - Py_DECREF(cb); } - Py_DECREF(phase_obj); - Py_XDECREF(info); - assert(!_PyErr_Occurred(tstate)); + gc_list_merge(&survivors, visited); + validate_old(gcstate); + gcstate->young.count = 0; + gcstate->old[gcstate->visited_space].count++; + Py_ssize_t scale_factor = gcstate->old[0].threshold; + if (scale_factor < 1) { + scale_factor = 1; + } + gcstate->work_to_do += survivor_count + survivor_count * SCAN_RATE_MULTIPLIER / scale_factor; + add_stats(gcstate, 0, stats); +} + +static inline int +is_in_visited(PyGC_Head *gc, int visited_space) +{ + assert(visited_space == 0 || flip_old_space(visited_space) == 0); + return gc_old_space(gc) == visited_space; } +struct container_and_flag { + PyGC_Head *container; + int visited_space; +}; -/* Find the oldest generation (highest numbered) where the count - * exceeds the threshold. Objects in the that generation and - * generations younger than it will be collected. */ +/* A traversal callback for adding to container) */ static int -gc_select_generation(GCState *gcstate) -{ - for (int i = NUM_GENERATIONS-1; i >= 0; i--) { - if (gcstate->generations[i].count > gcstate->generations[i].threshold) { - /* Avoid quadratic performance degradation in number - of tracked objects (see also issue #4074): - - To limit the cost of garbage collection, there are two strategies; - - make each collection faster, e.g. by scanning fewer objects - - do less collections - This heuristic is about the latter strategy. - - In addition to the various configurable thresholds, we only trigger a - full collection if the ratio - - long_lived_pending / long_lived_total - - is above a given value (hardwired to 25%). - - The reason is that, while "non-full" collections (i.e., collections of - the young and middle generations) will always examine roughly the same - number of objects -- determined by the aforementioned thresholds --, - the cost of a full collection is proportional to the total number of - long-lived objects, which is virtually unbounded. - - Indeed, it has been remarked that doing a full collection every - of object creations entails a dramatic performance - degradation in workloads which consist in creating and storing lots of - long-lived objects (e.g. building a large list of GC-tracked objects would - show quadratic performance, instead of linear as expected: see issue #4074). - - Using the above ratio, instead, yields amortized linear performance in - the total number of objects (the effect of which can be summarized - thusly: "each full garbage collection is more and more costly as the - number of objects grows, but we do fewer and fewer of them"). - - This heuristic was suggested by Martin von Löwis on python-dev in - June 2008. His original analysis and proposal can be found at: - http://mail.python.org/pipermail/python-dev/2008-June/080579.html - */ - if (i == NUM_GENERATIONS - 1 - && gcstate->long_lived_pending < gcstate->long_lived_total / 4) - { - continue; - } - return i; +visit_add_to_container(PyObject *op, void *arg) +{ + OBJECT_STAT_INC(object_visits); + struct container_and_flag *cf = (struct container_and_flag *)arg; + int visited = cf->visited_space; + assert(visited == get_gc_state()->visited_space); + if (_PyObject_IS_GC(op)) { + PyGC_Head *gc = AS_GC(op); + if (_PyObject_GC_IS_TRACKED(op) && + gc_old_space(gc) != visited) { + assert(!_Py_IsImmortal(op)); + gc_flip_old_space(gc); + gc_list_move(gc, cf->container); } } - return -1; + return 0; } - -/* This is the main function. Read this to understand how the - * collection process works. */ -static Py_ssize_t -gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason) +static uintptr_t +expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCState *gcstate) { - int i; - Py_ssize_t m = 0; /* # objects collected */ - Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */ - PyGC_Head *young; /* the generation we are examining */ - PyGC_Head *old; /* next older generation */ - PyGC_Head unreachable; /* non-problematic unreachable trash */ - PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ - PyGC_Head *gc; - _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ - GCState *gcstate = &tstate->interp->gc; - - // gc_collect_main() must not be called before _PyGC_Init - // or after _PyGC_Fini() - assert(gcstate->garbage != NULL); - assert(!_PyErr_Occurred(tstate)); + validate_list(container, collecting_clear_unreachable_clear); + struct container_and_flag arg = { + .container = container, + .visited_space = gcstate->visited_space, + }; + uintptr_t size = 0; + assert(GC_NEXT(gc) == container); + while (gc != container) { + /* Survivors will be moved to visited space, so they should + * have been marked as visited */ + assert(is_in_visited(gc, gcstate->visited_space)); + PyObject *op = FROM_GC(gc); + if (_Py_IsImmortal(op)) { + PyGC_Head *next = GC_NEXT(gc); + gc_list_move(gc, &get_gc_state()->permanent_generation.head); + gc = next; + continue; + } + traverseproc traverse = Py_TYPE(op)->tp_traverse; + (void) traverse(op, + visit_add_to_container, + &arg); + gc = GC_NEXT(gc); + size++; + } + return size; +} - int expected = 0; - if (!_Py_atomic_compare_exchange_int(&gcstate->collecting, &expected, 1)) { - // Don't start a garbage collection if one is already in progress. - return 0; +/* Do bookkeeping for a completed GC cycle */ +static void +completed_cycle(GCState *gcstate) +{ + assert(gc_list_is_empty(&gcstate->old[gcstate->visited_space^1].head)); + assert(gc_list_is_empty(&gcstate->young.head)); + gcstate->visited_space = flip_old_space(gcstate->visited_space); + if (gcstate->work_to_do > 0) { + gcstate->work_to_do = 0; } +} - if (generation == GENERATION_AUTO) { - // Select the oldest generation that needs collecting. We will collect - // objects from that generation and all generations younger than it. - generation = gc_select_generation(gcstate); - if (generation < 0) { - // No generation needs to be collected. - _Py_atomic_store_int(&gcstate->collecting, 0); - return 0; +static void +gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats) +{ + GCState *gcstate = &tstate->interp->gc; + if (gcstate->work_to_do <= 0) { + /* No work to do */ + return; + } + PyGC_Head *not_visited = &gcstate->old[gcstate->visited_space^1].head; + PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head; + PyGC_Head increment; + gc_list_init(&increment); + if (gc_list_is_empty(not_visited)) { + completed_cycle(gcstate); + return; + } + Py_ssize_t region_size = 0; + while (region_size < gcstate->work_to_do) { + if (gc_list_is_empty(not_visited)) { + break; } + PyGC_Head *gc = _PyGCHead_NEXT(not_visited); + gc_list_move(gc, &increment); + gc_set_old_space(gc, gcstate->visited_space); + region_size += expand_region_transitively_reachable(&increment, gc, gcstate); } - - assert(generation >= 0 && generation < NUM_GENERATIONS); - -#ifdef Py_STATS - if (_Py_stats) { - _Py_stats->object_stats.object_visits = 0; + assert(region_size == gc_list_size(&increment)); + PyGC_Head survivors; + gc_list_init(&survivors); + gc_collect_region(tstate, &increment, &survivors, UNTRACK_TUPLES, stats); + gc_list_merge(&survivors, visited); + assert(gc_list_is_empty(&increment)); + gcstate->work_to_do -= region_size; + validate_old(gcstate); + add_stats(gcstate, 1, stats); + if (gc_list_is_empty(not_visited)) { + completed_cycle(gcstate); } -#endif - GC_STAT_ADD(generation, collections, 1); +} - if (reason != _Py_GC_REASON_SHUTDOWN) { - invoke_gc_callback(tstate, "start", generation, 0, 0); - } - if (gcstate->debug & _PyGC_DEBUG_STATS) { - PySys_WriteStderr("gc: collecting generation %d...\n", generation); - show_stats_each_generations(gcstate); - t1 = _PyTime_GetPerfCounter(); +static void +gc_collect_full(PyThreadState *tstate, + struct gc_collection_stats *stats) +{ + GCState *gcstate = &tstate->interp->gc; + validate_old(gcstate); + PyGC_Head *young = &gcstate->young.head; + PyGC_Head *old0 = &gcstate->old[0].head; + PyGC_Head *old1 = &gcstate->old[1].head; + /* merge all generations into old0 */ + gc_list_merge(young, old0); + gcstate->young.count = 0; + PyGC_Head *gc = GC_NEXT(old1); + while (gc != old1) { + PyGC_Head *next = GC_NEXT(gc); + gc_set_old_space(gc, 0); + gc = next; } + gc_list_merge(old1, old0); - if (PyDTrace_GC_START_ENABLED()) { - PyDTrace_GC_START(generation); - } + gc_collect_region(tstate, old0, old0, + UNTRACK_TUPLES | UNTRACK_DICTS, + stats); + gcstate->visited_space = 1; + gcstate->young.count = 0; + gcstate->old[0].count = 0; + gcstate->old[1].count = 0; - /* update collection and allocation counters */ - if (generation+1 < NUM_GENERATIONS) { - gcstate->generations[generation+1].count += 1; - } - for (i = 0; i <= generation; i++) { - gcstate->generations[i].count = 0; - } + gcstate->work_to_do = - gcstate->young.threshold * 2; - /* merge younger generations with one we are currently collecting */ - for (i = 0; i < generation; i++) { - gc_list_merge(GEN_HEAD(gcstate, i), GEN_HEAD(gcstate, generation)); - } + _PyGC_ClearAllFreeLists(tstate->interp); + validate_old(gcstate); + add_stats(gcstate, 2, stats); +} - /* handy references */ - young = GEN_HEAD(gcstate, generation); - if (generation < NUM_GENERATIONS-1) { - old = GEN_HEAD(gcstate, generation+1); - } - else { - old = young; - } - validate_list(old, collecting_clear_unreachable_clear); +/* This is the main function. Read this to understand how the + * collection process works. */ +static void +gc_collect_region(PyThreadState *tstate, + PyGC_Head *from, + PyGC_Head *to, + int untrack, + struct gc_collection_stats *stats) +{ + PyGC_Head unreachable; /* non-problematic unreachable trash */ + PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ + PyGC_Head *gc; /* initialize to prevent a compiler warning */ + GCState *gcstate = &tstate->interp->gc; - deduce_unreachable(young, &unreachable); + assert(gcstate->garbage != NULL); + assert(!_PyErr_Occurred(tstate)); - untrack_tuples(young); - /* Move reachable objects to next generation. */ - if (young != old) { - if (generation == NUM_GENERATIONS - 2) { - gcstate->long_lived_pending += gc_list_size(young); - } - gc_list_merge(young, old); + gc_list_init(&unreachable); + deduce_unreachable(from, &unreachable); + validate_consistent_old_space(from); + if (untrack & UNTRACK_TUPLES) { + untrack_tuples(from); } - else { - /* We only un-track dicts in full collections, to avoid quadratic - dict build-up. See issue #14775. */ - untrack_dicts(young); - gcstate->long_lived_pending = 0; - gcstate->long_lived_total = gc_list_size(young); + if (untrack & UNTRACK_DICTS) { + untrack_dicts(from); } + validate_consistent_old_space(to); + if (from != to) { + gc_list_merge(from, to); + } + validate_consistent_old_space(to); + /* Move reachable objects to next generation. */ /* All objects in unreachable are trash, but objects reachable from * legacy finalizers (e.g. tp_del) can't safely be deleted. @@ -1380,10 +1489,8 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason) * and we move those into the finalizers list too. */ move_legacy_finalizer_reachable(&finalizers); - validate_list(&finalizers, collecting_clear_unreachable_clear); validate_list(&unreachable, collecting_set_unreachable_clear); - /* Print debugging information. */ if (gcstate->debug & _PyGC_DEBUG_COLLECTABLE) { for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { @@ -1392,89 +1499,99 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason) } /* Clear weakrefs and invoke callbacks as necessary. */ - m += handle_weakrefs(&unreachable, old); - - validate_list(old, collecting_clear_unreachable_clear); + stats->collected += handle_weakrefs(&unreachable, to); + validate_list(to, collecting_clear_unreachable_clear); validate_list(&unreachable, collecting_set_unreachable_clear); /* Call tp_finalize on objects which have one. */ finalize_garbage(tstate, &unreachable); - /* Handle any objects that may have resurrected after the call * to 'finalize_garbage' and continue the collection with the * objects that are still unreachable */ PyGC_Head final_unreachable; - handle_resurrected_objects(&unreachable, &final_unreachable, old); + gc_list_init(&final_unreachable); + handle_resurrected_objects(&unreachable, &final_unreachable, to); /* Call tp_clear on objects in the final_unreachable set. This will cause * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. */ - m += gc_list_size(&final_unreachable); - delete_garbage(tstate, gcstate, &final_unreachable, old); + stats->collected += gc_list_size(&final_unreachable); + delete_garbage(tstate, gcstate, &final_unreachable, to); /* Collect statistics on uncollectable objects found and print * debugging information. */ + Py_ssize_t n = 0; for (gc = GC_NEXT(&finalizers); gc != &finalizers; gc = GC_NEXT(gc)) { n++; if (gcstate->debug & _PyGC_DEBUG_UNCOLLECTABLE) debug_cycle("uncollectable", FROM_GC(gc)); } - if (gcstate->debug & _PyGC_DEBUG_STATS) { - double d = _PyTime_AsSecondsDouble(_PyTime_GetPerfCounter() - t1); - PySys_WriteStderr( - "gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n", - n+m, n, d); - } - + stats->uncollectable = n; /* Append instances in the uncollectable set to a Python * reachable list of garbage. The programmer has to deal with * this if they insist on creating this type of structure. */ - handle_legacy_finalizers(tstate, gcstate, &finalizers, old); - validate_list(old, collecting_clear_unreachable_clear); + handle_legacy_finalizers(tstate, gcstate, &finalizers, to); + validate_list(to, collecting_clear_unreachable_clear); +} - /* Clear free list only during the collection of the highest - * generation */ - if (generation == NUM_GENERATIONS-1) { - _PyGC_ClearAllFreeLists(tstate->interp); - } +/* Invoke progress callbacks to notify clients that garbage collection + * is starting or stopping + */ +static void +do_gc_callback(GCState *gcstate, const char *phase, + int generation, struct gc_collection_stats *stats) +{ + assert(!PyErr_Occurred()); - if (_PyErr_Occurred(tstate)) { - if (reason == _Py_GC_REASON_SHUTDOWN) { - _PyErr_Clear(tstate); - } - else { - PyErr_FormatUnraisable("Exception ignored in garbage collection"); + /* The local variable cannot be rebound, check it for sanity */ + assert(PyList_CheckExact(gcstate->callbacks)); + PyObject *info = NULL; + if (PyList_GET_SIZE(gcstate->callbacks) != 0) { + info = Py_BuildValue("{sisnsn}", + "generation", generation, + "collected", stats->collected, + "uncollectable", stats->uncollectable); + if (info == NULL) { + PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); + return; } } - /* Update stats */ - struct gc_generation_stats *stats = &gcstate->generation_stats[generation]; - stats->collections++; - stats->collected += m; - stats->uncollectable += n; - - GC_STAT_ADD(generation, objects_collected, m); -#ifdef Py_STATS - if (_Py_stats) { - GC_STAT_ADD(generation, object_visits, - _Py_stats->object_stats.object_visits); - _Py_stats->object_stats.object_visits = 0; + PyObject *phase_obj = PyUnicode_FromString(phase); + if (phase_obj == NULL) { + Py_XDECREF(info); + PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); + return; } -#endif - if (PyDTrace_GC_DONE_ENABLED()) { - PyDTrace_GC_DONE(n + m); + PyObject *stack[] = {phase_obj, info}; + for (Py_ssize_t i=0; icallbacks); i++) { + PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); + Py_INCREF(cb); /* make sure cb doesn't go away */ + r = PyObject_Vectorcall(cb, stack, 2, NULL); + if (r == NULL) { + PyErr_WriteUnraisable(cb); + } + else { + Py_DECREF(r); + } + Py_DECREF(cb); } + Py_DECREF(phase_obj); + Py_XDECREF(info); + assert(!PyErr_Occurred()); +} - if (reason != _Py_GC_REASON_SHUTDOWN) { - invoke_gc_callback(tstate, "stop", generation, m, n); +static void +invoke_gc_callback(GCState *gcstate, const char *phase, + int generation, struct gc_collection_stats *stats) +{ + if (gcstate->callbacks == NULL) { + return; } - - assert(!_PyErr_Occurred(tstate)); - _Py_atomic_store_int(&gcstate->collecting, 0); - return n + m; + do_gc_callback(gcstate, phase, generation, stats); } static int @@ -1549,7 +1666,7 @@ _PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generation) } } else { - if (append_objects(result, GEN_HEAD(gcstate, generation))) { + if (append_objects(result, GEN_HEAD(gcstate, (int)generation))) { goto error; } } @@ -1564,10 +1681,16 @@ void _PyGC_Freeze(PyInterpreterState *interp) { GCState *gcstate = &interp->gc; - for (int i = 0; i < NUM_GENERATIONS; ++i) { - gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); - gcstate->generations[i].count = 0; - } + gc_list_merge(&gcstate->young.head, &gcstate->permanent_generation.head); + gcstate->young.count = 0; + PyGC_Head*old0 = &gcstate->old[0].head; + PyGC_Head*old1 = &gcstate->old[1].head; + gc_list_merge(old0, &gcstate->permanent_generation.head); + gcstate->old[0].count = 0; + gc_list_set_space(old1, 0); + gc_list_merge(old1, &gcstate->permanent_generation.head); + gcstate->old[1].count = 0; + validate_old(gcstate); } void @@ -1575,7 +1698,8 @@ _PyGC_Unfreeze(PyInterpreterState *interp) { GCState *gcstate = &interp->gc; gc_list_merge(&gcstate->permanent_generation.head, - GEN_HEAD(gcstate, NUM_GENERATIONS-1)); + &gcstate->old[0].head); + validate_old(gcstate); } Py_ssize_t @@ -1611,32 +1735,100 @@ PyGC_IsEnabled(void) return gcstate->enabled; } -/* Public API to invoke gc.collect() from C */ +// Show stats for objects in each generations +static void +show_stats_each_generations(GCState *gcstate) +{ + char buf[100]; + size_t pos = 0; + + for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { + pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, + " %zd", + gc_list_size(GEN_HEAD(gcstate, i))); + } + + PySys_FormatStderr( + "gc: objects in each generation:%s\n" + "gc: objects in permanent generation: %zd\n", + buf, gc_list_size(&gcstate->permanent_generation.head)); +} + Py_ssize_t -PyGC_Collect(void) +_PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason) { - PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - if (!gcstate->enabled) { + int expected = 0; + if (!_Py_atomic_compare_exchange_int(&gcstate->collecting, &expected, 1)) { + // Don't start a garbage collection if one is already in progress. return 0; } - Py_ssize_t n; + struct gc_collection_stats stats = { 0 }; + if (reason != _Py_GC_REASON_SHUTDOWN) { + invoke_gc_callback(gcstate, "start", generation, &stats); + } + _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ + if (gcstate->debug & _PyGC_DEBUG_STATS) { + PySys_WriteStderr("gc: collecting generation %d...\n", generation); + show_stats_each_generations(gcstate); + t1 = _PyTime_GetPerfCounter(); + } + if (PyDTrace_GC_START_ENABLED()) { + PyDTrace_GC_START(generation); + } + GC_STAT_ADD(generation, collections, 1); PyObject *exc = _PyErr_GetRaisedException(tstate); - n = gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_MANUAL); + switch(generation) { + case 0: + gc_collect_young(tstate, &stats); + break; + case 1: + gc_collect_young(tstate, &stats); + gc_collect_increment(tstate, &stats); + break; + case 2: + gc_collect_full(tstate, &stats); + break; + default: + Py_UNREACHABLE(); + } + if (PyDTrace_GC_DONE_ENABLED()) { + PyDTrace_GC_DONE(stats.uncollectable + stats.collected); + } + if (reason != _Py_GC_REASON_SHUTDOWN) { + invoke_gc_callback(gcstate, "stop", generation, &stats); + } _PyErr_SetRaisedException(tstate, exc); + GC_STAT_ADD(generation, objects_collected, stats.collected); +#ifdef Py_STATS + if (_Py_stats) { + GC_STAT_ADD(generation, object_visits, + _Py_stats->object_stats.object_visits); + _Py_stats->object_stats.object_visits = 0; + } +#endif + validate_old(gcstate); + if (gcstate->debug & _PyGC_DEBUG_STATS) { + double d = _PyTime_AsSecondsDouble(_PyTime_GetPerfCounter() - t1); + PySys_WriteStderr( + "gc: done, %zd collected, %zd uncollectable, %.4fs elapsed\n", + stats.collected, stats.uncollectable, d); + } - return n; + _Py_atomic_store_int(&gcstate->collecting, 0); + return stats.uncollectable + stats.collected; } +/* Public API to invoke gc.collect() from C */ Py_ssize_t -_PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason) +PyGC_Collect(void) { - return gc_collect_main(tstate, generation, reason); + return _PyGC_Collect(_PyThreadState_GET(), 2, _Py_GC_REASON_MANUAL); } -Py_ssize_t +void _PyGC_CollectNoFail(PyThreadState *tstate) { /* Ideally, this function is only called on interpreter shutdown, @@ -1645,7 +1837,7 @@ _PyGC_CollectNoFail(PyThreadState *tstate) during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ - return gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_SHUTDOWN); + _PyGC_Collect(_PyThreadState_GET(), 2, _Py_GC_REASON_SHUTDOWN); } void @@ -1780,10 +1972,10 @@ _PyObject_GC_Link(PyObject *op) GCState *gcstate = &tstate->interp->gc; g->_gc_next = 0; g->_gc_prev = 0; - gcstate->generations[0].count++; /* number of allocated GC objects */ - if (gcstate->generations[0].count > gcstate->generations[0].threshold && + gcstate->young.count++; /* number of allocated GC objects */ + if (gcstate->young.count > gcstate->young.threshold && gcstate->enabled && - gcstate->generations[0].threshold && + gcstate->young.threshold && !_Py_atomic_load_int_relaxed(&gcstate->collecting) && !_PyErr_Occurred(tstate)) { @@ -1794,7 +1986,9 @@ _PyObject_GC_Link(PyObject *op) void _Py_RunGC(PyThreadState *tstate) { - gc_collect_main(tstate, GENERATION_AUTO, _Py_GC_REASON_HEAP); + if (tstate->interp->gc.enabled) { + _PyGC_Collect(tstate, 1, _Py_GC_REASON_HEAP); + } } static PyObject * @@ -1897,8 +2091,8 @@ PyObject_GC_Del(void *op) #endif } GCState *gcstate = get_gc_state(); - if (gcstate->generations[0].count > 0) { - gcstate->generations[0].count--; + if (gcstate->young.count > 0) { + gcstate->young.count--; } PyObject_Free(((char *)op)-presize); } @@ -1921,26 +2115,36 @@ PyObject_GC_IsFinalized(PyObject *obj) return 0; } +static int +visit_generation(gcvisitobjects_t callback, void *arg, struct gc_generation *gen) +{ + PyGC_Head *gc_list, *gc; + gc_list = &gen->head; + for (gc = GC_NEXT(gc_list); gc != gc_list; gc = GC_NEXT(gc)) { + PyObject *op = FROM_GC(gc); + Py_INCREF(op); + int res = callback(op, arg); + Py_DECREF(op); + if (!res) { + return -1; + } + } + return 0; +} + void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg) { - size_t i; GCState *gcstate = get_gc_state(); int origenstate = gcstate->enabled; gcstate->enabled = 0; - for (i = 0; i < NUM_GENERATIONS; i++) { - PyGC_Head *gc_list, *gc; - gc_list = GEN_HEAD(gcstate, i); - for (gc = GC_NEXT(gc_list); gc != gc_list; gc = GC_NEXT(gc)) { - PyObject *op = FROM_GC(gc); - Py_INCREF(op); - int res = callback(op, arg); - Py_DECREF(op); - if (!res) { - goto done; - } - } + if (visit_generation(callback, arg, &gcstate->young)) { + goto done; + } + if (visit_generation(callback, arg, &gcstate->old[0])) { + goto done; } + visit_generation(callback, arg, &gcstate->old[1]); done: gcstate->enabled = origenstate; } diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 8fbcdb15109b76..1c4da726866e4e 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -616,7 +616,7 @@ void _PyGC_InitState(GCState *gcstate) { // TODO: move to pycore_runtime_init.h once the incremental GC lands. - gcstate->generations[0].threshold = 2000; + gcstate->young.threshold = 2000; } @@ -911,8 +911,8 @@ cleanup_worklist(struct worklist *worklist) static bool gc_should_collect(GCState *gcstate) { - int count = _Py_atomic_load_int_relaxed(&gcstate->generations[0].count); - int threshold = gcstate->generations[0].threshold; + int count = _Py_atomic_load_int_relaxed(&gcstate->young.count); + int threshold = gcstate->young.threshold; if (count <= threshold || threshold == 0 || !gcstate->enabled) { return false; } @@ -920,7 +920,7 @@ gc_should_collect(GCState *gcstate) // objects. A few tests rely on immediate scheduling of the GC so we ignore // the scaled threshold if generations[1].threshold is set to zero. return (count > gcstate->long_lived_total / 4 || - gcstate->generations[1].threshold == 0); + gcstate->old[0].threshold == 0); } static void @@ -1031,10 +1031,15 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason) /* update collection and allocation counters */ if (generation+1 < NUM_GENERATIONS) { - gcstate->generations[generation+1].count += 1; + gcstate->old[generation].count += 1; } for (i = 0; i <= generation; i++) { - gcstate->generations[i].count = 0; + if (i == 0) { + gcstate->young.count = 0; + } + else { + gcstate->old[i-1].count = 0; + } } PyInterpreterState *interp = tstate->interp; @@ -1357,7 +1362,7 @@ _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason) return gc_collect_main(tstate, generation, reason); } -Py_ssize_t +void _PyGC_CollectNoFail(PyThreadState *tstate) { /* Ideally, this function is only called on interpreter shutdown, @@ -1366,7 +1371,7 @@ _PyGC_CollectNoFail(PyThreadState *tstate) during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ - return gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_SHUTDOWN); + gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_SHUTDOWN); } void @@ -1490,7 +1495,7 @@ _PyObject_GC_Link(PyObject *op) { PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - gcstate->generations[0].count++; + gcstate->young.count++; if (gc_should_collect(gcstate) && !_Py_atomic_load_int_relaxed(&gcstate->collecting)) @@ -1605,8 +1610,8 @@ PyObject_GC_Del(void *op) #endif } GCState *gcstate = get_gc_state(); - if (gcstate->generations[0].count > 0) { - gcstate->generations[0].count--; + if (gcstate->young.count > 0) { + gcstate->young.count--; } PyObject_Free(((char *)op)-presize); } diff --git a/Python/import.c b/Python/import.c index 2fd0c08a6bb5ae..dfc5ec1f2f2927 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1030,7 +1030,7 @@ _extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def) if (!already_set) { /* We assume that all module defs are statically allocated and will never be freed. Otherwise, we would incref here. */ - _Py_SetImmortal(def); + _Py_SetImmortal((PyObject *)def); } res = 0; diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 483f28b46dfec7..96b891481d9f46 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1753,8 +1753,11 @@ def is_waiting_for_gil(self): return (name == 'take_gil') def is_gc_collect(self): - '''Is this frame gc_collect_main() within the garbage-collector?''' - return self._gdbframe.name() in ('collect', 'gc_collect_main') + '''Is this frame a collector within the garbage-collector?''' + return self._gdbframe.name() in ( + 'collect', 'gc_collect_full', 'gc_collect_main', + 'gc_collect_young', 'gc_collect_increment' + ) def get_pyop(self): try: From bcccf1fb63870c1b7f8abe246e27b7fff343abd7 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Mon, 5 Feb 2024 10:35:59 -0800 Subject: [PATCH 56/62] gh-112075: Add gc shared bits (#114931) Add GC shared flags for objects to the GC bit states in free-threaded builds --- Include/internal/pycore_gc.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index d2f5c69b45ee39..aeb07238fc8345 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -43,6 +43,7 @@ static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) { # define _PyGC_BITS_FINALIZED (2) # define _PyGC_BITS_UNREACHABLE (4) # define _PyGC_BITS_FROZEN (8) +# define _PyGC_BITS_SHARED (16) #endif /* True if the object is currently tracked by the GC. */ @@ -68,6 +69,22 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) { return 1; } +#ifdef Py_GIL_DISABLED + +/* True if an object is shared between multiple threads and + * needs special purpose when freeing to do the possibility + * of in-flight lock-free reads occuring */ +static inline int _PyObject_GC_IS_SHARED(PyObject *op) { + return (op->ob_gc_bits & _PyGC_BITS_SHARED) != 0; +} +#define _PyObject_GC_IS_SHARED(op) _PyObject_GC_IS_SHARED(_Py_CAST(PyObject*, op)) + +static inline void _PyObject_GC_SET_SHARED(PyObject *op) { + op->ob_gc_bits |= _PyGC_BITS_SHARED; +} +#define _PyObject_GC_SET_SHARED(op) _PyObject_GC_SET_SHARED(_Py_CAST(PyObject*, op)) + +#endif /* Bit flags for _gc_prev */ /* Bit 0 is set when tp_finalize is called */ From 750489cc774df44daa2c0d23e8a404fe62be93d1 Mon Sep 17 00:00:00 2001 From: HarryLHW <123lhw321@gmail.com> Date: Tue, 6 Feb 2024 04:22:57 +0800 Subject: [PATCH 57/62] gh-114967: Fix "Built-in Exceptions" documentation ambiguous wording (#114968) Change the somewhat vague "listed below" to "listed in this chapter" in Doc/library/exceptions.rst. The exceptions are listed in multiple sections after two intermediate sections. --------- Co-authored-by: Terry Jan Reedy --- Doc/library/exceptions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index f821776c286133..3191315049ad5a 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -16,7 +16,7 @@ equivalent, even if they have the same name. .. index:: pair: statement; raise -The built-in exceptions listed below can be generated by the interpreter or +The built-in exceptions listed in this chapter can be generated by the interpreter or built-in functions. Except where mentioned, they have an "associated value" indicating the detailed cause of the error. This may be a string or a tuple of several items of information (e.g., an error code and a string explaining the From 4aa4f0906df9fc9c6c6f6657f2c521468c6b1688 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Feb 2024 22:42:43 +0200 Subject: [PATCH 58/62] gh-109475: Fix support of explicit option value "--" in argparse (GH-114814) For example "--option=--". --- Lib/argparse.py | 2 +- Lib/test/test_argparse.py | 16 ++++++++++++++++ ...024-01-31-20-07-11.gh-issue-109475.lmTb9S.rst | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-31-20-07-11.gh-issue-109475.lmTb9S.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 9e19f39fadd87b..2131d729746d41 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2485,7 +2485,7 @@ def parse_known_intermixed_args(self, args=None, namespace=None): # ======================== def _get_values(self, action, arg_strings): # for everything but PARSER, REMAINDER args, strip out first '--' - if action.nargs not in [PARSER, REMAINDER]: + if not action.option_strings and action.nargs not in [PARSER, REMAINDER]: try: arg_strings.remove('--') except ValueError: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 940d7e95f96e20..d1f3d40000140d 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5405,6 +5405,22 @@ def test_zero_or_more_optional(self): args = parser.parse_args([]) self.assertEqual(NS(x=[]), args) + def test_double_dash(self): + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--foo', nargs='*') + parser.add_argument('bar', nargs='*') + + args = parser.parse_args(['--foo=--']) + self.assertEqual(NS(foo=['--'], bar=[]), args) + args = parser.parse_args(['--foo', '--']) + self.assertEqual(NS(foo=[], bar=[]), args) + args = parser.parse_args(['-f--']) + self.assertEqual(NS(foo=['--'], bar=[]), args) + args = parser.parse_args(['-f', '--']) + self.assertEqual(NS(foo=[], bar=[]), args) + args = parser.parse_args(['--foo', 'a', 'b', '--', 'c', 'd']) + self.assertEqual(NS(foo=['a', 'b'], bar=['c', 'd']), args) + # =========================== # parse_intermixed_args tests diff --git a/Misc/NEWS.d/next/Library/2024-01-31-20-07-11.gh-issue-109475.lmTb9S.rst b/Misc/NEWS.d/next/Library/2024-01-31-20-07-11.gh-issue-109475.lmTb9S.rst new file mode 100644 index 00000000000000..7582cb2bcd7629 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-31-20-07-11.gh-issue-109475.lmTb9S.rst @@ -0,0 +1,2 @@ +Fix support of explicit option value "--" in :mod:`argparse` (e.g. +``--option=--``). From 09096a1647913526a3d4fa69a9d2056ec82a8f37 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 5 Feb 2024 21:49:17 +0100 Subject: [PATCH 59/62] gh-115015: Argument Clinic: fix generated code for METH_METHOD methods without params (#115016) --- Lib/test/clinic.test.c | 4 +- Lib/test/test_clinic.py | 20 ++++++++++ ...-02-05-02-45-51.gh-issue-115015.rgtiDB.rst | 5 +++ Modules/_io/clinic/bufferedio.c.h | 4 +- Modules/_io/clinic/bytesio.c.h | 4 +- Modules/_io/clinic/fileio.c.h | 4 +- Modules/_io/clinic/iobase.c.h | 4 +- Modules/_io/clinic/textio.c.h | 4 +- Modules/_io/clinic/winconsoleio.c.h | 4 +- Modules/_sre/clinic/sre.c.h | 6 +-- Modules/_testclinic.c | 37 +++++++++++++++++++ Modules/cjkcodecs/clinic/multibytecodec.c.h | 4 +- Modules/clinic/_asynciomodule.c.h | 6 +-- Modules/clinic/_curses_panel.c.h | 12 +++--- Modules/clinic/_dbmmodule.c.h | 6 +-- Modules/clinic/_elementtree.c.h | 6 +-- Modules/clinic/_gdbmmodule.c.h | 12 +++--- Modules/clinic/_lsprof.c.h | 4 +- Modules/clinic/_pickle.c.h | 4 +- Modules/clinic/_queuemodule.c.h | 4 +- Modules/clinic/_testclinic.c.h | 24 +++++++++++- Modules/clinic/_testmultiphase.c.h | 8 ++-- Modules/clinic/arraymodule.c.h | 4 +- Modules/clinic/md5module.c.h | 4 +- Modules/clinic/posixmodule.c.h | 4 +- Modules/clinic/sha1module.c.h | 4 +- Modules/clinic/sha2module.c.h | 6 +-- Modules/clinic/zlibmodule.c.h | 10 ++--- Tools/c-analyzer/cpython/globals-to-fix.tsv | 1 + Tools/clinic/clinic.py | 2 +- 30 files changed, 153 insertions(+), 68 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2024-02-05-02-45-51.gh-issue-115015.rgtiDB.rst diff --git a/Lib/test/clinic.test.c b/Lib/test/clinic.test.c index b15aeb898d35a1..168f6f73f6186f 100644 --- a/Lib/test/clinic.test.c +++ b/Lib/test/clinic.test.c @@ -4625,7 +4625,7 @@ Test_cls_no_params_impl(TestObj *self, PyTypeObject *cls); static PyObject * Test_cls_no_params(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "cls_no_params() takes no arguments"); return NULL; } @@ -4634,7 +4634,7 @@ Test_cls_no_params(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_s static PyObject * Test_cls_no_params_impl(TestObj *self, PyTypeObject *cls) -/*[clinic end generated code: output=cc8845f22cff3dcb input=e7e2e4e344e96a11]*/ +/*[clinic end generated code: output=4d68b4652c144af3 input=e7e2e4e344e96a11]*/ /*[clinic input] diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 7323bdd801f4be..e987ce54605497 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -3288,6 +3288,26 @@ def test_cloned_func_with_converter_exception_message(self): func = getattr(ac_tester, name) self.assertEqual(func(), name) + def test_meth_method_no_params(self): + obj = ac_tester.TestClass() + meth = obj.meth_method_no_params + check = partial(self.assertRaisesRegex, TypeError, "no arguments") + check(meth, 1) + check(meth, a=1) + + def test_meth_method_no_params_capi(self): + from _testcapi import pyobject_vectorcall + obj = ac_tester.TestClass() + meth = obj.meth_method_no_params + pyobject_vectorcall(meth, None, None) + pyobject_vectorcall(meth, (), None) + pyobject_vectorcall(meth, (), ()) + pyobject_vectorcall(meth, None, ()) + + check = partial(self.assertRaisesRegex, TypeError, "no arguments") + check(pyobject_vectorcall, meth, (1,), None) + check(pyobject_vectorcall, meth, (1,), ("a",)) + def test_depr_star_new(self): cls = ac_tester.DeprStarNew cls() diff --git a/Misc/NEWS.d/next/Tools-Demos/2024-02-05-02-45-51.gh-issue-115015.rgtiDB.rst b/Misc/NEWS.d/next/Tools-Demos/2024-02-05-02-45-51.gh-issue-115015.rgtiDB.rst new file mode 100644 index 00000000000000..d8739d28eb2b73 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2024-02-05-02-45-51.gh-issue-115015.rgtiDB.rst @@ -0,0 +1,5 @@ +Fix a bug in Argument Clinic that generated incorrect code for methods with +no parameters that use the :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS +` calling convention. Only the +positional parameter count was checked; any keyword argument passed would be +silently accepted. diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index d5bec5f71f5be8..64eddcd314a803 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -96,7 +96,7 @@ _io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls); static PyObject * _io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); return NULL; } @@ -1245,4 +1245,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=442b05b9a117df6c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4249187a725a3b3e input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 37023e49087647..620e9e3b84ea19 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -96,7 +96,7 @@ _io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls); static PyObject * _io_BytesIO_getbuffer(bytesio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "getbuffer() takes no arguments"); return NULL; } @@ -534,4 +534,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=2be0e05a8871b7e2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ef116925b8b9e535 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index cf3ba28b066cf7..5b5487d63eba90 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -27,7 +27,7 @@ _io_FileIO_close_impl(fileio *self, PyTypeObject *cls); static PyObject * _io_FileIO_close(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "close() takes no arguments"); return NULL; } @@ -528,4 +528,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=1c0f4a36f76b0c6a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e3d9446b4087020e input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 6bdfa1444015ac..bae80a265fab07 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -262,7 +262,7 @@ _io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls); static PyObject * _io__IOBase_fileno(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "fileno() takes no arguments"); return NULL; } @@ -438,4 +438,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=5a22bc5db0ecaacb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e7326fbefc52bfba input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 23b3cc8d71e098..f04ee729abc9ed 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -27,7 +27,7 @@ _io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls); static PyObject * _io__TextIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); return NULL; } @@ -1292,4 +1292,4 @@ _io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED return return_value; } -/*[clinic end generated code: output=d01aa598647c1385 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=93a5a91a22100a28 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index 6cab295c44611d..4696ecc5c843e6 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -29,7 +29,7 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self, PyTypeObject *cls); static PyObject * _io__WindowsConsoleIO_close(winconsoleio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "close() takes no arguments"); return NULL; } @@ -457,4 +457,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=04108fc26b187386 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2c2bc86713b21dd6 input=a9049054013a1b77]*/ diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index cd3fbbc720bdf1..48336c7a2fca26 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -1434,7 +1434,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_match(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "match() takes no arguments"); return NULL; } @@ -1455,10 +1455,10 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "search() takes no arguments"); return NULL; } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=ad513f31b99505fa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c3e711f0b2f43d66 input=a9049054013a1b77]*/ diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index 15e0093f15ba1e..fb0936bbccd318 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -1213,6 +1213,40 @@ clone_with_conv_f2_impl(PyObject *module, custom_t path) } +/*[clinic input] +class _testclinic.TestClass "PyObject *" "PyObject" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=668a591c65bec947]*/ + +/*[clinic input] +_testclinic.TestClass.meth_method_no_params + cls: defining_class + / +[clinic start generated code]*/ + +static PyObject * +_testclinic_TestClass_meth_method_no_params_impl(PyObject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=c140f100080c2fc8 input=6bd34503d11c63c1]*/ +{ + Py_RETURN_NONE; +} + +static struct PyMethodDef test_class_methods[] = { + _TESTCLINIC_TESTCLASS_METH_METHOD_NO_PARAMS_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject TestClass = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.TestClass", + .tp_basicsize = sizeof(PyObject), + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_methods = test_class_methods, +}; + + /*[clinic input] output push destination deprstar new file '{dirname}/clinic/_testclinic_depr.c.h' @@ -1906,6 +1940,9 @@ PyInit__testclinic(void) if (m == NULL) { return NULL; } + if (PyModule_AddType(m, &TestClass) < 0) { + goto error; + } if (PyModule_AddType(m, &DeprStarNew) < 0) { goto error; } diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 305ade17b1f1aa..b5639d5cf10a22 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -668,7 +668,7 @@ _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *se static PyObject * _multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "reset() takes no arguments"); return NULL; } @@ -682,4 +682,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=219a363662d2fbff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ee767a6d93c7108a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index d941c280a4300b..6a9c8ff6d8fdd9 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -120,7 +120,7 @@ _asyncio_Future_exception_impl(FutureObj *self, PyTypeObject *cls); static PyObject * _asyncio_Future_exception(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "exception() takes no arguments"); return NULL; } @@ -453,7 +453,7 @@ _asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls); static PyObject * _asyncio_Future_get_loop(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "get_loop() takes no arguments"); return NULL; } @@ -1487,4 +1487,4 @@ _asyncio_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=f3864d8e2af7635f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b26155080c82c472 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 7945d93b5433f7..457f71370afda9 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -19,7 +19,7 @@ _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments"); return NULL; } @@ -43,7 +43,7 @@ _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "hide() takes no arguments"); return NULL; } @@ -65,7 +65,7 @@ _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "show() takes no arguments"); return NULL; } @@ -87,7 +87,7 @@ _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "top() takes no arguments"); return NULL; } @@ -327,7 +327,7 @@ _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, static PyObject * _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments"); return NULL; } @@ -418,4 +418,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=636beecf71d96ff1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7bac14e9a1194c87 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index 5a4aba2825e03a..d06271e18a49b2 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -37,7 +37,7 @@ _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls); static PyObject * _dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); return NULL; } @@ -149,7 +149,7 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls); static PyObject * _dbm_dbm_clear(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "clear() takes no arguments"); return NULL; } @@ -218,4 +218,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=96fdd4bd7bd256c5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=743ce0cea116747e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 02375c8a61e73e..9622591a1aa855 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -87,7 +87,7 @@ _elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls); static PyObject * _elementtree_Element___copy__(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); return NULL; } @@ -644,7 +644,7 @@ _elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls); static PyObject * _elementtree_Element_itertext(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "itertext() takes no arguments"); return NULL; } @@ -1219,4 +1219,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=8fdaa17d3262800a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=218ec9e6a889f796 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index c7164e519d0e7d..626e4678809d4f 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -106,7 +106,7 @@ _gdbm_gdbm_keys_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_keys(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); return NULL; } @@ -132,7 +132,7 @@ _gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_firstkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "firstkey() takes no arguments"); return NULL; } @@ -211,7 +211,7 @@ _gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_reorganize(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "reorganize() takes no arguments"); return NULL; } @@ -236,7 +236,7 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_sync(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "sync() takes no arguments"); return NULL; } @@ -258,7 +258,7 @@ _gdbm_gdbm_clear_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_clear(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "clear() takes no arguments"); return NULL; } @@ -340,4 +340,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=c5ee922363d5a81f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6b4c19905ac9967d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index dfc003eb54774c..b3b7fda5660bfd 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -39,10 +39,10 @@ _lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); static PyObject * _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "getstats() takes no arguments"); return NULL; } return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=0615a53cce828f06 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c9d87d89863dc83 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index fb086925e3941d..5a6ae7be6b6ea7 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -328,7 +328,7 @@ _pickle_Unpickler_load_impl(UnpicklerObject *self, PyTypeObject *cls); static PyObject * _pickle_Unpickler_load(UnpicklerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "load() takes no arguments"); return NULL; } @@ -1077,4 +1077,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=ebe78653233827a6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bd63c85a8737b0aa input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index b3b6b8e96c135e..6f4c715c722965 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -278,7 +278,7 @@ _queue_SimpleQueue_get_nowait(simplequeueobject *self, PyTypeObject *cls, PyObje { PyObject *return_value = NULL; - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "get_nowait() takes no arguments"); goto exit; } @@ -349,4 +349,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=242950edc8f7dfd7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=44a718f40072018a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index fea30e778381de..bb516be37ec3f0 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -3141,4 +3141,26 @@ clone_with_conv_f2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py exit: return return_value; } -/*[clinic end generated code: output=90743ac900d60f9f input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_testclinic_TestClass_meth_method_no_params__doc__, +"meth_method_no_params($self, /)\n" +"--\n" +"\n"); + +#define _TESTCLINIC_TESTCLASS_METH_METHOD_NO_PARAMS_METHODDEF \ + {"meth_method_no_params", _PyCFunction_CAST(_testclinic_TestClass_meth_method_no_params), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testclinic_TestClass_meth_method_no_params__doc__}, + +static PyObject * +_testclinic_TestClass_meth_method_no_params_impl(PyObject *self, + PyTypeObject *cls); + +static PyObject * +_testclinic_TestClass_meth_method_no_params(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { + PyErr_SetString(PyExc_TypeError, "meth_method_no_params() takes no arguments"); + return NULL; + } + return _testclinic_TestClass_meth_method_no_params_impl(self, cls); +} +/*[clinic end generated code: output=6520c1ca5392a3f0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index c0a00954c16cbe..7ac361ece1acc3 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -27,7 +27,7 @@ _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject * static PyObject * _testmultiphase_StateAccessType_get_defining_module(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "get_defining_module() takes no arguments"); return NULL; } @@ -50,7 +50,7 @@ _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObjec static PyObject * _testmultiphase_StateAccessType_getmodulebydef_bad_def(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "getmodulebydef_bad_def() takes no arguments"); return NULL; } @@ -156,10 +156,10 @@ _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self, static PyObject * _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "get_count() takes no arguments"); return NULL; } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=d8c262af27b3b98d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2c199bad52e9cda7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index dbce0313541649..0b764e43e19437 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -652,7 +652,7 @@ array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls); static PyObject * array_arrayiterator___reduce__(arrayiterobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "__reduce__() takes no arguments"); return NULL; } @@ -667,4 +667,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=bf086c01e7e482bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3be987238a4bb431 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 7d4d3108dab9b6..ee7fb3d7c613f2 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -23,7 +23,7 @@ MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); static PyObject * MD5Type_copy(MD5object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -148,4 +148,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=bfadda44914804a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4dbca39332d3f52f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 1373bdef03ba5e..b49d64d4281889 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -11212,7 +11212,7 @@ os_DirEntry_is_symlink(DirEntry *self, PyTypeObject *defining_class, PyObject *c PyObject *return_value = NULL; int _return_value; - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "is_symlink() takes no arguments"); goto exit; } @@ -12588,4 +12588,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=43e4e557c771358a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=268af5cbc8baa9d4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index ee391656fb67c3..b89c7e505c788e 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -23,7 +23,7 @@ SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); static PyObject * SHA1Type_copy(SHA1object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -148,4 +148,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=41fc7579213b57b4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=af5a640df662066f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha2module.c.h b/Modules/clinic/sha2module.c.h index ec31d5545be4c1..cf4b88d52856b8 100644 --- a/Modules/clinic/sha2module.c.h +++ b/Modules/clinic/sha2module.c.h @@ -23,7 +23,7 @@ SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls); static PyObject * SHA256Type_copy(SHA256object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -45,7 +45,7 @@ SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls); static PyObject * SHA512Type_copy(SHA512object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -437,4 +437,4 @@ _sha2_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=1482d9de086e45c4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b46da764024b1764 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 6b09abe309bf48..7ff3edf5a557f8 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -637,7 +637,7 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -662,7 +662,7 @@ zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); return NULL; } @@ -735,7 +735,7 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); return NULL; } @@ -760,7 +760,7 @@ zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - if (nargs) { + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); return NULL; } @@ -1098,4 +1098,4 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=6dd97dc851c39031 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8bb840fb6af43dd4 input=a9049054013a1b77]*/ diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 0b02ad01d39983..1d9576d083d8dc 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -334,6 +334,7 @@ Modules/_testclinic.c - DeprStarNew - Modules/_testclinic.c - DeprKwdInit - Modules/_testclinic.c - DeprKwdInitNoInline - Modules/_testclinic.c - DeprKwdNew - +Modules/_testclinic.c - TestClass - ################################## diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index c1df83a72bd8ce..db57d17899af93 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -960,7 +960,7 @@ def parser_body( return_error = ('return NULL;' if simple_return else 'goto exit;') parser_code = [libclinic.normalize_snippet(""" - if (nargs) {{ + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {{ PyErr_SetString(PyExc_TypeError, "{name}() takes no arguments"); %s }} From 652fbf88c4c422ff17fefd4dcb5e06b5c0e26e74 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Feb 2024 22:51:11 +0200 Subject: [PATCH 60/62] gh-82626: Emit a warning when bool is used as a file descriptor (GH-111275) --- Doc/whatsnew/3.13.rst | 5 +++++ Lib/_pyio.py | 5 +++++ Lib/test/test_fileio.py | 8 ++++++++ Lib/test/test_genericpath.py | 6 ++++++ Lib/test/test_os.py | 14 ++++++++++++++ Lib/test/test_posix.py | 7 +++++++ .../2023-10-24-19-19-54.gh-issue-82626._hfLRf.rst | 2 ++ Modules/_io/fileio.c | 7 +++++++ Modules/faulthandler.c | 7 +++++++ Modules/posixmodule.c | 7 +++++++ Objects/fileobject.c | 7 +++++++ 11 files changed, 75 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-10-24-19-19-54.gh-issue-82626._hfLRf.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 0770e28d230b4b..9bac36ba0bffb8 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -145,6 +145,11 @@ Other Language Changes is rejected when the global is used in the :keyword:`else` block. (Contributed by Irit Katriel in :gh:`111123`.) +* Many functions now emit a warning if a boolean value is passed as + a file descriptor argument. + This can help catch some errors earlier. + (Contributed by Serhiy Storchaka in :gh:`82626`.) + * Added a new environment variable :envvar:`PYTHON_FROZEN_MODULES`. It determines whether or not frozen modules are ignored by the import machinery, equivalent of the :option:`-X frozen_modules <-X>` command-line option. diff --git a/Lib/_pyio.py b/Lib/_pyio.py index df2c29bfa9caee..8a0d0dc4b1a0b8 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1495,6 +1495,11 @@ def __init__(self, file, mode='r', closefd=True, opener=None): if isinstance(file, float): raise TypeError('integer argument expected, got float') if isinstance(file, int): + if isinstance(file, bool): + import warnings + warnings.warn("bool is used as a file descriptor", + RuntimeWarning, stacklevel=2) + file = int(file) fd = file if fd < 0: raise ValueError('negative file descriptor') diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 06d9b454add34c..06d5a8abf32083 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -484,6 +484,14 @@ def testInvalidFd(self): import msvcrt self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd()) + def testBooleanFd(self): + for fd in False, True: + with self.assertWarnsRegex(RuntimeWarning, + 'bool is used as a file descriptor') as cm: + f = self.FileIO(fd, closefd=False) + f.close() + self.assertEqual(cm.filename, __file__) + def testBadModeArgument(self): # verify that we get a sensible error message for bad mode argument bad_mode = "qwerty" diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index b77cd4c67d6b2a..f407ee3caf154c 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -165,6 +165,12 @@ def test_exists_fd(self): os.close(w) self.assertFalse(self.pathmodule.exists(r)) + def test_exists_bool(self): + for fd in False, True: + with self.assertWarnsRegex(RuntimeWarning, + 'bool is used as a file descriptor'): + self.pathmodule.exists(fd) + def test_isdir(self): filename = os_helper.TESTFN bfilename = os.fsencode(filename) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 86af1a8ed8ee15..2c8823ae47c726 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2195,12 +2195,15 @@ def test_chmod(self): class TestInvalidFD(unittest.TestCase): singles = ["fchdir", "dup", "fdatasync", "fstat", "fstatvfs", "fsync", "tcgetpgrp", "ttyname"] + singles_fildes = {"fchdir", "fdatasync", "fsync"} #singles.append("close") #We omit close because it doesn't raise an exception on some platforms def get_single(f): def helper(self): if hasattr(os, f): self.check(getattr(os, f)) + if f in self.singles_fildes: + self.check_bool(getattr(os, f)) return helper for f in singles: locals()["test_"+f] = get_single(f) @@ -2214,8 +2217,16 @@ def check(self, f, *args, **kwargs): self.fail("%r didn't raise an OSError with a bad file descriptor" % f) + def check_bool(self, f, *args, **kwargs): + with warnings.catch_warnings(): + warnings.simplefilter("error", RuntimeWarning) + for fd in False, True: + with self.assertRaises(RuntimeWarning): + f(fd, *args, **kwargs) + def test_fdopen(self): self.check(os.fdopen, encoding="utf-8") + self.check_bool(os.fdopen, encoding="utf-8") @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()') def test_isatty(self): @@ -2277,11 +2288,14 @@ def test_fchown(self): def test_fpathconf(self): self.check(os.pathconf, "PC_NAME_MAX") self.check(os.fpathconf, "PC_NAME_MAX") + self.check_bool(os.pathconf, "PC_NAME_MAX") + self.check_bool(os.fpathconf, "PC_NAME_MAX") @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()') def test_ftruncate(self): self.check(os.truncate, 0) self.check(os.ftruncate, 0) + self.check_bool(os.truncate, 0) @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()') def test_lseek(self): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 72e348fbbdcbc1..a45f620e18dc1d 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1514,6 +1514,13 @@ def test_stat_dir_fd(self): self.assertRaises(OverflowError, posix.stat, name, dir_fd=10**20) + for fd in False, True: + with self.assertWarnsRegex(RuntimeWarning, + 'bool is used as a file descriptor') as cm: + with self.assertRaises(OSError): + posix.stat('nonexisting', dir_fd=fd) + self.assertEqual(cm.filename, __file__) + @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()") def test_utime_dir_fd(self): with self.prepare_file() as (dir_fd, name, fullname): diff --git a/Misc/NEWS.d/next/Library/2023-10-24-19-19-54.gh-issue-82626._hfLRf.rst b/Misc/NEWS.d/next/Library/2023-10-24-19-19-54.gh-issue-82626._hfLRf.rst new file mode 100644 index 00000000000000..92a66b5bf0f635 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-24-19-19-54.gh-issue-82626._hfLRf.rst @@ -0,0 +1,2 @@ +Many functions now emit a warning if a boolean value is passed as a file +descriptor argument. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 9cf268ca0b26c8..6bb156e41fe43c 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -269,6 +269,13 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, self->fd = -1; } + if (PyBool_Check(nameobj)) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "bool is used as a file descriptor", 1)) + { + return -1; + } + } fd = PyLong_AsInt(nameobj); if (fd < 0) { if (!PyErr_Occurred()) { diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index a2e3c2300b3ce8..95d646c9c65b3c 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -119,6 +119,13 @@ faulthandler_get_fileno(PyObject **file_ptr) } } else if (PyLong_Check(file)) { + if (PyBool_Check(file)) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "bool is used as a file descriptor", 1)) + { + return -1; + } + } fd = PyLong_AsInt(file); if (fd == -1 && PyErr_Occurred()) return -1; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 40ff131b119d66..22891135bde0af 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -969,6 +969,13 @@ _fd_converter(PyObject *o, int *p) int overflow; long long_value; + if (PyBool_Check(o)) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "bool is used as a file descriptor", 1)) + { + return 0; + } + } PyObject *index = _PyNumber_Index(o); if (index == NULL) { return 0; diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 5522eba34eace9..e30ab952dff571 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -174,6 +174,13 @@ PyObject_AsFileDescriptor(PyObject *o) PyObject *meth; if (PyLong_Check(o)) { + if (PyBool_Check(o)) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "bool is used as a file descriptor", 1)) + { + return -1; + } + } fd = PyLong_AsInt(o); } else if (PyObject_GetOptionalAttr(o, &_Py_ID(fileno), &meth) < 0) { From c32bae52904723d99e1f98e2ef54570268d86467 Mon Sep 17 00:00:00 2001 From: mpage Date: Mon, 5 Feb 2024 13:48:37 -0800 Subject: [PATCH 61/62] gh-114944: Fix race between `_PyParkingLot_Park` and `_PyParkingLot_UnparkAll` when handling interrupts (#114945) Fix race between `_PyParkingLot_Park` and `_PyParkingLot_UnparkAll` when handling interrupts There is a potential race when `_PyParkingLot_UnparkAll` is executing in one thread and another thread is unblocked because of an interrupt in `_PyParkingLot_Park`. Consider the following scenario: 1. Thread T0 is blocked[^1] in `_PyParkingLot_Park` on address `A`. 2. Thread T1 executes `_PyParkingLot_UnparkAll` on address `A`. It finds the `wait_entry` for `T0` and unlinks[^2] its list node. 3. Immediately after (2), T0 is woken up due to an interrupt. It then segfaults trying to unlink[^3] the node that was previously unlinked in (2). To fix this we mark each waiter as unparking before releasing the bucket lock. `_PyParkingLot_Park` will wait to handle the coming wakeup, and not attempt to unlink the node, when this field is set. `_PyParkingLot_Unpark` does this already, presumably to handle this case. --- .../2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst | 1 + Python/parking_lot.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst new file mode 100644 index 00000000000000..fb41caf7c5f4fa --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst @@ -0,0 +1 @@ +Fixes a race between ``PyParkingLot_Park`` and ``_PyParkingLot_UnparkAll``. diff --git a/Python/parking_lot.c b/Python/parking_lot.c index c83d7443e289c5..8ba50fc1353ebd 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -244,6 +244,7 @@ dequeue(Bucket *bucket, const void *address) if (wait->addr == (uintptr_t)address) { llist_remove(node); --bucket->num_waiters; + wait->is_unparking = true; return wait; } } @@ -262,6 +263,7 @@ dequeue_all(Bucket *bucket, const void *address, struct llist_node *dst) llist_remove(node); llist_insert_tail(dst, node); --bucket->num_waiters; + wait->is_unparking = true; } } } @@ -337,8 +339,6 @@ _PyParkingLot_Unpark(const void *addr, _Py_unpark_fn_t *fn, void *arg) _PyRawMutex_Lock(&bucket->mutex); struct wait_entry *waiter = dequeue(bucket, addr); if (waiter) { - waiter->is_unparking = true; - int has_more_waiters = (bucket->num_waiters > 0); fn(arg, waiter->park_arg, has_more_waiters); } From bb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 6 Feb 2024 00:41:34 +0200 Subject: [PATCH 62/62] gh-83648: Support deprecation of options, arguments and subcommands in argparse (GH-114086) --- Doc/library/argparse.rst | 47 +++++- Doc/whatsnew/3.13.rst | 9 ++ Lib/argparse.py | 92 +++++++++--- Lib/test/test_argparse.py | 139 +++++++++++++++++- ...4-01-15-20-21-33.gh-issue-83648.HzD_fY.rst | 2 + 5 files changed, 262 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-01-15-20-21-33.gh-issue-83648.HzD_fY.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 1395d457f874b0..952643a46416d2 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -777,6 +777,8 @@ The add_argument() method * dest_ - The name of the attribute to be added to the object returned by :meth:`parse_args`. + * deprecated_ - Whether or not use of the argument is deprecated. + The following sections describe how each of these are used. @@ -1439,6 +1441,34 @@ behavior:: >>> parser.parse_args('--foo XXX'.split()) Namespace(bar='XXX') + +.. _deprecated: + +deprecated +^^^^^^^^^^ + +During a project's lifetime, some arguments may need to be removed from the +command line. Before removing them, you should inform +your users that the arguments are deprecated and will be removed. +The ``deprecated`` keyword argument of +:meth:`~ArgumentParser.add_argument`, which defaults to ``False``, +specifies if the argument is deprecated and will be removed +in the future. +For arguments, if ``deprecated`` is ``True``, then a warning will be +printed to standard error when the argument is used:: + + >>> import argparse + >>> parser = argparse.ArgumentParser(prog='snake.py') + >>> parser.add_argument('--legs', default=0, type=int, deprecated=True) + >>> parser.parse_args([]) + Namespace(legs=0) + >>> parser.parse_args(['--legs', '4']) # doctest: +SKIP + snake.py: warning: option '--legs' is deprecated + Namespace(legs=4) + +.. versionchanged:: 3.13 + + Action classes ^^^^^^^^^^^^^^ @@ -1842,7 +1872,8 @@ Sub-commands {foo,bar} additional help - Furthermore, ``add_parser`` supports an additional ``aliases`` argument, + Furthermore, :meth:`~_SubParsersAction.add_parser` supports an additional + *aliases* argument, which allows multiple strings to refer to the same subparser. This example, like ``svn``, aliases ``co`` as a shorthand for ``checkout``:: @@ -1853,6 +1884,20 @@ Sub-commands >>> parser.parse_args(['co', 'bar']) Namespace(foo='bar') + :meth:`~_SubParsersAction.add_parser` supports also an additional + *deprecated* argument, which allows to deprecate the subparser. + + >>> import argparse + >>> parser = argparse.ArgumentParser(prog='chicken.py') + >>> subparsers = parser.add_subparsers() + >>> run = subparsers.add_parser('run') + >>> fly = subparsers.add_parser('fly', deprecated=True) + >>> parser.parse_args(['fly']) # doctest: +SKIP + chicken.py: warning: command 'fly' is deprecated + Namespace() + + .. versionadded:: 3.13 + One particularly effective way of handling sub-commands is to combine the use of the :meth:`add_subparsers` method with calls to :meth:`set_defaults` so that each subparser knows which Python function it should execute. For diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 9bac36ba0bffb8..5e5f1e295f4d70 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -169,6 +169,15 @@ New Modules Improved Modules ================ +argparse +-------- + +* Add parameter *deprecated* in methods + :meth:`~argparse.ArgumentParser.add_argument` and :meth:`!add_parser` + which allows to deprecate command-line options, positional arguments and + subcommands. + (Contributed by Serhiy Storchaka in :gh:`83648`). + array ----- diff --git a/Lib/argparse.py b/Lib/argparse.py index 2131d729746d41..04ee3b19aca755 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -843,7 +843,8 @@ def __init__(self, choices=None, required=False, help=None, - metavar=None): + metavar=None, + deprecated=False): self.option_strings = option_strings self.dest = dest self.nargs = nargs @@ -854,6 +855,7 @@ def __init__(self, self.required = required self.help = help self.metavar = metavar + self.deprecated = deprecated def _get_kwargs(self): names = [ @@ -867,6 +869,7 @@ def _get_kwargs(self): 'required', 'help', 'metavar', + 'deprecated', ] return [(name, getattr(self, name)) for name in names] @@ -889,7 +892,8 @@ def __init__(self, choices=_deprecated_default, required=False, help=None, - metavar=_deprecated_default): + metavar=_deprecated_default, + deprecated=False): _option_strings = [] for option_string in option_strings: @@ -927,7 +931,8 @@ def __init__(self, choices=choices, required=required, help=help, - metavar=metavar) + metavar=metavar, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): @@ -950,7 +955,8 @@ def __init__(self, choices=None, required=False, help=None, - metavar=None): + metavar=None, + deprecated=False): if nargs == 0: raise ValueError('nargs for store actions must be != 0; if you ' 'have nothing to store, actions such as store ' @@ -967,7 +973,8 @@ def __init__(self, choices=choices, required=required, help=help, - metavar=metavar) + metavar=metavar, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, self.dest, values) @@ -982,7 +989,8 @@ def __init__(self, default=None, required=False, help=None, - metavar=None): + metavar=None, + deprecated=False): super(_StoreConstAction, self).__init__( option_strings=option_strings, dest=dest, @@ -990,7 +998,8 @@ def __init__(self, const=const, default=default, required=required, - help=help) + help=help, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, self.dest, self.const) @@ -1003,14 +1012,16 @@ def __init__(self, dest, default=False, required=False, - help=None): + help=None, + deprecated=False): super(_StoreTrueAction, self).__init__( option_strings=option_strings, dest=dest, const=True, - default=default, + deprecated=deprecated, required=required, - help=help) + help=help, + default=default) class _StoreFalseAction(_StoreConstAction): @@ -1020,14 +1031,16 @@ def __init__(self, dest, default=True, required=False, - help=None): + help=None, + deprecated=False): super(_StoreFalseAction, self).__init__( option_strings=option_strings, dest=dest, const=False, default=default, required=required, - help=help) + help=help, + deprecated=deprecated) class _AppendAction(Action): @@ -1042,7 +1055,8 @@ def __init__(self, choices=None, required=False, help=None, - metavar=None): + metavar=None, + deprecated=False): if nargs == 0: raise ValueError('nargs for append actions must be != 0; if arg ' 'strings are not supplying the value to append, ' @@ -1059,7 +1073,8 @@ def __init__(self, choices=choices, required=required, help=help, - metavar=metavar) + metavar=metavar, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): items = getattr(namespace, self.dest, None) @@ -1077,7 +1092,8 @@ def __init__(self, default=None, required=False, help=None, - metavar=None): + metavar=None, + deprecated=False): super(_AppendConstAction, self).__init__( option_strings=option_strings, dest=dest, @@ -1086,7 +1102,8 @@ def __init__(self, default=default, required=required, help=help, - metavar=metavar) + metavar=metavar, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): items = getattr(namespace, self.dest, None) @@ -1102,14 +1119,16 @@ def __init__(self, dest, default=None, required=False, - help=None): + help=None, + deprecated=False): super(_CountAction, self).__init__( option_strings=option_strings, dest=dest, nargs=0, default=default, required=required, - help=help) + help=help, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): count = getattr(namespace, self.dest, None) @@ -1124,13 +1143,15 @@ def __init__(self, option_strings, dest=SUPPRESS, default=SUPPRESS, - help=None): + help=None, + deprecated=False): super(_HelpAction, self).__init__( option_strings=option_strings, dest=dest, default=default, nargs=0, - help=help) + help=help, + deprecated=deprecated) def __call__(self, parser, namespace, values, option_string=None): parser.print_help() @@ -1144,7 +1165,8 @@ def __init__(self, version=None, dest=SUPPRESS, default=SUPPRESS, - help="show program's version number and exit"): + help="show program's version number and exit", + deprecated=False): super(_VersionAction, self).__init__( option_strings=option_strings, dest=dest, @@ -1188,6 +1210,7 @@ def __init__(self, self._parser_class = parser_class self._name_parser_map = {} self._choices_actions = [] + self._deprecated = set() super(_SubParsersAction, self).__init__( option_strings=option_strings, @@ -1198,7 +1221,7 @@ def __init__(self, help=help, metavar=metavar) - def add_parser(self, name, **kwargs): + def add_parser(self, name, *, deprecated=False, **kwargs): # set prog from the existing prefix if kwargs.get('prog') is None: kwargs['prog'] = '%s %s' % (self._prog_prefix, name) @@ -1226,6 +1249,10 @@ def add_parser(self, name, **kwargs): for alias in aliases: self._name_parser_map[alias] = parser + if deprecated: + self._deprecated.add(name) + self._deprecated.update(aliases) + return parser def _get_subactions(self): @@ -1241,13 +1268,17 @@ def __call__(self, parser, namespace, values, option_string=None): # select the parser try: - parser = self._name_parser_map[parser_name] + subparser = self._name_parser_map[parser_name] except KeyError: args = {'parser_name': parser_name, 'choices': ', '.join(self._name_parser_map)} msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) + if parser_name in self._deprecated: + parser._warning(_("command '%(parser_name)s' is deprecated") % + {'parser_name': parser_name}) + # parse all the remaining options into the namespace # store any unrecognized options on the object, so that the top # level parser can decide what to do with them @@ -1255,7 +1286,7 @@ def __call__(self, parser, namespace, values, option_string=None): # In case this subparser defines new defaults, we parse them # in a new namespace object and then update the original # namespace for the relevant parts. - subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) + subnamespace, arg_strings = subparser.parse_known_args(arg_strings, None) for key, value in vars(subnamespace).items(): setattr(namespace, key, value) @@ -1975,6 +2006,7 @@ def _parse_known_args(self, arg_strings, namespace): # converts arg strings to the appropriate and then takes the action seen_actions = set() seen_non_default_actions = set() + warned = set() def take_action(action, argument_strings, option_string=None): seen_actions.add(action) @@ -2070,6 +2102,10 @@ def consume_optional(start_index): # the Optional's string args stopped assert action_tuples for action, args, option_string in action_tuples: + if action.deprecated and option_string not in warned: + self._warning(_("option '%(option)s' is deprecated") % + {'option': option_string}) + warned.add(option_string) take_action(action, args, option_string) return stop @@ -2089,6 +2125,10 @@ def consume_positionals(start_index): for action, arg_count in zip(positionals, arg_counts): args = arg_strings[start_index: start_index + arg_count] start_index += arg_count + if args and action.deprecated and action.dest not in warned: + self._warning(_("argument '%(argument_name)s' is deprecated") % + {'argument_name': action.dest}) + warned.add(action.dest) take_action(action, args) # slice off the Positionals that we just parsed and return the @@ -2650,3 +2690,7 @@ def error(self, message): self.print_usage(_sys.stderr) args = {'prog': self.prog, 'message': message} self.exit(2, _('%(prog)s: error: %(message)s\n') % args) + + def _warning(self, message): + args = {'prog': self.prog, 'message': message} + self._print_message(_('%(prog)s: warning: %(message)s\n') % args, _sys.stderr) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index d1f3d40000140d..86d6e81a71642b 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5099,7 +5099,8 @@ def test_optional(self): string = ( "Action(option_strings=['--foo', '-a', '-b'], dest='b', " "nargs='+', const=None, default=42, type='int', " - "choices=[1, 2, 3], required=False, help='HELP', metavar='METAVAR')") + "choices=[1, 2, 3], required=False, help='HELP', " + "metavar='METAVAR', deprecated=False)") self.assertStringEqual(option, string) def test_argument(self): @@ -5116,7 +5117,8 @@ def test_argument(self): string = ( "Action(option_strings=[], dest='x', nargs='?', " "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], " - "required=True, help='H HH H', metavar='MV MV MV')" % float) + "required=True, help='H HH H', metavar='MV MV MV', " + "deprecated=False)" % float) self.assertStringEqual(argument, string) def test_namespace(self): @@ -5308,6 +5310,139 @@ def spam(string_to_convert): args = parser.parse_args('--foo spam!'.split()) self.assertEqual(NS(foo='foo_converted'), args) + +# ============================================== +# Check that deprecated arguments output warning +# ============================================== + +class TestDeprecatedArguments(TestCase): + + def test_deprecated_option(self): + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--foo', deprecated=True) + + with captured_stderr() as stderr: + parser.parse_args(['--foo', 'spam']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['-f', 'spam']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '-f' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['--foo', 'spam', '-f', 'ham']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--foo' is deprecated") + self.assertRegex(stderr, "warning: option '-f' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 2) + + with captured_stderr() as stderr: + parser.parse_args(['--foo', 'spam', '--foo', 'ham']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + def test_deprecated_boolean_option(self): + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--foo', action=argparse.BooleanOptionalAction, deprecated=True) + + with captured_stderr() as stderr: + parser.parse_args(['--foo']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['-f']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '-f' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['--no-foo']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--no-foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['--foo', '--no-foo']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: option '--foo' is deprecated") + self.assertRegex(stderr, "warning: option '--no-foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 2) + + def test_deprecated_arguments(self): + parser = argparse.ArgumentParser() + parser.add_argument('foo', nargs='?', deprecated=True) + parser.add_argument('bar', nargs='?', deprecated=True) + + with captured_stderr() as stderr: + parser.parse_args([]) + stderr = stderr.getvalue() + self.assertEqual(stderr.count('is deprecated'), 0) + + with captured_stderr() as stderr: + parser.parse_args(['spam']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: argument 'foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['spam', 'ham']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: argument 'foo' is deprecated") + self.assertRegex(stderr, "warning: argument 'bar' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 2) + + def test_deprecated_varargument(self): + parser = argparse.ArgumentParser() + parser.add_argument('foo', nargs='*', deprecated=True) + + with captured_stderr() as stderr: + parser.parse_args([]) + stderr = stderr.getvalue() + self.assertEqual(stderr.count('is deprecated'), 0) + + with captured_stderr() as stderr: + parser.parse_args(['spam']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: argument 'foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['spam', 'ham']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: argument 'foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + def test_deprecated_subparser(self): + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers() + subparsers.add_parser('foo', aliases=['baz'], deprecated=True) + subparsers.add_parser('bar') + + with captured_stderr() as stderr: + parser.parse_args(['bar']) + stderr = stderr.getvalue() + self.assertEqual(stderr.count('is deprecated'), 0) + + with captured_stderr() as stderr: + parser.parse_args(['foo']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: command 'foo' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + with captured_stderr() as stderr: + parser.parse_args(['baz']) + stderr = stderr.getvalue() + self.assertRegex(stderr, "warning: command 'baz' is deprecated") + self.assertEqual(stderr.count('is deprecated'), 1) + + # ================================================================== # Check semantics regarding the default argument and type conversion # ================================================================== diff --git a/Misc/NEWS.d/next/Library/2024-01-15-20-21-33.gh-issue-83648.HzD_fY.rst b/Misc/NEWS.d/next/Library/2024-01-15-20-21-33.gh-issue-83648.HzD_fY.rst new file mode 100644 index 00000000000000..bd3e27b4be0cf5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-01-15-20-21-33.gh-issue-83648.HzD_fY.rst @@ -0,0 +1,2 @@ +Support deprecation of options, positional arguments and subcommands in +:mod:`argparse`.