From 5c488caeb858690a696bc9f74fc74a274a3aa51c Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 10 Nov 2024 22:39:58 -0800 Subject: [PATCH 01/57] gh-117378: Clear up the NEWS entry wording (GH-126634) gh-117378: Clear up the NEWS entry wording. Docs are hard. Lets go shopping! --- .../Library/2024-11-07-01-40-11.gh-issue-117378.o9O5uM.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-11-07-01-40-11.gh-issue-117378.o9O5uM.rst b/Misc/NEWS.d/next/Library/2024-11-07-01-40-11.gh-issue-117378.o9O5uM.rst index cdbe21f9f9a663b..d7d4477ec17814d 100644 --- a/Misc/NEWS.d/next/Library/2024-11-07-01-40-11.gh-issue-117378.o9O5uM.rst +++ b/Misc/NEWS.d/next/Library/2024-11-07-01-40-11.gh-issue-117378.o9O5uM.rst @@ -11,7 +11,7 @@ It could also have a side effect of ``""`` remaining in :data:`sys.path` during forkserver preload imports instead of the absolute path from :func:`os.getcwd` at multiprocessing import time used in the worker ``sys.path``. -Potentially leading to incorrect imports from the wrong location during -preload. We are unaware of that actually happening. The issue was discovered -by someone observing unexpected preload performance gains. +The ``sys.path`` differences between phases in the child process could +potentially have caused preload to import incorrect things from the wrong +location. We are unaware of that actually having happened in practice. From 25257d61cfccc3b4189f96390a5c4db73fd5302c Mon Sep 17 00:00:00 2001 From: vivodi <103735539+vivodi@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:47:56 +0800 Subject: [PATCH 02/57] gh-126664: Use `else` instead of `finally` in "The with statement" documentation. (GH-126665) --- Doc/reference/compound_stmts.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 1b1e9f479cbe086..e73ce44270b0821 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -534,18 +534,15 @@ is semantically equivalent to:: enter = type(manager).__enter__ exit = type(manager).__exit__ value = enter(manager) - hit_except = False try: TARGET = value SUITE except: - hit_except = True if not exit(manager, *sys.exc_info()): raise - finally: - if not hit_except: - exit(manager, None, None, None) + else: + exit(manager, None, None, None) With more than one item, the context managers are processed as if multiple :keyword:`with` statements were nested:: From 82269c7d580e1aad71ff11fe891cf7f97eb45703 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Mon, 11 Nov 2024 03:59:23 -0300 Subject: [PATCH 03/57] Add missing fullstop `.` to whatsnew/3.8.rst (GH-126553) --- Doc/whatsnew/3.8.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index fc9f49e65af8473..bdc4ca5cab52450 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -936,7 +936,7 @@ Add option ``--json-lines`` to parse every input line as a separate JSON object. logging ------- -Added a *force* keyword argument to :func:`logging.basicConfig` +Added a *force* keyword argument to :func:`logging.basicConfig`. When set to true, any existing handlers attached to the root logger are removed and closed before carrying out the configuration specified by the other arguments. From 6ee542d491589b470ec7cdd353463ff9ff52d098 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sun, 10 Nov 2024 23:08:58 -0800 Subject: [PATCH 04/57] gh-126417: validate ABC methods on multiprocessing proxy types (#126454) Checks that appropriate dunder __ methods exist on the dict and list proxy types. Co-authored-by: Alex Waygood --- Lib/test/_test_multiprocessing.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index bcb024d8386fd14..8329a848a900883 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2464,6 +2464,19 @@ def test_list_isinstance(self): a = self.list() self.assertIsInstance(a, collections.abc.MutableSequence) + # MutableSequence also has __iter__, but we can iterate over + # ListProxy using __getitem__ instead. Adding __iter__ to ListProxy + # would change the behavior of a list modified during iteration. + mutable_sequence_methods = ( + '__contains__', '__delitem__', '__getitem__', '__iadd__', + '__len__', '__reversed__', '__setitem__', 'append', + 'clear', 'count', 'extend', 'index', 'insert', 'pop', 'remove', + 'reverse', + ) + for name in mutable_sequence_methods: + with self.subTest(name=name): + self.assertTrue(callable(getattr(a, name))) + def test_list_iter(self): a = self.list(list(range(10))) it = iter(a) @@ -2508,6 +2521,15 @@ def test_dict_isinstance(self): a = self.dict() self.assertIsInstance(a, collections.abc.MutableMapping) + mutable_mapping_methods = ( + '__contains__', '__delitem__', '__eq__', '__getitem__', '__iter__', + '__len__', '__ne__', '__setitem__', 'clear', 'get', 'items', + 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', + ) + for name in mutable_mapping_methods: + with self.subTest(name=name): + self.assertTrue(callable(getattr(a, name))) + def test_dict_iter(self): d = self.dict() indices = list(range(65, 70)) From 9fc2808eaf4e74a9f52f44d20a7d1110bd949d41 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 11 Nov 2024 14:35:56 +0300 Subject: [PATCH 05/57] gh-126654: Fix crash in several functions in `_interpreters` module (#126678) --- Lib/test/test__interpreters.py | 18 ++++++++++++++++++ ...4-11-11-13-00-21.gh-issue-126654.4gfP2y.rst | 2 ++ Modules/_interpretersmodule.c | 5 +++++ 3 files changed, 25 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-11-11-13-00-21.gh-issue-126654.4gfP2y.rst diff --git a/Lib/test/test__interpreters.py b/Lib/test/test__interpreters.py index 14cd50bd30502ce..bf3165e2341949f 100644 --- a/Lib/test/test__interpreters.py +++ b/Lib/test/test__interpreters.py @@ -551,6 +551,24 @@ def test_still_running(self): self.assertTrue(_interpreters.is_running(interp)) +class CommonTests(TestBase): + def setUp(self): + super().setUp() + self.id = _interpreters.create() + + def test_signatures(self): + # for method in ['exec', 'run_string', 'run_func']: + msg = "expected 'shared' to be a dict" + with self.assertRaisesRegex(TypeError, msg): + _interpreters.exec(self.id, 'a', 1) + with self.assertRaisesRegex(TypeError, msg): + _interpreters.exec(self.id, 'a', shared=1) + with self.assertRaisesRegex(TypeError, msg): + _interpreters.run_string(self.id, 'a', shared=1) + with self.assertRaisesRegex(TypeError, msg): + _interpreters.run_func(self.id, lambda: None, shared=1) + + class RunStringTests(TestBase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2024-11-11-13-00-21.gh-issue-126654.4gfP2y.rst b/Misc/NEWS.d/next/Library/2024-11-11-13-00-21.gh-issue-126654.4gfP2y.rst new file mode 100644 index 000000000000000..750158e6d4d3ae2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-11-13-00-21.gh-issue-126654.4gfP2y.rst @@ -0,0 +1,2 @@ +Fix crash when non-dict was passed to several functions in ``_interpreters`` +module. diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c index 95acdd69e53260f..a9a966e79e0920b 100644 --- a/Modules/_interpretersmodule.c +++ b/Modules/_interpretersmodule.c @@ -936,6 +936,11 @@ static int _interp_exec(PyObject *self, PyInterpreterState *interp, PyObject *code_arg, PyObject *shared_arg, PyObject **p_excinfo) { + if (shared_arg != NULL && !PyDict_CheckExact(shared_arg)) { + PyErr_SetString(PyExc_TypeError, "expected 'shared' to be a dict"); + return -1; + } + // Extract code. Py_ssize_t codestrlen = -1; PyObject *bytes_obj = NULL; From 819830f34a11ecaa3aada174ca8eedeb3f260630 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 11 Nov 2024 18:27:26 +0200 Subject: [PATCH 06/57] gh-126505: Fix bugs in compiling case-insensitive character classes (GH-126557) * upper-case non-BMP character was ignored * the ASCII flag was ignored when matching a character range whose upper bound is beyond the BMP region --- Lib/re/_compiler.py | 23 +++++--- Lib/test/test_re.py | 55 +++++++++++++++++++ ...-11-07-22-41-47.gh-issue-126505.iztYE1.rst | 4 ++ 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-07-22-41-47.gh-issue-126505.iztYE1.rst diff --git a/Lib/re/_compiler.py b/Lib/re/_compiler.py index 29109f8812ee7be..20dd561d1c1520f 100644 --- a/Lib/re/_compiler.py +++ b/Lib/re/_compiler.py @@ -255,11 +255,11 @@ def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): while True: try: if op is LITERAL: - if fixup: - lo = fixup(av) - charmap[lo] = 1 - if fixes and lo in fixes: - for k in fixes[lo]: + if fixup: # IGNORECASE and not LOCALE + av = fixup(av) + charmap[av] = 1 + if fixes and av in fixes: + for k in fixes[av]: charmap[k] = 1 if not hascased and iscased(av): hascased = True @@ -267,7 +267,7 @@ def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): charmap[av] = 1 elif op is RANGE: r = range(av[0], av[1]+1) - if fixup: + if fixup: # IGNORECASE and not LOCALE if fixes: for i in map(fixup, r): charmap[i] = 1 @@ -298,8 +298,7 @@ def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): # Character set contains non-BMP character codes. # For range, all BMP characters in the range are already # proceeded. - if fixup: - hascased = True + if fixup: # IGNORECASE and not LOCALE # For now, IN_UNI_IGNORE+LITERAL and # IN_UNI_IGNORE+RANGE_UNI_IGNORE work for all non-BMP # characters, because two characters (at least one of @@ -310,7 +309,13 @@ def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): # Also, both c.lower() and c.lower().upper() are single # characters for every non-BMP character. if op is RANGE: - op = RANGE_UNI_IGNORE + if fixes: # not ASCII + op = RANGE_UNI_IGNORE + hascased = True + else: + assert op is LITERAL + if not hascased and iscased(av): + hascased = True tail.append((op, av)) break diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index ff95f54026e1720..7bc702ec89a4a7b 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1136,6 +1136,39 @@ def test_ignore_case_set(self): self.assertTrue(re.match(br'[19a]', b'a', re.I)) self.assertTrue(re.match(br'[19a]', b'A', re.I)) self.assertTrue(re.match(br'[19A]', b'a', re.I)) + self.assertTrue(re.match(r'[19\xc7]', '\xc7', re.I)) + self.assertTrue(re.match(r'[19\xc7]', '\xe7', re.I)) + self.assertTrue(re.match(r'[19\xe7]', '\xc7', re.I)) + self.assertTrue(re.match(r'[19\xe7]', '\xe7', re.I)) + self.assertTrue(re.match(r'[19\u0400]', '\u0400', re.I)) + self.assertTrue(re.match(r'[19\u0400]', '\u0450', re.I)) + self.assertTrue(re.match(r'[19\u0450]', '\u0400', re.I)) + self.assertTrue(re.match(r'[19\u0450]', '\u0450', re.I)) + self.assertTrue(re.match(r'[19\U00010400]', '\U00010400', re.I)) + self.assertTrue(re.match(r'[19\U00010400]', '\U00010428', re.I)) + self.assertTrue(re.match(r'[19\U00010428]', '\U00010400', re.I)) + self.assertTrue(re.match(r'[19\U00010428]', '\U00010428', re.I)) + + self.assertTrue(re.match(br'[19A]', b'A', re.I)) + self.assertTrue(re.match(br'[19a]', b'a', re.I)) + self.assertTrue(re.match(br'[19a]', b'A', re.I)) + self.assertTrue(re.match(br'[19A]', b'a', re.I)) + self.assertTrue(re.match(r'[19A]', 'A', re.I|re.A)) + self.assertTrue(re.match(r'[19a]', 'a', re.I|re.A)) + self.assertTrue(re.match(r'[19a]', 'A', re.I|re.A)) + self.assertTrue(re.match(r'[19A]', 'a', re.I|re.A)) + self.assertTrue(re.match(r'[19\xc7]', '\xc7', re.I|re.A)) + self.assertIsNone(re.match(r'[19\xc7]', '\xe7', re.I|re.A)) + self.assertIsNone(re.match(r'[19\xe7]', '\xc7', re.I|re.A)) + self.assertTrue(re.match(r'[19\xe7]', '\xe7', re.I|re.A)) + self.assertTrue(re.match(r'[19\u0400]', '\u0400', re.I|re.A)) + self.assertIsNone(re.match(r'[19\u0400]', '\u0450', re.I|re.A)) + self.assertIsNone(re.match(r'[19\u0450]', '\u0400', re.I|re.A)) + self.assertTrue(re.match(r'[19\u0450]', '\u0450', re.I|re.A)) + self.assertTrue(re.match(r'[19\U00010400]', '\U00010400', re.I|re.A)) + self.assertIsNone(re.match(r'[19\U00010400]', '\U00010428', re.I|re.A)) + self.assertIsNone(re.match(r'[19\U00010428]', '\U00010400', re.I|re.A)) + self.assertTrue(re.match(r'[19\U00010428]', '\U00010428', re.I|re.A)) # Two different characters have the same lowercase. assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' @@ -1172,8 +1205,10 @@ def test_ignore_case_range(self): self.assertTrue(re.match(br'[9-a]', b'_', re.I)) self.assertIsNone(re.match(br'[9-A]', b'_', re.I)) self.assertTrue(re.match(r'[\xc0-\xde]', '\xd7', re.I)) + self.assertTrue(re.match(r'[\xc0-\xde]', '\xe7', re.I)) self.assertIsNone(re.match(r'[\xc0-\xde]', '\xf7', re.I)) self.assertTrue(re.match(r'[\xe0-\xfe]', '\xf7', re.I)) + self.assertTrue(re.match(r'[\xe0-\xfe]', '\xc7', re.I)) self.assertIsNone(re.match(r'[\xe0-\xfe]', '\xd7', re.I)) self.assertTrue(re.match(r'[\u0430-\u045f]', '\u0450', re.I)) self.assertTrue(re.match(r'[\u0430-\u045f]', '\u0400', re.I)) @@ -1184,6 +1219,26 @@ def test_ignore_case_range(self): self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010428', re.I)) self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010400', re.I)) + self.assertTrue(re.match(r'[\xc0-\xde]', '\xd7', re.I|re.A)) + self.assertIsNone(re.match(r'[\xc0-\xde]', '\xe7', re.I|re.A)) + self.assertTrue(re.match(r'[\xe0-\xfe]', '\xf7', re.I|re.A)) + self.assertIsNone(re.match(r'[\xe0-\xfe]', '\xc7', re.I|re.A)) + self.assertTrue(re.match(r'[\u0430-\u045f]', '\u0450', re.I|re.A)) + self.assertIsNone(re.match(r'[\u0430-\u045f]', '\u0400', re.I|re.A)) + self.assertIsNone(re.match(r'[\u0400-\u042f]', '\u0450', re.I|re.A)) + self.assertTrue(re.match(r'[\u0400-\u042f]', '\u0400', re.I|re.A)) + self.assertTrue(re.match(r'[\U00010428-\U0001044f]', '\U00010428', re.I|re.A)) + self.assertIsNone(re.match(r'[\U00010428-\U0001044f]', '\U00010400', re.I|re.A)) + self.assertIsNone(re.match(r'[\U00010400-\U00010427]', '\U00010428', re.I|re.A)) + self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010400', re.I|re.A)) + + self.assertTrue(re.match(r'[N-\x7f]', 'A', re.I|re.A)) + self.assertTrue(re.match(r'[n-\x7f]', 'Z', re.I|re.A)) + self.assertTrue(re.match(r'[N-\uffff]', 'A', re.I|re.A)) + self.assertTrue(re.match(r'[n-\uffff]', 'Z', re.I|re.A)) + self.assertTrue(re.match(r'[N-\U00010000]', 'A', re.I|re.A)) + self.assertTrue(re.match(r'[n-\U00010000]', 'Z', re.I|re.A)) + # Two different characters have the same lowercase. assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'[J-M]', '\u212a', re.I)) diff --git a/Misc/NEWS.d/next/Library/2024-11-07-22-41-47.gh-issue-126505.iztYE1.rst b/Misc/NEWS.d/next/Library/2024-11-07-22-41-47.gh-issue-126505.iztYE1.rst new file mode 100644 index 000000000000000..0a0f893a2688a0c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-07-22-41-47.gh-issue-126505.iztYE1.rst @@ -0,0 +1,4 @@ +Fix bugs in compiling case-insensitive :mod:`regular expressions ` with +character classes containing non-BMP characters: upper-case non-BMP +character did was ignored and the ASCII flag was ignored when +matching a character range whose upper bound is beyond the BMP region. From 79805d228440814c0674ab5190ef17f235503d2e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 11 Nov 2024 18:28:30 +0200 Subject: [PATCH 07/57] gh-117941: Reject option names starting with "--no-" in argparse.BooleanOptionalAction (GH-125894) They never worked correctly. --- Lib/argparse.py | 3 +++ Lib/test/test_argparse.py | 7 +++++++ .../Library/2024-10-23-20-44-30.gh-issue-117941.Y9jdlW.rst | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-10-23-20-44-30.gh-issue-117941.Y9jdlW.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 072cd5e7dc0d06e..5ecfdca17175e38 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -863,6 +863,9 @@ def __init__(self, _option_strings.append(option_string) if option_string.startswith('--'): + if option_string.startswith('--no-'): + raise ValueError(f'invalid option name {option_string!r} ' + f'for BooleanOptionalAction') option_string = '--no-' + option_string[2:] _option_strings.append(option_string) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index ba9876570385d35..cbf119ed2dabbb7 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -789,6 +789,13 @@ def test_const(self): self.assertIn("got an unexpected keyword argument 'const'", str(cm.exception)) + def test_invalid_name(self): + parser = argparse.ArgumentParser() + with self.assertRaises(ValueError) as cm: + parser.add_argument('--no-foo', action=argparse.BooleanOptionalAction) + self.assertEqual(str(cm.exception), + "invalid option name '--no-foo' for BooleanOptionalAction") + class TestBooleanOptionalActionRequired(ParserTestCase): """Tests BooleanOptionalAction required""" diff --git a/Misc/NEWS.d/next/Library/2024-10-23-20-44-30.gh-issue-117941.Y9jdlW.rst b/Misc/NEWS.d/next/Library/2024-10-23-20-44-30.gh-issue-117941.Y9jdlW.rst new file mode 100644 index 000000000000000..9c2553f0f0e8cd6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-23-20-44-30.gh-issue-117941.Y9jdlW.rst @@ -0,0 +1,2 @@ +:class:`!argparse.BooleanOptionalAction` now rejects option names starting +with ``--no-``. From 25aee21aa84061b5d8e08247c8581da1459f37e8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 11 Nov 2024 18:29:28 +0200 Subject: [PATCH 08/57] gh-126374: Add support of options with optional arguments in the getopt module (GH-126375) --- Doc/library/getopt.rst | 26 +++++- Doc/whatsnew/3.14.rst | 5 ++ Lib/getopt.py | 24 ++++-- Lib/test/test_getopt.py | 81 +++++++++++++++---- ...-11-03-23-25-07.gh-issue-126374.Xu_THP.rst | 1 + 5 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-03-23-25-07.gh-issue-126374.Xu_THP.rst diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index 3ab44b9fc561087..def0ea357bceb2a 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -38,7 +38,8 @@ exception: be parsed, without the leading reference to the running program. Typically, this means ``sys.argv[1:]``. *shortopts* is the string of option letters that the script wants to recognize, with options that require an argument followed by a - colon (``':'``; i.e., the same format that Unix :c:func:`!getopt` uses). + colon (``':'``) and options that accept an optional argument followed by + two colons (``'::'``); i.e., the same format that Unix :c:func:`!getopt` uses. .. note:: @@ -49,8 +50,10 @@ exception: *longopts*, if specified, must be a list of strings with the names of the long options which should be supported. The leading ``'--'`` characters should not be included in the option name. Long options which require an - argument should be followed by an equal sign (``'='``). Optional arguments - are not supported. To accept only long options, *shortopts* should be an + argument should be followed by an equal sign (``'='``). + Long options which accept an optional argument should be followed by + an equal sign and question mark (``'=?'``). + To accept only long options, *shortopts* should be an empty string. Long options on the command line can be recognized so long as they provide a prefix of the option name that matches exactly one of the accepted options. For example, if *longopts* is ``['foo', 'frob']``, the @@ -67,6 +70,9 @@ exception: options occur in the list in the same order in which they were found, thus allowing multiple occurrences. Long and short options may be mixed. + .. versionchanged:: 3.14 + Optional arguments are supported. + .. function:: gnu_getopt(args, shortopts, longopts=[]) @@ -124,6 +130,20 @@ Using long option names is equally easy: >>> args ['a1', 'a2'] +Optional arguments should be specified explicitly: + +.. doctest:: + + >>> s = '-Con -C --color=off --color a1 a2' + >>> args = s.split() + >>> args + ['-Con', '-C', '--color=off', '--color', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'C::', ['color=?']) + >>> optlist + [('-C', 'on'), ('-C', ''), ('--color', 'off'), ('--color', '')] + >>> args + ['a1', 'a2'] + In a script, typical usage is something like this: .. testcode:: diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index b9d2c27eb9a3214..4b2a64fd0fab9ca 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -314,6 +314,11 @@ functools to reserve a place for positional arguments. (Contributed by Dominykas Grigonis in :gh:`119127`.) +getopt +------ + +* Add support for options with optional arguments. + (Contributed by Serhiy Storchaka in :gh:`126374`.) http ---- diff --git a/Lib/getopt.py b/Lib/getopt.py index 1df5b96472a45cf..c12c08b29c79c4d 100644 --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -27,7 +27,6 @@ # - allow the caller to specify ordering # - RETURN_IN_ORDER option # - GNU extension with '-' as first character of option string -# - optional arguments, specified by double colons # - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" @@ -58,12 +57,14 @@ def getopt(args, shortopts, longopts = []): running program. Typically, this means "sys.argv[1:]". shortopts is the string of option letters that the script wants to recognize, with options that require an argument followed by a - colon (i.e., the same format that Unix getopt() uses). If + colon and options that accept an optional argument followed by + two colons (i.e., the same format that Unix getopt() uses). If specified, longopts is a list of strings with the names of the long options which should be supported. The leading '--' characters should not be included in the option name. Options which require an argument should be followed by an equal sign - ('='). + ('='). Options which acept an optional argument should be + followed by an equal sign and question mark ('=?'). The return value consists of two elements: the first is a list of (option, value) pairs; the second is the list of program arguments @@ -153,7 +154,7 @@ def do_longs(opts, opt, longopts, args): has_arg, opt = long_has_args(opt, longopts) if has_arg: - if optarg is None: + if optarg is None and has_arg != '?': if not args: raise GetoptError(_('option --%s requires argument') % opt, opt) optarg, args = args[0], args[1:] @@ -174,6 +175,8 @@ def long_has_args(opt, longopts): return False, opt elif opt + '=' in possibilities: return True, opt + elif opt + '=?' in possibilities: + return '?', opt # No exact match, so better be unique. if len(possibilities) > 1: # XXX since possibilities contains all valid continuations, might be @@ -181,6 +184,8 @@ def long_has_args(opt, longopts): raise GetoptError(_('option --%s not a unique prefix') % opt, opt) assert len(possibilities) == 1 unique_match = possibilities[0] + if unique_match.endswith('=?'): + return '?', unique_match[:-2] has_arg = unique_match.endswith('=') if has_arg: unique_match = unique_match[:-1] @@ -189,8 +194,9 @@ def long_has_args(opt, longopts): def do_shorts(opts, optstring, shortopts, args): while optstring != '': opt, optstring = optstring[0], optstring[1:] - if short_has_arg(opt, shortopts): - if optstring == '': + has_arg = short_has_arg(opt, shortopts) + if has_arg: + if optstring == '' and has_arg != '?': if not args: raise GetoptError(_('option -%s requires argument') % opt, opt) @@ -204,7 +210,11 @@ def do_shorts(opts, optstring, shortopts, args): def short_has_arg(opt, shortopts): for i in range(len(shortopts)): if opt == shortopts[i] != ':': - return shortopts.startswith(':', i+1) + if not shortopts.startswith(':', i+1): + return False + if shortopts.startswith('::', i+1): + return '?' + return True raise GetoptError(_('option -%s not recognized') % opt, opt) if __name__ == '__main__': diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index c8b3442de4aa77b..984bdb73f34aa44 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -19,21 +19,34 @@ def assertError(self, *args, **kwargs): self.assertRaises(getopt.GetoptError, *args, **kwargs) def test_short_has_arg(self): - self.assertTrue(getopt.short_has_arg('a', 'a:')) - self.assertFalse(getopt.short_has_arg('a', 'a')) + self.assertIs(getopt.short_has_arg('a', 'a:'), True) + self.assertIs(getopt.short_has_arg('a', 'a'), False) + self.assertEqual(getopt.short_has_arg('a', 'a::'), '?') self.assertError(getopt.short_has_arg, 'a', 'b') def test_long_has_args(self): has_arg, option = getopt.long_has_args('abc', ['abc=']) - self.assertTrue(has_arg) + self.assertIs(has_arg, True) self.assertEqual(option, 'abc') has_arg, option = getopt.long_has_args('abc', ['abc']) - self.assertFalse(has_arg) + self.assertIs(has_arg, False) self.assertEqual(option, 'abc') + has_arg, option = getopt.long_has_args('abc', ['abc=?']) + self.assertEqual(has_arg, '?') + self.assertEqual(option, 'abc') + + has_arg, option = getopt.long_has_args('abc', ['abcd=']) + self.assertIs(has_arg, True) + self.assertEqual(option, 'abcd') + has_arg, option = getopt.long_has_args('abc', ['abcd']) - self.assertFalse(has_arg) + self.assertIs(has_arg, False) + self.assertEqual(option, 'abcd') + + has_arg, option = getopt.long_has_args('abc', ['abcd=?']) + self.assertEqual(has_arg, '?') self.assertEqual(option, 'abcd') self.assertError(getopt.long_has_args, 'abc', ['def']) @@ -49,9 +62,9 @@ def test_do_shorts(self): self.assertEqual(opts, [('-a', '1')]) self.assertEqual(args, []) - #opts, args = getopt.do_shorts([], 'a=1', 'a:', []) - #self.assertEqual(opts, [('-a', '1')]) - #self.assertEqual(args, []) + opts, args = getopt.do_shorts([], 'a=1', 'a:', []) + self.assertEqual(opts, [('-a', '=1')]) + self.assertEqual(args, []) opts, args = getopt.do_shorts([], 'a', 'a:', ['1']) self.assertEqual(opts, [('-a', '1')]) @@ -61,6 +74,14 @@ def test_do_shorts(self): self.assertEqual(opts, [('-a', '1')]) self.assertEqual(args, ['2']) + opts, args = getopt.do_shorts([], 'a', 'a::', ['1']) + self.assertEqual(opts, [('-a', '')]) + self.assertEqual(args, ['1']) + + opts, args = getopt.do_shorts([], 'a1', 'a::', []) + self.assertEqual(opts, [('-a', '1')]) + self.assertEqual(args, []) + self.assertError(getopt.do_shorts, [], 'a1', 'a', []) self.assertError(getopt.do_shorts, [], 'a', 'a:', []) @@ -77,6 +98,22 @@ def test_do_longs(self): self.assertEqual(opts, [('--abcd', '1')]) self.assertEqual(args, []) + opts, args = getopt.do_longs([], 'abc', ['abc=?'], ['1']) + self.assertEqual(opts, [('--abc', '')]) + self.assertEqual(args, ['1']) + + opts, args = getopt.do_longs([], 'abc', ['abcd=?'], ['1']) + self.assertEqual(opts, [('--abcd', '')]) + self.assertEqual(args, ['1']) + + opts, args = getopt.do_longs([], 'abc=1', ['abc=?'], []) + self.assertEqual(opts, [('--abc', '1')]) + self.assertEqual(args, []) + + opts, args = getopt.do_longs([], 'abc=1', ['abcd=?'], []) + self.assertEqual(opts, [('--abcd', '1')]) + self.assertEqual(args, []) + opts, args = getopt.do_longs([], 'abc', ['ab', 'abc', 'abcd'], []) self.assertEqual(opts, [('--abc', '')]) self.assertEqual(args, []) @@ -95,7 +132,7 @@ def test_getopt(self): # note: the empty string between '-a' and '--beta' is significant: # it simulates an empty string option argument ('-a ""') on the # command line. - cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', + cmdline = ['-a1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', '', '--beta', 'arg1', 'arg2'] opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta']) @@ -106,17 +143,29 @@ def test_getopt(self): # accounted for in the code that calls getopt(). self.assertEqual(args, ['arg1', 'arg2']) + cmdline = ['-a1', '--alpha=2', '--alpha=', '-a', '--alpha', 'arg1', 'arg2'] + opts, args = getopt.getopt(cmdline, 'a::', ['alpha=?']) + self.assertEqual(opts, [('-a', '1'), ('--alpha', '2'), ('--alpha', ''), + ('-a', ''), ('--alpha', '')]) + self.assertEqual(args, ['arg1', 'arg2']) + self.assertError(getopt.getopt, cmdline, 'a:b', ['alpha', 'beta']) def test_gnu_getopt(self): # Test handling of GNU style scanning mode. - cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2'] + cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2', '--beta', + '3', 'arg2'] # GNU style opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta=']) - self.assertEqual(args, ['arg1']) - self.assertEqual(opts, [('-a', ''), ('-b', '1'), - ('--alpha', ''), ('--beta', '2')]) + self.assertEqual(args, ['arg1', 'arg2']) + self.assertEqual(opts, [('-a', ''), ('-b', '1'), ('--alpha', ''), + ('--beta', '2'), ('--beta', '3')]) + + opts, args = getopt.gnu_getopt(cmdline, 'ab::', ['alpha', 'beta=?']) + self.assertEqual(args, ['arg1', '1', '3', 'arg2']) + self.assertEqual(opts, [('-a', ''), ('-b', ''), ('--alpha', ''), + ('--beta', '2'), ('--beta', '')]) # recognize "-" as an argument opts, args = getopt.gnu_getopt(['-a', '-', '-b', '-'], 'ab:', []) @@ -126,13 +175,15 @@ def test_gnu_getopt(self): # Posix style via + opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta=']) self.assertEqual(opts, [('-a', '')]) - self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) + self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2', + '--beta', '3', 'arg2']) # Posix style via POSIXLY_CORRECT self.env["POSIXLY_CORRECT"] = "1" opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta=']) self.assertEqual(opts, [('-a', '')]) - self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) + self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2', + '--beta', '3', 'arg2']) def test_issue4629(self): longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) diff --git a/Misc/NEWS.d/next/Library/2024-11-03-23-25-07.gh-issue-126374.Xu_THP.rst b/Misc/NEWS.d/next/Library/2024-11-03-23-25-07.gh-issue-126374.Xu_THP.rst new file mode 100644 index 000000000000000..ad7ecfb6af9ec8b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-03-23-25-07.gh-issue-126374.Xu_THP.rst @@ -0,0 +1 @@ +Add support for options with optional arguments in the :mod:`getopt` module. From 6e25eb15410f781f632d536d555f38879432522c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E4=B9=9D=E9=BC=8E?= <109224573@qq.com> Date: Tue, 12 Nov 2024 01:10:49 +0800 Subject: [PATCH 09/57] Update documentation links to Microsoft's documentation pages (GH-126379) --- Doc/library/asyncio-eventloop.rst | 2 +- Doc/library/time.rst | 2 +- Doc/using/windows.rst | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 3ace6eda4d7f291..9f1aec148f8750b 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -1797,7 +1797,7 @@ By default asyncio is configured to use :class:`EventLoop`. .. seealso:: `MSDN documentation on I/O Completion Ports - `_. + `_. .. class:: EventLoop diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 9cd5db768e9853c..6265c2214eaa0dd 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -390,7 +390,7 @@ Functions threads ready to run, the function returns immediately, and the thread continues execution. On Windows 8.1 and newer the implementation uses a `high-resolution timer - `_ + `_ which provides resolution of 100 nanoseconds. If *secs* is zero, ``Sleep(0)`` is used. Unix implementation: diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index daaf8822af1161d..1a6322d72341ff8 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -435,7 +435,7 @@ When writing to the Windows Registry, the following behaviors exist: For more detail on the technical basis for these limitations, please consult Microsoft's documentation on packaged full-trust apps, currently available at `docs.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-behind-the-scenes -`_ +`_ .. _windows-nuget: @@ -536,7 +536,7 @@ dependents, such as Idle), pip and the Python documentation are not included. .. note:: The embedded distribution does not include the `Microsoft C Runtime - `_ and it is + `_ and it is the responsibility of the application installer to provide this. The runtime may have already been installed on a user's system previously or automatically via Windows Update, and can be detected by finding @@ -679,13 +679,13 @@ System variables, you need non-restricted access to your machine .. seealso:: - https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables + https://learn.microsoft.com/windows/win32/procthread/environment-variables Overview of environment variables on Windows - https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1 + https://learn.microsoft.com/windows-server/administration/windows-commands/set_1 The ``set`` command, for temporarily modifying environment variables - https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx + https://learn.microsoft.com/windows-server/administration/windows-commands/setx The ``setx`` command, for permanently modifying environment variables @@ -1291,13 +1291,13 @@ is a collection of modules for advanced Windows-specific support. This includes utilities for: * `Component Object Model - `_ + `_ (COM) * Win32 API calls * Registry * Event log * `Microsoft Foundation Classes - `_ + `_ (MFC) user interfaces `PythonWin Date: Mon, 11 Nov 2024 11:19:08 -0800 Subject: [PATCH 10/57] gh-84559: gh-103134: Whats new 3.14 entries for multiprocessing. (GH-126697) --- Doc/whatsnew/3.14.rst | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 4b2a64fd0fab9ca..c8f7dd162f1137c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -250,6 +250,12 @@ concurrent.futures same process) to Python code. This is separate from the proposed API in :pep:`734`. (Contributed by Eric Snow in :gh:`124548`.) +* The default ``ProcessPoolExecutor`` start method (see + :ref:`multiprocessing-start-methods`) changed from *fork* to *forkserver* on + platforms other than macOS & Windows. If you require the threading + incompatible *fork* start method you must explicitly request it by + supplying a *mp_context* to :class:`concurrent.futures.ProcessPoolExecutor`. + (Contributed by Gregory P. Smith in :gh:`84559`.) ctypes ------ @@ -357,6 +363,25 @@ json (Contributed by Trey Hunner in :gh:`122873`.) +multiprocessing +--------------- + +* The default start method (see :ref:`multiprocessing-start-methods`) changed + from *fork* to *forkserver* on platforms other than macOS & Windows where + it was already *spawn*. If you require the threading incompatible *fork* + start method you must explicitly request it using a context from + :func:`multiprocessing.get_context` (preferred) or change the default via + :func:`multiprocessing.set_start_method`. + (Contributed by Gregory P. Smith in :gh:`84559`.) +* The :ref:`multiprocessing proxy objects ` + for *list* and *dict* types gain previously overlooked missing methods: + + * :meth:`!clear` and :meth:`!copy` for proxies of :class:`list`. + * :meth:`~dict.fromkeys`, ``reversed(d)``, ``d | {}``, ``{} | d``, + ``d |= {'b': 2}`` for proxies of :class:`dict`. + + (Contributed by Roy Hyunjin Han for :gh:`103134`) + operator -------- @@ -511,14 +536,6 @@ Deprecated as a single positional argument. (Contributed by Serhiy Storchaka in :gh:`109218`.) -* :mod:`multiprocessing` and :mod:`concurrent.futures`: - The default start method (see :ref:`multiprocessing-start-methods`) changed - away from *fork* to *forkserver* on platforms where it was not already - *spawn* (Windows & macOS). If you require the threading incompatible *fork* - start method you must explicitly specify it when using :mod:`multiprocessing` - or :mod:`concurrent.futures` APIs. - (Contributed by Gregory P. Smith in :gh:`84559`.) - * :mod:`os`: :term:`Soft deprecate ` :func:`os.popen` and :func:`os.spawn* ` functions. They should no longer be used to From 3c6d2d123004d8e37a2111083e22e2a2c96dffd0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:08:54 +0200 Subject: [PATCH 11/57] gh-89416: Add RFC 9559 MIME types for Matroska formats (#126412) Co-authored-by: Zachary Ware Co-authored-by: Jelle Zijlstra --- Doc/whatsnew/3.14.rst | 14 ++++++ Lib/mimetypes.py | 3 ++ Lib/test/test_mimetypes.py | 47 +++++++++++-------- ...4-11-04-22-53-09.gh-issue-89416.YVQaas.rst | 2 + 4 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-04-22-53-09.gh-issue-89416.YVQaas.rst diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index c8f7dd162f1137c..f9b219828d3d94d 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -363,6 +363,19 @@ json (Contributed by Trey Hunner in :gh:`122873`.) +mimetypes +--------- + +* Add :rfc:`9559` MIME types for Matroska audiovisual data container + structures, containing: + + * audio with no video: ``audio/matroska`` (``.mka``) + * video: ``video/matroska`` (``.mkv``) + * stereoscopic video: ``video/matroska-3d`` (``.mk3d``) + + (Contributed by Hugo van Kemenade in :gh:`89416`.) + + multiprocessing --------------- @@ -382,6 +395,7 @@ multiprocessing (Contributed by Roy Hyunjin Han for :gh:`103134`) + operator -------- diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index d7c4e8444f8decf..fd343a78c98ae19 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -534,6 +534,7 @@ def _default_mime_types(): '.ass' : 'audio/aac', '.au' : 'audio/basic', '.snd' : 'audio/basic', + '.mka' : 'audio/matroska', '.mp3' : 'audio/mpeg', '.mp2' : 'audio/mpeg', '.opus' : 'audio/opus', @@ -595,6 +596,8 @@ def _default_mime_types(): '.sgml' : 'text/x-sgml', '.vcf' : 'text/x-vcard', '.xml' : 'text/xml', + '.mkv' : 'video/matroska', + '.mk3d' : 'video/matroska-3d', '.mp4' : 'video/mp4', '.mpeg' : 'video/mpeg', '.m1v' : 'video/mpeg', diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 58f6a4dfae08ba2..8d3e8fcafb67405 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -223,26 +223,33 @@ def test_guess_known_extensions(self): def test_preferred_extension(self): def check_extensions(): - self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin') - self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps') - self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u') - self.assertEqual(mimetypes.guess_extension('application/vnd.ms-excel'), '.xls') - self.assertEqual(mimetypes.guess_extension('application/vnd.ms-powerpoint'), '.ppt') - self.assertEqual(mimetypes.guess_extension('application/x-texinfo'), '.texi') - self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff') - self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl') - self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3') - self.assertEqual(mimetypes.guess_extension('image/avif'), '.avif') - self.assertEqual(mimetypes.guess_extension('image/webp'), '.webp') - self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg') - self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff') - self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml') - self.assertEqual(mimetypes.guess_extension('text/html'), '.html') - self.assertEqual(mimetypes.guess_extension('text/plain'), '.txt') - self.assertEqual(mimetypes.guess_extension('text/rtf'), '.rtf') - self.assertEqual(mimetypes.guess_extension('text/x-rst'), '.rst') - self.assertEqual(mimetypes.guess_extension('video/mpeg'), '.mpeg') - self.assertEqual(mimetypes.guess_extension('video/quicktime'), '.mov') + for mime_type, ext in ( + ("application/octet-stream", ".bin"), + ("application/postscript", ".ps"), + ("application/vnd.apple.mpegurl", ".m3u"), + ("application/vnd.ms-excel", ".xls"), + ("application/vnd.ms-powerpoint", ".ppt"), + ("application/x-texinfo", ".texi"), + ("application/x-troff", ".roff"), + ("application/xml", ".xsl"), + ("audio/matroska", ".mka"), + ("audio/mpeg", ".mp3"), + ("image/avif", ".avif"), + ("image/webp", ".webp"), + ("image/jpeg", ".jpg"), + ("image/tiff", ".tiff"), + ("message/rfc822", ".eml"), + ("text/html", ".html"), + ("text/plain", ".txt"), + ("text/rtf", ".rtf"), + ("text/x-rst", ".rst"), + ("video/matroska", ".mkv"), + ("video/matroska-3d", ".mk3d"), + ("video/mpeg", ".mpeg"), + ("video/quicktime", ".mov"), + ): + with self.subTest(mime_type=mime_type, ext=ext): + self.assertEqual(mimetypes.guess_extension(mime_type), ext) check_extensions() mimetypes.init() diff --git a/Misc/NEWS.d/next/Library/2024-11-04-22-53-09.gh-issue-89416.YVQaas.rst b/Misc/NEWS.d/next/Library/2024-11-04-22-53-09.gh-issue-89416.YVQaas.rst new file mode 100644 index 000000000000000..f1a2fcbaff25640 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-04-22-53-09.gh-issue-89416.YVQaas.rst @@ -0,0 +1,2 @@ +Add :rfc:`9559` MIME types for Matroska audiovisual container formats. Patch +by Hugo van Kemenade. From b697d8c48e5e47c37fdd5dd74de40dfb4d6c0d01 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 11 Nov 2024 14:49:41 -0700 Subject: [PATCH 12/57] gh-76785: Minor Cleanup of Exception-related Cross-interpreter State (gh-126602) This change makes it easier to backport the _interpreters, _interpqueues, and _interpchannels modules to Python 3.12. --- Include/internal/pycore_crossinterp.h | 10 ++- Modules/_interpretersmodule.c | 2 +- Python/crossinterp.c | 36 +++++++---- Python/crossinterp_exceptions.h | 91 ++++++++++++++------------- 4 files changed, 81 insertions(+), 58 deletions(-) diff --git a/Include/internal/pycore_crossinterp.h b/Include/internal/pycore_crossinterp.h index e91e911feb38cca..a7e71efc5daa494 100644 --- a/Include/internal/pycore_crossinterp.h +++ b/Include/internal/pycore_crossinterp.h @@ -11,6 +11,7 @@ extern "C" { #include "pycore_lock.h" // PyMutex #include "pycore_pyerrors.h" + /**************/ /* exceptions */ /**************/ @@ -163,8 +164,13 @@ struct _xi_state { // heap types _PyXIData_lookup_t data_lookup; - // heap types - PyObject *PyExc_NotShareableError; + struct xi_exceptions { + // static types + PyObject *PyExc_InterpreterError; + PyObject *PyExc_InterpreterNotFoundError; + // heap types + PyObject *PyExc_NotShareableError; + } exceptions; }; extern PyStatus _PyXI_Init(PyInterpreterState *interp); diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c index a9a966e79e0920b..eb4ac9847dcd2ba 100644 --- a/Modules/_interpretersmodule.c +++ b/Modules/_interpretersmodule.c @@ -1507,7 +1507,7 @@ module_exec(PyObject *mod) goto error; } PyObject *PyExc_NotShareableError = \ - _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError; + _PyInterpreterState_GetXIState(interp)->exceptions.PyExc_NotShareableError; if (PyModule_AddType(mod, (PyTypeObject *)PyExc_NotShareableError) < 0) { goto error; } diff --git a/Python/crossinterp.c b/Python/crossinterp.c index 2daba99988c12a1..b7aa8da8ac550ec 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -17,11 +17,11 @@ /* exceptions */ /**************/ -static int init_exceptions(PyInterpreterState *); -static void fini_exceptions(PyInterpreterState *); -static int _init_not_shareable_error_type(PyInterpreterState *); -static void _fini_not_shareable_error_type(PyInterpreterState *); -static PyObject * _get_not_shareable_error_type(PyInterpreterState *); +typedef struct xi_exceptions exceptions_t; +static int init_static_exctypes(exceptions_t *, PyInterpreterState *); +static void fini_static_exctypes(exceptions_t *, PyInterpreterState *); +static int init_heap_exctypes(exceptions_t *); +static void fini_heap_exctypes(exceptions_t *); #include "crossinterp_exceptions.h" @@ -205,7 +205,8 @@ static inline void _set_xid_lookup_failure(PyInterpreterState *interp, PyObject *obj, const char *msg) { - PyObject *exctype = _get_not_shareable_error_type(interp); + exceptions_t *state = &_PyInterpreterState_GetXIState(interp)->exceptions; + PyObject *exctype = state->PyExc_NotShareableError; assert(exctype != NULL); if (msg != NULL) { assert(obj == NULL); @@ -1605,7 +1606,9 @@ _propagate_not_shareable_error(_PyXI_session *session) return; } PyInterpreterState *interp = PyInterpreterState_Get(); - if (PyErr_ExceptionMatches(_get_not_shareable_error_type(interp))) { + exceptions_t *state = &_PyInterpreterState_GetXIState(interp)->exceptions; + assert(state->PyExc_NotShareableError != NULL); + if (PyErr_ExceptionMatches(state->PyExc_NotShareableError)) { // We want to propagate the exception directly. session->_error_override = _PyXI_ERR_NOT_SHAREABLE; session->error_override = &session->_error_override; @@ -1782,9 +1785,11 @@ _PyXI_Init(PyInterpreterState *interp) } xid_lookup_init(&_PyXI_GET_STATE(interp)->data_lookup); - // Initialize exceptions (heap types). - if (_init_not_shareable_error_type(interp) < 0) { - return _PyStatus_ERR("failed to initialize NotShareableError"); + // Initialize exceptions.(heap types). + // See _PyXI_InitTypes() for the static types. + if (init_heap_exctypes(&_PyXI_GET_STATE(interp)->exceptions) < 0) { + PyErr_PrintEx(0); + return _PyStatus_ERR("failed to initialize exceptions"); } return _PyStatus_OK(); @@ -1797,7 +1802,8 @@ void _PyXI_Fini(PyInterpreterState *interp) { // Finalize exceptions (heap types). - _fini_not_shareable_error_type(interp); + // See _PyXI_FiniTypes() for the static types. + fini_heap_exctypes(&_PyXI_GET_STATE(interp)->exceptions); // Finalize the XID lookup state (e.g. registry). xid_lookup_fini(&_PyXI_GET_STATE(interp)->data_lookup); @@ -1809,17 +1815,21 @@ _PyXI_Fini(PyInterpreterState *interp) PyStatus _PyXI_InitTypes(PyInterpreterState *interp) { - if (init_exceptions(interp) < 0) { + if (init_static_exctypes(&_PyXI_GET_STATE(interp)->exceptions, interp) < 0) { PyErr_PrintEx(0); return _PyStatus_ERR("failed to initialize an exception type"); } + // We would initialize heap types here too but that leads to ref leaks. + // Instead, we intialize them in _PyXI_Init(). return _PyStatus_OK(); } void _PyXI_FiniTypes(PyInterpreterState *interp) { - fini_exceptions(interp); + // We would finalize heap types here too but that leads to ref leaks. + // Instead, we finalize them in _PyXI_Fini(). + fini_static_exctypes(&_PyXI_GET_STATE(interp)->exceptions, interp); } diff --git a/Python/crossinterp_exceptions.h b/Python/crossinterp_exceptions.h index 278511da615c75d..3cb45d2067710b4 100644 --- a/Python/crossinterp_exceptions.h +++ b/Python/crossinterp_exceptions.h @@ -25,71 +25,78 @@ static PyTypeObject _PyExc_InterpreterNotFoundError = { }; PyObject *PyExc_InterpreterNotFoundError = (PyObject *)&_PyExc_InterpreterNotFoundError; -/* NotShareableError extends ValueError */ - -static int -_init_not_shareable_error_type(PyInterpreterState *interp) -{ - const char *name = "interpreters.NotShareableError"; - PyObject *base = PyExc_ValueError; - PyObject *ns = NULL; - PyObject *exctype = PyErr_NewException(name, base, ns); - if (exctype == NULL) { - return -1; - } - - _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError = exctype; - return 0; -} - -static void -_fini_not_shareable_error_type(PyInterpreterState *interp) -{ - Py_CLEAR(_PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError); -} - -static PyObject * -_get_not_shareable_error_type(PyInterpreterState *interp) -{ - assert(_PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError != NULL); - return _PyInterpreterState_GetXIState(interp)->PyExc_NotShareableError; -} - /* lifecycle */ static int -init_exceptions(PyInterpreterState *interp) +init_static_exctypes(exceptions_t *state, PyInterpreterState *interp) { + assert(state == &_PyXI_GET_STATE(interp)->exceptions); PyTypeObject *base = (PyTypeObject *)PyExc_Exception; - // builtin static types - + // PyExc_InterpreterError _PyExc_InterpreterError.tp_base = base; _PyExc_InterpreterError.tp_traverse = base->tp_traverse; _PyExc_InterpreterError.tp_clear = base->tp_clear; if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterError) < 0) { - return -1; + goto error; } + state->PyExc_InterpreterError = (PyObject *)&_PyExc_InterpreterError; + // PyExc_InterpreterNotFoundError _PyExc_InterpreterNotFoundError.tp_traverse = base->tp_traverse; _PyExc_InterpreterNotFoundError.tp_clear = base->tp_clear; if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterNotFoundError) < 0) { - return -1; + goto error; } + state->PyExc_InterpreterNotFoundError = + (PyObject *)&_PyExc_InterpreterNotFoundError; - // heap types + return 0; - // We would call _init_not_shareable_error_type() here too, - // but that leads to ref leaks +error: + fini_static_exctypes(state, interp); + return -1; +} + +static void +fini_static_exctypes(exceptions_t *state, PyInterpreterState *interp) +{ + assert(state == &_PyXI_GET_STATE(interp)->exceptions); + if (state->PyExc_InterpreterNotFoundError != NULL) { + state->PyExc_InterpreterNotFoundError = NULL; + _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterNotFoundError); + } + if (state->PyExc_InterpreterError != NULL) { + state->PyExc_InterpreterError = NULL; + _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterError); + } +} + +static int +init_heap_exctypes(exceptions_t *state) +{ + PyObject *exctype; + + /* NotShareableError extends ValueError */ + const char *name = "interpreters.NotShareableError"; + PyObject *base = PyExc_ValueError; + PyObject *ns = NULL; + exctype = PyErr_NewException(name, base, ns); + if (exctype == NULL) { + goto error; + } + state->PyExc_NotShareableError = exctype; return 0; + +error: + fini_heap_exctypes(state); + return -1; } static void -fini_exceptions(PyInterpreterState *interp) +fini_heap_exctypes(exceptions_t *state) { - // Likewise with _fini_not_shareable_error_type(). - _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterNotFoundError); - _PyStaticType_FiniBuiltin(interp, &_PyExc_InterpreterError); + Py_CLEAR(state->PyExc_NotShareableError); } From dff074d1446bab23578a6b228b0c59a17006299c Mon Sep 17 00:00:00 2001 From: "Tomas R." Date: Mon, 11 Nov 2024 23:16:39 +0100 Subject: [PATCH 13/57] gh-126413: Add translation tests for getopt and optparse (GH-126698) --- Lib/test/support/i18n_helper.py | 63 ++++++++++++++++++++ Lib/test/test_argparse.py | 54 ++--------------- Lib/test/test_getopt.py | 19 ++++-- Lib/test/test_optparse.py | 11 +++- Lib/test/translationdata/getopt/msgids.txt | 6 ++ Lib/test/translationdata/optparse/msgids.txt | 14 +++++ Makefile.pre.in | 2 + 7 files changed, 114 insertions(+), 55 deletions(-) create mode 100644 Lib/test/support/i18n_helper.py create mode 100644 Lib/test/translationdata/getopt/msgids.txt create mode 100644 Lib/test/translationdata/optparse/msgids.txt diff --git a/Lib/test/support/i18n_helper.py b/Lib/test/support/i18n_helper.py new file mode 100644 index 000000000000000..2e304f29e8ba7fd --- /dev/null +++ b/Lib/test/support/i18n_helper.py @@ -0,0 +1,63 @@ +import re +import subprocess +import sys +import unittest +from pathlib import Path +from test.support import REPO_ROOT, TEST_HOME_DIR, requires_subprocess +from test.test_tools import skip_if_missing + + +pygettext = Path(REPO_ROOT) / 'Tools' / 'i18n' / 'pygettext.py' + +msgid_pattern = re.compile(r'msgid(.*?)(?:msgid_plural|msgctxt|msgstr)', + re.DOTALL) +msgid_string_pattern = re.compile(r'"((?:\\"|[^"])*)"') + + +def _generate_po_file(path, *, stdout_only=True): + res = subprocess.run([sys.executable, pygettext, + '--no-location', '-o', '-', path], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + text=True) + if stdout_only: + return res.stdout + return res + + +def _extract_msgids(po): + msgids = [] + for msgid in msgid_pattern.findall(po): + msgid_string = ''.join(msgid_string_pattern.findall(msgid)) + msgid_string = msgid_string.replace(r'\"', '"') + if msgid_string: + msgids.append(msgid_string) + return sorted(msgids) + + +def _get_snapshot_path(module_name): + return Path(TEST_HOME_DIR) / 'translationdata' / module_name / 'msgids.txt' + + +@requires_subprocess() +class TestTranslationsBase(unittest.TestCase): + + def assertMsgidsEqual(self, module): + '''Assert that msgids extracted from a given module match a + snapshot. + + ''' + skip_if_missing('i18n') + res = _generate_po_file(module.__file__, stdout_only=False) + self.assertEqual(res.returncode, 0) + self.assertEqual(res.stderr, '') + msgids = _extract_msgids(res.stdout) + snapshot_path = _get_snapshot_path(module.__name__) + snapshot = snapshot_path.read_text().splitlines() + self.assertListEqual(msgids, snapshot) + + +def update_translation_snapshots(module): + contents = _generate_po_file(module.__file__) + msgids = _extract_msgids(contents) + snapshot_path = _get_snapshot_path(module.__name__) + snapshot_path.write_text('\n'.join(msgids)) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index cbf119ed2dabbb7..358cfb1c56aae49 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -7,10 +7,8 @@ import operator import os import py_compile -import re import shutil import stat -import subprocess import sys import textwrap import tempfile @@ -19,15 +17,11 @@ import warnings from enum import StrEnum -from pathlib import Path -from test.support import REPO_ROOT -from test.support import TEST_HOME_DIR from test.support import captured_stderr from test.support import import_helper from test.support import os_helper -from test.support import requires_subprocess from test.support import script_helper -from test.test_tools import skip_if_missing +from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots from unittest import mock @@ -7056,50 +7050,10 @@ def test_directory_in_zipfile_compiled(self): # Translation tests # ================= -pygettext = Path(REPO_ROOT) / 'Tools' / 'i18n' / 'pygettext.py' -snapshot_path = Path(TEST_HOME_DIR) / 'translationdata' / 'argparse' / 'msgids.txt' - -msgid_pattern = re.compile(r'msgid(.*?)(?:msgid_plural|msgctxt|msgstr)', re.DOTALL) -msgid_string_pattern = re.compile(r'"((?:\\"|[^"])*)"') - - -@requires_subprocess() -class TestTranslations(unittest.TestCase): +class TestTranslations(TestTranslationsBase): def test_translations(self): - # Test messages extracted from the argparse module against a snapshot - skip_if_missing('i18n') - res = generate_po_file(stdout_only=False) - self.assertEqual(res.returncode, 0) - self.assertEqual(res.stderr, '') - msgids = extract_msgids(res.stdout) - snapshot = snapshot_path.read_text().splitlines() - self.assertListEqual(msgids, snapshot) - - -def generate_po_file(*, stdout_only=True): - res = subprocess.run([sys.executable, pygettext, - '--no-location', '-o', '-', argparse.__file__], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - if stdout_only: - return res.stdout - return res - - -def extract_msgids(po): - msgids = [] - for msgid in msgid_pattern.findall(po): - msgid_string = ''.join(msgid_string_pattern.findall(msgid)) - msgid_string = msgid_string.replace(r'\"', '"') - if msgid_string: - msgids.append(msgid_string) - return sorted(msgids) - - -def update_translation_snapshots(): - contents = generate_po_file() - msgids = extract_msgids(contents) - snapshot_path.write_text('\n'.join(msgids)) + self.assertMsgidsEqual(argparse) def tearDownModule(): @@ -7111,6 +7065,6 @@ def tearDownModule(): if __name__ == '__main__': # To regenerate translation snapshots if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update': - update_translation_snapshots() + update_translation_snapshots(argparse) sys.exit(0) unittest.main() diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 984bdb73f34aa44..0675bcbb4e8247d 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -1,11 +1,12 @@ # test_getopt.py # David Goodger 2000-08-19 -from test.support.os_helper import EnvironmentVarGuard import doctest -import unittest - import getopt +import sys +import unittest +from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots +from test.support.os_helper import EnvironmentVarGuard sentinel = object() @@ -224,10 +225,20 @@ def test_libref_examples(): ['a1', 'a2'] """ + +class TestTranslations(TestTranslationsBase): + def test_translations(self): + self.assertMsgidsEqual(getopt) + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) return tests -if __name__ == "__main__": +if __name__ == '__main__': + # To regenerate translation snapshots + if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update': + update_translation_snapshots(getopt) + sys.exit(0) unittest.main() diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index 28b274462388eda..8655a0537a5e56a 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -15,7 +15,7 @@ from io import StringIO from test import support from test.support import os_helper - +from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots import optparse from optparse import make_option, Option, \ @@ -1656,5 +1656,14 @@ def test__all__(self): support.check__all__(self, optparse, not_exported=not_exported) +class TestTranslations(TestTranslationsBase): + def test_translations(self): + self.assertMsgidsEqual(optparse) + + if __name__ == '__main__': + # To regenerate translation snapshots + if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update': + update_translation_snapshots(optparse) + sys.exit(0) unittest.main() diff --git a/Lib/test/translationdata/getopt/msgids.txt b/Lib/test/translationdata/getopt/msgids.txt new file mode 100644 index 000000000000000..1ffab1f31abad5e --- /dev/null +++ b/Lib/test/translationdata/getopt/msgids.txt @@ -0,0 +1,6 @@ +option -%s not recognized +option -%s requires argument +option --%s must not have an argument +option --%s not a unique prefix +option --%s not recognized +option --%s requires argument \ No newline at end of file diff --git a/Lib/test/translationdata/optparse/msgids.txt b/Lib/test/translationdata/optparse/msgids.txt new file mode 100644 index 000000000000000..ac5317c736af8ce --- /dev/null +++ b/Lib/test/translationdata/optparse/msgids.txt @@ -0,0 +1,14 @@ +%prog [options] +%s option does not take a value +Options +Usage +Usage: %s\n +ambiguous option: %s (%s?) +complex +floating-point +integer +no such option: %s +option %s: invalid %s value: %r +option %s: invalid choice: %r (choose from %s) +show program's version number and exit +show this help message and exit \ No newline at end of file diff --git a/Makefile.pre.in b/Makefile.pre.in index a337223d4d8608c..8d94ba361fd934c 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2567,6 +2567,8 @@ TESTSUBDIRS= idlelib/idle_test \ test/tracedmodules \ test/translationdata \ test/translationdata/argparse \ + test/translationdata/getopt \ + test/translationdata/optparse \ test/typinganndata \ test/wheeldata \ test/xmltestdata \ From 036930d84409d0725a4ab95fb976f74d1698c41f Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 11 Nov 2024 17:49:48 -0500 Subject: [PATCH 14/57] Docs: re-create pages for removed modules to document their removal. (#126622) Will also need to change the redirects that were created here: https://github.com/python/psf-salt/pull/521/files --- Doc/library/aifc.rst | 15 +++++++ Doc/library/asynchat.rst | 17 ++++++++ Doc/library/asyncore.rst | 17 ++++++++ Doc/library/audioop.rst | 15 +++++++ Doc/library/cgi.rst | 19 +++++++++ Doc/library/cgitb.rst | 19 +++++++++ Doc/library/chunk.rst | 15 +++++++ Doc/library/crypt.rst | 20 ++++++++++ Doc/library/distutils.rst | 17 ++++++++ Doc/library/imghdr.rst | 19 +++++++++ Doc/library/imp.rst | 18 +++++++++ Doc/library/index.rst | 1 + Doc/library/mailcap.rst | 15 +++++++ Doc/library/msilib.rst | 15 +++++++ Doc/library/nis.rst | 15 +++++++ Doc/library/nntplib.rst | 15 +++++++ Doc/library/ossaudiodev.rst | 15 +++++++ Doc/library/pipes.rst | 17 ++++++++ Doc/library/removed.rst | 39 +++++++++++++++++++ Doc/library/smtpd.rst | 18 +++++++++ Doc/library/sndhdr.rst | 19 +++++++++ Doc/library/spwd.rst | 18 +++++++++ Doc/library/sunau.rst | 15 +++++++ Doc/library/telnetlib.rst | 19 +++++++++ Doc/library/uu.rst | 15 +++++++ Doc/library/xdrlib.rst | 15 +++++++ Doc/whatsnew/3.12.rst | 6 +++ ...-11-09-19-43-10.gh-issue-126622.YacfDc.rst | 3 ++ 28 files changed, 451 insertions(+) create mode 100644 Doc/library/aifc.rst create mode 100644 Doc/library/asynchat.rst create mode 100644 Doc/library/asyncore.rst create mode 100644 Doc/library/audioop.rst create mode 100644 Doc/library/cgi.rst create mode 100644 Doc/library/cgitb.rst create mode 100644 Doc/library/chunk.rst create mode 100644 Doc/library/crypt.rst create mode 100644 Doc/library/distutils.rst create mode 100644 Doc/library/imghdr.rst create mode 100644 Doc/library/imp.rst create mode 100644 Doc/library/mailcap.rst create mode 100644 Doc/library/msilib.rst create mode 100644 Doc/library/nis.rst create mode 100644 Doc/library/nntplib.rst create mode 100644 Doc/library/ossaudiodev.rst create mode 100644 Doc/library/pipes.rst create mode 100644 Doc/library/removed.rst create mode 100644 Doc/library/smtpd.rst create mode 100644 Doc/library/sndhdr.rst create mode 100644 Doc/library/spwd.rst create mode 100644 Doc/library/sunau.rst create mode 100644 Doc/library/telnetlib.rst create mode 100644 Doc/library/uu.rst create mode 100644 Doc/library/xdrlib.rst create mode 100644 Misc/NEWS.d/next/Documentation/2024-11-09-19-43-10.gh-issue-126622.YacfDc.rst diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst new file mode 100644 index 000000000000000..a756d679036ecbf --- /dev/null +++ b/Doc/library/aifc.rst @@ -0,0 +1,15 @@ +:mod:`!aifc` --- Read and write AIFF and AIFC files +=================================================== + +.. module:: aifc + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!aifc` module was +`Python 3.12 `_. diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst new file mode 100644 index 000000000000000..5e5c3a99fe66f1b --- /dev/null +++ b/Doc/library/asynchat.rst @@ -0,0 +1,17 @@ +:mod:`!asynchat` --- Asynchronous socket command/response handler +================================================================= + +.. module:: asynchat + :synopsis: Removed in 3.12. + :deprecated: + +.. deprecated-removed:: 3.6 3.12 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.12 ` after +being deprecated in Python 3.6. The removal was decided in :pep:`594`. + +Applications should use the :mod:`asyncio` module instead. + +The last version of Python that provided the :mod:`!asynchat` module was +`Python 3.11 `_. diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst new file mode 100644 index 000000000000000..22c9881c3cca362 --- /dev/null +++ b/Doc/library/asyncore.rst @@ -0,0 +1,17 @@ +:mod:`!asyncore` --- Asynchronous socket handler +================================================ + +.. module:: asyncore + :synopsis: Removed in 3.12. + :deprecated: + +.. deprecated-removed:: 3.6 3.12 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.12 ` after +being deprecated in Python 3.6. The removal was decided in :pep:`594`. + +Applications should use the :mod:`asyncio` module instead. + +The last version of Python that provided the :mod:`!asyncore` module was +`Python 3.11 `_. diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst new file mode 100644 index 000000000000000..3bc580b0bd34332 --- /dev/null +++ b/Doc/library/audioop.rst @@ -0,0 +1,15 @@ +:mod:`!audioop` --- Manipulate raw audio data +============================================= + +.. module:: audioop + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!audioop` module was +`Python 3.12 `_. diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst new file mode 100644 index 000000000000000..f9108fa954a906f --- /dev/null +++ b/Doc/library/cgi.rst @@ -0,0 +1,19 @@ +:mod:`!cgi` --- Common Gateway Interface support +================================================ + +.. module:: cgi + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +A fork of the module on PyPI can be used instead: :pypi:`legacy-cgi`. +This is a copy of the cgi module, no longer maintained or supported by the core +Python team. + +The last version of Python that provided the :mod:`!cgi` module was +`Python 3.12 `_. diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst new file mode 100644 index 000000000000000..fc646aa4c48acd0 --- /dev/null +++ b/Doc/library/cgitb.rst @@ -0,0 +1,19 @@ +:mod:`!cgitb` --- Traceback manager for CGI scripts +=================================================== + +.. module:: cgitb + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +A fork of the module on PyPI can now be used instead: :pypi:`legacy-cgi`. +This is a copy of the cgi module, no longer maintained or supported by the core +Python team. + +The last version of Python that provided the :mod:`!cgitb` module was +`Python 3.12 `_. diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst new file mode 100644 index 000000000000000..9950a0ea70649a8 --- /dev/null +++ b/Doc/library/chunk.rst @@ -0,0 +1,15 @@ +:mod:`!chunk` --- Read IFF chunked data +======================================= + +.. module:: chunk + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!chunk` module was +`Python 3.12 `_. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst new file mode 100644 index 000000000000000..9ff37196ccf69ff --- /dev/null +++ b/Doc/library/crypt.rst @@ -0,0 +1,20 @@ +:mod:`!crypt` --- Function to check Unix passwords +================================================== + +.. module:: crypt + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +Applications can use the :mod:`hashlib` module from the standard library. +Other possible replacements are third-party libraries from PyPI: +:pypi:`legacycrypt`, :pypi:`bcrypt`, :pypi:`argon2-cffi`, or :pypi:`passlib`. +These are not supported or maintained by the Python core team. + +The last version of Python that provided the :mod:`!crypt` module was +`Python 3.12 `_. diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst new file mode 100644 index 000000000000000..af63e035bf3c4ac --- /dev/null +++ b/Doc/library/distutils.rst @@ -0,0 +1,17 @@ +:mod:`!distutils` --- Building and installing Python modules +============================================================ + +.. module:: distutils + :synopsis: Removed in 3.12. + :deprecated: + +.. deprecated-removed:: 3.10 3.12 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.12 ` after +being deprecated in Python 3.10. The removal was decided in :pep:`632`, +which has `migration advice +`_. + +The last version of Python that provided the :mod:`!distutils` module was +`Python 3.11 `_. diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst new file mode 100644 index 000000000000000..56f26355f42558c --- /dev/null +++ b/Doc/library/imghdr.rst @@ -0,0 +1,19 @@ +:mod:`!imghdr` --- Determine the type of an image +================================================= + +.. module:: imghdr + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +Possible replacements are third-party libraries from PyPI: +:pypi:`filetype`, :pypi:`puremagic`, or :pypi:`python-magic`. +These are not supported or maintained by the Python core team. + +The last version of Python that provided the :mod:`!imghdr` module was +`Python 3.12 `_. diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst new file mode 100644 index 000000000000000..3dc4c568b1ae2f1 --- /dev/null +++ b/Doc/library/imp.rst @@ -0,0 +1,18 @@ +:mod:`!imp` --- Access the import internals +=========================================== + +.. module:: imp + :synopsis: Removed in 3.12. + :deprecated: + +.. deprecated-removed:: 3.4 3.12 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.12 ` after +being deprecated in Python 3.4. + +The :ref:`removal notice ` includes guidance for +migrating code from :mod:`!imp` to :mod:`importlib`. + +The last version of Python that provided the :mod:`!imp` module was +`Python 3.11 `_. diff --git a/Doc/library/index.rst b/Doc/library/index.rst index 0b348ae6f5c8c0a..951fbcf13fbb139 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -75,4 +75,5 @@ the `Python Package Index `_. unix.rst cmdline.rst superseded.rst + removed.rst security_warnings.rst diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst new file mode 100644 index 000000000000000..4467da146a5a05a --- /dev/null +++ b/Doc/library/mailcap.rst @@ -0,0 +1,15 @@ +:mod:`!mailcap` --- Mailcap file handling +========================================= + +.. module:: mailcap + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!mailcap` module was +`Python 3.12 `_. diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst new file mode 100644 index 000000000000000..eb1ac551ded456b --- /dev/null +++ b/Doc/library/msilib.rst @@ -0,0 +1,15 @@ +:mod:`!msilib` --- Read and write Microsoft Installer files +=========================================================== + +.. module:: msilib + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!msilib` module was +`Python 3.12 `_. diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst new file mode 100644 index 000000000000000..dcc36dd43fc313a --- /dev/null +++ b/Doc/library/nis.rst @@ -0,0 +1,15 @@ +:mod:`!nis` --- Interface to Sun’s NIS (Yellow Pages) +===================================================== + +.. module:: nis + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!nis` module was +`Python 3.12 `_. diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst new file mode 100644 index 000000000000000..8053fe8cb8b9e12 --- /dev/null +++ b/Doc/library/nntplib.rst @@ -0,0 +1,15 @@ +:mod:`!nntplib` --- NNTP protocol client +======================================== + +.. module:: nntplib + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!nntplib` module was +`Python 3.12 `_. diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst new file mode 100644 index 000000000000000..320adbeff825399 --- /dev/null +++ b/Doc/library/ossaudiodev.rst @@ -0,0 +1,15 @@ +:mod:`!ossaudiodev` --- Access to OSS-compatible audio devices +============================================================== + +.. module:: ossaudiodev + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!ossaudiodev` module was +`Python 3.12 `_. diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst new file mode 100644 index 000000000000000..d9bcc3a5d99c9b9 --- /dev/null +++ b/Doc/library/pipes.rst @@ -0,0 +1,17 @@ +:mod:`!pipes` --- Interface to shell pipelines +============================================== + +.. module:: pipes + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +Applications should use the :mod:`subprocess` module instead. + +The last version of Python that provided the :mod:`!pipes` module was +`Python 3.12 `_. diff --git a/Doc/library/removed.rst b/Doc/library/removed.rst new file mode 100644 index 000000000000000..4d75842eca1a03f --- /dev/null +++ b/Doc/library/removed.rst @@ -0,0 +1,39 @@ +:tocdepth: 1 + +.. _removed: + +*************** +Removed Modules +*************** + +The modules described in this chapter have been removed from the Python +standard library. They are documented here to help people find replacements. + + +.. toctree:: + :maxdepth: 1 + + aifc.rst + asynchat.rst + asyncore.rst + audioop.rst + cgi.rst + cgitb.rst + chunk.rst + crypt.rst + distutils.rst + imghdr.rst + imp.rst + mailcap.rst + msilib.rst + nis.rst + nntplib.rst + ossaudiodev.rst + pipes.rst + smtpd.rst + sndhdr.rst + spwd.rst + sunau.rst + telnetlib.rst + uu.rst + xdrlib.rst diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst new file mode 100644 index 000000000000000..c704f4a241b4692 --- /dev/null +++ b/Doc/library/smtpd.rst @@ -0,0 +1,18 @@ +:mod:`!smtpd` --- SMTP Server +============================= + +.. module:: smtpd + :synopsis: Removed in 3.12. + :deprecated: + +.. deprecated-removed:: 3.6 3.12 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.12 ` after +being deprecated in Python 3.6. The removal was decided in :pep:`594`. + +A possible replacement is the third-party :pypi:`aiosmtpd` library. This +library is not maintained or supported by the Python core team. + +The last version of Python that provided the :mod:`!smtpd` module was +`Python 3.11 `_. diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst new file mode 100644 index 000000000000000..6b71db4f6338a8f --- /dev/null +++ b/Doc/library/sndhdr.rst @@ -0,0 +1,19 @@ +:mod:`!sndhdr` --- Determine type of sound file +=============================================== + +.. module:: sndhdr + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +Possible replacements are third-party modules from PyPI: +:pypi:`filetype`, :pypi:`puremagic`, or :pypi:`python-magic`. +These are not supported or maintained by the Python core team. + +The last version of Python that provided the :mod:`!sndhdr` module was +`Python 3.12 `_. diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst new file mode 100644 index 000000000000000..c16854bb380e521 --- /dev/null +++ b/Doc/library/spwd.rst @@ -0,0 +1,18 @@ +:mod:`!spwd` --- The shadow password database +============================================= + +.. module:: spwd + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +A possible replacement is the third-party library :pypi:`python-pam`. +This library is not supported or maintained by the Python core team. + +The last version of Python that provided the :mod:`!spwd` module was +`Python 3.12 `_. diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst new file mode 100644 index 000000000000000..feb7768f8bdd68c --- /dev/null +++ b/Doc/library/sunau.rst @@ -0,0 +1,15 @@ +:mod:`!sunau` --- Read and write Sun AU files +============================================= + +.. module:: sunau + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!sunau` module was +`Python 3.12 `_. diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst new file mode 100644 index 000000000000000..6971ad33ff9751c --- /dev/null +++ b/Doc/library/telnetlib.rst @@ -0,0 +1,19 @@ +:mod:`!telnetlib` --- Telnet client +=================================== + +.. module:: telnetlib + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +Possible replacements are third-party libraries from PyPI: :pypi:`telnetlib3` +or :pypi:`Exscript`. These are not supported or maintained by the Python core +team. + +The last version of Python that provided the :mod:`!telnetlib` module was +`Python 3.12 `_. diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst new file mode 100644 index 000000000000000..0636d180294d474 --- /dev/null +++ b/Doc/library/uu.rst @@ -0,0 +1,15 @@ +:mod:`!uu` --- Encode and decode uuencode files +=============================================== + +.. module:: uu + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!uu` module was +`Python 3.12 `_. diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst new file mode 100644 index 000000000000000..59b801c8e4072e8 --- /dev/null +++ b/Doc/library/xdrlib.rst @@ -0,0 +1,15 @@ +:mod:`!xdrlib` --- Encode and decode XDR data +============================================= + +.. module:: xdrlib + :synopsis: Removed in 3.13. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + +This module is no longer part of the Python standard library. +It was :ref:`removed in Python 3.13 ` after +being deprecated in Python 3.11. The removal was decided in :pep:`594`. + +The last version of Python that provided the :mod:`!xdrlib` module was +`Python 3.12 `_. diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index d691185cb1ffc57..4fffc78a2377914 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1341,6 +1341,8 @@ Deprecated .. include:: ../deprecations/pending-removal-in-future.rst +.. _whatsnew312-removed: + Removed ======= @@ -1366,6 +1368,8 @@ configparser * :class:`configparser.ConfigParser` no longer has a ``readfp`` method. Use :meth:`~configparser.ConfigParser.read_file` instead. +.. _whatsnew312-removed-distutils: + distutils --------- @@ -1447,6 +1451,8 @@ importlib * ``importlib.abc.Finder``, ``pkgutil.ImpImporter``, and ``pkgutil.ImpLoader`` have been removed. (Contributed by Barry Warsaw in :gh:`98040`.) +.. _whatsnew312-removed-imp: + imp --- diff --git a/Misc/NEWS.d/next/Documentation/2024-11-09-19-43-10.gh-issue-126622.YacfDc.rst b/Misc/NEWS.d/next/Documentation/2024-11-09-19-43-10.gh-issue-126622.YacfDc.rst new file mode 100644 index 000000000000000..a2181b5712873b4 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2024-11-09-19-43-10.gh-issue-126622.YacfDc.rst @@ -0,0 +1,3 @@ +Added stub pages for removed modules explaining their removal, where to find +replacements, and linking to the last Python version that supported them. +Contributed by Ned Batchelder. From a6d48e8f8323758771f5e130f67c9bdf7b4f25c5 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 11 Nov 2024 15:58:46 -0700 Subject: [PATCH 15/57] gh-76785: Improved Subinterpreters Compatibility with 3.12 (1/2) (gh-126704) These changes makes it easier to backport the _interpreters, _interpqueues, and _interpchannels modules to Python 3.12. This involves the following: * rename several structs and typedefs * add several typedefs * stop using the PyThreadState.state field directly in parking_lot.c --- Include/internal/pycore_crossinterp.h | 20 +++++----- .../pycore_crossinterp_data_registry.h | 18 ++++----- Include/internal/pycore_interp.h | 4 +- Include/internal/pycore_pystate.h | 6 +++ Include/internal/pycore_runtime.h | 4 +- Modules/_interpchannelsmodule.c | 2 +- Python/crossinterp.c | 37 +++++++++++-------- Python/crossinterp_data_lookup.h | 4 +- Python/parking_lot.c | 3 +- 9 files changed, 55 insertions(+), 43 deletions(-) diff --git a/Include/internal/pycore_crossinterp.h b/Include/internal/pycore_crossinterp.h index a7e71efc5daa494..66719796aeee227 100644 --- a/Include/internal/pycore_crossinterp.h +++ b/Include/internal/pycore_crossinterp.h @@ -39,14 +39,14 @@ extern int _Py_CallInInterpreterAndRawFree( /* cross-interpreter data */ /**************************/ -typedef struct _xid _PyXIData_t; -typedef PyObject *(*xid_newobjectfunc)(_PyXIData_t *); +typedef struct _xidata _PyXIData_t; +typedef PyObject *(*xid_newobjfunc)(_PyXIData_t *); typedef void (*xid_freefunc)(void *); // _PyXIData_t is similar to Py_buffer as an effectively // opaque struct that holds data outside the object machinery. This // is necessary to pass safely between interpreters in the same process. -struct _xid { +struct _xidata { // data is the cross-interpreter-safe derivation of a Python object // (see _PyObject_GetXIData). It will be NULL if the // new_object func (below) encodes the data. @@ -72,7 +72,7 @@ struct _xid { // interpreter given the data. The resulting object (a new // reference) will be equivalent to the original object. This field // is required. - xid_newobjectfunc new_object; + xid_newobjfunc new_object; // free is called when the data is released. If it is NULL then // nothing will be done to free the data. For some types this is // okay (e.g. bytes) and for those types this field should be set @@ -117,11 +117,11 @@ PyAPI_FUNC(int) _PyXIData_ReleaseAndRawFree(_PyXIData_t *); PyAPI_FUNC(void) _PyXIData_Init( _PyXIData_t *data, PyInterpreterState *interp, void *shared, PyObject *obj, - xid_newobjectfunc new_object); + xid_newobjfunc new_object); PyAPI_FUNC(int) _PyXIData_InitWithSize( _PyXIData_t *, PyInterpreterState *interp, const size_t, PyObject *, - xid_newobjectfunc); + xid_newobjfunc); PyAPI_FUNC(void) _PyXIData_Clear( PyInterpreterState *, _PyXIData_t *); // Normally the Init* functions are sufficient. The only time @@ -155,12 +155,12 @@ PyAPI_FUNC(void) _PyXIData_Clear( PyInterpreterState *, _PyXIData_t *); /* runtime state & lifecycle */ /*****************************/ -struct _xi_runtime_state { +typedef struct { // builtin types _PyXIData_lookup_t data_lookup; -}; +} _PyXI_global_state_t; -struct _xi_state { +typedef struct { // heap types _PyXIData_lookup_t data_lookup; @@ -171,7 +171,7 @@ struct _xi_state { // heap types PyObject *PyExc_NotShareableError; } exceptions; -}; +} _PyXI_state_t; extern PyStatus _PyXI_Init(PyInterpreterState *interp); extern void _PyXI_Fini(PyInterpreterState *interp); diff --git a/Include/internal/pycore_crossinterp_data_registry.h b/Include/internal/pycore_crossinterp_data_registry.h index 2990c6af62e952a..04f25bc05fd1b80 100644 --- a/Include/internal/pycore_crossinterp_data_registry.h +++ b/Include/internal/pycore_crossinterp_data_registry.h @@ -7,30 +7,30 @@ // alternative would be to add a tp_* slot for a class's // xidatafunc. It would be simpler and more efficient. -struct _xidregitem; +struct _xid_regitem; -struct _xidregitem { - struct _xidregitem *prev; - struct _xidregitem *next; +typedef struct _xid_regitem { + struct _xid_regitem *prev; + struct _xid_regitem *next; /* This can be a dangling pointer, but only if weakref is set. */ PyTypeObject *cls; /* This is NULL for builtin types. */ PyObject *weakref; size_t refcount; xidatafunc getdata; -}; +} _PyXIData_regitem_t; -struct _xidregistry { +typedef struct { int global; /* builtin types or heap types */ int initialized; PyMutex mutex; - struct _xidregitem *head; -}; + _PyXIData_regitem_t *head; +} _PyXIData_registry_t; PyAPI_FUNC(int) _PyXIData_RegisterClass(PyTypeObject *, xidatafunc); PyAPI_FUNC(int) _PyXIData_UnregisterClass(PyTypeObject *); struct _xid_lookup_state { // XXX Remove this field once we have a tp_* slot. - struct _xidregistry registry; + _PyXIData_registry_t registry; }; diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 9e3b4299693bbc6..824b865eda60df8 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -16,7 +16,7 @@ extern "C" { #include "pycore_code.h" // struct callable_cache #include "pycore_codecs.h" // struct codecs_state #include "pycore_context.h" // struct _Py_context_state -#include "pycore_crossinterp.h" // struct _xidregistry +#include "pycore_crossinterp.h" // _PyXI_state_t #include "pycore_dict_state.h" // struct _Py_dict_state #include "pycore_dtoa.h" // struct _dtoa_state #include "pycore_exceptions.h" // struct _Py_exc_state @@ -205,7 +205,7 @@ struct _is { freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; /* cross-interpreter data and utils */ - struct _xi_state xi; + _PyXI_state_t xi; #ifdef HAVE_FORK PyObject *before_forkers; diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index fade55945b7dbf3..edcd75a55b686b7 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -141,6 +141,12 @@ _PyThreadState_GET(void) #endif } +static inline int +_PyThreadState_IsAttached(PyThreadState *tstate) +{ + return (_Py_atomic_load_int_relaxed(&tstate->state) == _Py_THREAD_ATTACHED); +} + // Attaches the current thread to the interpreter. // // This may block while acquiring the GIL (if the GIL is enabled) or while diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index 7f592aa6cf9f057..2f2cec22cf1589c 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -11,7 +11,7 @@ extern "C" { #include "pycore_atexit.h" // struct _atexit_runtime_state #include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_ceval_state.h" // struct _ceval_runtime_state -#include "pycore_crossinterp.h" // struct _xidregistry +#include "pycore_crossinterp.h" // _PyXI_global_state_t #include "pycore_debug_offsets.h" // _Py_DebugOffsets #include "pycore_faulthandler.h" // struct _faulthandler_runtime_state #include "pycore_floatobject.h" // struct _Py_float_runtime_state @@ -106,7 +106,7 @@ typedef struct pyruntimestate { tools. */ /* cross-interpreter data and utils */ - struct _xi_runtime_state xi; + _PyXI_global_state_t xi; struct _pymem_allocators allocators; struct _obmalloc_global_state obmalloc; diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index b8d7dfb87cce0e1..cd3c50269385680 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -63,7 +63,7 @@ _globals (static struct globals): data (void *) obj (PyObject *) interpid (int64_t) - new_object (xid_newobjectfunc) + new_object (xid_newobjfunc) free (xid_freefunc) last (struct _channelitem *): ... diff --git a/Python/crossinterp.c b/Python/crossinterp.c index b7aa8da8ac550ec..dfdb5f9d87a7c7f 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -126,7 +126,7 @@ void _PyXIData_Init(_PyXIData_t *data, PyInterpreterState *interp, void *shared, PyObject *obj, - xid_newobjectfunc new_object) + xid_newobjfunc new_object) { assert(data != NULL); assert(new_object != NULL); @@ -150,7 +150,7 @@ int _PyXIData_InitWithSize(_PyXIData_t *data, PyInterpreterState *interp, const size_t size, PyObject *obj, - xid_newobjectfunc new_object) + xid_newobjfunc new_object) { assert(size > 0); // For now we always free the shared data in the same interpreter @@ -202,11 +202,9 @@ _check_xidata(PyThreadState *tstate, _PyXIData_t *data) } static inline void -_set_xid_lookup_failure(PyInterpreterState *interp, - PyObject *obj, const char *msg) +_set_xid_lookup_failure(_PyXI_state_t *state, PyObject *obj, const char *msg) { - exceptions_t *state = &_PyInterpreterState_GetXIState(interp)->exceptions; - PyObject *exctype = state->PyExc_NotShareableError; + PyObject *exctype = state->exceptions.PyExc_NotShareableError; assert(exctype != NULL); if (msg != NULL) { assert(obj == NULL); @@ -226,10 +224,11 @@ int _PyObject_CheckXIData(PyObject *obj) { PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXI_state_t *state = _PyXI_GET_STATE(interp); xidatafunc getdata = lookup_getdata(interp, obj); if (getdata == NULL) { if (!PyErr_Occurred()) { - _set_xid_lookup_failure(interp, obj, NULL); + _set_xid_lookup_failure(state, obj, NULL); } return -1; } @@ -241,6 +240,7 @@ _PyObject_GetXIData(PyObject *obj, _PyXIData_t *data) { PyThreadState *tstate = PyThreadState_Get(); PyInterpreterState *interp = tstate->interp; + _PyXI_state_t *state = _PyXI_GET_STATE(interp); // Reset data before re-populating. *data = (_PyXIData_t){0}; @@ -252,7 +252,7 @@ _PyObject_GetXIData(PyObject *obj, _PyXIData_t *data) if (getdata == NULL) { Py_DECREF(obj); if (!PyErr_Occurred()) { - _set_xid_lookup_failure(interp, obj, NULL); + _set_xid_lookup_failure(state, obj, NULL); } return -1; } @@ -969,6 +969,7 @@ _PyXI_ClearExcInfo(_PyXI_excinfo *info) static int _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp) { + _PyXI_state_t *state; assert(!PyErr_Occurred()); switch (code) { case _PyXI_ERR_NO_ERROR: _Py_FALLTHROUGH; @@ -999,7 +1000,8 @@ _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp) "failed to apply namespace to __main__"); break; case _PyXI_ERR_NOT_SHAREABLE: - _set_xid_lookup_failure(interp, NULL, NULL); + state = _PyXI_GET_STATE(interp); + _set_xid_lookup_failure(state, NULL, NULL); break; default: #ifdef Py_DEBUG @@ -1061,7 +1063,8 @@ _PyXI_ApplyError(_PyXI_error *error) } else if (error->code == _PyXI_ERR_NOT_SHAREABLE) { // Propagate the exception directly. - _set_xid_lookup_failure(error->interp, NULL, error->uncaught.msg); + _PyXI_state_t *state = _PyXI_GET_STATE(error->interp); + _set_xid_lookup_failure(state, NULL, error->uncaught.msg); } else { // Raise an exception corresponding to the code. @@ -1606,9 +1609,9 @@ _propagate_not_shareable_error(_PyXI_session *session) return; } PyInterpreterState *interp = PyInterpreterState_Get(); - exceptions_t *state = &_PyInterpreterState_GetXIState(interp)->exceptions; - assert(state->PyExc_NotShareableError != NULL); - if (PyErr_ExceptionMatches(state->PyExc_NotShareableError)) { + _PyXI_state_t *state = _PyXI_GET_STATE(interp); + assert(state->exceptions.PyExc_NotShareableError != NULL); + if (PyErr_ExceptionMatches(state->exceptions.PyExc_NotShareableError)) { // We want to propagate the exception directly. session->_error_override = _PyXI_ERR_NOT_SHAREABLE; session->error_override = &session->_error_override; @@ -1779,11 +1782,13 @@ _PyXI_Exit(_PyXI_session *session) PyStatus _PyXI_Init(PyInterpreterState *interp) { + _PyXI_state_t *state = _PyXI_GET_STATE(interp); + // Initialize the XID lookup state (e.g. registry). if (_Py_IsMainInterpreter(interp)) { xid_lookup_init(&_PyXI_GET_GLOBAL_STATE(interp)->data_lookup); } - xid_lookup_init(&_PyXI_GET_STATE(interp)->data_lookup); + xid_lookup_init(&state->data_lookup); // Initialize exceptions.(heap types). // See _PyXI_InitTypes() for the static types. @@ -1801,12 +1806,14 @@ _PyXI_Init(PyInterpreterState *interp) void _PyXI_Fini(PyInterpreterState *interp) { + _PyXI_state_t *state = _PyXI_GET_STATE(interp); + // Finalize exceptions (heap types). // See _PyXI_FiniTypes() for the static types. fini_heap_exctypes(&_PyXI_GET_STATE(interp)->exceptions); // Finalize the XID lookup state (e.g. registry). - xid_lookup_fini(&_PyXI_GET_STATE(interp)->data_lookup); + xid_lookup_fini(&state->data_lookup); if (_Py_IsMainInterpreter(interp)) { xid_lookup_fini(&_PyXI_GET_GLOBAL_STATE(interp)->data_lookup); } diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 88c662a3df00d64..9048f90cff160a9 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -1,8 +1,8 @@ #include "pycore_weakref.h" // _PyWeakref_GET_REF() -typedef struct _xidregistry dlregistry_t; -typedef struct _xidregitem dlregitem_t; +typedef _PyXIData_registry_t dlregistry_t; +typedef _PyXIData_regitem_t dlregitem_t; // forward diff --git a/Python/parking_lot.c b/Python/parking_lot.c index bffc959e5d09784..8edf43235942ab3 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -221,8 +221,7 @@ _PySemaphore_Wait(_PySemaphore *sema, PyTime_t timeout, int detach) PyThreadState *tstate = NULL; if (detach) { tstate = _PyThreadState_GET(); - if (tstate && _Py_atomic_load_int_relaxed(&tstate->state) == - _Py_THREAD_ATTACHED) { + if (tstate && _PyThreadState_IsAttached(tstate)) { // Only detach if we are attached PyEval_ReleaseThread(tstate); } From 494360afd00dc8f6b549f160525c3e86ec14905d Mon Sep 17 00:00:00 2001 From: Beomsoo Kim Date: Tue, 12 Nov 2024 09:11:40 +0900 Subject: [PATCH 16/57] gh-58749: Remove incorrect language spec claims about the global statement (GH-126523) * Removes erroneous explanation of the `global` statement restrictions; a name declared as global can be subsequently bound using any kind of name binding operation. * Updates `test_global.py` to also test various name-binding scenarios for global variables to ensure correct behavior --- Doc/reference/simple_stmts.rst | 21 +--- Lib/test/test_global.py | 213 ++++++++++++++++++++++++++++----- Misc/ACKS | 1 + 3 files changed, 191 insertions(+), 44 deletions(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 24df4a6ba7b6784..a005395bfc402eb 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -966,25 +966,14 @@ The :keyword:`!global` statement .. productionlist:: python-grammar global_stmt: "global" `identifier` ("," `identifier`)* -The :keyword:`global` statement is a declaration which holds for the entire -current code block. It means that the listed identifiers are to be interpreted -as globals. It would be impossible to assign to a global variable without +The :keyword:`global` causes the listed identifiers to be interpreted +as globals. It would be impossible to assign to a global variable without :keyword:`!global`, although free variables may refer to globals without being declared global. -Names listed in a :keyword:`global` statement must not be used in the same code -block textually preceding that :keyword:`!global` statement. - -Names listed in a :keyword:`global` statement must not be defined as formal -parameters, or as targets in :keyword:`with` statements or :keyword:`except` clauses, or in a :keyword:`for` target list, :keyword:`class` -definition, function definition, :keyword:`import` statement, or -:term:`variable annotations `. - -.. impl-detail:: - - The current implementation does not enforce some of these restrictions, but - programs should not abuse this freedom, as future implementations may enforce - them or silently change the meaning of the program. +The global statement applies to the entire scope of a function or +class body. A :exc:`SyntaxError` is raised if a variable is used or +assigned to prior to its global declaration in the scope. .. index:: pair: built-in function; exec diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py index f5b38c25ea07288..11d0bd54e8b69b9 100644 --- a/Lib/test/test_global.py +++ b/Lib/test/test_global.py @@ -1,7 +1,19 @@ -"""Verify that warnings are issued for global statements following use.""" +"""This module includes tests for syntax errors that occur when a name +declared as `global` is used in ways that violate the language +specification, such as after assignment, usage, or annotation. The tests +verify that syntax errors are correctly raised for improper `global` +statements following variable use or assignment within functions. +Additionally, it tests various name-binding scenarios for global +variables to ensure correct behavior. +See `test_scope.py` for additional related behavioral tests covering +variable scoping and usage in different contexts. +""" + +import contextlib from test.support import check_syntax_error from test.support.warnings_helper import check_warnings +from types import SimpleNamespace import unittest import warnings @@ -12,40 +24,185 @@ def setUp(self): self.enterContext(check_warnings()) warnings.filterwarnings("error", module="") - def test1(self): - prog_text_1 = """\ -def wrong1(): - a = 1 - b = 2 - global a - global b + ###################################################### + ### Syntax error cases as covered in Python/symtable.c + ###################################################### + + def test_name_param(self): + prog_text = """\ +def fn(name_param): + global name_param """ - check_syntax_error(self, prog_text_1, lineno=4, offset=5) + check_syntax_error(self, prog_text, lineno=2, offset=5) - def test2(self): - prog_text_2 = """\ -def wrong2(): - print(x) - global x + def test_name_after_assign(self): + prog_text = """\ +def fn(): + name_assign = 1 + global name_assign """ - check_syntax_error(self, prog_text_2, lineno=3, offset=5) + check_syntax_error(self, prog_text, lineno=3, offset=5) - def test3(self): - prog_text_3 = """\ -def wrong3(): - print(x) - x = 2 - global x + def test_name_after_use(self): + prog_text = """\ +def fn(): + print(name_use) + global name_use """ - check_syntax_error(self, prog_text_3, lineno=4, offset=5) + check_syntax_error(self, prog_text, lineno=3, offset=5) - def test4(self): - prog_text_4 = """\ -global x -x = 2 + def test_name_annot(self): + prog_text_3 = """\ +def fn(): + name_annot: int + global name_annot """ - # this should work - compile(prog_text_4, "", "exec") + check_syntax_error(self, prog_text_3, lineno=3, offset=5) + + ############################################################# + ### Tests for global variables across all name binding cases, + ### as described in executionmodel.rst + ############################################################# + + def test_assignment_statement(self): + global name_assignment_statement + value = object() + name_assignment_statement = value + self.assertIs(globals()["name_assignment_statement"], value) + del name_assignment_statement + + def test_unpacking_assignment(self): + global name_unpacking_assignment + value = object() + _, name_unpacking_assignment = [None, value] + self.assertIs(globals()["name_unpacking_assignment"], value) + del name_unpacking_assignment + + def test_assignment_expression(self): + global name_assignment_expression + value = object() + if name_assignment_expression := value: + pass + self.assertIs(globals()["name_assignment_expression"], value) + del name_assignment_expression + + def test_iteration_variable(self): + global name_iteration_variable + value = object() + for name_iteration_variable in [value]: + pass + self.assertIs(globals()["name_iteration_variable"], value) + del name_iteration_variable + + def test_func_def(self): + global name_func_def + + def name_func_def(): + pass + + value = name_func_def + self.assertIs(globals()["name_func_def"], value) + del name_func_def + + def test_class_def(self): + global name_class_def + + class name_class_def: + pass + + value = name_class_def + self.assertIs(globals()["name_class_def"], value) + del name_class_def + + def test_type_alias(self): + global name_type_alias + type name_type_alias = tuple[int, int] + value = name_type_alias + self.assertIs(globals()["name_type_alias"], value) + del name_type_alias + + def test_caught_exception(self): + global name_caught_exc + + try: + 1 / 0 + except ZeroDivisionError as name_caught_exc: + value = name_caught_exc + # `name_caught_exc` is cleared automatically after the except block + self.assertIs(globals()["name_caught_exc"], value) + + def test_caught_exception_group(self): + global name_caught_exc_group + try: + try: + 1 / 0 + except ZeroDivisionError as exc: + raise ExceptionGroup("eg", [exc]) + except* ZeroDivisionError as name_caught_exc_group: + value = name_caught_exc_group + # `name_caught_exc` is cleared automatically after the except block + self.assertIs(globals()["name_caught_exc_group"], value) + + def test_enter_result(self): + global name_enter_result + value = object() + with contextlib.nullcontext(value) as name_enter_result: + pass + self.assertIs(globals()["name_enter_result"], value) + del name_enter_result + + def test_import_result(self): + global name_import_result + value = contextlib + import contextlib as name_import_result + + self.assertIs(globals()["name_import_result"], value) + del name_import_result + + def test_match(self): + global name_match + value = object() + match value: + case name_match: + pass + self.assertIs(globals()["name_match"], value) + del name_match + + def test_match_as(self): + global name_match_as + value = object() + match value: + case _ as name_match_as: + pass + self.assertIs(globals()["name_match_as"], value) + del name_match_as + + def test_match_seq(self): + global name_match_seq + value = object() + match (None, value): + case (_, name_match_seq): + pass + self.assertIs(globals()["name_match_seq"], value) + del name_match_seq + + def test_match_map(self): + global name_match_map + value = object() + match {"key": value}: + case {"key": name_match_map}: + pass + self.assertIs(globals()["name_match_map"], value) + del name_match_map + + def test_match_attr(self): + global name_match_attr + value = object() + match SimpleNamespace(key=value): + case SimpleNamespace(key=name_match_attr): + pass + self.assertIs(globals()["name_match_attr"], value) + del name_match_attr def setUpModule(): diff --git a/Misc/ACKS b/Misc/ACKS index 1a25088052f4e10..6b5d7bf80cee6de 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -953,6 +953,7 @@ Sanyam Khurana Tyler Kieft Mads Kiilerich Jason Killen +Beomsoo Bombs Kim Derek D. Kim Gihwan Kim Jan Kim From c45be8aa71ad886e12e8c897274498e4d828c9a5 Mon Sep 17 00:00:00 2001 From: Diego Russo Date: Tue, 12 Nov 2024 01:20:10 +0000 Subject: [PATCH 17/57] GH-126195: Use M1 JIT memory protection APIs (GH-126196) --- ...4-10-30-18-16-10.gh-issue-126195.6ezBpr.rst | 1 + Python/jit.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-30-18-16-10.gh-issue-126195.6ezBpr.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-30-18-16-10.gh-issue-126195.6ezBpr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-30-18-16-10.gh-issue-126195.6ezBpr.rst new file mode 100644 index 000000000000000..01424d8a545d782 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-30-18-16-10.gh-issue-126195.6ezBpr.rst @@ -0,0 +1 @@ +Improve JIT performance by 1.4% on macOS Apple Silicon by using platform-specific memory protection APIs. Patch by Diego Russo. diff --git a/Python/jit.c b/Python/jit.c index 90f693dfb7c41b9..7dd0da7a45055a9 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -58,7 +58,12 @@ jit_alloc(size_t size) int failed = memory == NULL; #else int flags = MAP_ANONYMOUS | MAP_PRIVATE; - unsigned char *memory = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0); + int prot = PROT_READ | PROT_WRITE; +# ifdef MAP_JIT + flags |= MAP_JIT; + prot |= PROT_EXEC; +# endif + unsigned char *memory = mmap(NULL, size, prot, flags, -1, 0); int failed = memory == MAP_FAILED; #endif if (failed) { @@ -102,8 +107,11 @@ mark_executable(unsigned char *memory, size_t size) int old; int failed = !VirtualProtect(memory, size, PAGE_EXECUTE_READ, &old); #else + int failed = 0; __builtin___clear_cache((char *)memory, (char *)memory + size); - int failed = mprotect(memory, size, PROT_EXEC | PROT_READ); +#ifndef MAP_JIT + failed = mprotect(memory, size, PROT_EXEC | PROT_READ); +#endif #endif if (failed) { jit_error("unable to protect executable memory"); @@ -499,6 +507,9 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz if (memory == NULL) { return -1; } +#ifdef MAP_JIT + pthread_jit_write_protect_np(0); +#endif // Update the offsets of each instruction: for (size_t i = 0; i < length; i++) { state.instruction_starts[i] += (uintptr_t)memory; @@ -529,6 +540,9 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz data += group->data_size; assert(code == memory + code_size); assert(data == memory + code_size + data_size); +#ifdef MAP_JIT + pthread_jit_write_protect_np(1); +#endif if (mark_executable(memory, total_size)) { jit_free(memory, total_size); return -1; From 599bfc986d2c32c507822ef785b63619bd616608 Mon Sep 17 00:00:00 2001 From: Sahil Prajapati Date: Tue, 12 Nov 2024 12:18:38 +0530 Subject: [PATCH 18/57] gh-84852: Add MIME types for .eot, ,otf, .ttf, .woff and .woff2 fonts (#20199) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/whatsnew/3.14.rst | 10 ++++++++++ Lib/mimetypes.py | 5 +++++ Lib/test/test_mimetypes.py | 5 +++++ .../2020-05-19-01-12-47.gh-issue-84852.FEjHJW.rst | 2 ++ 4 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-05-19-01-12-47.gh-issue-84852.FEjHJW.rst diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index f9b219828d3d94d..9c032637d651ec2 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -366,6 +366,16 @@ json mimetypes --------- +* Add MS and :rfc:`8081` MIME types for fonts: + + * Embedded OpenType: ``application/vnd.ms-fontobject`` + * OpenType Layout (OTF) ``font/otf`` + * TrueType: ``font/ttf`` + * WOFF 1.0 ``font/woff`` + * WOFF 2.0 ``font/woff2`` + + (Contributed by Sahil Prajapati and Hugo van Kemenade in :gh:`84852`.) + * Add :rfc:`9559` MIME types for Matroska audiovisual data container structures, containing: diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index fd343a78c98ae19..210d2264757d084 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -479,6 +479,7 @@ def _default_mime_types(): '.m3u8' : 'application/vnd.apple.mpegurl', '.xls' : 'application/vnd.ms-excel', '.xlb' : 'application/vnd.ms-excel', + '.eot' : 'application/vnd.ms-fontobject', '.ppt' : 'application/vnd.ms-powerpoint', '.pot' : 'application/vnd.ms-powerpoint', '.ppa' : 'application/vnd.ms-powerpoint', @@ -543,6 +544,10 @@ def _default_mime_types(): '.aiff' : 'audio/x-aiff', '.ra' : 'audio/x-pn-realaudio', '.wav' : 'audio/x-wav', + '.otf' : 'font/otf', + '.ttf' : 'font/ttf', + '.woff' : 'font/woff', + '.woff2' : 'font/woff2', '.avif' : 'image/avif', '.bmp' : 'image/bmp', '.gif' : 'image/gif', diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 8d3e8fcafb67405..c4bb8dfb1a74229 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -228,12 +228,17 @@ def check_extensions(): ("application/postscript", ".ps"), ("application/vnd.apple.mpegurl", ".m3u"), ("application/vnd.ms-excel", ".xls"), + ("application/vnd.ms-fontobject", ".eot"), ("application/vnd.ms-powerpoint", ".ppt"), ("application/x-texinfo", ".texi"), ("application/x-troff", ".roff"), ("application/xml", ".xsl"), ("audio/matroska", ".mka"), ("audio/mpeg", ".mp3"), + ("font/otf", ".otf"), + ("font/ttf", ".ttf"), + ("font/woff", ".woff"), + ("font/woff2", ".woff2"), ("image/avif", ".avif"), ("image/webp", ".webp"), ("image/jpeg", ".jpg"), diff --git a/Misc/NEWS.d/next/Library/2020-05-19-01-12-47.gh-issue-84852.FEjHJW.rst b/Misc/NEWS.d/next/Library/2020-05-19-01-12-47.gh-issue-84852.FEjHJW.rst new file mode 100644 index 000000000000000..2581697591af629 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-19-01-12-47.gh-issue-84852.FEjHJW.rst @@ -0,0 +1,2 @@ +Add MIME types for MS Embedded OpenType, OpenType Layout, TrueType, +WOFF 1.0 and 2.0 fonts. Patch by Sahil Prajapati and Hugo van Kemenade. From 0052a8c638518447baf39ae02b6ff6a309efd4ce Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 12 Nov 2024 10:51:13 +0300 Subject: [PATCH 19/57] Fix error message of "Check if Autoconf files are up to date" job (#126683) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f63c4606220494f..b769bba72816d68 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: # Check for changes in regenerated files if test -n "$changes"; then echo "Generated files not up to date." - echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" + echo "Perhaps you forgot to run make regen-configure ;)" echo "configure files must be regenerated with a specific version of autoconf." echo "$changes" echo "" From feb3e0b19cb03f06364a3f5e970f0861b8883d1c Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 12 Nov 2024 01:17:07 -0800 Subject: [PATCH 20/57] gh-126699: allow AsyncIterator to be used as a base for Protocols (#126702) --- Lib/test/test_typing.py | 3 +++ Lib/typing.py | 3 ++- .../Library/2024-11-11-13-24-22.gh-issue-126699.ONGbMd.rst | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-11-13-24-22.gh-issue-126699.ONGbMd.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 2f1f9e86a0bce4e..244ce1e5da9bd28 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4255,6 +4255,9 @@ class CustomProtocol(TestCase, Protocol): class CustomContextManager(typing.ContextManager, Protocol): pass + class CustomAsyncIterator(typing.AsyncIterator, Protocol): + pass + def test_non_runtime_protocol_isinstance_check(self): class P(Protocol): x: int diff --git a/Lib/typing.py b/Lib/typing.py index c924c7670425529..8e6381033fd28e2 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1940,7 +1940,8 @@ def _allow_reckless_class_checks(depth=2): _PROTO_ALLOWLIST = { 'collections.abc': [ 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', - 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer', + 'AsyncIterator', 'Hashable', 'Sized', 'Container', 'Collection', + 'Reversible', 'Buffer', ], 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], } diff --git a/Misc/NEWS.d/next/Library/2024-11-11-13-24-22.gh-issue-126699.ONGbMd.rst b/Misc/NEWS.d/next/Library/2024-11-11-13-24-22.gh-issue-126699.ONGbMd.rst new file mode 100644 index 000000000000000..9741294487d7160 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-11-13-24-22.gh-issue-126699.ONGbMd.rst @@ -0,0 +1 @@ +Allow :class:`collections.abc.AsyncIterator` to be a base for Protocols. From f223efb2a2d6a3e86556be7295cbbd3ef839f489 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 12 Nov 2024 13:23:57 +0300 Subject: [PATCH 21/57] gh-126525: Fix `makeunicodedata.py` output on macOS and Windows (#126526) --- Tools/unicode/makeunicodedata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index c94de7f9377b749..889ae8fc869b8ad 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -35,7 +35,7 @@ from textwrap import dedent from typing import Iterator, List, Optional, Set, Tuple -SCRIPT = sys.argv[0] +SCRIPT = os.path.normpath(sys.argv[0]) VERSION = "3.3" # The Unicode Database From 0ef84b0e2bf511b2cb5268a9ce64d7f2209fb3c4 Mon Sep 17 00:00:00 2001 From: Daehee Kim Date: Tue, 12 Nov 2024 21:01:56 +0900 Subject: [PATCH 22/57] gh-126209: Fix inconsistency of `skip_file_prefixes` in `warnings.warn`'s C and Python implementations (GH-126329) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Terry Jan Reedy Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Kirill Podoprigora --- Lib/test/test_warnings/__init__.py | 12 ++++++++++++ Lib/test/test_warnings/data/stacklevel.py | 10 ++++++---- .../2024-11-02-18-01-31.gh-issue-126209.2ZIhrS.rst | 3 +++ Python/_warnings.c | 3 ++- 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-02-18-01-31.gh-issue-126209.2ZIhrS.rst diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 8b59630717e790d..4e3c877896f295e 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -533,6 +533,18 @@ def test_skip_file_prefixes(self): warning_tests.package("prefix02", stacklevel=3) self.assertIn("unittest", w[-1].filename) + def test_skip_file_prefixes_file_path(self): + # see: gh-126209 + with warnings_state(self.module): + skipped = warning_tests.__file__ + with original_warnings.catch_warnings( + record=True, module=self.module, + ) as w: + warning_tests.outer("msg", skip_file_prefixes=(skipped,)) + + self.assertEqual(len(w), 1) + self.assertNotEqual(w[-1].filename, skipped) + def test_skip_file_prefixes_type_errors(self): with warnings_state(self.module): warn = warning_tests.warnings.warn diff --git a/Lib/test/test_warnings/data/stacklevel.py b/Lib/test/test_warnings/data/stacklevel.py index c6dd24733b3b747..fe36242d3d20c22 100644 --- a/Lib/test/test_warnings/data/stacklevel.py +++ b/Lib/test/test_warnings/data/stacklevel.py @@ -4,11 +4,13 @@ import warnings from test.test_warnings.data import package_helper -def outer(message, stacklevel=1): - inner(message, stacklevel) -def inner(message, stacklevel=1): - warnings.warn(message, stacklevel=stacklevel) +def outer(message, stacklevel=1, skip_file_prefixes=()): + inner(message, stacklevel, skip_file_prefixes) + +def inner(message, stacklevel=1, skip_file_prefixes=()): + warnings.warn(message, stacklevel=stacklevel, + skip_file_prefixes=skip_file_prefixes) def package(message, *, stacklevel): package_helper.inner_api(message, stacklevel=stacklevel, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-02-18-01-31.gh-issue-126209.2ZIhrS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-02-18-01-31.gh-issue-126209.2ZIhrS.rst new file mode 100644 index 000000000000000..727f7f8180ab22d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-02-18-01-31.gh-issue-126209.2ZIhrS.rst @@ -0,0 +1,3 @@ +Fix an issue with ``skip_file_prefixes`` parameter which resulted in an inconsistent +behaviour between the C and Python implementations of :func:`warnings.warn`. +Patch by Daehee Kim. diff --git a/Python/_warnings.c b/Python/_warnings.c index 3f9e73b5376223b..e05ba99e8eaec4b 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -803,7 +803,8 @@ is_filename_to_skip(PyObject *filename, PyTupleObject *skip_file_prefixes) for (Py_ssize_t idx = 0; idx < prefixes; ++idx) { PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx); - Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix, 0, -1, -1); + Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix, + 0, PY_SSIZE_T_MAX, -1); if (found == 1) { return true; } From 37c57dfad12744608091653fd753a1f770e2479b Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 12 Nov 2024 18:01:34 +0530 Subject: [PATCH 23/57] gh-126405: fix use-after-free in `_asyncio.Future.remove_done_callback` (#126733) --- Modules/_asynciomodule.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 617a3dca35d9c25..f883125a2c70b26 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1017,8 +1017,10 @@ _asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls, if (len == 1) { PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0); + Py_INCREF(cb_tup); int cmp = PyObject_RichCompareBool( PyTuple_GET_ITEM(cb_tup, 0), fn, Py_EQ); + Py_DECREF(cb_tup); if (cmp == -1) { return NULL; } From 6e3bb8a91380ba98d704f2dca8e98923c0abc8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:10:10 +0100 Subject: [PATCH 24/57] gh-126595: fix a crash when calling `itertools.count(sys.maxsize)` (#126617) --- Lib/test/test_itertools.py | 8 ++++++++ .../2024-11-09-10-31-10.gh-issue-126595.A-7MyC.rst | 2 ++ Modules/itertoolsmodule.c | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-11-09-10-31-10.gh-issue-126595.A-7MyC.rst diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index a52e1d3fa142d98..b94d688738f9e82 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -494,6 +494,8 @@ def test_count(self): self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)]) self.assertRaises(TypeError, count, 2, 3, 4) self.assertRaises(TypeError, count, 'a') + self.assertEqual(take(3, count(maxsize)), + [maxsize, maxsize + 1, maxsize + 2]) self.assertEqual(take(10, count(maxsize-5)), list(range(maxsize-5, maxsize+5))) self.assertEqual(take(10, count(-maxsize-5)), @@ -540,6 +542,12 @@ def test_count_with_step(self): self.assertEqual(take(20, count(-maxsize-15, 3)), take(20, range(-maxsize-15,-maxsize+100, 3))) self.assertEqual(take(3, count(10, maxsize+5)), list(range(10, 10+3*(maxsize+5), maxsize+5))) + self.assertEqual(take(3, count(maxsize, 2)), + [maxsize, maxsize + 2, maxsize + 4]) + self.assertEqual(take(3, count(maxsize, maxsize)), + [maxsize, 2 * maxsize, 3 * maxsize]) + self.assertEqual(take(3, count(-maxsize, maxsize)), + [-maxsize, 0, maxsize]) self.assertEqual(take(3, count(2, 1.25)), [2, 3.25, 4.5]) self.assertEqual(take(3, count(2, 3.25-4j)), [2, 5.25-4j, 8.5-8j]) self.assertEqual(take(3, count(Decimal('1.1'), Decimal('.1'))), diff --git a/Misc/NEWS.d/next/Library/2024-11-09-10-31-10.gh-issue-126595.A-7MyC.rst b/Misc/NEWS.d/next/Library/2024-11-09-10-31-10.gh-issue-126595.A-7MyC.rst new file mode 100644 index 000000000000000..84a5dc0b23922f5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-09-10-31-10.gh-issue-126595.A-7MyC.rst @@ -0,0 +1,2 @@ +Fix a crash when instantiating :class:`itertools.count` with an initial +count of :data:`sys.maxsize` on debug builds. Patch by Bénédikt Tran. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1201fa094902d7e..78fbdcdf77a9236 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3291,6 +3291,9 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, PyErr_Clear(); fast_mode = 0; } + else if (cnt == PY_SSIZE_T_MAX) { + fast_mode = 0; + } } } else { cnt = 0; From abb90ba46c597a1b192027e914ad312dd62d2462 Mon Sep 17 00:00:00 2001 From: Sayandip Dutta Date: Tue, 12 Nov 2024 18:41:58 +0530 Subject: [PATCH 25/57] gh-125916: Allow functools.reduce() 'initial' to be a keyword argument (#125917) --- Doc/library/functools.rst | 7 ++- Doc/whatsnew/3.14.rst | 5 +++ Lib/functools.py | 2 +- Lib/test/test_functools.py | 23 ++++++++++ Misc/ACKS | 1 + ...-10-24-13-40-20.gh-issue-126916.MAgz6D.rst | 2 + Modules/_functoolsmodule.c | 4 +- Modules/clinic/_functoolsmodule.c.h | 45 +++++++++++++++---- 8 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-24-13-40-20.gh-issue-126916.MAgz6D.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index e26a2226aa947a7..a9aceee41700048 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -453,7 +453,7 @@ The :mod:`functools` module defines the following functions: .. versionadded:: 3.4 -.. function:: reduce(function, iterable[, initial], /) +.. function:: reduce(function, iterable, /[, initial]) Apply *function* of two arguments cumulatively to the items of *iterable*, from left to right, so as to reduce the iterable to a single value. For example, @@ -468,7 +468,7 @@ The :mod:`functools` module defines the following functions: initial_missing = object() - def reduce(function, iterable, initial=initial_missing, /): + def reduce(function, iterable, /, initial=initial_missing): it = iter(iterable) if initial is initial_missing: value = next(it) @@ -481,6 +481,9 @@ The :mod:`functools` module defines the following functions: See :func:`itertools.accumulate` for an iterator that yields all intermediate values. + .. versionchanged:: next + *initial* is now supported as a keyword argument. + .. decorator:: singledispatch Transform a function into a :term:`single-dispatch value + reduce(function, iterable, /[, initial]) -> value Apply a function of two arguments cumulatively to the items of an iterable, from left to right. diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index d590af090abc6ef..6d60f6941c4c5d5 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -1005,6 +1005,29 @@ def __getitem__(self, i): d = {"one": 1, "two": 2, "three": 3} self.assertEqual(self.reduce(add, d), "".join(d.keys())) + # test correctness of keyword usage of `initial` in `reduce` + def test_initial_keyword(self): + def add(x, y): + return x + y + self.assertEqual( + self.reduce(add, ['a', 'b', 'c'], ''), + self.reduce(add, ['a', 'b', 'c'], initial=''), + ) + self.assertEqual( + self.reduce(add, [['a', 'c'], [], ['d', 'w']], []), + self.reduce(add, [['a', 'c'], [], ['d', 'w']], initial=[]), + ) + self.assertEqual( + self.reduce(lambda x, y: x*y, range(2,8), 1), + self.reduce(lambda x, y: x*y, range(2,8), initial=1), + ) + self.assertEqual( + self.reduce(lambda x, y: x*y, range(2,21), 1), + self.reduce(lambda x, y: x*y, range(2,21), initial=1), + ) + self.assertRaises(TypeError, self.reduce, add, [0, 1], initial="") + self.assertEqual(self.reduce(42, "", initial="1"), "1") # func is never called with one item + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestReduceC(TestReduce, unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index 6b5d7bf80cee6de..dce322fc8677439 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -485,6 +485,7 @@ Luke Dunstan Virgil Dupras Bruno Dupuis Andy Dustman +Sayandip Dutta Gary Duzan Eugene Dvurechenski Karmen Dykstra diff --git a/Misc/NEWS.d/next/Library/2024-10-24-13-40-20.gh-issue-126916.MAgz6D.rst b/Misc/NEWS.d/next/Library/2024-10-24-13-40-20.gh-issue-126916.MAgz6D.rst new file mode 100644 index 000000000000000..cbe2fc166ba6af5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-24-13-40-20.gh-issue-126916.MAgz6D.rst @@ -0,0 +1,2 @@ +Allow the *initial* parameter of :func:`functools.reduce` to be passed as a keyword argument. +Patch by Sayandip Dutta. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index d2afe1a1bea018b..5e0cf057dcd1a29 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -937,8 +937,8 @@ _functools.reduce function as func: object iterable as seq: object - initial as result: object = NULL / + initial as result: object = NULL Apply a function of two arguments cumulatively to the items of an iterable, from left to right. @@ -953,7 +953,7 @@ calculates ((((1 + 2) + 3) + 4) + 5). static PyObject * _functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq, PyObject *result) -/*[clinic end generated code: output=30d898fe1267c79d input=d233c2670cba7f66]*/ +/*[clinic end generated code: output=30d898fe1267c79d input=1511e9a8c38581ac]*/ { PyObject *args, *it; diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h index 760877928db60d8..afd5eb4eb12b782 100644 --- a/Modules/clinic/_functoolsmodule.c.h +++ b/Modules/clinic/_functoolsmodule.c.h @@ -69,7 +69,7 @@ _functools_cmp_to_key(PyObject *module, PyObject *const *args, Py_ssize_t nargs, } PyDoc_STRVAR(_functools_reduce__doc__, -"reduce($module, function, iterable, initial=, /)\n" +"reduce($module, function, iterable, /, initial=)\n" "--\n" "\n" "Apply a function of two arguments cumulatively to the items of an iterable, from left to right.\n" @@ -82,30 +82,59 @@ PyDoc_STRVAR(_functools_reduce__doc__, "calculates ((((1 + 2) + 3) + 4) + 5)."); #define _FUNCTOOLS_REDUCE_METHODDEF \ - {"reduce", _PyCFunction_CAST(_functools_reduce), METH_FASTCALL, _functools_reduce__doc__}, + {"reduce", _PyCFunction_CAST(_functools_reduce), METH_FASTCALL|METH_KEYWORDS, _functools_reduce__doc__}, static PyObject * _functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq, PyObject *result); static PyObject * -_functools_reduce(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +_functools_reduce(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "initial", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "reduce", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *func; PyObject *seq; PyObject *result = NULL; - if (!_PyArg_CheckPositional("reduce", nargs, 2, 3)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { goto exit; } func = args[0]; seq = args[1]; - if (nargs < 3) { - goto skip_optional; + if (!noptargs) { + goto skip_optional_pos; } result = args[2]; -skip_optional: +skip_optional_pos: return_value = _functools_reduce_impl(module, func, seq, result); exit: @@ -159,4 +188,4 @@ _functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ig return return_value; } -/*[clinic end generated code: output=0c3df7e5131200b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e6edcc01f0720daf input=a9049054013a1b77]*/ From 8ff7efb46d34ee454239bd86ff5136f386b9749b Mon Sep 17 00:00:00 2001 From: "RUANG (James Roy)" Date: Tue, 12 Nov 2024 21:18:06 +0800 Subject: [PATCH 26/57] gh-126061: Add PyLong_IsPositive/Zero/Negative() functions (#126065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sergey B Kirpichev Co-authored-by: Peter Bierma Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/c-api/long.rst | 33 ++++++++++++++ Doc/whatsnew/3.14.rst | 5 +++ Include/cpython/longobject.h | 18 ++++++++ Lib/test/test_capi/test_long.py | 45 +++++++++++++++++++ ...-10-28-15-56-03.gh-issue-126061.Py51_1.rst | 3 ++ Modules/_testcapi/long.c | 27 +++++++++++ Objects/longobject.c | 33 ++++++++++++++ 7 files changed, 164 insertions(+) create mode 100644 Misc/NEWS.d/next/C_API/2024-10-28-15-56-03.gh-issue-126061.Py51_1.rst diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 9ff3e5265004a10..32bb451b08d4138 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -582,6 +582,39 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionadded:: 3.14 +.. c:function:: int PyLong_IsPositive(PyObject *obj) + + Check if the integer object *obj* is positive (``obj > 0``). + + If *obj* is an instance of :c:type:`PyLongObject` or its subtype, + return ``1`` when it's positive and ``0`` otherwise. Else set an + exception and return ``-1``. + + .. versionadded:: next + + +.. c:function:: int PyLong_IsNegative(PyObject *obj) + + Check if the integer object *obj* is negative (``obj < 0``). + + If *obj* is an instance of :c:type:`PyLongObject` or its subtype, + return ``1`` when it's negative and ``0`` otherwise. Else set an + exception and return ``-1``. + + .. versionadded:: next + + +.. c:function:: int PyLong_IsZero(PyObject *obj) + + Check if the integer object *obj* is zero. + + If *obj* is an instance of :c:type:`PyLongObject` or its subtype, + return ``1`` when it's zero and ``0`` otherwise. Else set an + exception and return ``-1``. + + .. versionadded:: next + + .. c:function:: PyObject* PyLong_GetInfo(void) On success, return a read only :term:`named tuple`, that holds diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 66f8c432aead61f..20bd3aa52214540 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -807,6 +807,11 @@ New features an interned string and deallocate it during module shutdown. (Contributed by Eddie Elizondo in :gh:`113601`.) +* Add :c:func:`PyLong_IsPositive`, :c:func:`PyLong_IsNegative` + and :c:func:`PyLong_IsZero` for checking if :c:type:`PyLongObject` + is positive, negative, or zero, respectively. + (Contribued by James Roy and Sergey B Kirpichev in :gh:`126061`.) + * Add new functions to convert C ```` numbers from/to Python :class:`int`: diff --git a/Include/cpython/longobject.h b/Include/cpython/longobject.h index c1214d5e3714ead..4d6e618f831ad8a 100644 --- a/Include/cpython/longobject.h +++ b/Include/cpython/longobject.h @@ -61,6 +61,24 @@ PyAPI_FUNC(PyObject*) PyLong_FromUnsignedNativeBytes(const void* buffer, PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op); PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op); +/* PyLong_IsPositive. Check if the integer object is positive. + + - On success, return 1 if *obj is positive, and 0 otherwise. + - On failure, set an exception, and return -1. */ +PyAPI_FUNC(int) PyLong_IsPositive(PyObject *obj); + +/* PyLong_IsNegative. Check if the integer object is negative. + + - On success, return 1 if *obj is negative, and 0 otherwise. + - On failure, set an exception, and return -1. */ +PyAPI_FUNC(int) PyLong_IsNegative(PyObject *obj); + +/* PyLong_IsZero. Check if the integer object is zero. + + - On success, return 1 if *obj is zero, and 0 if it is non-zero. + - On failure, set an exception, and return -1. */ +PyAPI_FUNC(int) PyLong_IsZero(PyObject *obj); + /* PyLong_GetSign. Get the sign of an integer object: 0, -1 or +1 for zero, negative or positive integer, respectively. diff --git a/Lib/test/test_capi/test_long.py b/Lib/test/test_capi/test_long.py index 925fccd660bde38..a77094588a0edf7 100644 --- a/Lib/test/test_capi/test_long.py +++ b/Lib/test/test_capi/test_long.py @@ -643,6 +643,51 @@ def test_long_getsign(self): # CRASHES getsign(NULL) + def test_long_ispositive(self): + # Test PyLong_IsPositive() + ispositive = _testcapi.pylong_ispositive + self.assertEqual(ispositive(1), 1) + self.assertEqual(ispositive(123), 1) + self.assertEqual(ispositive(-1), 0) + self.assertEqual(ispositive(0), 0) + self.assertEqual(ispositive(True), 1) + self.assertEqual(ispositive(False), 0) + self.assertEqual(ispositive(IntSubclass(-1)), 0) + self.assertRaises(TypeError, ispositive, 1.0) + self.assertRaises(TypeError, ispositive, Index(123)) + + # CRASHES ispositive(NULL) + + def test_long_isnegative(self): + # Test PyLong_IsNegative() + isnegative = _testcapi.pylong_isnegative + self.assertEqual(isnegative(1), 0) + self.assertEqual(isnegative(123), 0) + self.assertEqual(isnegative(-1), 1) + self.assertEqual(isnegative(0), 0) + self.assertEqual(isnegative(True), 0) + self.assertEqual(isnegative(False), 0) + self.assertEqual(isnegative(IntSubclass(-1)), 1) + self.assertRaises(TypeError, isnegative, 1.0) + self.assertRaises(TypeError, isnegative, Index(123)) + + # CRASHES isnegative(NULL) + + def test_long_iszero(self): + # Test PyLong_IsZero() + iszero = _testcapi.pylong_iszero + self.assertEqual(iszero(1), 0) + self.assertEqual(iszero(-1), 0) + self.assertEqual(iszero(0), 1) + self.assertEqual(iszero(True), 0) + self.assertEqual(iszero(False), 1) + self.assertEqual(iszero(IntSubclass(-1)), 0) + self.assertEqual(iszero(IntSubclass(0)), 1) + self.assertRaises(TypeError, iszero, 1.0) + self.assertRaises(TypeError, iszero, Index(123)) + + # CRASHES iszero(NULL) + def test_long_asint32(self): # Test PyLong_AsInt32() and PyLong_FromInt32() to_int32 = _testlimitedcapi.pylong_asint32 diff --git a/Misc/NEWS.d/next/C_API/2024-10-28-15-56-03.gh-issue-126061.Py51_1.rst b/Misc/NEWS.d/next/C_API/2024-10-28-15-56-03.gh-issue-126061.Py51_1.rst new file mode 100644 index 000000000000000..0a4ad4ea2874cfc --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-10-28-15-56-03.gh-issue-126061.Py51_1.rst @@ -0,0 +1,3 @@ +Add :c:func:`PyLong_IsPositive`, :c:func:`PyLong_IsNegative` +and :c:func:`PyLong_IsZero` for checking if a :c:type:`PyLongObject` +is positive, negative, or zero, respectively. diff --git a/Modules/_testcapi/long.c b/Modules/_testcapi/long.c index 2b5e85d57075226..ebea09080ef11c7 100644 --- a/Modules/_testcapi/long.c +++ b/Modules/_testcapi/long.c @@ -105,6 +105,30 @@ pylong_getsign(PyObject *module, PyObject *arg) } +static PyObject * +pylong_ispositive(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + RETURN_INT(PyLong_IsPositive(arg)); +} + + +static PyObject * +pylong_isnegative(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + RETURN_INT(PyLong_IsNegative(arg)); +} + + +static PyObject * +pylong_iszero(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + RETURN_INT(PyLong_IsZero(arg)); +} + + static PyObject * pylong_aspid(PyObject *module, PyObject *arg) { @@ -124,6 +148,9 @@ static PyMethodDef test_methods[] = { {"pylong_fromnativebytes", pylong_fromnativebytes, METH_VARARGS}, {"pylong_getsign", pylong_getsign, METH_O}, {"pylong_aspid", pylong_aspid, METH_O}, + {"pylong_ispositive", pylong_ispositive, METH_O}, + {"pylong_isnegative", pylong_isnegative, METH_O}, + {"pylong_iszero", pylong_iszero, METH_O}, {NULL}, }; diff --git a/Objects/longobject.c b/Objects/longobject.c index b4c0f63a9843ce5..4aa35685b509f27 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -784,6 +784,39 @@ PyLong_AsUnsignedLongMask(PyObject *op) return val; } +int +PyLong_IsPositive(PyObject *obj) +{ + assert(obj != NULL); + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_TypeError, "expected int, got %T", obj); + return -1; + } + return _PyLong_IsPositive((PyLongObject *)obj); +} + +int +PyLong_IsNegative(PyObject *obj) +{ + assert(obj != NULL); + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_TypeError, "expected int, got %T", obj); + return -1; + } + return _PyLong_IsNegative((PyLongObject *)obj); +} + +int +PyLong_IsZero(PyObject *obj) +{ + assert(obj != NULL); + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_TypeError, "expected int, got %T", obj); + return -1; + } + return _PyLong_IsZero((PyLongObject *)obj); +} + int _PyLong_Sign(PyObject *vv) { From 91f4908798074db6c41925b4417bee1f933aca93 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:59:19 +0200 Subject: [PATCH 27/57] gh-126133: Only use start year in PSF copyright, remove end years (#126236) --- Doc/conf.py | 5 +---- Doc/copyright.rst | 2 +- Doc/license.rst | 2 +- LICENSE | 2 +- Lib/email/__init__.py | 2 +- Lib/email/_parseaddr.py | 2 +- Lib/email/base64mime.py | 2 +- Lib/email/charset.py | 2 +- Lib/email/encoders.py | 2 +- Lib/email/errors.py | 2 +- Lib/email/feedparser.py | 2 +- Lib/email/generator.py | 2 +- Lib/email/header.py | 2 +- Lib/email/iterators.py | 2 +- Lib/email/message.py | 2 +- Lib/email/mime/application.py | 2 +- Lib/email/mime/audio.py | 2 +- Lib/email/mime/base.py | 2 +- Lib/email/mime/image.py | 2 +- Lib/email/mime/message.py | 2 +- Lib/email/mime/multipart.py | 2 +- Lib/email/mime/nonmultipart.py | 2 +- Lib/email/mime/text.py | 2 +- Lib/email/parser.py | 2 +- Lib/email/quoprimime.py | 2 +- Lib/email/utils.py | 2 +- Lib/functools.py | 2 +- Lib/optparse.py | 2 +- Lib/test/test_csv.py | 2 +- Lib/test/test_email/test_asian_codecs.py | 2 +- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_email/torture_test.py | 2 +- Lib/test/test_plistlib.py | 2 +- Lib/textwrap.py | 2 +- Lib/unittest/__init__.py | 2 +- Lib/wsgiref/headers.py | 2 +- Mac/BuildScript/resources/License.rtf | 2 +- Mac/PythonLauncher/Info.plist.in | 4 ++-- Modules/_decimal/docstrings.h | 2 +- Modules/_decimal/tests/bench.py | 2 +- Modules/_functoolsmodule.c | 2 +- PC/python_ver_rc.h | 2 +- PC/store_info.txt | 2 +- Python/getcopyright.c | 2 +- README.rst | 4 ++-- 45 files changed, 47 insertions(+), 50 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 73d7d5db26ff7b9..738c9901eef06fd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -67,10 +67,7 @@ # General substitutions. project = 'Python' -if sphinx.version_info[:2] >= (8, 1): - copyright = "2001-%Y, Python Software Foundation" -else: - copyright = f"2001-{time.strftime('%Y')}, Python Software Foundation" +copyright = "2001 Python Software Foundation" # We look for the Include/patchlevel.h file in the current Python source tree # and replace the values accordingly. diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 8629ed1fc38009f..9210d5f50ed8415 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright © 2001-2024 Python Software Foundation. All rights reserved. +Copyright © 2001 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. diff --git a/Doc/license.rst b/Doc/license.rst index 674ac5f56e6f971..428dc22b817ebe6 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -100,7 +100,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2024 Python Software Foundation; All Rights + copyright, i.e., "Copyright © 2001 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/LICENSE b/LICENSE index 14603b95c2e23b5..20cf39097c68baa 100644 --- a/LICENSE +++ b/LICENSE @@ -83,7 +83,7 @@ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, -i.e., "Copyright (c) 2001-2024 Python Software Foundation; All Rights Reserved" +i.e., "Copyright (c) 2001 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on diff --git a/Lib/email/__init__.py b/Lib/email/__init__.py index 9fa477830041859..6d597006e5eefe1 100644 --- a/Lib/email/__init__.py +++ b/Lib/email/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py index 36625e35ffb6a7e..84917038874ba1f 100644 --- a/Lib/email/_parseaddr.py +++ b/Lib/email/_parseaddr.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2007 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Contact: email-sig@python.org """Email address parsing code. diff --git a/Lib/email/base64mime.py b/Lib/email/base64mime.py index d440de95255bf13..a5a3f737a97b519 100644 --- a/Lib/email/base64mime.py +++ b/Lib/email/base64mime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2007 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Author: Ben Gertzfield # Contact: email-sig@python.org diff --git a/Lib/email/charset.py b/Lib/email/charset.py index cfd5a0c456e497c..5036c3f58a5633c 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Ben Gertzfield, Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/encoders.py b/Lib/email/encoders.py index 17bd1ab7b19f325..55741a22a07b204 100644 --- a/Lib/email/encoders.py +++ b/Lib/email/encoders.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/errors.py b/Lib/email/errors.py index 02aa5eced6ae461..6bc744bd59c5bb4 100644 --- a/Lib/email/errors.py +++ b/Lib/email/errors.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index 06d6b4a3afcd070..b2bc4afc1cc26f1 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2006 Python Software Foundation +# Copyright (C) 2004 Python Software Foundation # Authors: Baxter, Wouters and Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 205caf0fe9e81db..ab5bd0653e440c4 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2010 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/header.py b/Lib/email/header.py index 66a1d46db50c459..113a81f41314ec1 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2007 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Author: Ben Gertzfield, Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/iterators.py b/Lib/email/iterators.py index 2f436aefc2300b6..08ede3ec679613a 100644 --- a/Lib/email/iterators.py +++ b/Lib/email/iterators.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/message.py b/Lib/email/message.py index 08192c50a8ff5cb..a58afc5fe5f68e5 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/application.py b/Lib/email/mime/application.py index f67cbad3f034076..9a9d213d2a940d1 100644 --- a/Lib/email/mime/application.py +++ b/Lib/email/mime/application.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Keith Dart # Contact: email-sig@python.org diff --git a/Lib/email/mime/audio.py b/Lib/email/mime/audio.py index aa0c4905cbb2b4d..85f4a955238c520 100644 --- a/Lib/email/mime/audio.py +++ b/Lib/email/mime/audio.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Anthony Baxter # Contact: email-sig@python.org diff --git a/Lib/email/mime/base.py b/Lib/email/mime/base.py index f601f621cec3933..da4c6e591a5cb85 100644 --- a/Lib/email/mime/base.py +++ b/Lib/email/mime/base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/image.py b/Lib/email/mime/image.py index 4b7f2f9cbad4252..dab9685848172b3 100644 --- a/Lib/email/mime/image.py +++ b/Lib/email/mime/image.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/message.py b/Lib/email/mime/message.py index 61836b5a7861fca..13d9ff599f86dbb 100644 --- a/Lib/email/mime/message.py +++ b/Lib/email/mime/message.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/multipart.py b/Lib/email/mime/multipart.py index 47fc218e1ae032c..1abb84d5fed0bb2 100644 --- a/Lib/email/mime/multipart.py +++ b/Lib/email/mime/multipart.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2006 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/nonmultipart.py b/Lib/email/mime/nonmultipart.py index a41386eb148c0c8..5beab3a441e2bc6 100644 --- a/Lib/email/mime/nonmultipart.py +++ b/Lib/email/mime/nonmultipart.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2006 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/mime/text.py b/Lib/email/mime/text.py index 7672b7891386009..aa4da7f8217e433 100644 --- a/Lib/email/mime/text.py +++ b/Lib/email/mime/text.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/email/parser.py b/Lib/email/parser.py index 475aa2b1a66680f..039f03cba74fa0c 100644 --- a/Lib/email/parser.py +++ b/Lib/email/parser.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw, Thomas Wouters, Anthony Baxter # Contact: email-sig@python.org diff --git a/Lib/email/quoprimime.py b/Lib/email/quoprimime.py index 500bbc5151769d3..27c7ea55c7871fd 100644 --- a/Lib/email/quoprimime.py +++ b/Lib/email/quoprimime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Ben Gertzfield # Contact: email-sig@python.org diff --git a/Lib/email/utils.py b/Lib/email/utils.py index f276303197396b1..7eab74dc0db9df6 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2010 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org diff --git a/Lib/functools.py b/Lib/functools.py index bde0a3e95b8275d..eff6540c7f606e0 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -6,7 +6,7 @@ # Written by Nick Coghlan , # Raymond Hettinger , # and Łukasz Langa . -# Copyright (C) 2006-2024 Python Software Foundation. +# Copyright (C) 2006 Python Software Foundation. # See C source code for _functools credits/copyright __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', diff --git a/Lib/optparse.py b/Lib/optparse.py index 04112eca37c801a..cbe3451ced8bc37 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -43,7 +43,7 @@ __copyright__ = """ Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved. -Copyright (c) 2002-2006 Python Software Foundation. All rights reserved. +Copyright (c) 2002 Python Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index ce5c03659f19795..4af8f7f480e759c 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001,2002 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # csv package unit tests import copy diff --git a/Lib/test/test_email/test_asian_codecs.py b/Lib/test/test_email/test_asian_codecs.py index 1e0caeeaed0810a..ca44f54c69b39bc 100644 --- a/Lib/test/test_email/test_asian_codecs.py +++ b/Lib/test/test_email/test_asian_codecs.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2006 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # Contact: email-sig@python.org # email package unit tests for (optional) Asian codecs diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 65ddbabcaa19978..abe9ef2e94409f8 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2010 Python Software Foundation +# Copyright (C) 2001 Python Software Foundation # Contact: email-sig@python.org # email package unit tests diff --git a/Lib/test/test_email/torture_test.py b/Lib/test/test_email/torture_test.py index 9cf9362c9b77e02..d15948a38b25dd3 100644 --- a/Lib/test/test_email/torture_test.py +++ b/Lib/test/test_email/torture_test.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2004 Python Software Foundation +# Copyright (C) 2002 Python Software Foundation # # A torture test of the email package. This should not be run as part of the # standard Python test suite since it requires several meg of email messages diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index b231b05f864ab9e..a0c76e5dec5ebe0 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -1,4 +1,4 @@ -# Copyright (C) 2003-2013 Python Software Foundation +# Copyright (C) 2003 Python Software Foundation import copy import operator import pickle diff --git a/Lib/textwrap.py b/Lib/textwrap.py index 7ca393d1c371aad..1bf07aa46cad99f 100644 --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -2,7 +2,7 @@ """ # Copyright (C) 1999-2001 Gregory P. Ward. -# Copyright (C) 2002, 2003 Python Software Foundation. +# Copyright (C) 2002 Python Software Foundation. # Written by Greg Ward import re diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index 324e5d038aef03a..78ff6bb4fdcce5d 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -27,7 +27,7 @@ def testMultiply(self): http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell -Copyright (c) 2003-2010 Python Software Foundation +Copyright (c) 2003 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. diff --git a/Lib/wsgiref/headers.py b/Lib/wsgiref/headers.py index 05d2ba4c664e5e0..c78879f80c7df24 100644 --- a/Lib/wsgiref/headers.py +++ b/Lib/wsgiref/headers.py @@ -1,7 +1,7 @@ """Manage HTTP Response Headers Much of this module is red-handedly pilfered from email.message in the stdlib, -so portions are Copyright (C) 2001,2002 Python Software Foundation, and were +so portions are Copyright (C) 2001 Python Software Foundation, and were written by Barry Warsaw. """ diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 1255d1ce48ed6cf..b5cb8ec41c86e21 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -64,7 +64,7 @@ Some software incorporated into Python is under different licenses. The licenses \f1\b0 \ 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\ \ -2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright \'a9 2001-2020 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\ +2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright \'a9 2001 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\ \ 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\ \ diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 233694788ac2b7b..ce8f27cd7d4de70 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,9 +40,9 @@ CFBundleExecutable Python Launcher NSHumanReadableCopyright - Copyright © 2001-2024 Python Software Foundation + Copyright © 2001 Python Software Foundation CFBundleGetInfoString - %VERSION%, © 2001-2024 Python Software Foundation + %VERSION%, © 2001 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index b34bff83d3f4e95..5abd7b9d807e195 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2012 Python Software Foundation. All Rights Reserved. + * Copyright (c) 2001 Python Software Foundation. All Rights Reserved. * Modified and extended by Stefan Krah. */ diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 640290f2ec7962c..6605e9a92e2dde4 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -1,5 +1,5 @@ # -# Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved. +# Copyright (C) 2001 Python Software Foundation. All Rights Reserved. # Modified and extended by Stefan Krah. # diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 5e0cf057dcd1a29..24b38063dde9e54 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -18,7 +18,7 @@ class _functools._lru_cache_wrapper "PyObject *" "&lru_cache_type_spec" /* _functools module written and maintained by Hye-Shik Chang with adaptations by Raymond Hettinger - Copyright (c) 2004, 2005, 2006 Python Software Foundation. + Copyright (c) 2004 Python Software Foundation. All rights reserved. */ diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h index 08509f96ed1db89..ee867fe41224c37 100644 --- a/PC/python_ver_rc.h +++ b/PC/python_ver_rc.h @@ -5,7 +5,7 @@ #include "winver.h" #define PYTHON_COMPANY "Python Software Foundation" -#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2024 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." +#define PYTHON_COPYRIGHT "Copyright \xA9 2001 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." #define MS_WINDOWS #include "modsupport.h" diff --git a/PC/store_info.txt b/PC/store_info.txt index f6a85cb8ebec1fd..d150ba17cbe62dd 100644 --- a/PC/store_info.txt +++ b/PC/store_info.txt @@ -109,7 +109,7 @@ PSF LICENSE AGREEMENT FOR PYTHON 3.9 analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 3.9 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2018 Python Software Foundation; All Rights + copyright, i.e., "Copyright © 2001 Python Software Foundation; All Rights Reserved" are retained in Python 3.9 alone or in any derivative version prepared by Licensee. diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 066c2ed66acddfe..964584ddf7998ea 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2024 Python Software Foundation.\n\ +Copyright (c) 2001 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/README.rst b/README.rst index 3f694771e090cb7..0134aafe2a969a5 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ This is Python version 3.14.0 alpha 1 :target: https://discuss.python.org/ -Copyright © 2001-2024 Python Software Foundation. All rights reserved. +Copyright © 2001 Python Software Foundation. All rights reserved. See the end of this file for further copyright and license information. @@ -215,7 +215,7 @@ Copyright and License Information --------------------------------- -Copyright © 2001-2024 Python Software Foundation. All rights reserved. +Copyright © 2001 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. From 6b2a19681eb5c132caa73a268724c7d502794867 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 12 Nov 2024 19:19:15 +0200 Subject: [PATCH 28/57] gh-95382: Use cache for indentations in the JSON encoder (GH-118636) --- Modules/_json.c | 182 +++++++++++++++++++++++++++++++----------------- 1 file changed, 118 insertions(+), 64 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index ce0093ab431d05b..a99abbe72bf7a08 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -86,11 +86,11 @@ encoder_dealloc(PyObject *self); static int encoder_clear(PyEncoderObject *self); static int -encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *seq, PyObject *newline_indent); +encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level, PyObject *indent_cache); static int -encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *obj, PyObject *newline_indent); +encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *obj, Py_ssize_t indent_level, PyObject *indent_cache); static int -encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *dct, PyObject *newline_indent); +encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level, PyObject *indent_cache); static PyObject * _encoded_const(PyObject *obj); static void @@ -1252,17 +1252,92 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)s; } + +/* indent_cache is a list that contains intermixed values at even and odd + * positions: + * + * 2*k : '\n' + indent * (k + initial_indent_level) + * strings written after opening and before closing brackets + * 2*k-1 : item_separator + '\n' + indent * (k + initial_indent_level) + * strings written between items + * + * Its size is always an odd number. + */ static PyObject * -_create_newline_indent(PyObject *indent, Py_ssize_t indent_level) +create_indent_cache(PyEncoderObject *s, Py_ssize_t indent_level) { PyObject *newline_indent = PyUnicode_FromOrdinal('\n'); if (newline_indent != NULL && indent_level) { PyUnicode_AppendAndDel(&newline_indent, - PySequence_Repeat(indent, indent_level)); + PySequence_Repeat(s->indent, indent_level)); + } + if (newline_indent == NULL) { + return NULL; + } + PyObject *indent_cache = PyList_New(1); + if (indent_cache == NULL) { + Py_DECREF(newline_indent); + return NULL; } - return newline_indent; + PyList_SET_ITEM(indent_cache, 0, newline_indent); + return indent_cache; +} + +/* Extend indent_cache by adding values for the next level. + * It should have values for the indent_level-1 level before the call. + */ +static int +update_indent_cache(PyEncoderObject *s, + Py_ssize_t indent_level, PyObject *indent_cache) +{ + assert(indent_level * 2 == PyList_GET_SIZE(indent_cache) + 1); + assert(indent_level > 0); + PyObject *newline_indent = PyList_GET_ITEM(indent_cache, (indent_level - 1)*2); + newline_indent = PyUnicode_Concat(newline_indent, s->indent); + if (newline_indent == NULL) { + return -1; + } + PyObject *separator_indent = PyUnicode_Concat(s->item_separator, newline_indent); + if (separator_indent == NULL) { + Py_DECREF(newline_indent); + return -1; + } + + if (PyList_Append(indent_cache, separator_indent) < 0 || + PyList_Append(indent_cache, newline_indent) < 0) + { + Py_DECREF(separator_indent); + Py_DECREF(newline_indent); + return -1; + } + Py_DECREF(separator_indent); + Py_DECREF(newline_indent); + return 0; } +static PyObject * +get_item_separator(PyEncoderObject *s, + Py_ssize_t indent_level, PyObject *indent_cache) +{ + assert(indent_level > 0); + if (indent_level * 2 > PyList_GET_SIZE(indent_cache)) { + if (update_indent_cache(s, indent_level, indent_cache) < 0) { + return NULL; + } + } + assert(indent_level * 2 < PyList_GET_SIZE(indent_cache)); + return PyList_GET_ITEM(indent_cache, indent_level * 2 - 1); +} + +static int +write_newline_indent(PyUnicodeWriter *writer, + Py_ssize_t indent_level, PyObject *indent_cache) +{ + PyObject *newline_indent = PyList_GET_ITEM(indent_cache, indent_level * 2); + return PyUnicodeWriter_WriteStr(writer, newline_indent); +} + + static PyObject * encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) { @@ -1280,20 +1355,20 @@ encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) return NULL; } - PyObject *newline_indent = NULL; + PyObject *indent_cache = NULL; if (self->indent != Py_None) { - newline_indent = _create_newline_indent(self->indent, indent_level); - if (newline_indent == NULL) { + indent_cache = create_indent_cache(self, indent_level); + if (indent_cache == NULL) { PyUnicodeWriter_Discard(writer); return NULL; } } - if (encoder_listencode_obj(self, writer, obj, newline_indent)) { + if (encoder_listencode_obj(self, writer, obj, indent_level, indent_cache)) { PyUnicodeWriter_Discard(writer); - Py_XDECREF(newline_indent); + Py_XDECREF(indent_cache); return NULL; } - Py_XDECREF(newline_indent); + Py_XDECREF(indent_cache); PyObject *str = PyUnicodeWriter_Finish(writer); if (str == NULL) { @@ -1381,7 +1456,8 @@ _steal_accumulate(PyUnicodeWriter *writer, PyObject *stolen) static int encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, - PyObject *obj, PyObject *newline_indent) + PyObject *obj, + Py_ssize_t indent_level, PyObject *indent_cache) { /* Encode Python object obj to a JSON term */ PyObject *newobj; @@ -1421,14 +1497,14 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, else if (PyList_Check(obj) || PyTuple_Check(obj)) { if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_list(s, writer, obj, newline_indent); + rv = encoder_listencode_list(s, writer, obj, indent_level, indent_cache); _Py_LeaveRecursiveCall(); return rv; } else if (PyDict_Check(obj)) { if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_dict(s, writer, obj, newline_indent); + rv = encoder_listencode_dict(s, writer, obj, indent_level, indent_cache); _Py_LeaveRecursiveCall(); return rv; } @@ -1462,7 +1538,7 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, Py_XDECREF(ident); return -1; } - rv = encoder_listencode_obj(s, writer, newobj, newline_indent); + rv = encoder_listencode_obj(s, writer, newobj, indent_level, indent_cache); _Py_LeaveRecursiveCall(); Py_DECREF(newobj); @@ -1485,7 +1561,7 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, static int encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *first, PyObject *dct, PyObject *key, PyObject *value, - PyObject *newline_indent, + Py_ssize_t indent_level, PyObject *indent_cache, PyObject *item_separator) { PyObject *keystr = NULL; @@ -1541,7 +1617,7 @@ encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *firs if (PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { return -1; } - if (encoder_listencode_obj(s, writer, value, newline_indent) < 0) { + if (encoder_listencode_obj(s, writer, value, indent_level, indent_cache) < 0) { _PyErr_FormatNote("when serializing %T item %R", dct, key); return -1; } @@ -1550,15 +1626,14 @@ encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *firs static int encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, - PyObject *dct, PyObject *newline_indent) + PyObject *dct, + Py_ssize_t indent_level, PyObject *indent_cache) { /* Encode Python dict dct a JSON term */ PyObject *ident = NULL; PyObject *items = NULL; PyObject *key, *value; bool first = true; - PyObject *new_newline_indent = NULL; - PyObject *separator_indent = NULL; if (PyDict_GET_SIZE(dct) == 0) { /* Fast path */ @@ -1585,19 +1660,13 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, goto bail; } - PyObject *current_item_separator = s->item_separator; // borrowed reference + PyObject *separator = s->item_separator; // borrowed reference if (s->indent != Py_None) { - new_newline_indent = PyUnicode_Concat(newline_indent, s->indent); - if (new_newline_indent == NULL) { - goto bail; - } - separator_indent = PyUnicode_Concat(current_item_separator, new_newline_indent); - if (separator_indent == NULL) { - goto bail; - } - // update item separator with a borrowed reference - current_item_separator = separator_indent; - if (PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { + indent_level++; + separator = get_item_separator(s, indent_level, indent_cache); + if (separator == NULL || + write_newline_indent(writer, indent_level, indent_cache) < 0) + { goto bail; } } @@ -1618,8 +1687,8 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, key = PyTuple_GET_ITEM(item, 0); value = PyTuple_GET_ITEM(item, 1); if (encoder_encode_key_value(s, writer, &first, dct, key, value, - new_newline_indent, - current_item_separator) < 0) + indent_level, indent_cache, + separator) < 0) goto bail; } Py_CLEAR(items); @@ -1628,8 +1697,8 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, Py_ssize_t pos = 0; while (PyDict_Next(dct, &pos, &key, &value)) { if (encoder_encode_key_value(s, writer, &first, dct, key, value, - new_newline_indent, - current_item_separator) < 0) + indent_level, indent_cache, + separator) < 0) goto bail; } } @@ -1640,10 +1709,8 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, Py_CLEAR(ident); } if (s->indent != Py_None) { - Py_CLEAR(new_newline_indent); - Py_CLEAR(separator_indent); - - if (PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { + indent_level--; + if (write_newline_indent(writer, indent_level, indent_cache) < 0) { goto bail; } } @@ -1656,20 +1723,17 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, bail: Py_XDECREF(items); Py_XDECREF(ident); - Py_XDECREF(separator_indent); - Py_XDECREF(new_newline_indent); return -1; } static int encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, - PyObject *seq, PyObject *newline_indent) + PyObject *seq, + Py_ssize_t indent_level, PyObject *indent_cache) { PyObject *ident = NULL; PyObject *s_fast = NULL; Py_ssize_t i; - PyObject *new_newline_indent = NULL; - PyObject *separator_indent = NULL; ident = NULL; s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); @@ -1702,20 +1766,13 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, PyObject *separator = s->item_separator; // borrowed reference if (s->indent != Py_None) { - new_newline_indent = PyUnicode_Concat(newline_indent, s->indent); - if (new_newline_indent == NULL) { - goto bail; - } - - if (PyUnicodeWriter_WriteStr(writer, new_newline_indent) < 0) { - goto bail; - } - - separator_indent = PyUnicode_Concat(separator, new_newline_indent); - if (separator_indent == NULL) { + indent_level++; + separator = get_item_separator(s, indent_level, indent_cache); + if (separator == NULL || + write_newline_indent(writer, indent_level, indent_cache) < 0) + { goto bail; } - separator = separator_indent; // assign separator with borrowed reference } for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); @@ -1723,7 +1780,7 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, if (PyUnicodeWriter_WriteStr(writer, separator) < 0) goto bail; } - if (encoder_listencode_obj(s, writer, obj, new_newline_indent)) { + if (encoder_listencode_obj(s, writer, obj, indent_level, indent_cache)) { _PyErr_FormatNote("when serializing %T item %zd", seq, i); goto bail; } @@ -1735,9 +1792,8 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, } if (s->indent != Py_None) { - Py_CLEAR(new_newline_indent); - Py_CLEAR(separator_indent); - if (PyUnicodeWriter_WriteStr(writer, newline_indent) < 0) { + indent_level--; + if (write_newline_indent(writer, indent_level, indent_cache) < 0) { goto bail; } } @@ -1751,8 +1807,6 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, bail: Py_XDECREF(ident); Py_DECREF(s_fast); - Py_XDECREF(separator_indent); - Py_XDECREF(new_newline_indent); return -1; } From 73cf0690997647c9801d9ebba43305a868d3b776 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 12 Nov 2024 10:41:51 -0700 Subject: [PATCH 29/57] gh-76785: Improved Subinterpreters Compatibility with 3.12 (2/2) (gh-126707) These changes makes it easier to backport the _interpreters, _interpqueues, and _interpchannels modules to Python 3.12. This involves the following: * add the _PyXI_GET_STATE() and _PyXI_GET_GLOBAL_STATE() macros * add _PyXIData_lookup_context_t and _PyXIData_GetLookupContext() * add _Py_xi_state_init() and _Py_xi_state_fini() --- Include/internal/pycore_crossinterp.h | 33 +++- .../pycore_crossinterp_data_registry.h | 9 +- Modules/_interpchannelsmodule.c | 7 +- Modules/_interpqueuesmodule.c | 11 +- Modules/_interpreters_common.h | 15 +- Modules/_interpretersmodule.c | 17 +- Modules/_testinternalcapi.c | 8 +- Python/crossinterp.c | 163 +++++++++++++----- Python/crossinterp_data_lookup.h | 75 ++++---- 9 files changed, 247 insertions(+), 91 deletions(-) diff --git a/Include/internal/pycore_crossinterp.h b/Include/internal/pycore_crossinterp.h index 66719796aeee227..69a60d73e05c269 100644 --- a/Include/internal/pycore_crossinterp.h +++ b/Include/internal/pycore_crossinterp.h @@ -100,9 +100,26 @@ typedef int (*xidatafunc)(PyThreadState *tstate, PyObject *, _PyXIData_t *); typedef struct _xid_lookup_state _PyXIData_lookup_t; -PyAPI_FUNC(xidatafunc) _PyXIData_Lookup(PyObject *); -PyAPI_FUNC(int) _PyObject_CheckXIData(PyObject *); -PyAPI_FUNC(int) _PyObject_GetXIData(PyObject *, _PyXIData_t *); +typedef struct { + _PyXIData_lookup_t *global; + _PyXIData_lookup_t *local; + PyObject *PyExc_NotShareableError; +} _PyXIData_lookup_context_t; + +PyAPI_FUNC(int) _PyXIData_GetLookupContext( + PyInterpreterState *, + _PyXIData_lookup_context_t *); + +PyAPI_FUNC(xidatafunc) _PyXIData_Lookup( + _PyXIData_lookup_context_t *, + PyObject *); +PyAPI_FUNC(int) _PyObject_CheckXIData( + _PyXIData_lookup_context_t *, + PyObject *); +PyAPI_FUNC(int) _PyObject_GetXIData( + _PyXIData_lookup_context_t *, + PyObject *, + _PyXIData_t *); /* using cross-interpreter data */ @@ -173,12 +190,20 @@ typedef struct { } exceptions; } _PyXI_state_t; +#define _PyXI_GET_GLOBAL_STATE(interp) (&(interp)->runtime->xi) +#define _PyXI_GET_STATE(interp) (&(interp)->xi) + +#ifndef Py_BUILD_CORE_MODULE extern PyStatus _PyXI_Init(PyInterpreterState *interp); extern void _PyXI_Fini(PyInterpreterState *interp); extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp); extern void _PyXI_FiniTypes(PyInterpreterState *interp); +#endif // Py_BUILD_CORE_MODULE -#define _PyInterpreterState_GetXIState(interp) (&(interp)->xi) +int _Py_xi_global_state_init(_PyXI_global_state_t *); +void _Py_xi_global_state_fini(_PyXI_global_state_t *); +int _Py_xi_state_init(_PyXI_state_t *, PyInterpreterState *); +void _Py_xi_state_fini(_PyXI_state_t *, PyInterpreterState *); /***************************/ diff --git a/Include/internal/pycore_crossinterp_data_registry.h b/Include/internal/pycore_crossinterp_data_registry.h index 04f25bc05fd1b80..bbad4de770857f1 100644 --- a/Include/internal/pycore_crossinterp_data_registry.h +++ b/Include/internal/pycore_crossinterp_data_registry.h @@ -27,8 +27,13 @@ typedef struct { _PyXIData_regitem_t *head; } _PyXIData_registry_t; -PyAPI_FUNC(int) _PyXIData_RegisterClass(PyTypeObject *, xidatafunc); -PyAPI_FUNC(int) _PyXIData_UnregisterClass(PyTypeObject *); +PyAPI_FUNC(int) _PyXIData_RegisterClass( + _PyXIData_lookup_context_t *, + PyTypeObject *, + xidatafunc); +PyAPI_FUNC(int) _PyXIData_UnregisterClass( + _PyXIData_lookup_context_t *, + PyTypeObject *); struct _xid_lookup_state { // XXX Remove this field once we have a tp_* slot. diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index cd3c50269385680..75d69ade1d3c9b3 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -1758,6 +1758,11 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj, } int64_t interpid = PyInterpreterState_GetID(interp); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + // Look up the channel. PyThread_type_lock mutex = NULL; _channel_state *chan = NULL; @@ -1779,7 +1784,7 @@ channel_send(_channels *channels, int64_t cid, PyObject *obj, PyThread_release_lock(mutex); return -1; } - if (_PyObject_GetXIData(obj, data) != 0) { + if (_PyObject_GetXIData(&ctx, obj, data) != 0) { PyThread_release_lock(mutex); GLOBAL_FREE(data); return -1; diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 8d0e223db7ff194..808938a9e8cd16a 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1127,6 +1127,12 @@ queue_destroy(_queues *queues, int64_t qid) static int queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop) { + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + // Look up the queue. _queue *queue = NULL; int err = _queues_lookup(queues, qid, &queue); @@ -1141,13 +1147,12 @@ queue_put(_queues *queues, int64_t qid, PyObject *obj, int fmt, int unboundop) _queue_unmark_waiter(queue, queues->mutex); return -1; } - if (_PyObject_GetXIData(obj, data) != 0) { + if (_PyObject_GetXIData(&ctx, obj, data) != 0) { _queue_unmark_waiter(queue, queues->mutex); GLOBAL_FREE(data); return -1; } - assert(_PyXIData_INTERPID(data) == \ - PyInterpreterState_GetID(PyInterpreterState_Get())); + assert(_PyXIData_INTERPID(data) == PyInterpreterState_GetID(interp)); // Add the data to the queue. int64_t interpid = -1; // _queueitem_init() will set it. diff --git a/Modules/_interpreters_common.h b/Modules/_interpreters_common.h index b0e31a33734dabc..a6c639feea5d14a 100644 --- a/Modules/_interpreters_common.h +++ b/Modules/_interpreters_common.h @@ -8,15 +8,24 @@ static int ensure_xid_class(PyTypeObject *cls, xidatafunc getdata) { - //assert(cls->tp_flags & Py_TPFLAGS_HEAPTYPE); - return _PyXIData_RegisterClass(cls, getdata); + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + return _PyXIData_RegisterClass(&ctx, cls, getdata); } #ifdef REGISTERS_HEAP_TYPES static int clear_xid_class(PyTypeObject *cls) { - return _PyXIData_UnregisterClass(cls); + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + return _PyXIData_UnregisterClass(&ctx, cls); } #endif diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c index eb4ac9847dcd2ba..a36823c4bb982b4 100644 --- a/Modules/_interpretersmodule.c +++ b/Modules/_interpretersmodule.c @@ -1186,7 +1186,13 @@ object_is_shareable(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - if (_PyObject_CheckXIData(obj) == 0) { + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return NULL; + } + + if (_PyObject_CheckXIData(&ctx, obj) == 0) { Py_RETURN_TRUE; } PyErr_Clear(); @@ -1485,6 +1491,11 @@ module_exec(PyObject *mod) PyInterpreterState *interp = PyInterpreterState_Get(); module_state *state = get_module_state(mod); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + #define ADD_WHENCE(NAME) \ if (PyModule_AddIntConstant(mod, "WHENCE_" #NAME, \ _PyInterpreterState_WHENCE_##NAME) < 0) \ @@ -1506,9 +1517,7 @@ module_exec(PyObject *mod) if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterNotFoundError) < 0) { goto error; } - PyObject *PyExc_NotShareableError = \ - _PyInterpreterState_GetXIState(interp)->exceptions.PyExc_NotShareableError; - if (PyModule_AddType(mod, (PyTypeObject *)PyExc_NotShareableError) < 0) { + if (PyModule_AddType(mod, (PyTypeObject *)ctx.PyExc_NotShareableError) < 0) { goto error; } diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 327a077671047c6..2c1ebcbbfdf4197 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1797,6 +1797,12 @@ _xid_capsule_destructor(PyObject *capsule) static PyObject * get_crossinterp_data(PyObject *self, PyObject *args) { + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyXIData_lookup_context_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return NULL; + } + PyObject *obj = NULL; if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) { return NULL; @@ -1806,7 +1812,7 @@ get_crossinterp_data(PyObject *self, PyObject *args) if (data == NULL) { return NULL; } - if (_PyObject_GetXIData(obj, data) != 0) { + if (_PyObject_GetXIData(&ctx, obj, data) != 0) { _PyXIData_Free(data); return NULL; } diff --git a/Python/crossinterp.c b/Python/crossinterp.c index dfdb5f9d87a7c7f..fe7d75f6b72f68a 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -9,10 +9,6 @@ #include "pycore_pyerrors.h" // _PyErr_Clear() -#define _PyXI_GET_GLOBAL_STATE(interp) (&(interp)->runtime->xi) -#define _PyXI_GET_STATE(interp) (&(interp)->xi) - - /**************/ /* exceptions */ /**************/ @@ -68,7 +64,7 @@ _Py_CallInInterpreterAndRawFree(PyInterpreterState *interp, static void xid_lookup_init(_PyXIData_lookup_t *); static void xid_lookup_fini(_PyXIData_lookup_t *); -static xidatafunc lookup_getdata(PyInterpreterState *, PyObject *); +static xidatafunc lookup_getdata(_PyXIData_lookup_context_t *, PyObject *); #include "crossinterp_data_lookup.h" @@ -202,9 +198,9 @@ _check_xidata(PyThreadState *tstate, _PyXIData_t *data) } static inline void -_set_xid_lookup_failure(_PyXI_state_t *state, PyObject *obj, const char *msg) +_set_xid_lookup_failure(dlcontext_t *ctx, PyObject *obj, const char *msg) { - PyObject *exctype = state->exceptions.PyExc_NotShareableError; + PyObject *exctype = ctx->PyExc_NotShareableError; assert(exctype != NULL); if (msg != NULL) { assert(obj == NULL); @@ -221,14 +217,12 @@ _set_xid_lookup_failure(_PyXI_state_t *state, PyObject *obj, const char *msg) } int -_PyObject_CheckXIData(PyObject *obj) +_PyObject_CheckXIData(_PyXIData_lookup_context_t *ctx, PyObject *obj) { - PyInterpreterState *interp = PyInterpreterState_Get(); - _PyXI_state_t *state = _PyXI_GET_STATE(interp); - xidatafunc getdata = lookup_getdata(interp, obj); + xidatafunc getdata = lookup_getdata(ctx, obj); if (getdata == NULL) { if (!PyErr_Occurred()) { - _set_xid_lookup_failure(state, obj, NULL); + _set_xid_lookup_failure(ctx, obj, NULL); } return -1; } @@ -236,11 +230,11 @@ _PyObject_CheckXIData(PyObject *obj) } int -_PyObject_GetXIData(PyObject *obj, _PyXIData_t *data) +_PyObject_GetXIData(_PyXIData_lookup_context_t *ctx, + PyObject *obj, _PyXIData_t *data) { PyThreadState *tstate = PyThreadState_Get(); PyInterpreterState *interp = tstate->interp; - _PyXI_state_t *state = _PyXI_GET_STATE(interp); // Reset data before re-populating. *data = (_PyXIData_t){0}; @@ -248,11 +242,11 @@ _PyObject_GetXIData(PyObject *obj, _PyXIData_t *data) // Call the "getdata" func for the object. Py_INCREF(obj); - xidatafunc getdata = lookup_getdata(interp, obj); + xidatafunc getdata = lookup_getdata(ctx, obj); if (getdata == NULL) { Py_DECREF(obj); if (!PyErr_Occurred()) { - _set_xid_lookup_failure(state, obj, NULL); + _set_xid_lookup_failure(ctx, obj, NULL); } return -1; } @@ -969,7 +963,8 @@ _PyXI_ClearExcInfo(_PyXI_excinfo *info) static int _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp) { - _PyXI_state_t *state; + dlcontext_t ctx; + assert(!PyErr_Occurred()); switch (code) { case _PyXI_ERR_NO_ERROR: _Py_FALLTHROUGH; @@ -1000,8 +995,10 @@ _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp) "failed to apply namespace to __main__"); break; case _PyXI_ERR_NOT_SHAREABLE: - state = _PyXI_GET_STATE(interp); - _set_xid_lookup_failure(state, NULL, NULL); + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + _set_xid_lookup_failure(&ctx, NULL, NULL); break; default: #ifdef Py_DEBUG @@ -1063,8 +1060,11 @@ _PyXI_ApplyError(_PyXI_error *error) } else if (error->code == _PyXI_ERR_NOT_SHAREABLE) { // Propagate the exception directly. - _PyXI_state_t *state = _PyXI_GET_STATE(error->interp); - _set_xid_lookup_failure(state, NULL, error->uncaught.msg); + dlcontext_t ctx; + if (_PyXIData_GetLookupContext(error->interp, &ctx) < 0) { + return NULL; + } + _set_xid_lookup_failure(&ctx, NULL, error->uncaught.msg); } else { // Raise an exception corresponding to the code. @@ -1151,7 +1151,12 @@ _sharednsitem_set_value(_PyXI_namespace_item *item, PyObject *value) PyErr_NoMemory(); return -1; } - if (_PyObject_GetXIData(value, item->data) != 0) { + PyInterpreterState *interp = PyInterpreterState_Get(); + dlcontext_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + return -1; + } + if (_PyObject_GetXIData(&ctx, value, item->data) != 0) { PyMem_RawFree(item->data); item->data = NULL; // The caller may want to propagate PyExc_NotShareableError @@ -1609,9 +1614,13 @@ _propagate_not_shareable_error(_PyXI_session *session) return; } PyInterpreterState *interp = PyInterpreterState_Get(); - _PyXI_state_t *state = _PyXI_GET_STATE(interp); - assert(state->exceptions.PyExc_NotShareableError != NULL); - if (PyErr_ExceptionMatches(state->exceptions.PyExc_NotShareableError)) { + dlcontext_t ctx; + if (_PyXIData_GetLookupContext(interp, &ctx) < 0) { + PyErr_FormatUnraisable( + "Exception ignored while propagating not shareable error"); + return; + } + if (PyErr_ExceptionMatches(ctx.PyExc_NotShareableError)) { // We want to propagate the exception directly. session->_error_override = _PyXI_ERR_NOT_SHAREABLE; session->error_override = &session->_error_override; @@ -1779,22 +1788,87 @@ _PyXI_Exit(_PyXI_session *session) /* runtime lifecycle */ /*********************/ +int +_Py_xi_global_state_init(_PyXI_global_state_t *state) +{ + assert(state != NULL); + xid_lookup_init(&state->data_lookup); + return 0; +} + +void +_Py_xi_global_state_fini(_PyXI_global_state_t *state) +{ + assert(state != NULL); + xid_lookup_fini(&state->data_lookup); +} + +int +_Py_xi_state_init(_PyXI_state_t *state, PyInterpreterState *interp) +{ + assert(state != NULL); + assert(interp == NULL || state == _PyXI_GET_STATE(interp)); + + xid_lookup_init(&state->data_lookup); + + // Initialize exceptions. + if (interp != NULL) { + if (init_static_exctypes(&state->exceptions, interp) < 0) { + fini_heap_exctypes(&state->exceptions); + return -1; + } + } + if (init_heap_exctypes(&state->exceptions) < 0) { + return -1; + } + + return 0; +} + +void +_Py_xi_state_fini(_PyXI_state_t *state, PyInterpreterState *interp) +{ + assert(state != NULL); + assert(interp == NULL || state == _PyXI_GET_STATE(interp)); + + fini_heap_exctypes(&state->exceptions); + if (interp != NULL) { + fini_static_exctypes(&state->exceptions, interp); + } + + xid_lookup_fini(&state->data_lookup); +} + + PyStatus _PyXI_Init(PyInterpreterState *interp) { - _PyXI_state_t *state = _PyXI_GET_STATE(interp); - - // Initialize the XID lookup state (e.g. registry). if (_Py_IsMainInterpreter(interp)) { - xid_lookup_init(&_PyXI_GET_GLOBAL_STATE(interp)->data_lookup); + _PyXI_global_state_t *global_state = _PyXI_GET_GLOBAL_STATE(interp); + if (global_state == NULL) { + PyErr_PrintEx(0); + return _PyStatus_ERR( + "failed to get global cross-interpreter state"); + } + if (_Py_xi_global_state_init(global_state) < 0) { + PyErr_PrintEx(0); + return _PyStatus_ERR( + "failed to initialize global cross-interpreter state"); + } } - xid_lookup_init(&state->data_lookup); - // Initialize exceptions.(heap types). - // See _PyXI_InitTypes() for the static types. - if (init_heap_exctypes(&_PyXI_GET_STATE(interp)->exceptions) < 0) { + _PyXI_state_t *state = _PyXI_GET_STATE(interp); + if (state == NULL) { + PyErr_PrintEx(0); + return _PyStatus_ERR( + "failed to get interpreter's cross-interpreter state"); + } + // The static types were already initialized in _PyXI_InitTypes(), + // so we pass in NULL here to avoid initializing them again. + if (_Py_xi_state_init(state, NULL) < 0) { PyErr_PrintEx(0); - return _PyStatus_ERR("failed to initialize exceptions"); + return _PyStatus_ERR( + "failed to initialize interpreter's cross-interpreter state"); } return _PyStatus_OK(); @@ -1807,15 +1881,19 @@ void _PyXI_Fini(PyInterpreterState *interp) { _PyXI_state_t *state = _PyXI_GET_STATE(interp); +#ifndef NDEBUG + if (state == NULL) { + PyErr_PrintEx(0); + return; + } +#endif + // The static types will be finalized soon in _PyXI_FiniTypes(), + // so we pass in NULL here to avoid finalizing them right now. + _Py_xi_state_fini(state, NULL); - // Finalize exceptions (heap types). - // See _PyXI_FiniTypes() for the static types. - fini_heap_exctypes(&_PyXI_GET_STATE(interp)->exceptions); - - // Finalize the XID lookup state (e.g. registry). - xid_lookup_fini(&state->data_lookup); if (_Py_IsMainInterpreter(interp)) { - xid_lookup_fini(&_PyXI_GET_GLOBAL_STATE(interp)->data_lookup); + _PyXI_global_state_t *global_state = _PyXI_GET_GLOBAL_STATE(interp); + _Py_xi_global_state_fini(global_state); } } @@ -1824,7 +1902,8 @@ _PyXI_InitTypes(PyInterpreterState *interp) { if (init_static_exctypes(&_PyXI_GET_STATE(interp)->exceptions, interp) < 0) { PyErr_PrintEx(0); - return _PyStatus_ERR("failed to initialize an exception type"); + return _PyStatus_ERR( + "failed to initialize the cross-interpreter exception types"); } // We would initialize heap types here too but that leads to ref leaks. // Instead, we intialize them in _PyXI_Init(). diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 9048f90cff160a9..48e5d9762cd6970 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -1,6 +1,7 @@ #include "pycore_weakref.h" // _PyWeakref_GET_REF() +typedef _PyXIData_lookup_context_t dlcontext_t; typedef _PyXIData_registry_t dlregistry_t; typedef _PyXIData_regitem_t dlregitem_t; @@ -8,7 +9,7 @@ typedef _PyXIData_regitem_t dlregitem_t; // forward static void _xidregistry_init(dlregistry_t *); static void _xidregistry_fini(dlregistry_t *); -static xidatafunc _lookup_getdata_from_registry(PyInterpreterState *, PyObject *); +static xidatafunc _lookup_getdata_from_registry(dlcontext_t *, PyObject *); /* used in crossinterp.c */ @@ -26,22 +27,43 @@ xid_lookup_fini(_PyXIData_lookup_t *state) } static xidatafunc -lookup_getdata(PyInterpreterState *interp, PyObject *obj) +lookup_getdata(dlcontext_t *ctx, PyObject *obj) { /* Cross-interpreter objects are looked up by exact match on the class. We can reassess this policy when we move from a global registry to a tp_* slot. */ - return _lookup_getdata_from_registry(interp, obj); + return _lookup_getdata_from_registry(ctx, obj); } /* exported API */ +int +_PyXIData_GetLookupContext(PyInterpreterState *interp, + _PyXIData_lookup_context_t *res) +{ + _PyXI_global_state_t *global = _PyXI_GET_GLOBAL_STATE(interp); + if (global == NULL) { + assert(PyErr_Occurred()); + return -1; + } + _PyXI_state_t *local = _PyXI_GET_STATE(interp); + if (local == NULL) { + assert(PyErr_Occurred()); + return -1; + } + *res = (dlcontext_t){ + .global = &global->data_lookup, + .local = &local->data_lookup, + .PyExc_NotShareableError = local->exceptions.PyExc_NotShareableError, + }; + return 0; +} + xidatafunc -_PyXIData_Lookup(PyObject *obj) +_PyXIData_Lookup(_PyXIData_lookup_context_t *ctx, PyObject *obj) { - PyInterpreterState *interp = PyInterpreterState_Get(); - return lookup_getdata(interp, obj); + return lookup_getdata(ctx, obj); } @@ -110,25 +132,12 @@ _xidregistry_unlock(dlregistry_t *registry) /* accessing the registry */ static inline dlregistry_t * -_get_global_xidregistry(_PyRuntimeState *runtime) +_get_xidregistry_for_type(dlcontext_t *ctx, PyTypeObject *cls) { - return &runtime->xi.data_lookup.registry; -} - -static inline dlregistry_t * -_get_xidregistry(PyInterpreterState *interp) -{ - return &interp->xi.data_lookup.registry; -} - -static inline dlregistry_t * -_get_xidregistry_for_type(PyInterpreterState *interp, PyTypeObject *cls) -{ - dlregistry_t *registry = _get_global_xidregistry(interp->runtime); if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { - registry = _get_xidregistry(interp); + return &ctx->local->registry; } - return registry; + return &ctx->global->registry; } static dlregitem_t* _xidregistry_remove_entry(dlregistry_t *, dlregitem_t *); @@ -160,11 +169,11 @@ _xidregistry_find_type(dlregistry_t *xidregistry, PyTypeObject *cls) } static xidatafunc -_lookup_getdata_from_registry(PyInterpreterState *interp, PyObject *obj) +_lookup_getdata_from_registry(dlcontext_t *ctx, PyObject *obj) { PyTypeObject *cls = Py_TYPE(obj); - dlregistry_t *xidregistry = _get_xidregistry_for_type(interp, cls); + dlregistry_t *xidregistry = _get_xidregistry_for_type(ctx, cls); _xidregistry_lock(xidregistry); dlregitem_t *matched = _xidregistry_find_type(xidregistry, cls); @@ -241,7 +250,8 @@ _xidregistry_clear(dlregistry_t *xidregistry) } int -_PyXIData_RegisterClass(PyTypeObject *cls, xidatafunc getdata) +_PyXIData_RegisterClass(_PyXIData_lookup_context_t *ctx, + PyTypeObject *cls, xidatafunc getdata) { if (!PyType_Check(cls)) { PyErr_Format(PyExc_ValueError, "only classes may be registered"); @@ -253,8 +263,7 @@ _PyXIData_RegisterClass(PyTypeObject *cls, xidatafunc getdata) } int res = 0; - PyInterpreterState *interp = _PyInterpreterState_GET(); - dlregistry_t *xidregistry = _get_xidregistry_for_type(interp, cls); + dlregistry_t *xidregistry = _get_xidregistry_for_type(ctx, cls); _xidregistry_lock(xidregistry); dlregitem_t *matched = _xidregistry_find_type(xidregistry, cls); @@ -272,11 +281,10 @@ _PyXIData_RegisterClass(PyTypeObject *cls, xidatafunc getdata) } int -_PyXIData_UnregisterClass(PyTypeObject *cls) +_PyXIData_UnregisterClass(_PyXIData_lookup_context_t *ctx, PyTypeObject *cls) { int res = 0; - PyInterpreterState *interp = _PyInterpreterState_GET(); - dlregistry_t *xidregistry = _get_xidregistry_for_type(interp, cls); + dlregistry_t *xidregistry = _get_xidregistry_for_type(ctx, cls); _xidregistry_lock(xidregistry); dlregitem_t *matched = _xidregistry_find_type(xidregistry, cls); @@ -500,6 +508,11 @@ _tuple_shared_free(void* data) static int _tuple_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data) { + dlcontext_t ctx; + if (_PyXIData_GetLookupContext(tstate->interp, &ctx) < 0) { + return -1; + } + Py_ssize_t len = PyTuple_GET_SIZE(obj); if (len < 0) { return -1; @@ -526,7 +539,7 @@ _tuple_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data) int res = -1; if (!_Py_EnterRecursiveCallTstate(tstate, " while sharing a tuple")) { - res = _PyObject_GetXIData(item, data); + res = _PyObject_GetXIData(&ctx, item, data); _Py_LeaveRecursiveCallTstate(tstate); } if (res < 0) { From a83472f49b958c55befd82c871be26afbf500306 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 12 Nov 2024 09:54:13 -0800 Subject: [PATCH 30/57] gh-126705: Make os.PathLike more like a protocol (#126706) it can now be used as a base class in other protocols --- Lib/test/test_typing.py | 4 ++++ Lib/typing.py | 1 + .../Library/2024-11-11-14-52-21.gh-issue-126705.0W7jFW.rst | 1 + 3 files changed, 6 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-11-11-14-52-21.gh-issue-126705.0W7jFW.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 244ce1e5da9bd28..aa42beca5f9256b 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -8,6 +8,7 @@ import inspect import itertools import operator +import os import pickle import re import sys @@ -4252,6 +4253,9 @@ def test_builtin_protocol_allowlist(self): class CustomProtocol(TestCase, Protocol): pass + class CustomPathLikeProtocol(os.PathLike, Protocol): + pass + class CustomContextManager(typing.ContextManager, Protocol): pass diff --git a/Lib/typing.py b/Lib/typing.py index 8e6381033fd28e2..938e52922aee034 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1944,6 +1944,7 @@ def _allow_reckless_class_checks(depth=2): 'Reversible', 'Buffer', ], 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], + 'os': ['PathLike'], } diff --git a/Misc/NEWS.d/next/Library/2024-11-11-14-52-21.gh-issue-126705.0W7jFW.rst b/Misc/NEWS.d/next/Library/2024-11-11-14-52-21.gh-issue-126705.0W7jFW.rst new file mode 100644 index 000000000000000..f49c9c765d778f9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-11-14-52-21.gh-issue-126705.0W7jFW.rst @@ -0,0 +1 @@ +Allow :class:`os.PathLike` to be a base for Protocols. From 03924b5deeb766fabd53ced28ba707e4dd08fb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:08:49 +0100 Subject: [PATCH 31/57] gh-89083: add support for UUID version 8 (RFC 9562) (#123224) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/library/uuid.rst | 42 +++++++++++++++---- Doc/whatsnew/3.14.rst | 8 ++++ Lib/test/test_uuid.py | 35 +++++++++++++++- Lib/uuid.py | 41 ++++++++++++++---- ...4-08-22-12-12-35.gh-issue-89083.b6zFh0.rst | 2 + 5 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-08-22-12-12-35.gh-issue-89083.b6zFh0.rst diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 0f2d7820cb25c82..6166c22caedf812 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -1,8 +1,8 @@ -:mod:`!uuid` --- UUID objects according to :rfc:`4122` +:mod:`!uuid` --- UUID objects according to :rfc:`9562` ====================================================== .. module:: uuid - :synopsis: UUID objects (universally unique identifiers) according to RFC 4122 + :synopsis: UUID objects (universally unique identifiers) according to RFC 9562 .. moduleauthor:: Ka-Ping Yee .. sectionauthor:: George Yoshida @@ -12,7 +12,8 @@ This module provides immutable :class:`UUID` objects (the :class:`UUID` class) and the functions :func:`uuid1`, :func:`uuid3`, :func:`uuid4`, :func:`uuid5` for -generating version 1, 3, 4, and 5 UUIDs as specified in :rfc:`4122`. +generating version 1, 3, 4, 5, and 8 UUIDs as specified in :rfc:`9562` (which +supersedes :rfc:`4122`). If all you want is a unique ID, you should probably call :func:`uuid1` or :func:`uuid4`. Note that :func:`uuid1` may compromise privacy since it creates @@ -65,7 +66,7 @@ which relays any information about the UUID's safety, using this enumeration: Exactly one of *hex*, *bytes*, *bytes_le*, *fields*, or *int* must be given. The *version* argument is optional; if given, the resulting UUID will have its - variant and version number set according to :rfc:`4122`, overriding bits in the + variant and version number set according to :rfc:`9562`, overriding bits in the given *hex*, *bytes*, *bytes_le*, *fields*, or *int*. Comparison of UUID objects are made by way of comparing their @@ -137,7 +138,7 @@ which relays any information about the UUID's safety, using this enumeration: .. attribute:: UUID.urn - The UUID as a URN as specified in :rfc:`4122`. + The UUID as a URN as specified in :rfc:`9562`. .. attribute:: UUID.variant @@ -149,9 +150,13 @@ which relays any information about the UUID's safety, using this enumeration: .. attribute:: UUID.version - The UUID version number (1 through 5, meaningful only when the variant is + The UUID version number (1 through 8, meaningful only when the variant is :const:`RFC_4122`). + .. versionchanged:: next + Added UUID version 8. + + .. attribute:: UUID.is_safe An enumeration of :class:`SafeUUID` which indicates whether the platform @@ -216,6 +221,23 @@ The :mod:`uuid` module defines the following functions: .. index:: single: uuid5 + +.. function:: uuid8(a=None, b=None, c=None) + + Generate a pseudo-random UUID according to + :rfc:`RFC 9562, §5.8 <9562#section-5.8>`. + + When specified, the parameters *a*, *b* and *c* are expected to be + positive integers of 48, 12 and 62 bits respectively. If they exceed + their expected bit count, only their least significant bits are kept; + non-specified arguments are substituted for a pseudo-random integer of + appropriate size. + + .. versionadded:: next + +.. index:: single: uuid8 + + The :mod:`uuid` module defines the following namespace identifiers for use with :func:`uuid3` or :func:`uuid5`. @@ -252,7 +274,9 @@ of the :attr:`~UUID.variant` attribute: .. data:: RFC_4122 - Specifies the UUID layout given in :rfc:`4122`. + Specifies the UUID layout given in :rfc:`4122`. This constant is kept + for backward compatibility even though :rfc:`4122` has been superseded + by :rfc:`9562`. .. data:: RESERVED_MICROSOFT @@ -267,7 +291,7 @@ of the :attr:`~UUID.variant` attribute: .. seealso:: - :rfc:`4122` - A Universally Unique IDentifier (UUID) URN Namespace + :rfc:`9562` - A Universally Unique IDentifier (UUID) URN Namespace This specification defines a Uniform Resource Name namespace for UUIDs, the internal format of UUIDs, and methods of generating UUIDs. @@ -283,7 +307,7 @@ The :mod:`uuid` module can be executed as a script from the command line. .. code-block:: sh - python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5}] [-n NAMESPACE] [-N NAME] + python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5,uuid8}] [-n NAMESPACE] [-N NAME] The following options are accepted: diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 20bd3aa52214540..c2cf46902fd7fe1 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -517,6 +517,14 @@ unittest (Contributed by Jacob Walls in :gh:`80958`.) +uuid +---- + +* Add support for UUID version 8 via :func:`uuid.uuid8` as specified + in :rfc:`9562`. + (Contributed by Bénédikt Tran in :gh:`89083`.) + + .. Add improved modules above alphabetically, not here at the end. Optimizations diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index e177464c00f7a65..7bd26a8ca34b628 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -8,8 +8,10 @@ import io import os import pickle +import random import sys import weakref +from itertools import product from unittest import mock py_uuid = import_helper.import_fresh_module('uuid', blocked=['_uuid']) @@ -267,7 +269,7 @@ def test_exceptions(self): # Version number out of range. badvalue(lambda: self.uuid.UUID('00'*16, version=0)) - badvalue(lambda: self.uuid.UUID('00'*16, version=6)) + badvalue(lambda: self.uuid.UUID('00'*16, version=42)) # Integer value out of range. badvalue(lambda: self.uuid.UUID(int=-1)) @@ -681,6 +683,37 @@ def test_uuid5(self): equal(u, self.uuid.UUID(v)) equal(str(u), v) + def test_uuid8(self): + equal = self.assertEqual + u = self.uuid.uuid8() + + equal(u.variant, self.uuid.RFC_4122) + equal(u.version, 8) + + for (_, hi, mid, lo) in product( + range(10), # repeat 10 times + [None, 0, random.getrandbits(48)], + [None, 0, random.getrandbits(12)], + [None, 0, random.getrandbits(62)], + ): + u = self.uuid.uuid8(hi, mid, lo) + equal(u.variant, self.uuid.RFC_4122) + equal(u.version, 8) + if hi is not None: + equal((u.int >> 80) & 0xffffffffffff, hi) + if mid is not None: + equal((u.int >> 64) & 0xfff, mid) + if lo is not None: + equal(u.int & 0x3fffffffffffffff, lo) + + def test_uuid8_uniqueness(self): + # Test that UUIDv8-generated values are unique + # (up to a negligible probability of failure). + u1 = self.uuid.uuid8() + u2 = self.uuid.uuid8() + self.assertNotEqual(u1.int, u2.int) + self.assertEqual(u1.version, u2.version) + @support.requires_fork() def testIssue8621(self): # On at least some versions of OSX self.uuid.uuid4 generates diff --git a/Lib/uuid.py b/Lib/uuid.py index 4d4f06cfc9ebbe3..9c6ad9643cf6d5d 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -1,8 +1,8 @@ -r"""UUID objects (universally unique identifiers) according to RFC 4122. +r"""UUID objects (universally unique identifiers) according to RFC 4122/9562. This module provides immutable UUID objects (class UUID) and the functions -uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 -UUIDs as specified in RFC 4122. +uuid1(), uuid3(), uuid4(), uuid5(), and uuid8() for generating version 1, 3, +4, 5, and 8 UUIDs as specified in RFC 4122/9562. If all you want is a unique ID, you should probably call uuid1() or uuid4(). Note that uuid1() may compromise privacy since it creates a UUID containing @@ -124,12 +124,12 @@ class UUID: int the UUID as a 128-bit integer - urn the UUID as a URN as specified in RFC 4122 + urn the UUID as a URN as specified in RFC 4122/9562 variant the UUID variant (one of the constants RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) - version the UUID version number (1 through 5, meaningful only + version the UUID version number (1 through 8, meaningful only when the variant is RFC_4122) is_safe An enum indicating whether the UUID has been generated in @@ -214,9 +214,9 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, if not 0 <= int < 1<<128: raise ValueError('int is out of range (need a 128-bit value)') if version is not None: - if not 1 <= version <= 5: + if not 1 <= version <= 8: raise ValueError('illegal version number') - # Set the variant to RFC 4122. + # Set the variant to RFC 4122/9562. int &= ~(0xc000 << 48) int |= 0x8000 << 48 # Set the version number. @@ -355,7 +355,7 @@ def variant(self): @property def version(self): - # The version bits are only meaningful for RFC 4122 UUIDs. + # The version bits are only meaningful for RFC 4122/9562 UUIDs. if self.variant == RFC_4122: return int((self.int >> 76) & 0xf) @@ -719,6 +719,28 @@ def uuid5(namespace, name): hash = sha1(namespace.bytes + name).digest() return UUID(bytes=hash[:16], version=5) +def uuid8(a=None, b=None, c=None): + """Generate a UUID from three custom blocks. + + * 'a' is the first 48-bit chunk of the UUID (octets 0-5); + * 'b' is the mid 12-bit chunk (octets 6-7); + * 'c' is the last 62-bit chunk (octets 8-15). + + When a value is not specified, a pseudo-random value is generated. + """ + if a is None: + import random + a = random.getrandbits(48) + if b is None: + import random + b = random.getrandbits(12) + if c is None: + import random + c = random.getrandbits(62) + int_uuid_8 = (a & 0xffff_ffff_ffff) << 80 + int_uuid_8 |= (b & 0xfff) << 64 + int_uuid_8 |= c & 0x3fff_ffff_ffff_ffff + return UUID(int=int_uuid_8, version=8) def main(): """Run the uuid command line interface.""" @@ -726,7 +748,8 @@ def main(): "uuid1": uuid1, "uuid3": uuid3, "uuid4": uuid4, - "uuid5": uuid5 + "uuid5": uuid5, + "uuid8": uuid8, } uuid_namespace_funcs = ("uuid3", "uuid5") namespaces = { diff --git a/Misc/NEWS.d/next/Library/2024-08-22-12-12-35.gh-issue-89083.b6zFh0.rst b/Misc/NEWS.d/next/Library/2024-08-22-12-12-35.gh-issue-89083.b6zFh0.rst new file mode 100644 index 000000000000000..d37d585d51b4908 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-08-22-12-12-35.gh-issue-89083.b6zFh0.rst @@ -0,0 +1,2 @@ +Add :func:`uuid.uuid8` for generating UUIDv8 objects as specified in +:rfc:`9562`. Patch by Bénédikt Tran From 7577307ebdaeef6702b639e22a896080e81aae4e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 12 Nov 2024 21:10:29 +0200 Subject: [PATCH 32/57] gh-116897: Deprecate generic false values in urllib.parse.parse_qsl() (GH-116903) Accepting objects with false values (like 0 and []) except empty strings and byte-like objects and None in urllib.parse functions parse_qsl() and parse_qs() is now deprecated. --- Doc/library/urllib.parse.rst | 8 ++++++ Doc/whatsnew/3.14.rst | 7 ++++++ Lib/test/test_urlparse.py | 10 +++++++- Lib/urllib/parse.py | 25 +++++++++++++------ ...-03-16-13-38-27.gh-issue-116897.UDQTjp.rst | 4 +++ 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-03-16-13-38-27.gh-issue-116897.UDQTjp.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index fb5353e1895bf9d..0501dc8733b2cdf 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -239,6 +239,10 @@ or on combining URL components into a URL string. query parameter separator. This has been changed to allow only a single separator key, with ``&`` as the default separator. + .. deprecated:: 3.14 + Accepting objects with false values (like ``0`` and ``[]``) except empty + strings and byte-like objects and ``None`` is now deprecated. + .. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&') @@ -745,6 +749,10 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.5 Added the *quote_via* parameter. + .. deprecated:: 3.14 + Accepting objects with false values (like ``0`` and ``[]``) except empty + strings and byte-like objects and ``None`` is now deprecated. + .. seealso:: diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index c2cf46902fd7fe1..a98fe3f468b685b 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -583,6 +583,13 @@ Deprecated Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest. (Contributed by Bénédikt Tran in :gh:`119698`.) +* :mod:`urllib.parse`: + Accepting objects with false values (like ``0`` and ``[]``) except empty + strings, byte-like objects and ``None`` in :mod:`urllib.parse` functions + :func:`~urllib.parse.parse_qsl` and :func:`~urllib.parse.parse_qs` is now + deprecated. + (Contributed by Serhiy Storchaka in :gh:`116897`.) + .. Add deprecations above alphabetically, not here at the end. .. include:: ../deprecations/pending-removal-in-3.15.rst diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 297fb4831c16bfc..4516bdea6adb198 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1314,9 +1314,17 @@ def test_parse_qsl_bytes(self): def test_parse_qsl_false_value(self): kwargs = dict(keep_blank_values=True, strict_parsing=True) - for x in '', b'', None, 0, 0.0, [], {}, memoryview(b''): + for x in '', b'', None, memoryview(b''): self.assertEqual(urllib.parse.parse_qsl(x, **kwargs), []) self.assertRaises(ValueError, urllib.parse.parse_qsl, x, separator=1) + for x in 0, 0.0, [], {}: + with self.assertWarns(DeprecationWarning) as cm: + self.assertEqual(urllib.parse.parse_qsl(x, **kwargs), []) + self.assertEqual(cm.filename, __file__) + with self.assertWarns(DeprecationWarning) as cm: + self.assertEqual(urllib.parse.parse_qs(x, **kwargs), {}) + self.assertEqual(cm.filename, __file__) + self.assertRaises(ValueError, urllib.parse.parse_qsl, x, separator=1) def test_parse_qsl_errors(self): self.assertRaises(TypeError, urllib.parse.parse_qsl, list(b'a=b')) diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index a721d777c82f828..8d7631d5693ece9 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -753,7 +753,8 @@ def parse_qs(qs, keep_blank_values=False, strict_parsing=False, parsed_result = {} pairs = parse_qsl(qs, keep_blank_values, strict_parsing, encoding=encoding, errors=errors, - max_num_fields=max_num_fields, separator=separator) + max_num_fields=max_num_fields, separator=separator, + _stacklevel=2) for name, value in pairs: if name in parsed_result: parsed_result[name].append(value) @@ -763,7 +764,7 @@ def parse_qs(qs, keep_blank_values=False, strict_parsing=False, def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, - encoding='utf-8', errors='replace', max_num_fields=None, separator='&'): + encoding='utf-8', errors='replace', max_num_fields=None, separator='&', *, _stacklevel=1): """Parse a query given as a string argument. Arguments: @@ -791,7 +792,6 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, Returns a list, as G-d intended. """ - if not separator or not isinstance(separator, (str, bytes)): raise ValueError("Separator must be of type string or bytes.") if isinstance(qs, str): @@ -800,12 +800,21 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, eq = '=' def _unquote(s): return unquote_plus(s, encoding=encoding, errors=errors) + elif qs is None: + return [] else: - if not qs: - return [] - # Use memoryview() to reject integers and iterables, - # acceptable by the bytes constructor. - qs = bytes(memoryview(qs)) + try: + # Use memoryview() to reject integers and iterables, + # acceptable by the bytes constructor. + qs = bytes(memoryview(qs)) + except TypeError: + if not qs: + warnings.warn(f"Accepting {type(qs).__name__} objects with " + f"false value in urllib.parse.parse_qsl() is " + f"deprecated as of 3.14", + DeprecationWarning, stacklevel=_stacklevel + 1) + return [] + raise if isinstance(separator, str): separator = bytes(separator, 'ascii') eq = b'=' diff --git a/Misc/NEWS.d/next/Library/2024-03-16-13-38-27.gh-issue-116897.UDQTjp.rst b/Misc/NEWS.d/next/Library/2024-03-16-13-38-27.gh-issue-116897.UDQTjp.rst new file mode 100644 index 000000000000000..6c8e4b16f20de86 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-03-16-13-38-27.gh-issue-116897.UDQTjp.rst @@ -0,0 +1,4 @@ +Accepting objects with false values (like ``0`` and ``[]``) except empty +strings, byte-like objects and ``None`` in :mod:`urllib.parse` functions +:func:`~urllib.parse.parse_qsl` and :func:`~urllib.parse.parse_qs` is now +deprecated. From bf224bd7cef5d24eaff35945ebe7ffe14df7710f Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Tue, 12 Nov 2024 19:52:30 +0000 Subject: [PATCH 33/57] GH-120423: `pathname2url()`: handle forward slashes in Windows paths (#126593) Adjust `urllib.request.pathname2url()` so that forward slashes in Windows paths are handled identically to backward slashes. --- Lib/nturl2path.py | 13 +++++++------ Lib/test/test_urllib.py | 5 +++++ .../2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst | 2 ++ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst diff --git a/Lib/nturl2path.py b/Lib/nturl2path.py index 2f9fec7893afd1b..9ecabff21c33e14 100644 --- a/Lib/nturl2path.py +++ b/Lib/nturl2path.py @@ -44,20 +44,21 @@ def pathname2url(p): import urllib.parse # First, clean up some special forms. We are going to sacrifice # the additional information anyway - if p[:4] == '\\\\?\\': + p = p.replace('\\', '/') + if p[:4] == '//?/': p = p[4:] - if p[:4].upper() == 'UNC\\': - p = '\\\\' + p[4:] + if p[:4].upper() == 'UNC/': + p = '//' + p[4:] elif p[1:2] != ':': raise OSError('Bad path: ' + p) if not ':' in p: - # No drive specifier, just convert slashes and quote the name - return urllib.parse.quote(p.replace('\\', '/')) + # No DOS drive specified, just quote the pathname + return urllib.parse.quote(p) comp = p.split(':', maxsplit=2) if len(comp) != 2 or len(comp[0]) > 1: error = 'Bad path: ' + p raise OSError(error) drive = urllib.parse.quote(comp[0].upper()) - tail = urllib.parse.quote(comp[1].replace('\\', '/')) + tail = urllib.parse.quote(comp[1]) return '///' + drive + ':' + tail diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 28369b21db06d45..66e948fc3a06bed 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1542,6 +1542,11 @@ def test_pathname2url_win(self): self.assertEqual(fn('\\\\some\\share\\'), '//some/share/') self.assertEqual(fn('\\\\some\\share\\a\\b.c'), '//some/share/a/b.c') self.assertEqual(fn('\\\\some\\share\\a\\b%#c\xe9'), '//some/share/a/b%25%23c%C3%A9') + # Alternate path separator + self.assertEqual(fn('C:/a/b.c'), '///C:/a/b.c') + self.assertEqual(fn('//some/share/a/b.c'), '//some/share/a/b.c') + self.assertEqual(fn('//?/C:/dir'), '///C:/dir') + self.assertEqual(fn('//?/unc/server/share/dir'), '//server/share/dir') # Round-tripping urls = ['///C:', '///folder/test/', diff --git a/Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst b/Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst new file mode 100644 index 000000000000000..b475257ceb6610d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-08-17-05-10.gh-issue-120423.7rdLVV.rst @@ -0,0 +1,2 @@ +Fix issue where :func:`urllib.request.pathname2url` mishandled Windows paths +with embedded forward slashes. From 5610860840aa71b186fc5639211dd268b817d65f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 12 Nov 2024 20:53:58 +0000 Subject: [PATCH 34/57] gh-126688: Reinit import lock after fork (#126692) The PyMutex implementation supports unlocking after fork because we clear the list of waiters in parking_lot.c. This doesn't work as well for _PyRecursiveMutex because on some systems, such as SerenityOS, the thread id is not preserved across fork(). --- Include/internal/pycore_import.h | 1 + .../2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst | 2 ++ Modules/posixmodule.c | 1 + Python/import.c | 7 +++++++ 4 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 290ba95e1a0ad7c..318c712bdfa1749 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -21,6 +21,7 @@ extern int _PyImport_SetModuleString(const char *name, PyObject* module); extern void _PyImport_AcquireLock(PyInterpreterState *interp); extern void _PyImport_ReleaseLock(PyInterpreterState *interp); +extern void _PyImport_ReInitLock(PyInterpreterState *interp); // This is used exclusively for the sys and builtins modules: extern int _PyImport_FixupBuiltin( diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst new file mode 100644 index 000000000000000..30aa5722f0ea02f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst @@ -0,0 +1,2 @@ +Fix a crash when calling :func:`os.fork` on some operating systems, +including SerenityOS. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1ce2baecb8a9649..da7399de86f2137 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -678,6 +678,7 @@ PyOS_AfterFork_Child(void) _PyEval_StartTheWorldAll(&_PyRuntime); _PyThreadState_DeleteList(list); + _PyImport_ReInitLock(tstate->interp); _PyImport_ReleaseLock(tstate->interp); _PySignal_AfterFork(); diff --git a/Python/import.c b/Python/import.c index 29bd8bf68ff5e1e..09fe95fa1fb6478 100644 --- a/Python/import.c +++ b/Python/import.c @@ -122,6 +122,13 @@ _PyImport_ReleaseLock(PyInterpreterState *interp) _PyRecursiveMutex_Unlock(&IMPORT_LOCK(interp)); } +void +_PyImport_ReInitLock(PyInterpreterState *interp) +{ + // gh-126688: Thread id may change after fork() on some operating systems. + IMPORT_LOCK(interp).thread = PyThread_get_thread_ident_ex(); +} + /***************/ /* sys.modules */ From 4b00aba42e4d9440d22e399ec2122fe8601bbe54 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Tue, 12 Nov 2024 22:18:03 +0100 Subject: [PATCH 35/57] gh-119826: Improved fallback for ntpath.abspath() on Windows (GH-119938) --- Lib/ntpath.py | 49 ++++++++++++------- Lib/test/test_ntpath.py | 3 ++ ...-06-02-11-48-19.gh-issue-119826.N1obGa.rst | 1 + 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 1b1873f08b608bf..5481bb8888ef591 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -553,28 +553,21 @@ def normpath(path): return prefix + sep.join(comps) -def _abspath_fallback(path): - """Return the absolute version of a path as a fallback function in case - `nt._getfullpathname` is not available or raises OSError. See bpo-31047 for - more. - - """ - - path = os.fspath(path) - if not isabs(path): - if isinstance(path, bytes): - cwd = os.getcwdb() - else: - cwd = os.getcwd() - path = join(cwd, path) - return normpath(path) - # Return an absolute path. try: from nt import _getfullpathname except ImportError: # not running on Windows - mock up something sensible - abspath = _abspath_fallback + def abspath(path): + """Return the absolute version of a path.""" + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + cwd = os.getcwdb() + else: + cwd = os.getcwd() + path = join(cwd, path) + return normpath(path) else: # use native Windows method on Windows def abspath(path): @@ -582,7 +575,27 @@ def abspath(path): try: return _getfullpathname(normpath(path)) except (OSError, ValueError): - return _abspath_fallback(path) + # See gh-75230, handle outside for cleaner traceback + pass + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + sep = b'\\' + getcwd = os.getcwdb + else: + sep = '\\' + getcwd = os.getcwd + drive, root, path = splitroot(path) + # Either drive or root can be nonempty, but not both. + if drive or root: + try: + path = join(_getfullpathname(drive + root), path) + except (OSError, ValueError): + # Drive "\0:" cannot exist; use the root directory. + path = drive + sep + path + else: + path = join(getcwd(), path) + return normpath(path) try: from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 64cbfaaaaa06904..4f59184dfcfdc70 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -806,6 +806,9 @@ def test_abspath(self): tester('ntpath.abspath("C:\\spam. . .")', "C:\\spam") tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") + self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) + self.assertEqual(ntpath.abspath("C:\x00"), ntpath.join(ntpath.abspath("C:"), "\x00")) + self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") tester('ntpath.abspath("//../..")', "\\\\..\\") diff --git a/Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst b/Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst new file mode 100644 index 000000000000000..6901e7475dd0827 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst @@ -0,0 +1 @@ +Always return an absolute path for :func:`os.path.abspath` on Windows. From 8cc6e5c8751139e86b2a9fa5228795e6c5caaff9 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhang Date: Tue, 12 Nov 2024 16:23:40 -0500 Subject: [PATCH 36/57] gh-126757: fix minor typo (GH-126758) --- Python/bltinmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index a3f41190261a053..85ebd5b00cc18bf 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -3336,7 +3336,7 @@ _PyBuiltin_Init(PyInterpreterState *interp) SETBUILTIN("False", Py_False); SETBUILTIN("True", Py_True); SETBUILTIN("bool", &PyBool_Type); - SETBUILTIN("memoryview", &PyMemoryView_Type); + SETBUILTIN("memoryview", &PyMemoryView_Type); SETBUILTIN("bytearray", &PyByteArray_Type); SETBUILTIN("bytes", &PyBytes_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); From 2e39d77ddeb51505d65fd54ccfcd72615c6b1927 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 13 Nov 2024 05:24:33 +0100 Subject: [PATCH 37/57] bpo-46128: Strip IsolatedAsyncioTestCase frames from reported stacktraces (#30196) * Strip IsolatedAsyncioTestCase frames from reported stacktraces * Update Misc/NEWS.d/next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --------- Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade --- Lib/unittest/async_case.py | 1 + .../next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index bd06eb3207697a7..6000af1cef0a78c 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -5,6 +5,7 @@ from .case import TestCase +__unittest = True class IsolatedAsyncioTestCase(TestCase): # Names intentionally have a long prefix diff --git a/Misc/NEWS.d/next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst b/Misc/NEWS.d/next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst new file mode 100644 index 000000000000000..7d11d20d94e8a3c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-19-10-47-24.bpo-46128.Qv3EK1.rst @@ -0,0 +1,2 @@ +Strip :class:`unittest.IsolatedAsyncioTestCase` stack frames from reported +stacktraces. From 1e40c5ba47780ddd91868abb3aa064f5ba3015e4 Mon Sep 17 00:00:00 2001 From: Red4Ru <39802734+Red4Ru@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:20:38 +0300 Subject: [PATCH 38/57] gh-104745: Limit starting a patcher more than once without stopping it (#126649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, this would cause an `AttributeError` if the patch stopped more than once after this, and would also disrupt the original patched object. --------- Co-authored-by: Peter Bierma Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_unittest/testmock/testpatch.py | 52 ++++++++++++++++++- Lib/unittest/mock.py | 9 ++++ ...-11-10-18-14-51.gh-issue-104745.zAa5Ke.rst | 3 ++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-10-18-14-51.gh-issue-104745.zAa5Ke.rst diff --git a/Lib/test/test_unittest/testmock/testpatch.py b/Lib/test/test_unittest/testmock/testpatch.py index f26e74ce0bc1ba7..037c021e6eafcfa 100644 --- a/Lib/test/test_unittest/testmock/testpatch.py +++ b/Lib/test/test_unittest/testmock/testpatch.py @@ -745,6 +745,54 @@ def test_stop_idempotent(self): self.assertIsNone(patcher.stop()) + def test_exit_idempotent(self): + patcher = patch(foo_name, 'bar', 3) + with patcher: + patcher.stop() + + + def test_second_start_failure(self): + patcher = patch(foo_name, 'bar', 3) + patcher.start() + try: + self.assertRaises(RuntimeError, patcher.start) + finally: + patcher.stop() + + + def test_second_enter_failure(self): + patcher = patch(foo_name, 'bar', 3) + with patcher: + self.assertRaises(RuntimeError, patcher.start) + + + def test_second_start_after_stop(self): + patcher = patch(foo_name, 'bar', 3) + patcher.start() + patcher.stop() + patcher.start() + patcher.stop() + + + def test_property_setters(self): + mock_object = Mock() + mock_bar = mock_object.bar + patcher = patch.object(mock_object, 'bar', 'x') + with patcher: + self.assertEqual(patcher.is_local, False) + self.assertIs(patcher.target, mock_object) + self.assertEqual(patcher.temp_original, mock_bar) + patcher.is_local = True + patcher.target = mock_bar + patcher.temp_original = mock_object + self.assertEqual(patcher.is_local, True) + self.assertIs(patcher.target, mock_bar) + self.assertEqual(patcher.temp_original, mock_object) + # if changes are left intact, they may lead to disruption as shown below (it might be what someone needs though) + self.assertEqual(mock_bar.bar, mock_object) + self.assertEqual(mock_object.bar, 'x') + + def test_patchobject_start_stop(self): original = something patcher = patch.object(PTModule, 'something', 'foo') @@ -1098,7 +1146,7 @@ def test_new_callable_patch(self): self.assertIsNot(m1, m2) for mock in m1, m2: - self.assertNotCallable(m1) + self.assertNotCallable(mock) def test_new_callable_patch_object(self): @@ -1111,7 +1159,7 @@ def test_new_callable_patch_object(self): self.assertIsNot(m1, m2) for mock in m1, m2: - self.assertNotCallable(m1) + self.assertNotCallable(mock) def test_new_callable_keyword_arguments(self): diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 21ca061a77c26f5..55cb4b1f6aff901 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1360,6 +1360,7 @@ def __init__( self.autospec = autospec self.kwargs = kwargs self.additional_patchers = [] + self.is_started = False def copy(self): @@ -1472,6 +1473,9 @@ def get_original(self): def __enter__(self): """Perform the patch.""" + if self.is_started: + raise RuntimeError("Patch is already started") + new, spec, spec_set = self.new, self.spec, self.spec_set autospec, kwargs = self.autospec, self.kwargs new_callable = self.new_callable @@ -1603,6 +1607,7 @@ def __enter__(self): self.temp_original = original self.is_local = local self._exit_stack = contextlib.ExitStack() + self.is_started = True try: setattr(self.target, self.attribute, new_attr) if self.attribute_name is not None: @@ -1622,6 +1627,9 @@ def __enter__(self): def __exit__(self, *exc_info): """Undo the patch.""" + if not self.is_started: + return + if self.is_local and self.temp_original is not DEFAULT: setattr(self.target, self.attribute, self.temp_original) else: @@ -1638,6 +1646,7 @@ def __exit__(self, *exc_info): del self.target exit_stack = self._exit_stack del self._exit_stack + self.is_started = False return exit_stack.__exit__(*exc_info) diff --git a/Misc/NEWS.d/next/Library/2024-11-10-18-14-51.gh-issue-104745.zAa5Ke.rst b/Misc/NEWS.d/next/Library/2024-11-10-18-14-51.gh-issue-104745.zAa5Ke.rst new file mode 100644 index 000000000000000..c83a10769820cfe --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-10-18-14-51.gh-issue-104745.zAa5Ke.rst @@ -0,0 +1,3 @@ +Limit starting a patcher (from :func:`unittest.mock.patch` or +:func:`unittest.mock.patch.object`) more than +once without stopping it From ba088c8f9cf7163b0f28c507cb1343befe21997e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 13 Nov 2024 10:25:10 +0100 Subject: [PATCH 39/57] gh-71936: Fix race condition in multiprocessing.Pool (GH-124973) * gh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori --- Lib/multiprocessing/managers.py | 33 +++++++++++-------- Misc/ACKS | 1 + ...2-10-15-10-18-20.gh-issue-71936.MzJjc_.rst | 1 + 3 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-10-15-10-18-20.gh-issue-71936.MzJjc_.rst diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index a5d2f53613952e1..040f4674d735c04 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -759,22 +759,29 @@ class BaseProxy(object): _address_to_local = {} _mutex = util.ForkAwareThreadLock() + # Each instance gets a `_serial` number. Unlike `id(...)`, this number + # is never reused. + _next_serial = 1 + def __init__(self, token, serializer, manager=None, authkey=None, exposed=None, incref=True, manager_owned=False): with BaseProxy._mutex: - tls_idset = BaseProxy._address_to_local.get(token.address, None) - if tls_idset is None: - tls_idset = util.ForkAwareLocal(), ProcessLocalSet() - BaseProxy._address_to_local[token.address] = tls_idset + tls_serials = BaseProxy._address_to_local.get(token.address, None) + if tls_serials is None: + tls_serials = util.ForkAwareLocal(), ProcessLocalSet() + BaseProxy._address_to_local[token.address] = tls_serials + + self._serial = BaseProxy._next_serial + BaseProxy._next_serial += 1 # self._tls is used to record the connection used by this # thread to communicate with the manager at token.address - self._tls = tls_idset[0] + self._tls = tls_serials[0] - # self._idset is used to record the identities of all shared - # objects for which the current process owns references and + # self._all_serials is a set used to record the identities of all + # shared objects for which the current process owns references and # which are in the manager at token.address - self._idset = tls_idset[1] + self._all_serials = tls_serials[1] self._token = token self._id = self._token.id @@ -857,20 +864,20 @@ def _incref(self): dispatch(conn, None, 'incref', (self._id,)) util.debug('INCREF %r', self._token.id) - self._idset.add(self._id) + self._all_serials.add(self._serial) state = self._manager and self._manager._state self._close = util.Finalize( self, BaseProxy._decref, - args=(self._token, self._authkey, state, - self._tls, self._idset, self._Client), + args=(self._token, self._serial, self._authkey, state, + self._tls, self._all_serials, self._Client), exitpriority=10 ) @staticmethod - def _decref(token, authkey, state, tls, idset, _Client): - idset.discard(token.id) + def _decref(token, serial, authkey, state, tls, idset, _Client): + idset.discard(serial) # check whether manager is still alive if state is None or state.value == State.STARTED: diff --git a/Misc/ACKS b/Misc/ACKS index dce322fc8677439..08cd293eac38358 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -733,6 +733,7 @@ Larry Hastings Tim Hatch Zac Hatfield-Dodds Shane Hathaway +Akinori Hattori Michael Haubenwallner Janko Hauser Flavian Hautbois diff --git a/Misc/NEWS.d/next/Library/2022-10-15-10-18-20.gh-issue-71936.MzJjc_.rst b/Misc/NEWS.d/next/Library/2022-10-15-10-18-20.gh-issue-71936.MzJjc_.rst new file mode 100644 index 000000000000000..a0959cc086fa9e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-10-15-10-18-20.gh-issue-71936.MzJjc_.rst @@ -0,0 +1 @@ +Fix a race condition in :class:`multiprocessing.pool.Pool`. From a12690ef49e8fc8a3af4c5f1757eb3caffb35e03 Mon Sep 17 00:00:00 2001 From: Ritvik Pasham Date: Wed, 13 Nov 2024 06:51:01 -0500 Subject: [PATCH 40/57] gh-126341: add release check to `__iter__` method of `memoryview` (#126759) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Peter Bierma Co-authored-by: Victor Stinner Co-authored-by: sobolevn --- Lib/test/test_buffer.py | 2 ++ .../2024-11-12-19-24-00.gh-issue-126341.5SdAe1.rst | 1 + Objects/memoryobject.c | 1 + 3 files changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-12-19-24-00.gh-issue-126341.5SdAe1.rst diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index ae938d12c9401b1..cb38a69e390f3ab 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -3910,6 +3910,8 @@ def test_memoryview_check_released(self): self.assertRaises(ValueError, memoryview, m) # memoryview.cast() self.assertRaises(ValueError, m.cast, 'c') + # memoryview.__iter__() + self.assertRaises(ValueError, m.__iter__) # getbuffer() self.assertRaises(ValueError, ndarray, m) # memoryview.tolist() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-12-19-24-00.gh-issue-126341.5SdAe1.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-12-19-24-00.gh-issue-126341.5SdAe1.rst new file mode 100644 index 000000000000000..c2436d2ebf4d09f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-12-19-24-00.gh-issue-126341.5SdAe1.rst @@ -0,0 +1 @@ +Now :exc:`ValueError` is raised instead of :exc:`SystemError` when trying to iterate over a released :class:`memoryview` object. diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index d4672e8198cb24e..25634f997ac66b5 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -3356,6 +3356,7 @@ memory_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } + CHECK_RELEASED(seq); PyMemoryViewObject *obj = (PyMemoryViewObject *)seq; int ndims = obj->view.ndim; if (ndims == 0) { From 29b5323c4567dc7772e1d30a7ba1cbad52fe10a9 Mon Sep 17 00:00:00 2001 From: Taneli Hukkinen <3275109+hukkin@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:52:16 +0200 Subject: [PATCH 41/57] gh-126175: Add attributes to TOMLDecodeError. Deprecate free-form `__init__` args (GH-126428) --- Doc/library/tomllib.rst | 31 +++- Lib/test/test_tomllib/test_error.py | 34 +++- Lib/tomllib/_parser.py | 148 ++++++++++++------ ...-11-05-09-54-49.gh-issue-126175.spnjJr.rst | 2 + 4 files changed, 163 insertions(+), 52 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-05-09-54-49.gh-issue-126175.spnjJr.rst diff --git a/Doc/library/tomllib.rst b/Doc/library/tomllib.rst index 521a7a17fb3e8bc..4b88b2e29e78220 100644 --- a/Doc/library/tomllib.rst +++ b/Doc/library/tomllib.rst @@ -60,9 +60,36 @@ This module defines the following functions: The following exceptions are available: -.. exception:: TOMLDecodeError +.. exception:: TOMLDecodeError(msg, doc, pos) - Subclass of :exc:`ValueError`. + Subclass of :exc:`ValueError` with the following additional attributes: + + .. attribute:: msg + + The unformatted error message. + + .. attribute:: doc + + The TOML document being parsed. + + .. attribute:: pos + + The index of *doc* where parsing failed. + + .. attribute:: lineno + + The line corresponding to *pos*. + + .. attribute:: colno + + The column corresponding to *pos*. + + .. versionchanged:: next + Added the *msg*, *doc* and *pos* parameters. + Added the :attr:`msg`, :attr:`doc`, :attr:`pos`, :attr:`lineno` and :attr:`colno` attributes. + + .. deprecated:: next + Passing free-form positional arguments is deprecated. Examples diff --git a/Lib/test/test_tomllib/test_error.py b/Lib/test/test_tomllib/test_error.py index d2ef59a29ca350c..3a8587492859ca6 100644 --- a/Lib/test/test_tomllib/test_error.py +++ b/Lib/test/test_tomllib/test_error.py @@ -49,7 +49,9 @@ def test_type_error(self): self.assertEqual(str(exc_info.exception), "Expected str object, not 'bool'") def test_module_name(self): - self.assertEqual(tomllib.TOMLDecodeError().__module__, tomllib.__name__) + self.assertEqual( + tomllib.TOMLDecodeError("", "", 0).__module__, tomllib.__name__ + ) def test_invalid_parse_float(self): def dict_returner(s: str) -> dict: @@ -64,3 +66,33 @@ def list_returner(s: str) -> list: self.assertEqual( str(exc_info.exception), "parse_float must not return dicts or lists" ) + + def test_deprecated_tomldecodeerror(self): + for args in [ + (), + ("err msg",), + (None,), + (None, "doc"), + ("err msg", None), + (None, "doc", None), + ("err msg", "doc", None), + ("one", "two", "three", "four"), + ("one", "two", 3, "four", "five"), + ]: + with self.assertWarns(DeprecationWarning): + e = tomllib.TOMLDecodeError(*args) # type: ignore[arg-type] + self.assertEqual(e.args, args) + + def test_tomldecodeerror(self): + msg = "error parsing" + doc = "v=1\n[table]\nv='val'" + pos = 13 + formatted_msg = "error parsing (at line 3, column 2)" + e = tomllib.TOMLDecodeError(msg, doc, pos) + self.assertEqual(e.args, (formatted_msg,)) + self.assertEqual(str(e), formatted_msg) + self.assertEqual(e.msg, msg) + self.assertEqual(e.doc, doc) + self.assertEqual(e.pos, pos) + self.assertEqual(e.lineno, 3) + self.assertEqual(e.colno, 2) diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py index 5671326646ca5a6..4d208bcfb4a9a67 100644 --- a/Lib/tomllib/_parser.py +++ b/Lib/tomllib/_parser.py @@ -8,6 +8,7 @@ import string from types import MappingProxyType from typing import Any, BinaryIO, NamedTuple +import warnings from ._re import ( RE_DATETIME, @@ -50,8 +51,68 @@ ) +class DEPRECATED_DEFAULT: + """Sentinel to be used as default arg during deprecation + period of TOMLDecodeError's free-form arguments.""" + + class TOMLDecodeError(ValueError): - """An error raised if a document is not valid TOML.""" + """An error raised if a document is not valid TOML. + + Adds the following attributes to ValueError: + msg: The unformatted error message + doc: The TOML document being parsed + pos: The index of doc where parsing failed + lineno: The line corresponding to pos + colno: The column corresponding to pos + """ + + def __init__( + self, + msg: str = DEPRECATED_DEFAULT, # type: ignore[assignment] + doc: str = DEPRECATED_DEFAULT, # type: ignore[assignment] + pos: Pos = DEPRECATED_DEFAULT, # type: ignore[assignment] + *args: Any, + ): + if ( + args + or not isinstance(msg, str) + or not isinstance(doc, str) + or not isinstance(pos, int) + ): + warnings.warn( + "Free-form arguments for TOMLDecodeError are deprecated. " + "Please set 'msg' (str), 'doc' (str) and 'pos' (int) arguments only.", + DeprecationWarning, + stacklevel=2, + ) + if pos is not DEPRECATED_DEFAULT: # type: ignore[comparison-overlap] + args = pos, *args + if doc is not DEPRECATED_DEFAULT: # type: ignore[comparison-overlap] + args = doc, *args + if msg is not DEPRECATED_DEFAULT: # type: ignore[comparison-overlap] + args = msg, *args + ValueError.__init__(self, *args) + return + + lineno = doc.count("\n", 0, pos) + 1 + if lineno == 1: + colno = pos + 1 + else: + colno = pos - doc.rindex("\n", 0, pos) + + if pos >= len(doc): + coord_repr = "end of document" + else: + coord_repr = f"line {lineno}, column {colno}" + errmsg = f"{msg} (at {coord_repr})" + ValueError.__init__(self, errmsg) + + self.msg = msg + self.doc = doc + self.pos = pos + self.lineno = lineno + self.colno = colno def load(fp: BinaryIO, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: @@ -118,7 +179,7 @@ def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: # n pos, header = create_dict_rule(src, pos, out) pos = skip_chars(src, pos, TOML_WS) elif char != "#": - raise suffixed_err(src, pos, "Invalid statement") + raise TOMLDecodeError("Invalid statement", src, pos) # 3. Skip comment pos = skip_comment(src, pos) @@ -129,8 +190,8 @@ def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: # n except IndexError: break if char != "\n": - raise suffixed_err( - src, pos, "Expected newline or end of document after a statement" + raise TOMLDecodeError( + "Expected newline or end of document after a statement", src, pos ) pos += 1 @@ -256,12 +317,12 @@ def skip_until( except ValueError: new_pos = len(src) if error_on_eof: - raise suffixed_err(src, new_pos, f"Expected {expect!r}") from None + raise TOMLDecodeError(f"Expected {expect!r}", src, new_pos) from None if not error_on.isdisjoint(src[pos:new_pos]): while src[pos] not in error_on: pos += 1 - raise suffixed_err(src, pos, f"Found invalid character {src[pos]!r}") + raise TOMLDecodeError(f"Found invalid character {src[pos]!r}", src, pos) return new_pos @@ -292,15 +353,17 @@ def create_dict_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: pos, key = parse_key(src, pos) if out.flags.is_(key, Flags.EXPLICIT_NEST) or out.flags.is_(key, Flags.FROZEN): - raise suffixed_err(src, pos, f"Cannot declare {key} twice") + raise TOMLDecodeError(f"Cannot declare {key} twice", src, pos) out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) try: out.data.get_or_create_nest(key) except KeyError: - raise suffixed_err(src, pos, "Cannot overwrite a value") from None + raise TOMLDecodeError("Cannot overwrite a value", src, pos) from None if not src.startswith("]", pos): - raise suffixed_err(src, pos, "Expected ']' at the end of a table declaration") + raise TOMLDecodeError( + "Expected ']' at the end of a table declaration", src, pos + ) return pos + 1, key @@ -310,7 +373,7 @@ def create_list_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: pos, key = parse_key(src, pos) if out.flags.is_(key, Flags.FROZEN): - raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + raise TOMLDecodeError(f"Cannot mutate immutable namespace {key}", src, pos) # Free the namespace now that it points to another empty list item... out.flags.unset_all(key) # ...but this key precisely is still prohibited from table declaration @@ -318,10 +381,12 @@ def create_list_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: try: out.data.append_nest_to_list(key) except KeyError: - raise suffixed_err(src, pos, "Cannot overwrite a value") from None + raise TOMLDecodeError("Cannot overwrite a value", src, pos) from None if not src.startswith("]]", pos): - raise suffixed_err(src, pos, "Expected ']]' at the end of an array declaration") + raise TOMLDecodeError( + "Expected ']]' at the end of an array declaration", src, pos + ) return pos + 2, key @@ -336,22 +401,22 @@ def key_value_rule( for cont_key in relative_path_cont_keys: # Check that dotted key syntax does not redefine an existing table if out.flags.is_(cont_key, Flags.EXPLICIT_NEST): - raise suffixed_err(src, pos, f"Cannot redefine namespace {cont_key}") + raise TOMLDecodeError(f"Cannot redefine namespace {cont_key}", src, pos) # Containers in the relative path can't be opened with the table syntax or # dotted key/value syntax in following table sections. out.flags.add_pending(cont_key, Flags.EXPLICIT_NEST) if out.flags.is_(abs_key_parent, Flags.FROZEN): - raise suffixed_err( - src, pos, f"Cannot mutate immutable namespace {abs_key_parent}" + raise TOMLDecodeError( + f"Cannot mutate immutable namespace {abs_key_parent}", src, pos ) try: nest = out.data.get_or_create_nest(abs_key_parent) except KeyError: - raise suffixed_err(src, pos, "Cannot overwrite a value") from None + raise TOMLDecodeError("Cannot overwrite a value", src, pos) from None if key_stem in nest: - raise suffixed_err(src, pos, "Cannot overwrite a value") + raise TOMLDecodeError("Cannot overwrite a value", src, pos) # Mark inline table and array namespaces recursively immutable if isinstance(value, (dict, list)): out.flags.set(header + key, Flags.FROZEN, recursive=True) @@ -368,7 +433,7 @@ def parse_key_value_pair( except IndexError: char = None if char != "=": - raise suffixed_err(src, pos, "Expected '=' after a key in a key/value pair") + raise TOMLDecodeError("Expected '=' after a key in a key/value pair", src, pos) pos += 1 pos = skip_chars(src, pos, TOML_WS) pos, value = parse_value(src, pos, parse_float) @@ -406,7 +471,7 @@ def parse_key_part(src: str, pos: Pos) -> tuple[Pos, str]: return parse_literal_str(src, pos) if char == '"': return parse_one_line_basic_str(src, pos) - raise suffixed_err(src, pos, "Invalid initial character for a key part") + raise TOMLDecodeError("Invalid initial character for a key part", src, pos) def parse_one_line_basic_str(src: str, pos: Pos) -> tuple[Pos, str]: @@ -430,7 +495,7 @@ def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list] if c == "]": return pos + 1, array if c != ",": - raise suffixed_err(src, pos, "Unclosed array") + raise TOMLDecodeError("Unclosed array", src, pos) pos += 1 pos = skip_comments_and_array_ws(src, pos) @@ -450,20 +515,20 @@ def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos pos, key, value = parse_key_value_pair(src, pos, parse_float) key_parent, key_stem = key[:-1], key[-1] if flags.is_(key, Flags.FROZEN): - raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + raise TOMLDecodeError(f"Cannot mutate immutable namespace {key}", src, pos) try: nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) except KeyError: - raise suffixed_err(src, pos, "Cannot overwrite a value") from None + raise TOMLDecodeError("Cannot overwrite a value", src, pos) from None if key_stem in nest: - raise suffixed_err(src, pos, f"Duplicate inline table key {key_stem!r}") + raise TOMLDecodeError(f"Duplicate inline table key {key_stem!r}", src, pos) nest[key_stem] = value pos = skip_chars(src, pos, TOML_WS) c = src[pos : pos + 1] if c == "}": return pos + 1, nested_dict.dict if c != ",": - raise suffixed_err(src, pos, "Unclosed inline table") + raise TOMLDecodeError("Unclosed inline table", src, pos) if isinstance(value, (dict, list)): flags.set(key, Flags.FROZEN, recursive=True) pos += 1 @@ -485,7 +550,7 @@ def parse_basic_str_escape( except IndexError: return pos, "" if char != "\n": - raise suffixed_err(src, pos, "Unescaped '\\' in a string") + raise TOMLDecodeError("Unescaped '\\' in a string", src, pos) pos += 1 pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) return pos, "" @@ -496,7 +561,7 @@ def parse_basic_str_escape( try: return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] except KeyError: - raise suffixed_err(src, pos, "Unescaped '\\' in a string") from None + raise TOMLDecodeError("Unescaped '\\' in a string", src, pos) from None def parse_basic_str_escape_multiline(src: str, pos: Pos) -> tuple[Pos, str]: @@ -506,11 +571,13 @@ def parse_basic_str_escape_multiline(src: str, pos: Pos) -> tuple[Pos, str]: def parse_hex_char(src: str, pos: Pos, hex_len: int) -> tuple[Pos, str]: hex_str = src[pos : pos + hex_len] if len(hex_str) != hex_len or not HEXDIGIT_CHARS.issuperset(hex_str): - raise suffixed_err(src, pos, "Invalid hex value") + raise TOMLDecodeError("Invalid hex value", src, pos) pos += hex_len hex_int = int(hex_str, 16) if not is_unicode_scalar_value(hex_int): - raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") + raise TOMLDecodeError( + "Escaped character is not a Unicode scalar value", src, pos + ) return pos, chr(hex_int) @@ -567,7 +634,7 @@ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]: try: char = src[pos] except IndexError: - raise suffixed_err(src, pos, "Unterminated string") from None + raise TOMLDecodeError("Unterminated string", src, pos) from None if char == '"': if not multiline: return pos + 1, result + src[start_pos:pos] @@ -582,7 +649,7 @@ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]: start_pos = pos continue if char in error_on: - raise suffixed_err(src, pos, f"Illegal character {char!r}") + raise TOMLDecodeError(f"Illegal character {char!r}", src, pos) pos += 1 @@ -630,7 +697,7 @@ def parse_value( # noqa: C901 try: datetime_obj = match_to_datetime(datetime_match) except ValueError as e: - raise suffixed_err(src, pos, "Invalid date or datetime") from e + raise TOMLDecodeError("Invalid date or datetime", src, pos) from e return datetime_match.end(), datetime_obj localtime_match = RE_LOCALTIME.match(src, pos) if localtime_match: @@ -651,24 +718,7 @@ def parse_value( # noqa: C901 if first_four in {"-inf", "+inf", "-nan", "+nan"}: return pos + 4, parse_float(first_four) - raise suffixed_err(src, pos, "Invalid value") - - -def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: - """Return a `TOMLDecodeError` where error message is suffixed with - coordinates in source.""" - - def coord_repr(src: str, pos: Pos) -> str: - if pos >= len(src): - return "end of document" - line = src.count("\n", 0, pos) + 1 - if line == 1: - column = pos + 1 - else: - column = pos - src.rindex("\n", 0, pos) - return f"line {line}, column {column}" - - return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") + raise TOMLDecodeError("Invalid value", src, pos) def is_unicode_scalar_value(codepoint: int) -> bool: diff --git a/Misc/NEWS.d/next/Library/2024-11-05-09-54-49.gh-issue-126175.spnjJr.rst b/Misc/NEWS.d/next/Library/2024-11-05-09-54-49.gh-issue-126175.spnjJr.rst new file mode 100644 index 000000000000000..de7ce88c8d0f281 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-05-09-54-49.gh-issue-126175.spnjJr.rst @@ -0,0 +1,2 @@ +Add ``msg``, ``doc``, ``pos``, ``lineno`` and ``colno`` attributes to :exc:`tomllib.TOMLDecodeError`. +Deprecate instantiating with free-form arguments. From d00878b06a05ea04790813dba70b09cc1d11bf45 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 13 Nov 2024 08:27:16 -0500 Subject: [PATCH 42/57] gh-123619: Add an unstable C API function for enabling deferred reference counting (GH-123635) Co-authored-by: Sam Gross --- Doc/c-api/object.rst | 24 ++++++++++ Doc/whatsnew/3.14.rst | 3 ++ Include/cpython/object.h | 7 +++ Lib/test/test_capi/test_object.py | 46 +++++++++++++++++++ ...-09-03-13-33-33.gh-issue-123619.HhgUUI.rst | 2 + Modules/_testcapi/object.c | 9 +++- Modules/_testinternalcapi.c | 9 ++++ Objects/object.c | 29 ++++++++++++ 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C_API/2024-09-03-13-33-33.gh-issue-123619.HhgUUI.rst diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 630114a4339110f..1e1cf6e6bfd7e9b 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -575,3 +575,27 @@ Object Protocol has the :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag set. .. versionadded:: 3.13 + +.. c:function:: int PyUnstable_Object_EnableDeferredRefcount(PyObject *obj) + + Enable `deferred reference counting `_ on *obj*, + if supported by the runtime. In the :term:`free-threaded ` build, + this allows the interpreter to avoid reference count adjustments to *obj*, + which may improve multi-threaded performance. The tradeoff is + that *obj* will only be deallocated by the tracing garbage collector. + + This function returns ``1`` if deferred reference counting is enabled on *obj* + (including when it was enabled before the call), + and ``0`` if deferred reference counting is not supported or if the hint was + ignored by the runtime. This function is thread-safe, and cannot fail. + + This function does nothing on builds with the :term:`GIL` enabled, which do + not support deferred reference counting. This also does nothing if *obj* is not + an object tracked by the garbage collector (see :func:`gc.is_tracked` and + :c:func:`PyObject_GC_IsTracked`). + + This function is intended to be used soon after *obj* is created, + by the code that creates it. + + .. versionadded:: next + diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index a98fe3f468b685b..31754fb55fcf020 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -890,6 +890,9 @@ New features * Add :c:func:`PyType_Freeze` function to make a type immutable. (Contributed by Victor Stinner in :gh:`121654`.) +* Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling + deferred reference counting, as outlined in :pep:`703`. + Porting to Python 3.14 ---------------------- diff --git a/Include/cpython/object.h b/Include/cpython/object.h index f0f61796cd3ec80..e4797029da431e5 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -527,3 +527,10 @@ typedef enum { typedef int (*PyRefTracer)(PyObject *, PyRefTracerEvent event, void *); PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data); PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**); + +/* Enable PEP-703 deferred reference counting on the object. + * + * Returns 1 if deferred reference counting was successfully enabled, and + * 0 if the runtime ignored it. This function cannot fail. + */ +PyAPI_FUNC(int) PyUnstable_Object_EnableDeferredRefcount(PyObject *); diff --git a/Lib/test/test_capi/test_object.py b/Lib/test/test_capi/test_object.py index cc9c9b688f00e21..a38b203ed12fa27 100644 --- a/Lib/test/test_capi/test_object.py +++ b/Lib/test/test_capi/test_object.py @@ -1,10 +1,13 @@ import enum import unittest +from test import support from test.support import import_helper from test.support import os_helper +from test.support import threading_helper _testlimitedcapi = import_helper.import_module('_testlimitedcapi') _testcapi = import_helper.import_module('_testcapi') +_testinternalcapi = import_helper.import_module('_testinternalcapi') class Constant(enum.IntEnum): @@ -131,5 +134,48 @@ def test_ClearWeakRefsNoCallbacks_no_weakref_support(self): _testcapi.pyobject_clear_weakrefs_no_callbacks(obj) +class EnableDeferredRefcountingTest(unittest.TestCase): + """Test PyUnstable_Object_EnableDeferredRefcount""" + @support.requires_resource("cpu") + def test_enable_deferred_refcount(self): + from threading import Thread + + self.assertEqual(_testcapi.pyobject_enable_deferred_refcount("not tracked"), 0) + foo = [] + self.assertEqual(_testcapi.pyobject_enable_deferred_refcount(foo), int(support.Py_GIL_DISABLED)) + + # Make sure reference counting works on foo now + self.assertEqual(foo, []) + if support.Py_GIL_DISABLED: + self.assertTrue(_testinternalcapi.has_deferred_refcount(foo)) + + # Make sure that PyUnstable_Object_EnableDeferredRefcount is thread safe + def silly_func(obj): + self.assertIn( + _testcapi.pyobject_enable_deferred_refcount(obj), + (0, 1) + ) + + silly_list = [1, 2, 3] + threads = [ + Thread(target=silly_func, args=(silly_list,)) for _ in range(5) + ] + + with threading_helper.catch_threading_exception() as cm: + for t in threads: + t.start() + + for i in range(10): + silly_list.append(i) + + for t in threads: + t.join() + + self.assertIsNone(cm.exc_value) + + if support.Py_GIL_DISABLED: + self.assertTrue(_testinternalcapi.has_deferred_refcount(silly_list)) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/C_API/2024-09-03-13-33-33.gh-issue-123619.HhgUUI.rst b/Misc/NEWS.d/next/C_API/2024-09-03-13-33-33.gh-issue-123619.HhgUUI.rst new file mode 100644 index 000000000000000..ac821b5326026e6 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-03-13-33-33.gh-issue-123619.HhgUUI.rst @@ -0,0 +1,2 @@ +Added the :c:func:`PyUnstable_Object_EnableDeferredRefcount` function for +enabling :pep:`703` deferred reference counting. diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c index 1c76e766a790f07..3af5429ef00985e 100644 --- a/Modules/_testcapi/object.c +++ b/Modules/_testcapi/object.c @@ -124,13 +124,20 @@ pyobject_clear_weakrefs_no_callbacks(PyObject *self, PyObject *obj) Py_RETURN_NONE; } +static PyObject * +pyobject_enable_deferred_refcount(PyObject *self, PyObject *obj) +{ + int result = PyUnstable_Object_EnableDeferredRefcount(obj); + return PyLong_FromLong(result); +} + static PyMethodDef test_methods[] = { {"call_pyobject_print", call_pyobject_print, METH_VARARGS}, {"pyobject_print_null", pyobject_print_null, METH_VARARGS}, {"pyobject_print_noref_object", pyobject_print_noref_object, METH_VARARGS}, {"pyobject_print_os_error", pyobject_print_os_error, METH_VARARGS}, {"pyobject_clear_weakrefs_no_callbacks", pyobject_clear_weakrefs_no_callbacks, METH_O}, - + {"pyobject_enable_deferred_refcount", pyobject_enable_deferred_refcount, METH_O}, {NULL}, }; diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 2c1ebcbbfdf4197..b02f794d27d5bd2 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -2069,6 +2069,14 @@ identify_type_slot_wrappers(PyObject *self, PyObject *Py_UNUSED(ignored)) return _PyType_GetSlotWrapperNames(); } + +static PyObject * +has_deferred_refcount(PyObject *self, PyObject *op) +{ + return PyBool_FromLong(_PyObject_HasDeferredRefcount(op)); +} + + static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, @@ -2165,6 +2173,7 @@ static PyMethodDef module_functions[] = { GH_119213_GETARGS_METHODDEF {"get_static_builtin_types", get_static_builtin_types, METH_NOARGS}, {"identify_type_slot_wrappers", identify_type_slot_wrappers, METH_NOARGS}, + {"has_deferred_refcount", has_deferred_refcount, METH_O}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/object.c b/Objects/object.c index 7cc74a8dc0d8eb9..052dea9ad1feff0 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2519,6 +2519,35 @@ _PyObject_SetDeferredRefcount(PyObject *op) #endif } +int +PyUnstable_Object_EnableDeferredRefcount(PyObject *op) +{ +#ifdef Py_GIL_DISABLED + if (!PyType_IS_GC(Py_TYPE(op))) { + // Deferred reference counting doesn't work + // on untracked types. + return 0; + } + + uint8_t bits = _Py_atomic_load_uint8(&op->ob_gc_bits); + if ((bits & _PyGC_BITS_DEFERRED) != 0) + { + // Nothing to do. + return 0; + } + + if (_Py_atomic_compare_exchange_uint8(&op->ob_gc_bits, &bits, bits | _PyGC_BITS_DEFERRED) == 0) + { + // Someone beat us to it! + return 0; + } + _Py_atomic_add_ssize(&op->ob_ref_shared, _Py_REF_SHARED(_Py_REF_DEFERRED, 0)); + return 1; +#else + return 0; +#endif +} + void _Py_ResurrectReference(PyObject *op) { From b2bbdc56e3276f3b37ea5cf5f73f49c4cce6d9f6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 13 Nov 2024 17:46:10 +0100 Subject: [PATCH 43/57] gh-126456: Fix _pyrepl curses tigetstr() (#126472) --- Lib/_pyrepl/_minimal_curses.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/_pyrepl/_minimal_curses.py b/Lib/_pyrepl/_minimal_curses.py index 849617bf7585e46..d884f880f50ac75 100644 --- a/Lib/_pyrepl/_minimal_curses.py +++ b/Lib/_pyrepl/_minimal_curses.py @@ -34,7 +34,7 @@ def _find_clib() -> str: clib.setupterm.restype = ctypes.c_int clib.tigetstr.argtypes = [ctypes.c_char_p] -clib.tigetstr.restype = ctypes.POINTER(ctypes.c_char) +clib.tigetstr.restype = ctypes.c_ssize_t clib.tparm.argtypes = [ctypes.c_char_p] + 9 * [ctypes.c_int] # type: ignore[operator] clib.tparm.restype = ctypes.c_char_p @@ -56,7 +56,7 @@ def tigetstr(cap): if not isinstance(cap, bytes): cap = cap.encode("ascii") result = clib.tigetstr(cap) - if ctypes.cast(result, ctypes.c_void_p).value == ERR: + if result == ERR: return None return ctypes.cast(result, ctypes.c_char_p).value From 8c9c6d3c1234e730c0beb2a6123e68fe98e57ede Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Thu, 14 Nov 2024 02:09:26 +0900 Subject: [PATCH 44/57] gh-123465: Ensure PyType_FromMetaclass avoids extra strcmp (GH-125460) use else --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4af7f0273aae91a..a6cf3da542b6913 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4761,10 +4761,10 @@ PyType_FromMetaclass( if (strcmp(memb->name, "__weaklistoffset__") == 0) { weaklistoffset_member = memb; } - if (strcmp(memb->name, "__dictoffset__") == 0) { + else if (strcmp(memb->name, "__dictoffset__") == 0) { dictoffset_member = memb; } - if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { vectorcalloffset_member = memb; } } From 3c9996909402fadc98e6ca2a64e75a71a7427352 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 13 Nov 2024 12:31:20 -0600 Subject: [PATCH 45/57] gh-126623: Update libexpat to 2.6.4, make future updates easier (GH-126792) Update libexpat to 2.6.4, make future updates easier. --- ...-11-13-11-09-12.gh-issue-126623.TO7NnR.rst | 1 + Misc/sbom.spdx.json | 22 +++---- Modules/expat/expat.h | 6 +- Modules/expat/expat_external.h | 9 ++- Modules/expat/refresh.sh | 57 +++++++++++++++++++ Modules/expat/xmlparse.c | 18 ++++-- Tools/build/generate_sbom.py | 28 +++++++++ 7 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2024-11-13-11-09-12.gh-issue-126623.TO7NnR.rst create mode 100755 Modules/expat/refresh.sh diff --git a/Misc/NEWS.d/next/Security/2024-11-13-11-09-12.gh-issue-126623.TO7NnR.rst b/Misc/NEWS.d/next/Security/2024-11-13-11-09-12.gh-issue-126623.TO7NnR.rst new file mode 100644 index 000000000000000..f09a158af2a475f --- /dev/null +++ b/Misc/NEWS.d/next/Security/2024-11-13-11-09-12.gh-issue-126623.TO7NnR.rst @@ -0,0 +1 @@ +Upgrade libexpat to 2.6.4 diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index cc73e93009b43fe..583ad84e18fd4a3 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -48,11 +48,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "6aaee1b194bea30f0a60d1cce71eada8b14d3526" + "checksumValue": "373cc00d87782a736970644d863ff2ebbd0e4886" }, { "algorithm": "SHA256", - "checksumValue": "7bd4e53a8015534b5bbb58afe1a131b3989d3d4fca29bca685c44d34bcaa2555" + "checksumValue": "0f750bc336e510d14ac9a3e63fc2399f60f3f04f0061c426e86751ed5fba90e4" } ], "fileName": "Modules/expat/expat.h" @@ -62,11 +62,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "b70ce53fdc25ae482681ae2f6623c3c8edc9c1b7" + "checksumValue": "9e615c6e5c3ba00670f674a6b071bb855b0b563d" }, { "algorithm": "SHA256", - "checksumValue": "86afb425ec9999eb4f1ec9ab2fb41c58c4aa5cb9bf934b8c94264670fc5a961d" + "checksumValue": "3d90a4b65c40a3f848c36100f4d73b933a015c7b7cd85c28e4331a6b845c1ad0" } ], "fileName": "Modules/expat/expat_external.h" @@ -128,18 +128,18 @@ "fileName": "Modules/expat/nametab.h" }, { - "SPDXID": "SPDXRef-FILE-Modules-expat-pyexpatns.h", + "SPDXID": "SPDXRef-FILE-Modules-expat-refresh.sh", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "f50c899172acd93fc539007bfb43315b83d407e4" + "checksumValue": "a9b0a33b8359cfe94b23972a1605daf8dcc605d9" }, { "algorithm": "SHA256", - "checksumValue": "d571b8258cfaa067a20adef553e5fcedd6671ca4a8841483496de031bd904567" + "checksumValue": "19eb541460bc2ca8b87118acd3c048f6af77affbf8719ac29aa7b6c8d70f83fd" } ], - "fileName": "Modules/expat/pyexpatns.h" + "fileName": "Modules/expat/refresh.sh" }, { "SPDXID": "SPDXRef-FILE-Modules-expat-siphash.h", @@ -188,11 +188,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "b2ec0ad170ccc21e63fbcfc8d7404cdd756eedd3" + "checksumValue": "3199fbd38b6fb158f73d5c8de6b6e6e3812ef803" }, { "algorithm": "SHA256", - "checksumValue": "92159d4e17393e56ee85f47d9fb31348695a58589899aa01e7536cdc88f60b85" + "checksumValue": "c1518244dd5ea397e345d00e12cc45d42f43453ed208218559c981c97a0583e2" } ], "fileName": "Modules/expat/xmlparse.c" @@ -1749,7 +1749,7 @@ "spdxElementId": "SPDXRef-PACKAGE-expat" }, { - "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-pyexpatns.h", + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-refresh.sh", "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-expat" }, diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index d0d6015a66283f4..523b37d8d5787d8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -130,7 +130,9 @@ enum XML_Error { /* Added in 2.3.0. */ XML_ERROR_NO_BUFFER, /* Added in 2.4.0. */ - XML_ERROR_AMPLIFICATION_LIMIT_BREACH + XML_ERROR_AMPLIFICATION_LIMIT_BREACH, + /* Added in 2.6.4. */ + XML_ERROR_NOT_STARTED, }; enum XML_Content_Type { @@ -1066,7 +1068,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 6 -#define XML_MICRO_VERSION 3 +#define XML_MICRO_VERSION 4 #ifdef __cplusplus } diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 12c560e14716ff0..567872b09836e1c 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -40,6 +40,10 @@ #ifndef Expat_External_INCLUDED #define Expat_External_INCLUDED 1 +/* Namespace external symbols to allow multiple libexpat version to + co-exist. */ +#include "pyexpatns.h" + /* External API definitions */ /* Expat tries very hard to make the API boundary very specifically @@ -64,11 +68,6 @@ compiled with the cdecl calling convention as the default since system headers may assume the cdecl convention. */ - -/* Namespace external symbols to allow multiple libexpat version to - co-exist. */ -#include "pyexpatns.h" - #ifndef XMLCALL # if defined(_MSC_VER) # define XMLCALL __cdecl diff --git a/Modules/expat/refresh.sh b/Modules/expat/refresh.sh new file mode 100755 index 000000000000000..82a9dbc23ad26b7 --- /dev/null +++ b/Modules/expat/refresh.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# Use this script to update libexpat + +set -e +set -o pipefail + +if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then + echo "A bash version >= 4 required. Got: $BASH_VERSION" >&2 + exit 1 +fi + +# Update this when updating to a new version after verifying that the changes +# the update brings in are good. These values are used for verifying the SBOM, too. +expected_libexpat_tag="R_2_6_4" +expected_libexpat_version="2.6.4" +expected_libexpat_sha256="fd03b7172b3bd7427a3e7a812063f74754f24542429b634e0db6511b53fb2278" + +expat_dir="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" +cd ${expat_dir} + +# Step 1: download and copy files +curl --location "https://github.com/libexpat/libexpat/releases/download/${expected_libexpat_tag}/expat-${expected_libexpat_version}.tar.gz" > libexpat.tar.gz +echo "${expected_libexpat_sha256} libexpat.tar.gz" | sha256sum --check + +# Step 2: Pull files from the libexpat distribution +declare -a lib_files +lib_files=( + ascii.h + asciitab.h + expat.h + expat_external.h + iasciitab.h + internal.h + latin1tab.h + nametab.h + siphash.h + utf8tab.h + winconfig.h + xmlparse.c + xmlrole.c + xmlrole.h + xmltok.c + xmltok.h + xmltok_impl.c + xmltok_impl.h + xmltok_ns.c +) +for f in "${lib_files[@]}"; do + tar xzvf libexpat.tar.gz "expat-${expected_libexpat_version}/lib/${f}" --strip-components 2 +done +rm libexpat.tar.gz + +# Step 3: Add the namespacing include to expat_external.h +sed -i 's/#define Expat_External_INCLUDED 1/&\n\n\/* Namespace external symbols to allow multiple libexpat version to\n co-exist. \*\/\n#include "pyexpatns.h"/' expat_external.h + +echo "Updated; verify all is okay using git diff and git status." diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index d9285b213b38bd4..a4e091e7c33c0ae 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+) +/* c5625880f4bf417c1463deee4eb92d86ff413f802048621c57e25fe483eb59e4 (2.6.4+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -40,6 +40,7 @@ Copyright (c) 2023 Owain Davies Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow Copyright (c) 2024 Berkay Eren Ürün + Copyright (c) 2024 Hanno Böck Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -2234,6 +2235,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { + case XML_INITIALIZED: + parser->m_errorCode = XML_ERROR_NOT_STARTED; + return XML_STATUS_ERROR; case XML_SUSPENDED: if (resumable) { parser->m_errorCode = XML_ERROR_SUSPENDED; @@ -2244,7 +2248,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; - default: + case XML_PARSING: if (resumable) { #ifdef XML_DTD if (parser->m_isParamEntity) { @@ -2255,6 +2259,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { parser->m_parsingStatus.parsing = XML_SUSPENDED; } else parser->m_parsingStatus.parsing = XML_FINISHED; + break; + default: + assert(0); } return XML_STATUS_OK; } @@ -2519,6 +2526,9 @@ XML_ErrorString(enum XML_Error code) { case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: return XML_L( "limit on input amplification factor (from DTD and entities) breached"); + /* Added in 2.6.4. */ + case XML_ERROR_NOT_STARTED: + return XML_L("parser not started"); } return NULL; } @@ -7856,7 +7866,7 @@ accountingReportDiff(XML_Parser rootParser, assert(! rootParser->m_parentParser); fprintf(stderr, - " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", + " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%u, xmlparse.c:%d) %*s\"", bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", levelsAwayFromRootParser, source_line, 10, ""); @@ -7969,7 +7979,7 @@ entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, fprintf( stderr, - "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", + "expat: Entities(%p): Count %9u, depth %2u/%2u %*s%s%s; %s length %d (xmlparse.c:%d)\n", (void *)rootParser, rootParser->m_entity_stats.countEverOpened, rootParser->m_entity_stats.currentDepth, rootParser->m_entity_stats.maximumDepthSeen, diff --git a/Tools/build/generate_sbom.py b/Tools/build/generate_sbom.py index 020f874cffeaef7..5c4a725102d79aa 100644 --- a/Tools/build/generate_sbom.py +++ b/Tools/build/generate_sbom.py @@ -59,6 +59,8 @@ class PackageFiles(typing.NamedTuple): include=["Modules/expat/**"], exclude=[ "Modules/expat/expat_config.h", + "Modules/expat/pyexpatns.h", + "Modules/_hacl/refresh.sh", ] ), "macholib": PackageFiles( @@ -218,6 +220,32 @@ def check_sbom_packages(sbom_data: dict[str, typing.Any]) -> None: "HACL* SBOM version doesn't match value in 'Modules/_hacl/refresh.sh'" ) + # libexpat specifies its expected rev in a refresh script. + if package["name"] == "libexpat": + libexpat_refresh_sh = (CPYTHON_ROOT_DIR / "Modules/expat/refresh.sh").read_text() + libexpat_expected_version_match = re.search( + r"expected_libexpat_version=\"([0-9]+\.[0-9]+\.[0-9]+)\"", + libexpat_refresh_sh + ) + libexpat_expected_sha256_match = re.search( + r"expected_libexpat_sha256=\"[a-f0-9]{40}\"", + libexpat_refresh_sh + ) + libexpat_expected_version = libexpat_expected_version_match and libexpat_expected_version_match.group(1) + libexpat_expected_sha256 = libexpat_expected_sha256_match and libexpat_expected_sha256_match.group(1) + + error_if( + libexpat_expected_version != version, + "libexpat SBOM version doesn't match value in 'Modules/expat/refresh.sh'" + ) + error_if( + package["checksums"] != [{ + "algorithm": "SHA256", + "checksumValue": libexpat_expected_sha256 + }], + "libexpat SBOM checksum doesn't match value in 'Modules/expat/refresh.sh'" + ) + # License must be on the approved list for SPDX. license_concluded = package["licenseConcluded"] error_if( From 12ca7e622ff21ba3b7c90c62be6f6f82d543f25b Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 13 Nov 2024 22:29:28 +0300 Subject: [PATCH 46/57] gh-109413: Enable `strict_optional` for `libregrtest/main.py` (#126394) --- Lib/test/libregrtest/cmdline.py | 4 +--- Lib/test/libregrtest/main.py | 19 +++++++++++++++++-- Lib/test/libregrtest/mypy.ini | 4 +--- Lib/test/libregrtest/run_workers.py | 2 ++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 8bef04cba811388..0c94fcc19070711 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -148,7 +148,7 @@ def __init__(self, **kwargs) -> None: self.randomize = False self.fromfile = None self.fail_env_changed = False - self.use_resources = None + self.use_resources: list[str] = [] self.trace = False self.coverdir = 'coverage' self.runleaks = False @@ -403,8 +403,6 @@ def _parse_args(args, **kwargs): raise TypeError('%r is an invalid keyword argument ' 'for this function' % k) setattr(ns, k, v) - if ns.use_resources is None: - ns.use_resources = [] parser = _create_parser() # Issue #14191: argparse doesn't support "intermixed" positional and diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 133eba8ffe8e698..49209b0cec756ec 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -123,7 +123,7 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False): self.python_cmd = None self.coverage: bool = ns.trace self.coverage_dir: StrPath | None = ns.coverdir - self.tmp_dir: StrPath | None = ns.tempdir + self._tmp_dir: StrPath | None = ns.tempdir # Randomize self.randomize: bool = ns.randomize @@ -159,6 +159,8 @@ def log(self, line: str = '') -> None: self.logger.log(line) def find_tests(self, tests: TestList | None = None) -> tuple[TestTuple, TestList | None]: + if tests is None: + tests = [] if self.single_test_run: self.next_single_filename = os.path.join(self.tmp_dir, 'pynexttest') try: @@ -454,6 +456,11 @@ def finalize_tests(self, coverage: trace.CoverageResults | None) -> None: self.results.write_junit(self.junit_filename) def display_summary(self) -> None: + if self.first_runtests is None: + raise ValueError( + "Should never call `display_summary()` before calling `_run_test()`" + ) + duration = time.perf_counter() - self.logger.start_time filtered = bool(self.match_tests) @@ -708,7 +715,15 @@ def _init(self): strip_py_suffix(self.cmdline_args) - self.tmp_dir = get_temp_dir(self.tmp_dir) + self._tmp_dir = get_temp_dir(self._tmp_dir) + + @property + def tmp_dir(self) -> StrPath: + if self._tmp_dir is None: + raise ValueError( + "Should never use `.tmp_dir` before calling `.main()`" + ) + return self._tmp_dir def main(self, tests: TestList | None = None) -> NoReturn: if self.want_add_python_opts: diff --git a/Lib/test/libregrtest/mypy.ini b/Lib/test/libregrtest/mypy.ini index 22c7c7a9acef148..da75a27158a6003 100644 --- a/Lib/test/libregrtest/mypy.ini +++ b/Lib/test/libregrtest/mypy.ini @@ -22,10 +22,8 @@ disallow_untyped_defs = False check_untyped_defs = False warn_return_any = False -disable_error_code = return - # Enable --strict-optional for these ASAP: -[mypy-Lib.test.libregrtest.main.*,Lib.test.libregrtest.run_workers.*] +[mypy-Lib.test.libregrtest.run_workers.*] strict_optional = False # Various internal modules that typeshed deliberately doesn't have stubs for: diff --git a/Lib/test/libregrtest/run_workers.py b/Lib/test/libregrtest/run_workers.py index 387ddf9614cf793..dcc817ae9aceb62 100644 --- a/Lib/test/libregrtest/run_workers.py +++ b/Lib/test/libregrtest/run_workers.py @@ -211,6 +211,7 @@ def _run_process(self, runtests: WorkerRunTests, output_fd: int, # on reading closed stdout raise ExitThread raise + return None except: self._kill() raise @@ -544,6 +545,7 @@ def _get_result(self) -> QueueOutput | None: running = get_running(self.workers) if running: self.log(running) + return None def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result From 35010b8cf2e6f5f2791fb336951c518e4f087a43 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 13 Nov 2024 22:50:46 +0200 Subject: [PATCH 47/57] gh-126390: Support for preserving order of options and nonoption arguments in gnu_getopt() (GH-126393) --- Doc/library/getopt.rst | 24 +++++++++++++++++++ Doc/whatsnew/3.14.rst | 3 +++ Lib/getopt.py | 18 ++++++++++---- Lib/test/test_getopt.py | 6 +++++ ...-11-04-13-16-18.gh-issue-126390.Cxvqa5.rst | 2 ++ 5 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-04-13-16-18.gh-issue-126390.Cxvqa5.rst diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index def0ea357bceb2a..891885d3afbf7a9 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -85,6 +85,16 @@ exception: variable :envvar:`!POSIXLY_CORRECT` is set, then option processing stops as soon as a non-option argument is encountered. + If the first character of the option string is ``'-'``, non-option arguments + that are followed by options are added to the list of option-and-value pairs + as a pair that has ``None`` as its first element and the list of non-option + arguments as its second element. + The second element of the :func:`!gnu_getopt` result is a list of + program arguments after the last option. + + .. versionchanged:: 3.14 + Support for returning intermixed options and non-option arguments in order. + .. exception:: GetoptError @@ -144,6 +154,20 @@ Optional arguments should be specified explicitly: >>> args ['a1', 'a2'] +The order of options and non-option arguments can be preserved: + +.. doctest:: + + >>> s = 'a1 -x a2 a3 a4 --long a5 a6' + >>> args = s.split() + >>> args + ['a1', '-x', 'a2', 'a3', 'a4', '--long', 'a5', 'a6'] + >>> optlist, args = getopt.gnu_getopt(args, '-x:', ['long=']) + >>> optlist + [(None, ['a1']), ('-x', 'a2'), (None, ['a3', 'a4']), ('--long', 'a5')] + >>> args + ['a6'] + In a script, typical usage is something like this: .. testcode:: diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 31754fb55fcf020..d38188f00547549 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -331,6 +331,9 @@ getopt * Add support for options with optional arguments. (Contributed by Serhiy Storchaka in :gh:`126374`.) +* Add support for returning intermixed options and non-option arguments in order. + (Contributed by Serhiy Storchaka in :gh:`126390`.) + http ---- diff --git a/Lib/getopt.py b/Lib/getopt.py index c12c08b29c79c4d..a9c452a601ee816 100644 --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -24,9 +24,6 @@ # TODO for gnu_getopt(): # # - GNU getopt_long_only mechanism -# - allow the caller to specify ordering -# - RETURN_IN_ORDER option -# - GNU extension with '-' as first character of option string # - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" @@ -63,7 +60,7 @@ def getopt(args, shortopts, longopts = []): long options which should be supported. The leading '--' characters should not be included in the option name. Options which require an argument should be followed by an equal sign - ('='). Options which acept an optional argument should be + ('='). Options which accept an optional argument should be followed by an equal sign and question mark ('=?'). The return value consists of two elements: the first is a list of @@ -116,8 +113,13 @@ def gnu_getopt(args, shortopts, longopts = []): else: longopts = list(longopts) + return_in_order = False + if shortopts.startswith('-'): + shortopts = shortopts[1:] + all_options_first = False + return_in_order = True # Allow options after non-option arguments? - if shortopts.startswith('+'): + elif shortopts.startswith('+'): shortopts = shortopts[1:] all_options_first = True elif os.environ.get("POSIXLY_CORRECT"): @@ -131,8 +133,14 @@ def gnu_getopt(args, shortopts, longopts = []): break if args[0][:2] == '--': + if return_in_order and prog_args: + opts.append((None, prog_args)) + prog_args = [] opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) elif args[0][:1] == '-' and args[0] != '-': + if return_in_order and prog_args: + opts.append((None, prog_args)) + prog_args = [] opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) else: if all_options_first: diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 0675bcbb4e8247d..ed967ad27619ae3 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -173,6 +173,12 @@ def test_gnu_getopt(self): self.assertEqual(args, ['-']) self.assertEqual(opts, [('-a', ''), ('-b', '-')]) + # Return positional arguments intermixed with options. + opts, args = getopt.gnu_getopt(cmdline, '-ab:', ['alpha', 'beta=']) + self.assertEqual(args, ['arg2']) + self.assertEqual(opts, [('-a', ''), (None, ['arg1']), ('-b', '1'), ('--alpha', ''), + ('--beta', '2'), ('--beta', '3')]) + # Posix style via + opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta=']) self.assertEqual(opts, [('-a', '')]) diff --git a/Misc/NEWS.d/next/Library/2024-11-04-13-16-18.gh-issue-126390.Cxvqa5.rst b/Misc/NEWS.d/next/Library/2024-11-04-13-16-18.gh-issue-126390.Cxvqa5.rst new file mode 100644 index 000000000000000..3b32bb512f65566 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-04-13-16-18.gh-issue-126390.Cxvqa5.rst @@ -0,0 +1,2 @@ +Add support for returning intermixed options and non-option arguments in +order in :func:`getopt.gnu_getopt`. From 142104ce78a8717f99eb42ce030eb29775dd550c Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 13 Nov 2024 21:57:33 +0100 Subject: [PATCH 48/57] gh-89640: Pull in update to float word order detection in autoconf-archive (#126747) --- .github/workflows/build.yml | 2 +- Tools/build/regen-configure.sh | 2 +- aclocal.m4 | 96 ++++++++++++-- configure | 226 ++++++++++++++++----------------- configure.ac | 3 - 5 files changed, 195 insertions(+), 134 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b769bba72816d68..c854c13e12f9226 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: # reproducible: to get the same tools versions (autoconf, aclocal, ...) runs-on: ubuntu-24.04 container: - image: ghcr.io/python/autoconf:2024.10.16.11360930377 + image: ghcr.io/python/autoconf:2024.11.11.11786316759 timeout-minutes: 60 needs: check_source if: needs.check_source.outputs.run_tests == 'true' diff --git a/Tools/build/regen-configure.sh b/Tools/build/regen-configure.sh index e1ecefddeb87320..d2a613b1e40dc11 100755 --- a/Tools/build/regen-configure.sh +++ b/Tools/build/regen-configure.sh @@ -5,7 +5,7 @@ set -e -x # The check_autoconf_regen job of .github/workflows/build.yml must kept in # sync with this script. Use the same container image than the job so the job # doesn't need to run autoreconf in a container. -IMAGE="ghcr.io/python/autoconf:2024.10.16.11360930377" +IMAGE="ghcr.io/python/autoconf:2024.11.11.11786316759" AUTORECONF="autoreconf -ivf -Werror" WORK_DIR="/src" diff --git a/aclocal.m4 b/aclocal.m4 index b082a5b1bc5e074..920c2b38560faa0 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -91,7 +91,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 12 +#serial 14 AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], [AC_CACHE_CHECK(whether float word ordering is bigendian, @@ -112,10 +112,10 @@ int main (int argc, char *argv[]) ]])], [ -if grep noonsees conftest$EXEEXT >/dev/null ; then +if grep noonsees conftest* > /dev/null ; then ax_cv_c_float_words_bigendian=yes fi -if grep seesnoon conftest$EXEEXT >/dev/null ; then +if grep seesnoon conftest* >/dev/null ; then if test "$ax_cv_c_float_words_bigendian" = unknown; then ax_cv_c_float_words_bigendian=no else @@ -398,7 +398,7 @@ AC_DEFUN([AX_CHECK_OPENSSL], [ AC_SUBST([OPENSSL_LDFLAGS]) ]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . @@ -486,7 +486,7 @@ dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -dnl only at the first occurence in configure.ac, so if the first place +dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], @@ -555,14 +555,14 @@ if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - m4_default([$4], [AC_MSG_ERROR( + m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS @@ -574,7 +574,7 @@ _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( + m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -584,10 +584,10 @@ _PKG_TEXT To get pkg-config, see .])[]dnl ]) else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) - $3 + $3 fi[]dnl ])dnl PKG_CHECK_MODULES @@ -674,6 +674,74 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. diff --git a/configure b/configure index 7a9d9627e50dfcf..b1ced3106618ba6 100755 --- a/configure +++ b/configure @@ -13717,12 +13717,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBUUID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid >= 2.20" 2>&1` else - LIBUUID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid >= 2.20" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBUUID_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBUUID_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -13974,11 +13974,11 @@ LIBS=$save_LIBS else - LIBUUID_CFLAGS=$pkg_cv_LIBUUID_CFLAGS - LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + LIBUUID_CFLAGS=$pkg_cv_LIBUUID_CFLAGS + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_uuid=yes + have_uuid=yes printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h @@ -14666,12 +14666,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBFFI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libffi" 2>&1` + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libffi" 2>&1` else - LIBFFI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libffi" 2>&1` + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libffi" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBFFI_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBFFI_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -14817,11 +14817,11 @@ LIBS=$save_LIBS else - LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS - LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS + LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS + LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_libffi=yes + have_libffi=yes fi fi @@ -15143,25 +15143,25 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` + LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` else - LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` + LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBMPDEC_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBMPDEC_PKG_ERRORS" >&5 - LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} LIBMPDEC_LIBS=${LIBMPDEC_LIBS-"-lmpdec -lm"} LIBMPDEC_INTERNAL= elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} LIBMPDEC_LIBS=${LIBMPDEC_LIBS-"-lmpdec -lm"} LIBMPDEC_INTERNAL= else - LIBMPDEC_CFLAGS=$pkg_cv_LIBMPDEC_CFLAGS - LIBMPDEC_LIBS=$pkg_cv_LIBMPDEC_LIBS + LIBMPDEC_CFLAGS=$pkg_cv_LIBMPDEC_CFLAGS + LIBMPDEC_LIBS=$pkg_cv_LIBMPDEC_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -15412,12 +15412,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` + LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` else - LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` + LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBSQLITE3_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBSQLITE3_PKG_ERRORS" >&5 LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} @@ -15433,8 +15433,8 @@ printf "%s\n" "no" >&6; } else - LIBSQLITE3_CFLAGS=$pkg_cv_LIBSQLITE3_CFLAGS - LIBSQLITE3_LIBS=$pkg_cv_LIBSQLITE3_LIBS + LIBSQLITE3_CFLAGS=$pkg_cv_LIBSQLITE3_CFLAGS + LIBSQLITE3_LIBS=$pkg_cv_LIBSQLITE3_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -16176,24 +16176,24 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - TCLTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$_QUERY" 2>&1` + TCLTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$_QUERY" 2>&1` else - TCLTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$_QUERY" 2>&1` + TCLTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$_QUERY" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$TCLTK_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$TCLTK_PKG_ERRORS" >&5 - found_tcltk=no + found_tcltk=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - found_tcltk=no + found_tcltk=no else - TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS - TCLTK_LIBS=$pkg_cv_TCLTK_LIBS + TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS + TCLTK_LIBS=$pkg_cv_TCLTK_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - found_tcltk=yes + found_tcltk=yes fi fi @@ -16273,14 +16273,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` else - X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$X11_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (x11) were not met: + as_fn_error $? "Package requirements (x11) were not met: $X11_PKG_ERRORS @@ -16293,7 +16293,7 @@ See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -16306,8 +16306,8 @@ See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else - X11_CFLAGS=$pkg_cv_X11_CFLAGS - X11_LIBS=$pkg_cv_X11_LIBS + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -20712,12 +20712,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` else - ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$ZLIB_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$ZLIB_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -20975,8 +20975,8 @@ LIBS=$save_LIBS else - ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS - ZLIB_LIBS=$pkg_cv_ZLIB_LIBS + ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS + ZLIB_LIBS=$pkg_cv_ZLIB_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -21060,12 +21060,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` else - BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$BZIP2_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$BZIP2_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -21229,11 +21229,11 @@ LIBS=$save_LIBS else - BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS - BZIP2_LIBS=$pkg_cv_BZIP2_LIBS + BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS + BZIP2_LIBS=$pkg_cv_BZIP2_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_bzip2=yes + have_bzip2=yes fi @@ -21288,12 +21288,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` else - LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBLZMA_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBLZMA_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -21457,11 +21457,11 @@ LIBS=$save_LIBS else - LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS - LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS + LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS + LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_liblzma=yes + have_liblzma=yes fi @@ -24174,10 +24174,10 @@ if ac_fn_c_try_link "$LINENO" then : -if grep noonsees conftest$EXEEXT >/dev/null ; then +if grep noonsees conftest* > /dev/null ; then ax_cv_c_float_words_bigendian=yes fi -if grep seesnoon conftest$EXEEXT >/dev/null ; then +if grep seesnoon conftest* >/dev/null ; then if test "$ax_cv_c_float_words_bigendian" = unknown; then ax_cv_c_float_words_bigendian=no else @@ -24213,10 +24213,6 @@ printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h # but if it's not big or little, then it must be this? printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h - ;; #( - wasm*) : - -printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h ;; #( *) : as_fn_error $? "Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system." "$LINENO" 5 ;; @@ -25296,12 +25292,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "readline" 2>&1` + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "readline" 2>&1` else - LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "readline" 2>&1` + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "readline" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBREADLINE_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBREADLINE_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -25459,8 +25455,8 @@ LIBS=$save_LIBS else - LIBREADLINE_CFLAGS=$pkg_cv_LIBREADLINE_CFLAGS - LIBREADLINE_LIBS=$pkg_cv_LIBREADLINE_LIBS + LIBREADLINE_CFLAGS=$pkg_cv_LIBREADLINE_CFLAGS + LIBREADLINE_LIBS=$pkg_cv_LIBREADLINE_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -25527,12 +25523,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1` + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1` else - LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1` + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$LIBEDIT_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$LIBEDIT_PKG_ERRORS" >&5 save_CFLAGS=$CFLAGS @@ -25694,8 +25690,8 @@ LIBS=$save_LIBS else - LIBEDIT_CFLAGS=$pkg_cv_LIBEDIT_CFLAGS - LIBEDIT_LIBS=$pkg_cv_LIBEDIT_LIBS + LIBEDIT_CFLAGS=$pkg_cv_LIBEDIT_CFLAGS + LIBEDIT_LIBS=$pkg_cv_LIBEDIT_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -26556,21 +26552,21 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` else - CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$CURSES_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 - have_curses=no + have_curses=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - have_curses=no + have_curses=no else - CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS - CURSES_LIBS=$pkg_cv_CURSES_LIBS + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -26629,21 +26625,21 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` else - PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$PANEL_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 - have_panel=no + have_panel=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - have_panel=no + have_panel=no else - PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS - PANEL_LIBS=$pkg_cv_PANEL_LIBS + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -26710,21 +26706,21 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` else - CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$CURSES_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 - have_curses=no + have_curses=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - have_curses=no + have_curses=no else - CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS - CURSES_LIBS=$pkg_cv_CURSES_LIBS + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -26783,21 +26779,21 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` else - PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$PANEL_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 - have_panel=no + have_panel=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - have_panel=no + have_panel=no else - PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS - PANEL_LIBS=$pkg_cv_PANEL_LIBS + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } diff --git a/configure.ac b/configure.ac index bc3d2d0e63b77ae..3a55cbc13203933 100644 --- a/configure.ac +++ b/configure.ac @@ -5918,9 +5918,6 @@ AX_C_FLOAT_WORDS_BIGENDIAN( AC_DEFINE([DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754], [1], [Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM mixed-endian order (byte order 45670123)])], - [wasm*], [AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1], - [Define if C doubles are 64-bit IEEE 754 binary format, - stored with the least significant byte first])], [AC_MSG_ERROR([m4_normalize([ Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) From f6b0361c17552197f44be16435e4a5cb4b1d60ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Wed, 13 Nov 2024 21:58:57 +0100 Subject: [PATCH 49/57] gh-126188: Update bundled pip to 24.3.1 (gh-126805) Update bundled pip to 24.3.1 --- Lib/ensurepip/__init__.py | 2 +- ...ne-any.whl => pip-24.3.1-py3-none-any.whl} | Bin 1815170 -> 1822182 bytes ...-11-13-20-03-18.gh-issue-126188.RJLKk-.rst | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) rename Lib/ensurepip/_bundled/{pip-24.2-py3-none-any.whl => pip-24.3.1-py3-none-any.whl} (84%) create mode 100644 Misc/NEWS.d/next/Library/2024-11-13-20-03-18.gh-issue-126188.RJLKk-.rst diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 585afc85836c065..645ad998129348e 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] -_PIP_VERSION = "24.2" +_PIP_VERSION = "24.3.1" # Directory of system wheel packages. Some Linux distribution packaging # policies recommend against bundling dependencies. For example, Fedora diff --git a/Lib/ensurepip/_bundled/pip-24.2-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-24.3.1-py3-none-any.whl similarity index 84% rename from Lib/ensurepip/_bundled/pip-24.2-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-24.3.1-py3-none-any.whl index 542cdd1e7284ae5318664cd6a0f43fe9458d1d6c..5f1d35be6dd56b0e9f5ff0b6f555d43cd1853dda 100644 GIT binary patch delta 242128 zcmZ6yQ*lP;(AdGz(H#yV z*eUvWtB@#s)va`)?n|6Zf9G~a!-r^EQwn*P&{G|-G5$$_b!2h1Z+C2m$DyRn0M8;Y zn2Iny@*9KCVfPwi%+{DlJ}9|Bq{}?dqTx9stmyP7Z-42IADzH5+H~sCJYmZvjC`d?_PR6JwXxx(yvJhh67Nl;F!^$+rtC7 zC*9{!ES4ANS`i&Qw-x3&huj-WK^P4T3oT`|X`Y2;*BO&=YYp@@0W+Z|-qGUDRyK1D z4LzNM%%9q_!23$+4L@zWsZu(f?QelcC3>LMjrcm9N1;Gn6@zT<-gJ_60Bxdc|2?Pp zGEK(Q;;sLaL^1Zx@3m4~tgDkmGqBr*M;`Cb!M8_228LdwHSs^<9rWH~+aQv}oiW`wjEI#k8-b3@~an%?yLG0`onKn#oUcm7$>d zOH1L8K<^iWHV&Ae?|F8r_CX5Pf@q}e3BFKciu5(Pf^mF_-_K_viggJON;M|vV=(TJdMy0eRpVr!kZHO-7Hv@U^z_#Ll=+Sl{~ zWOKXuajeT7o5+rBsHu*ng{oAe=nL8#B_ENtbB{R`em%90^8#Mb&uhL?>VcFPD0o|C ztF9O1+&8?=Z>dcQj^*kdh0LqNt1}&xuzd+vXH;&|VvwxDhAqdf*58#xpTWh@$_I|A zSqI-*P^Tb8Zy1Yk_K@aI$x@>Zo;|t(ynVVN!Waq?UFLET1h|u|MJd!}RXDH*wIxs) z31U5bi#WR&dM3m?S%WdduZ+F*^(&x<|8hOz>r+T{-F?)=1Bo2D1RYLo!JMW`C7SR- zHr6SKu*y9;tU98;CT@-muJ9E%uB)@}O}kS#=BsqAIa$-3lvNrnMrBAMb5Jk<-nf}1 zP{I@t_4}6Q=+FcQz>6ZDXoUv-z8r&ZE8Hu(6tbrrW}hx<-Ov&R-SD8_03o6fhHQCg z#2EYBrKKHt@1LPsuaSwjRxWHt0VPBpCDK5qw(1R)?}yi-@LCVDwpUy}_1y8VhIq&Y zClhYnPe>cC1;F%7oa0ZRK9K7J-vjNR%jI-aSe=kr9EYMUGegLQ+=jWA{f>69qU=-~ zPQT;)-q|aOAGhHKM74gQbu#uH@W^0sh`>eC%gLs-keR}DEycZ*SKQD(42cGAcS{n7 z6yvu`9@O;MDUThl809?0sR_qWgJyvw*3(0U1JWThT#lbd1f6iQlQ*h?rqIN$bjGGx zucq|W;G<>oWYeX{GIPNqth4r{z;jZ;r34L_wX7#w7Q*p)8q4q|k+9uX2D(5r+WGuR zw-}WIXcZ~a@}cZ0N>=IOnMqns>i3LjO$C!UL%%MsX9{h@FKATi3;GVNLaIqk&O%m{ zd_~yE2^un$O3X(es=vfQxt;>)ke`h)@ip;v%wGgDWrE` zmwRXyD=2D6AqDY>FkfCP*!a5;Dt$#Z_etZt&%AwCNc8-uc ztPG(?Y*pVeL-k<+X&98o&;f+Wl9#1|PGNFK=zQu5`37~ZMxsub=H7u$k^1F z#Lq0bRaN33>>fIWxoG+Y1B$52S1zo9rQkvVDa~FNP-s}Zg#zmwkD*>V(=H0$v{SCW zMJ}oBT0YfPI|~Sp1RUy(8jq9*(NCcKqK?=M$Ub221di)u2+!8zmJNXf_nM}27VuP z{@;817W^?NLjn8Nb&zO++341ii5-(@P-9L`l~4FYbJ^^5l}0(#RN*)gS{&wczkOMBjEZjfx(B6yn$dr(mfxu%YfMt3PN5R^HUoi8MxBVIo&s14E*;yJWE*k>qBnYt>9Y z%7>G9RFt03A5jzzxQ+Pg!DgPU)yKf_$+@;onAUEqRxvWyttr-M=|{rVd-K9nX?mnVh$q_?del$~g+Ln6)1Wv`urJ~qtYn`&m z(T1I{_r|g2OQ%Q-WAhE0c{uxv+CdxdpYN(qJJ1PnM87?cy zDYIWB^5hM3z}oHS^oNlA*{NwMU@Au$ug!E(d{A((uBP}4aj03`V^`_tk*NJ6-<+4d z5i~*h&9^nF>_Xf-VKpg+=YdD&Mi-CqXhm9m&)N73Kq=)!%(PBrD53Dt;- zIG(czQAMh-Zf^OCuX*_2K2$S65_bg5OxbK|3uwhL(GX4o9vN}9j#!~PoN(N57Gnm> zD?bFvF4%Xcjkkza-FJmJ%oZZ6vV@0EU^DIYV!@9JFgmOJm_>ZIme7I6Y5OB<7K}LN z*X34MUzL@zjPK=6{IAab#NGo*gEx?Ohc;cmM*qhhlCCY{F zm8G%{Rz07}$q9I4XqoH+!3dZcjlv>v%|!Am9ywgIM#Xt#6!(#SeKZ@MJ*wRJg5`uX z3HL%}G)erYcL+OX7xiAsfe%a)zBlWMkPhC@4is%TswTfd@Ui_lU5(RxrTa;`Tzjlt z(Ul8nN|}_9v_2+_tYIb~PZ0@yur4D_Kp@D&)5Vm9&az5i8ZtV~6zI1_d*<=O93l#R zyp=k5W!(l3(dMcIXN|6&tB7DJJ82_m`bUTxc5r}Zkm(F70kNK#lYtZ$M_M+@O;1{N zXe&kzI5`E^2lgTkn~0K7Ty3oD`WzK8%kneKF=nOOPYrOu$&@j0Kx;VkDQCtQFgE73 zwhzDRCE;pmNhj-Ctms$ON0FMYXQ)R>=wM*b@A*pznKM zEATbliBcp$b0MRtezkDuIUcWmbFSzQ;p8VdPR6MG31m z&fic6kS3?zW5fZwb$0{}mNlnd5a$Vzz(1=GWy|^sI|@1jBI2^qQ%*5auROc{dg_bp z1KmI31dhNz;+NxGu*do^Xg}gJcLuHq-&cv|MO?6K84=~B-~am3i_w1=-5LIGXe3lR zg9!Hz^8``>0GR(5L0UVwnY%Q~VGzUrhmf3!;ZgnvA<+}4`_K>o0M3@l(JU0ek;Lyu zbkj?Hdh2ATOR}1j>%*w7KaUk%ggnw0WaJk_$XH1cLIM4Nc@{d2l51=i_gd#0C&whp z_OA?VcmXM8TuuEWweciyi=P%9K5srFxhL`h5-#c#-oM34%;+Y>6E*L}4N^@oBs}-@ z-XtY8qs1c42{g;m9R>9aB0X<_wPM;;;+fHA?Gw=|lTp6Z19tihNp=hbs2}L9m1aj! z(i#&aa0|Lt{wcL)C~5OQz|p=a1#8UI_Q%>YWDpp#2c#em(~W;cX(!2;@20_d7gv<$ z5;a9i-d3rQ78o5{(=~LV*XxbbVREw@zDeeu;NzdINqBR}9#_^WH8|x0Q~#P~QmEdO zO%*YvKGweCEnE2447lty(cAGhYe=#^f~V;pdso266^dt=kupQU*Z#ghdC(rOI~+Os z85*%bU;E`G0AtXV+x4<{x%EtX#}YY_$VH3d?#+zqh^oHd`$B{t`79>%@kAWVC<&kF z1Vo}5gUe%v0DB4jP)$V#x==UHPhZe=A}x^hlo?(HJ2ApR6gBaDk12NIN0aHi1n8!g zhIQ;ieB)&@b^(ZXARZEjL)FyRS)o9i;iEfk%!#BiLTTHJsFM~<(0jmME#(&p2w`4| zwxgAZ`Q_ht**^p-3^@b93X5q{k#t3t54(3q+hCi6j>bGZ8&N)hC3J&abfOFQol4{B zLJK6B8WEBDpGHO>f_zHk4zRMIZ)fv2(CzA&`$Kirg6T)NKRKX-==3Itun6$+`FVd* zFcdj){8_-td|y+hvm}vHbD}KWV~a4d0CT4^au8+y(vS`lbP(9B z!$iO1y^|1}f_ijHq`3k9V}wE0I2N9in&RZ)Qdd+6si-I8HY(`e%ykWhjD%!|OCnL! zvv}BwQg%nln~VB}6vQzV6J!lSlj%4k)+7AN6yfA5l8H@`_LfAmbc_LxN^t?3P$04E zrMKA8#W+epyx=x967&U{XiSnkVn)h2XrHkdHSj)$Kh4-dd%~SvG+waa4%Dfj>;=Be zFd&HC$aVP0ZmHyT)`1SJFk|s%Me^ttByt$1ZFDk~TBuD-acG#W5~eW#M5_|i$Jz8* zdNGf56Fy8NIAl>0y5daYGVVif6(crwtpWnM8PpLVC}0ek2q_=x_Le7=!DJUm#HRrr z%??ErFB~v$puQRG218}k9F*yYR|J`IV4YgrXV}_PkYcRU?X}MI5#vE^H&qND^y^2e zoF(b|#r@j_KGSKvR}K4ov*bO9!y~}}NpQOt=Zx_|#%N0xYr~xJO4~^Ry-ajRfka#) zVp}cHdS`o4o{bq#>Z(P-l&vfS;nm;y>V`&^lzHobYw0_ z`4Sv)DNiqtydjn+d#D79SWJ1Rp;}lDjmUF)I%O4Nm{3bz@4>|1(O}TS&Da;LwIDSP zZX%bv8&HzfD7rF3Ef=^>+U2O#f;NI9PkGkBV>Y`J(&+w-mpR|P>9Sn8#@IDI%CO{L zwd^-_c8udHR$Z+R;h0Z8jgd!GRwlizeMF-95@ARu@(^YO@P3^e7TdiJW!}gMvk0I& zR+m@xt86P>pUb!%yqIzmphiZdCX7ZMrk0(F9yn~!9gb~*D>gQx{MJ(kjV5qr_RY({ zwq^Ur+U+!)tB#VdrH%PQ!`9|rA6;FU)8!}5CWn^Cu$^V3UsMp-1Xc*$x>!%RR4?g` z&OVzQ9=6!KI^Cm)L+FpIFb>PBgE`liV6<}MVkp}>g*~26lRSyLP*YtO2!m@uXK5px zxNxREpGQ;mZ63MHauBs$m}E172&%$Bn1Ub2;WRQyL^Jd5s(<;=PO2WI#1ktP_?S%S zwZ_!8!!zBxo3@T8IQjKV(|MlET>E~u@FGk;<^9Pl+QwAQ%DpB;a^25=JqCWk)lqhR zJ@KVVy!U=S3VOI2v>~NX)pgc(-~6^;o&V}+{lQ$` zh?Lyb-n#2TFX3yxZv%(tE__Bkq1da9d7Ei0&<7XUf~#!dTC-Jzj@o-+H~XMV6CX-( zdiL}H^IIe>ND?wsfBull@+e?6mhtueW(W!mfO z^j8*fH2uw_cn%F)r?0eDQYSxIA)ovD$h~si-iyJ4?z+RZSo)9p4L>_zhYx=ZK_^sR zyxeVT+y@)XPQ4E9B4^mnqz}kPS$8BfK@5KOba-%9lEjTP7N%rxx(GQfGq|_Y|S^H5`lP+26;nzdGkGIO52y7|45bQrJ zA?(46hT~M3@e?S;EDcg+*Q#y`X?Sr3BzR zSL{DMVet8-r`P_aiMD2MZ7nu6!$Q(trNr}+;0rG%S!gEO11AM(KY%^pBM+Ah2M zfnUKAh@^F(giA67@+1ny71}_2BEsAb*BLPpt*^m^KUuV+GdY3Y^7~A?(uEwTYlZw{ zO`9TDeP!sj95!%Z%(?srtsKE_RHfyFE{P5xlM$J6;k4F=kwtqw8_YU))r3{{BzYSS zC!_aeryYMR)eYqYW?JrpH9(0-`a6kqP&l!tDr-?w@RQI2vo`P#h31@XCYLbh5gOvf zer-wz+0J|BZ&LM3XVu}8{PI48v+I!Eg7g1~c} znJkHXz-$2#BJW9Epz4_Pw?jxFbBj_uw;-G3EY#cfyeLWKjox8L613Y1>0}%`0Snwo z?A$P`N5^3txN2KD_Xqmmg7NPW+qe}uZ~Ehl*l(AxA+TyLRDx1>CPH*Xm<8ens69@) zB5guxBeZccZ_(>4fg=JYLt68al;lu;en00~W$Tj&e>ssft+|jl~Z5Uwved{;mYZ z@O+^br=)`e1VZW{S;ENiVw-=M81{A`stO1SwG#P@IZ&~R4(*h`nN1V`yz2iV6>=}K zP3c_%9INroM2A9p)Kk6=_DR-Er%;Y8CIu_sPQA9eF?&t;;knCiaqALa^!#>yju&`t z(N#!!CU%ZOx3oFu(e=!Aazp0JrwX;}?kcJi$F93TdNW6sSeZR-)BqEaFZc&v$|x(2 zA1m@4;&p#{@~I_GC3#)lM=k$M)EZNNch*J-C_3x&w(M)q425v%$+~ ztA`NX@e?!$lH%DsU->IKQ6Fw*&w1z8LOgcO4f6a2&BKpW8L7etA+IbcWqN%H`m)Wr zS63>tuuBY~TT$iwscna>b8NMU*iFE!4u_655#EE4tCT+2PRNDQbF3J0KJUGbH@Z*< zm@4|iD7H3i#d7k;)x9?EA~88st{ZPfm^HRMp03%(6*WcHQgajEov$f~ecnCQDO)PV zLrM4+38`)RjOT##dNEHWf4mFfh*CvbGqHs%Io?c(+f=W{tI*uC7QPUZu#vhv$^hau zY4v#6`bOZ=F!z-}1%O1!!8kl|f4Bb-s2XBRgNd%a5caM$T`}PD zPFr;dMDnwKg2akl)P)}qx`S=6n{ZoRTqeT4Q^}FIS*lqvqO85lRa}g#m=Jg4jwx4<5hF*y;>5j z0Y?m)WltAYn8Uqe5CM;t^}4&X5}S< z8Y~lP(A5vSLktWpQH)Rz3-w<$K7;R6rKoh&LfdOv0_%k6?13AQTOOfYS!sM0Tkl{QX+%gci9X#huIwps1}=!BZN)e5&ia4bw(zn|0U9TiHN7$g-c6 zbImY^_q2~l3s{`m=mS0t4XWZ(%UUQWYiqICG7L5V6=ZIjr7M6VjdD{h~2anhgAtFrAPQ>Y=byA6J3f0cAD~a+TPzcJ#CW)~} z??W{h$aHH~T{eN%8WzHUNkb!-l2RBZp6a!{>d*7gHh9QQaHri>6 zoM1ys_XGpk&3NSOsqw9bcG^sG=(S7sbYv&h<7zZTA_bIUZAZadDDSDpA^y%|3KCLs zL38tDz+AlXT;`@5IZjFwrz}I)Q{Ld&o1@XNYN1=^ov-7Rh~rM8{EE$1TXcn;(B|?A zq2CWV;&;L~r#IIM5OqZK;QAWQ+nlwGueB)5U&I5}hyVPQspCr4a1e8 z6`ks;o;?P|Ef#tLXJ5#d3UzO5@|S1qZOMnWWs-reiiN6G`9(>K654x*C6hE)j=Ivf z4{jbyMgj9T2yNJDWbSoZ(mML_^;JK(Nl#+~SuumL_%D5qJ-|a(of@LlsCHiluKX{0 z3k5Qem5FiAybUb*Yi!tXrFf9A!(&q$t^@{Z@JdzHaYRgP(GfWD0`=z@vT9l>UbRa$ zUIMzjSu^dgP{aKYNI$nyBQOS2n#wpy{ZBdFqQT*MK4Tx&x(Hv4yi>PlYT_)%d~J)N ze++sB6eSC9-T6Q)AOQe`zF;Ni=`J(%HDv=r^d~Trb7i2!>K7|7hWGJHA+J%@)gyxv z1*A5QVdEhVEUC4-G}Jc*8sB^kY;88HN1w?8N|!Kf$yCJ)aZ*$@u-2p(Gaep%2?p5H zt^0!H85C;c#5!eUZvP0?UKF`0FsPOO5^CL~envAcnUE^2T{N+kriTb-gF1ukrup_5m)dhYyjRYPfMD;;%wcY3+WnKS z>rcI`4pECIrZp@Gw^0sbmhVaQ3I#o^4~`tw`dzzCfE5ud8L{yv9zWE}ul(Wrgc9!v zE$C>g#LYomsJLn{oe<^>O6MwiN7Z>?!B~gxfpMaOOBPLv-a5wLTrq<-y+q8v!@G82 zIrb^ygw>b3f5a6s=3*p#=MxVtL4~Ao3h|XwxhX(aadx|WTUtCUP2)*moxy=t+G9~~ z7Dk@`E+-Ads+T5oYw1|o+=Wchw$v$z9WYgH{6Quex)DQE6l^sFLH$jVuSf%!T;VB~ zG(R2DmpNS@j`K#!WkL0DDA;`dOwZWM^Z zYY<%>lWhptIbR}Jq#vZ;srm}gqh1R1r^G7_vx3)+))cD*yN*Z7(ZQTgBOOaT&lDc| zTO_O(MUF;@;s7};1}sv*hw4N0&9o3^a3H2vLaPqBGZM6x>I$8&!VzkpEXIUc??Nnm zcstz{vr^tA8oKIsL|Xy=KKo7#QuGd|ZUX$6HD%V-oyEm#_6_cX3ECgv#d_LA*?4Br zbguIOZyd{OK7NnC{r))uaDJIdDpy$zOI>FR`sg+bNJF>v6uZ+^B48Ms`@?(C&hw8 z3c=|_AhN(f!;c0f%LK|mut3S0o{1nWHBn5`b8-##H|KoBw$It@G9PyrBnK{1`_Rh$ ziUd1YL(NYFnv-NmK?~qASANU& z0-eDPNNe>#&N5BsnF{b6xr>E7M5XckUZf=B$u@D+C?Ivi{Xv6449-Ydt036b4olJ7 z`%ABj*YExqsefa^(@3lbp5n)k8%8U;nfEj3EAwvJ%>!yXPP;{&S32D?EH`WmCin`4 zrz7UFpbB(*E{kqbtE8r&CpYaht`!P$p5*mdAd1&seynby0}}yYId3v<;-|~?o<+wv z${o&XKD92AW*RW~|iPpdzQ zfos=FzO!l%ZTzzxs@Qu5I-z)Mgz+#5(ry{(pI^cEozuvJ+rInQCLb@=17!L`k;%WN z=5i5ienI^@2Fa^#OSY|}Pn?<3uN-=HaC(}G-n}~fn`8o&g7f3#hH=K<(ZR;Z4cLR6 z!4%)0ZILM=IZ*dd?W}_~Bpx}(sw%^%-M>ag>I$DrmT{pP(JR})1ypjQXiq>ai<+H= zK~$-mumfE!wc7) z;H9mha10Bf1t2L>gm_}f-$ISGfrP6IfZKsiyl5$r#Br!oQ8AiiA4)Y{%xd1>bRG&1 z*}maI&3py3NnG^ajkl2l8f!`!Q}5O7{3A)}i*S)HRkLq#8rFCV z&TXRujivJ#h7)b#6@)Hk0%U})G};iL@1g6^$=AaNAmbkew51QD;=fc4gj!ztsa(sT zG~f~EoLq6?-1@s_Cfnm0Ig5+@pqCu1uvxGiGgIB3Ua4NF>Pwh$N<85W)#4jZVC%wU zEp*#5n@fQ`>%jNb&_1UzR0>Kd8YEMqG8&HD{xog!to_v z`D)Ncm%@ z-)f2oU5>PGQ1)%a42wb;Z6ai(_OD6)dy}ufL)i@%zL#En3`>$7umz}*oB296AjoXU z`*O=17w2+!i?**;ySBE#%7%TqdQ5svuI7@jGc0F;tSaC$bNjTSX zlKYb)1k>1&wk+H#!EIwCj(N-{UT3wPU(>w>oK%7bVNGBOIHL8(#hKar?rWc15)|3_ z@d%Tb>qg1cV~(p=&GDMkg+Rh~Q=hEBP3n3)iwe+&2g`{?YMTsW^K{3z zcBJw}FJ}EoQ*Nf`F5dQt_RAJ$EF4@;=VuOe?9VUUAM^|TO$;lv&&Yf8r zLfe$%0|ax$&xzdCXLUVkf17Gs_^VzZXvpB(J(!=gfgt$My83Lce%3d81DTpD{;fBR z8*LH!WW~Y$Jub&TIK%M=E)qe~&Bsm2fRZ{|rN>Bf3)N22_oiYB+jo?a9|9@LA zk}^8%e_A!AE+pK47PCdnfBJQDzf0bKE;CmP=>M!~pMKc?k+j8Bj~!Gi%uVj{I)p^Zpqfo|7V5M>5p z?@|ks&5>1e83}6dJ=m3mghlDlXSQ&Rj+LG3FWaIrx;R0EKh!TfRrdQvE=jw6I@c+a+B!i3)JO@rB!0stxcd!g~_1tc{O_eaypV!a6y%16Mr6Xbhua^ zbyZb8bu>JTIjDOt7W-A`;df>Ntcw3Z_33oA-zxZV4fRBKZy7v@S5~ktif;u^eH6!g zh64NniR*)59dVGqDb_2QBK0=G9Fu9lKY)$`tGp?3j~CY4+R`oD_-!u+GtWKaNkU5| zPg{WKKGUI3pdi8sOJtoQZCk7>@ItUH8(-{NyZruLqkA3y z(~t^#ocnaS`^H)I=5VJzFX6e3@yH1jed_hRya1{PYFjN@3rwzvi9XG|!3kthoBvZugt+m0cz~;cqhJV2}H%giJ^6 ziPs*d9DYCrhfDM%4VFcmW`gAeuMUp_?_tUAY_Ea@$mq-Kk&--1_f%K+&CY@qa-=e< zfzh@+$0xKPY)V%*IA+9QfYRJu0XC4o_aHq>X0B*fqfD}SOCBxapi0qNb3JNdtiwYJ zDts$Iozt>7cUW1J;$Bq0H#;u9@LT`>PQ1Mvr7+DhC0V;|u^{4bCfcFxsx|P;n+y>V zZK}T<@dig{t3X&zSK`s~I=Z*$q5JHTu`_xI0V7dShrPL1AjDRT#eEcOhZ2~}B)_1G z`xAHf2D4i?)OzQ5cCMw_M%II;SQm=$R39Niq}G&eUAkIomWFbfdcZd#Ad-(>9ofh8 z#GP0{PsxKJZxbYT=6KVJD|_z^ZAX&bo-^hpv{NsNB-YnCk@|9ZH_>_Dzhy|M`G7G= zry*VAT1N(D)M$jE%T(~*QV&?Aj5BRK!L>YFfY3lmb9dhtm*v`;um?TM{?74R6?}_n zPLb^tYq^j^vv9e8s|VpY?szSjjU-ZvV8}<_ohUz0mfK<-(K%lns?V^EZoJX00z6ds zeUlAK03<9qboN*RgL>{g(GREI2PH>I^O5be~hCtKy*P<9LMr;kcSu&j3}8U&(4`-;v5)Yk6r7sCIY zRU7r|Bq07vcBRdEkSPD>C&aI7z3GjAT|v?`003^XvnxhA5(_R&vU^tr5NV$^Vzrg~ zwG5(EUcn!~BP<6?0skf{Y0!?pi>4y%hl(=$SOY41vO^dn;n&^XL9akctswC0g_}pI zNw){r$VM#=|8X9e5#Cz+Zt%dYP)4YY*H(p>mAllWLXN-KGX!!pJ4jM|p4x_7$jvRB z6HK4Wee{F(_x6RQwRXz`uy2Bemz%pBhlc!hk+mcaXes|J@c>m}w7#fa?zOTE4_+R; zvUVQQ2ch9F%!4edWMjVmdGQOvmE)$i?F1Jj{4=98$2_VGzptt^OYypv%;f|DoY&yD+47 z07hl5?M8gpq};`!P;c5;vzuNrg4Nv#C7ejjBj{vhF8*%%Z=VjL&g16w3(t|6Ib?FH z!@mB8lEZIv>lXh8;*-Of11%@JIw6giiaD9gheY{xRvZR-@U&fkk*&45H9-wUH?HSO z6!?U6d^aLgP*D^MaC&a@C)$oMXZ4-{ii=BI;pbDn1{L%v1#$1@rhwuDV7%kbSpjv* znVR)2;oW{9Q)vt(9E=|d5}gDVFF(+W(&Pd)1tV#;g#zj~)fiE9a^e(hIKD(?E6Lf~>k}QN<;jTzvE^F!PMaDpu%tONm4c;H15jTX5QD7C zk`x%UoF(mhy{w(0W55=hjeabF(R87uTPmyLG)Omskp3ZLL3)<0IjBRHgzc@6EAeuR z*@BoV;7*V*yj*fho_vI14+;G%0j8MQLM|i(c{j>QTBpEm0$M5uJD1z$xv!Xtv&U+P zU1BfCw#9=U7{jglXBgp67sl#~Owzt*e>DLnahGKiB(SdD_Qs8fE{9Of1ZIpi0u@b- z1xB4^nkRh_;WLt~a%bI)c%0}gPMiDThPU|k^Uj?%JQtb;uP|uhFiC-l%6bfiiI^`PqzpAd0=rwsCQTS`4f^Xc$Sp$XK2chs5aM zp&glANV7-ggBnz{h*JsX-Odry)(NZXM94d95)`5~%%BdE{R#EnT=x$dk#VfqGyG5X zag;b-Ah`-2R=GI4#X5ft8Yi;??g?yNqISoV90dHwks#dUHqjsh1RCX9@bTvU6VG(n zr@TkgTfw*w>#MKH0Y7(#4cxSe-X%fWj)z$McKZSUN6UC@%Q!vwUFphg-7L(S`c5}Ss@vb)k;2M}8?ws-kPtnoS75*7Q_GrwY-?Ea( z#Ns&oT-8^^J{$Q%}%oNF$Da(8$@Q_RRhEX43wRfxAM3;w6CX9#=bdvJ$6Lpp$ z1r{ZrUy44Hnjt1s;4Isyf4bI3s_NFUZ`{}~Bhr=@KxSjq5B0N%*Tw>=XTk;%9tjOyM^tWqg4d@-!Ej7@w`YBC>`LR zG-(tB-=IswJ%}ThI(N>pSO`VpVT)@5ijT>C3lkf;b7f&9U%~4T%e?-5^=nvd<4X%^qh3s>Y5idmudhDxR?VyMt(pgzSVvLf|(Fj5=VGcj|E zU*sAL9?FG@a)x7M4iH%cOPfAnNzg%Ynr}rm$ zUMFN5PYY|XHXlt+k4uPZdusv|wp8~OOSbKLTF00Gxi=3XM%??#$Wa{IceJYs`mY8r zLdtN*g+a^iR8CzJ9<)@xI@)dnlHe$yx^sOEuB7|c+>V*|?o|dr+_tLNWyOvOARdw%oTh%XsDZ_HdF2H&Ha5N9C5#08U6D)xL$@IAN5FtAUGe~< zSMWN2oR4NT)`e*(YvJTSfMTjo)eS!@{sgvs$VX~2Vu6W=n7Np`JRIns2YbU$}l zNLXx+C+U+iSS24OCks6`1Vw0*Z!>tx2o&%h9NR3QI6x_F-(O(@Eg;-@wZIJ#o;e1m99wwwuv&1L<_%z3v`pop_Smw! z3Amk0Oom;Ts;!ZI&360WBB%UO> z_G+t#Y!*$a)ph3qG$OXCmvfsvuQoY6lOf5-<(oRTsSA+}ro%w<>R;cs*F$rFy_tM& z0=hz;#wm||Sj=#`!`zIXNm&7B&Ua8@rA0?0VA}M?l>Zz`{DdLWKsh{MIN}xH>4^Kh zRjzvl-bL|%g^qkGeSs+FSiVEUTdhpF8oDC(JUpFPz3GxDNg&Jg&_mKF+GpNZJ4 z>DO}R2Byj%SXk_Ic>B<=a=uv)*ia_X_i`d?YkF)qw&=Z*qr1LC-B+JPis|W@nf%Eb zs^v3dx`RX@g&J84uwn*>$vM=@FzuQ`z;^YM86-Im#Q$0ai-XS(4?Di79u?7)g z46{XstTtL71pKO9`r_6^>0WFlsoA?z7#ZT?bZ!seZ@8cldj%4qtOfA}fR5tq5}9Q) z)mWo2V^&1<$RS#9AQ`32P3lpmAEl%|#d@;_C29a#mYhR{ohTkVL?hEJ%jy%McxuPH zN;X&ngg4C##zOe_yP68vFC!cgyzG;4GxnG1(+UAyEmARoRZT{&8ORj^30n$ ztmvGN=Fdm4{eFsxsb^$Db}+4cij;hRg&T`}4vjKA4m*y?$>DyuLl6`uA6{>Fxyl6E znP$6?G?jsO+cw?POhb-2ab>vi(7VOT#^P*7AX`HSu;)@>=c2`lOTy@;tIpVjErIsE z%^BHmg`g@<_5(1M%J^czh;lSDtCqCd7C+{%*WnKnQGL9I;=Xy})5~~dzfLr|hw4{1Ne$h3CqF7c= zI|1>;H}nPm?52eh)6q9=X)wjyVVT5tIJSLjlP`i#K0};;2MqhMb6+r>_hh`A9a6!S z+pztVLU%>#qwV|F$UFT;`rjzT5r!VI5)1$+f=x~=!%FrV#|2`6=W|3QK(0prLj+9- zu;}*not!I7R@P>XvdN&*!|u^v&v9bPwQYSQ;_eCMd$$LZoQ!{5O{>B?mP$A!+QlFP zJ3ES7j^V%7rTjvKKa{D+5n)+hLU5{YM=WlOO4S)JHM=j(zkS{wL|Vu9?E(bM9-xd8qh*!Q`zr>e%UdtTSMi3l5pcVQae6yUzz(*>aA}H( z9SN!eDTo`p*S+yz8R{yfUjS;-yE%t2bbL+ zH+m$Xv8)ml6!SND=%Q;PUV1ElJ?N@ATkn5-u`YBcXv7P@+Oh1?E9lKq4OpR>Ziq#( z=Q&u`;0g|`G3CnK_A#7D_nkdeQdPy;rnp#+=5J!r5h#nM#1&J*sp?eo9RevOMh~c| zwYEg>#mdg9dUPACz|G0=Ma=>mk(d|%THg&aR|!fi^UZ_F?O00$GcwWfS0WI20{N+bvNDsar2bh@*i$xK zF&MZe@lkX7rAC2Psq<5W|7~pqQI~m$KOZK)m%w*;_9N4dNcuTOWC$OYB1nTZ?;8|) z-<@Aq^E@h4b~G@{lZx>p&+(C2kdU}teWs3A6P0q&^Zwhw8jwq3!!<@+t^xiYXK|DLk5|Ay%Kl}&AWaBxR=EF$LGg&-WPeWr z`tb=|>+j?sY;16Ri2r5}?@!`A`5?&Fkf|it;6xx@Jn-kg6d9yV01o%h)PfW|;-BdQ z1-Jv@f2PrR9t?FK7q`RwKT|@WwS|-ON12TS%?-QtA85b_J)t91b(+P#yM><3{?=AD zb9=aqCNTpX_|Dynn<`9IrG`$oAMc&4ub-$Dttcn&ieL0EZ;ZIIrnaI6P_pCrp2WiM zqcSg}m(ShXdDf&Ihzm}6XfVlKZ*rS((^#C|>H}SD59hiCI%;bEJU^cR?d*WQjih$! z*7|jijGffY6J!%MspqZP0&g%1)*bCt}=8T&7kvM;Zz8cXDz!99vF*=FpGGV_RSRt|?8T z%!6E2%6?w1^-iXG#+U~^Y6nB!M9Q=Hy{hwmn{t^<< zPmw|~U&_K_Bbm57=H9mUUgFPuWG;0w9}C@!t0FD*zd7beEF}-{tJfy0Py#J~Ud8P5`@PWBW5PlzO}& zJG^v!GYaMsT=-^IcD6wkK&(b*nr0{C^0&I~@v?#{6dkK3u$Rl2kTSQmLKS8c@_kRU zPs@J31e{s3Uy&APjZGw)#e^NE(K<~zkey7d%(%$^tu7W+#ykBAHEmeE%XgyTf6!AD z*Nk3(O}y1C+#uc8$^9DY?ur6>A%`g`g@K~%@iR({`<{)#<7m^r5KXDlNT2Vbvl33w z;jR@I`FUgtSYT3kykifygS=GkxE}X{nbC<5Urj-VJ()qlssa=2QsUVmiIOFc1!m@K z{(L9jq)3;u+E}7xrg-&HtI#&Y%1%8tYU?ug zY7cCIG=>G#6EGKBj|A0^@Et*9#-ETrM@O=U1GNdxusvg=QQR3eA#B2;f?R-T1Gh4% z8qAd#2>22yDIydyH@OeWWlCklo>CiuIG2~AviPP+Ioc`bz9P=npRbyDJfUlEpXS0p znP^Rm`;z>jhX2yA>%qc_qg04s6%axqj8d?n^T`WrlwM{qA}vrYj@M;IsiX)+KP)RV z_*V?63ewR!SWHijm7w&SZZ6Luv*G@WO)`WTPY@;-2cbX?001Tsbps@WKDabVKhLVDv?4IB0(l)J*Fi5QwD66vPT z0bM|Xa^FUyQeXp2J}bZYViM?hkG34O48nRnptj(v2_d?QNj9%EPGk@D(4HQi%-*wn z%EPIUcI##4k`y?s+b}7@XLnX`!8q7GcJ=Bpcj37zsoAYyixp)u!mh2BHAs#gEDhIq zrqNKDG*wJK?$(nE*-nZPH={9J1>Zg;2M&+w3NraWE9{Z19aAOFcadEl)k^49il}U` zdIH%zzrZM>Af<@GchN-Fx_hC3P5)*i67||lOz}^eS~1`?td9z9^79aRg#SZmcUiN( zJ@=A32aPkXnx_*@S+mza7M)^jo4mWw9Mf!5^c%cVA*_2h|Lg31%mQ?7UeUJ=3E;tW1BG}~Wl6b#9TdK2d5=+8-omM3}Z$D#wfO3HW z^FZ>vyv@T_FDf!rPRixniSe9st({u{(|)vH7nq?FhP3l z?M9`0J${Z|T0jP~lC0UGm!g){YhwmZ{EI7kh!lo)nCGa0!jM0r>xN_b^I=(XBt2VH zF3#AD9e_n^(=Q55%AhE+{z_aD4y}YcWuGst-COYedWDG?(Be`vby(N@ODpE0Jj~=9 zb}-0VL}*Af93p@#+-R~vSQ=<(ZdqjfC_Id3&$^62s~qw<$eho;u};-?D<&h z=@-D{+`P{(E}<1I74$eciD?WA&<**VXLIiW5raY6&iMs~49E9Y30i(P(eD}C)y!1J ziDhvUO5gn2N~{=5We32a-h7BS5LsA23*dds$}1(@p>c(B8_SkB)X6{xvYc0a@k`3{ z$4qrPUBY)pL;s>@f>zN#cM{{!hN>>ZF-Mf$-)^Sa7J6qtb(1H=VXo0(Jwa9VKWXdf zjk8C^d-$` z_DE?#@#6%9t*c{a7EgA5jK7ON>Q-Ph!Q;?$>Nl&n+(N2x z^Su&nPohIVe*4)cz}2nWgRfqh(al*nXbx@xQ!iFbFUfn~S9L%$y!=TPttrM;URp_J zU@1q)*wqjYk~x&o+<+>0-p5eX?~}b9d=Zqr6E|7x7euPM!!lo>GhV-I_ERI*z zxuG~}6o8(XD)=xIum7c;`6bU!njy=AUWezGz*0QYVV~yU8BO>9+tS3hXQ|gI_kh@>_F&AkM zksP3l-$#Am2L-lLWm6L)v)A`?uKO7tQ&Hnna^;>Qk52{Ld0`oh)aehuH&7Ebhop2> zwUTuSpb!0KpLR$P?gkoHiK*uk**-~NT0g1@9^dz8ymH%6 z?VO4qGlk@yC2Q8|Q73dOLAgRIuqN>1WQ$(S{;{;aWtDOuN=+f;+MQ}}$OtrpR~HzH zoQj%+rvpy~QvA$wA8YRTL&*?wsK4gc73#KkMs{>c-@4>Bz{_NxZO*2%!TN(7<>&8o zG{=@*p;`sM;_IEXoshf%l_NeRtL9)V1tA}S2jmxLz-LJ=1R}yW+wTT?r5hx!0Z!8g z8|~I1=J3i!w1qY7Ef-}&0SBzO@W{^IZysVS3CZ2Cz|F%IG4Vg5M9qb~CkgN#Gyn>F zXr;3Iy!b^p9>2lI5KK#MG=fPwC^Q4;mhkt&F=-BZf&k8tUohj>8WtN zSl)=X7V$7zN`9xT?V&?!h*LgpyPXqNZyVXZsA-wT#}lk#Q9nK#^PM(iY21BFjp<{j zOg=-i1m=A0o)K+f7VKY z>7@gVK4Miq7<1kJGGnf5E|2wgkdq91byqUFJS!Y<9RbgoU_fXSz*u^#6 zP%elbW)xjTelNN0SqFr9msb6P@ia)Z^QzIrd|Z>%L~1>$mAG`(4=a_Ut2RxygY*p6v6u;fkDW% zV9?bw+$}qUa>z3fP~>!|CCO9v4i*k=C&=W!OZ_b*SB>>#_IibCeEpMt@O6BCmUceR z>4d5v)8~mVj(ON9d`vI0eZajxwu$N&Hhx2&QBdhOUTDa@tUob-KeOUsz_+MOO8K%* zXb76EkbC6qmoygz<1|A7Upr^U2NFKvpsF7_Pn_iKJ=QMz{=Bw(XM zIWJN(KOEV-)TQ-VTa8r73hB7I{K+BVhiG%O6$D$l)HQFZ>BY98*1%mA0-QX%x^Qut6r zBuHb2Q3rirS$02^J4+f>4#2~%W`>&+;xk!}YM`-tz>nn2&-4yloqS>|Qb?S7p}}h< zCY@XCfSJ#v-SV^9*vP-TV*L;FRh%ex)utpz5I`7e*L?$ zL=!aXa3&qZ0!hK-E3dwL+dd3VVj9$`?-cILLI9g5bJas_SnR9N zZ2ldF1Q6G6pRug=35~({`Mz-n~zq&9447Va6@Sj7s zMEPR)!(fqF1G+CI*B>sSo=Bu-f$$8wf-aT6@JgP8T4o>^coQCbYxpRtogf!OhM2#7 z_O$%`nWPRy&cKTJLPrWbARus7#H@RTIWv)t4d(wo*q~qP;8Oo+0h=NCm%lUtq+1Ryz)3%%vo>u$Oo(Ff=9!Un z@Z{OUA#V>GgkKbs%sDM)k?~C-{Y5tkFW>S8Y7)lkgl#zr)}w-aHo^%x-7uFX0_F>w z6L?Za3%1kI8s@7u$DY1!U{heH*E9LS7G<0-Stu5zLd7oQ`-Lr+?~HZj!XaG>e3zuB zCw1+rh39WzqfrD7jF1(nu z)0#v8Qp(6^L?F7pZ-;BuC>47Y#49!2qn=G7DV?0jws%B)+6OT2X8-iaH{v40_ONvC zzpyArssI%GY*-VKD1_Zq^zsG%LZvz;+oUZ`qG4Yf7=Z*Xl0v^<;Vua;FKI+luo*^) zA3Vp^xUKm093Qh!+;v~?= ztJToVI})L+5)XT%#p7jH3Z~MQ)~FIMR8%X{OqAXl?Hqf|l6|!)HXclFE#$ni2!T#B z*R3kGzHb1!D9cRjZrkw^bsw145)=JQVMR@>+(mx-d`(8N_@n00X~KBa2+U4Vm4?ks zK+35NVtC7;PUcUxlF~Q9VI*wKu;ix6B0>>9GIs(O>qc=VR}TsPDC^=cGO8_@O9Wi= z(5b#$@7GcJdIDK|1JVk!{AR}1vD8+7Qa!nv{?0yJBH5<(3W!SQ+xEdezH@y+a{e8I0FS z4yPica6fkNcQq>7ot}sQGdU2i-4KQBpL!XN_(BH~ZG>b8*~w+2g9Z<-}efii}&& z)9M?r$$E}9XKy`vI}qNfUo;ex2fGKBwe~0s%|Z{N^o!=gS3&9JMN%`!*u4|!ZwadD_<|16c;v`RN*Wy71c zUNE|115O3n7WW9OxI-#uq0FCH<`?+^`y%0ZR&4A^zuD=kn|H6!`lrbH?O1iw^&LLv z0I`jCsmOfq1cpZ9aBE@Ua`8E)cLcTXadn{1fn1N1s!q#wJ%n`hHX}SFJti~Y$OLRC zVRHz#<>;+)eL@fXBUXakF*^z^&jcMXXJ3V>hm7 zCOt)+obKYwlCzST^(>D^MlQ3sbYbGP0ogrFUQnEw>@_LM&+SK93#`psL-EAQ7`KCR zo*5Yqe=b`5yyyv`!woGs(1iRMLUiz>SPW{u^sb`(%%G|Tpv1qBe}i68uO9yAl~#eL z)6c&A=XH`kzAQhdS%24@LDK=Kah}=L>{QA3|TOGr1WCNUxfE&CC!tgP^h!Z%=2h;!>uhmM1LZ5PEw9FyXuo=ifQDfatxP;r_HS~M zvod~)xYPT-j}`yeeR+LtZ>{(xxbdUx#5Hdk7ty5Nca3lRT?afCj}Rgcfh4EFCqNEe z$$-aV>{y zzh#9VS!ObhsgTLa2QGCq#h;JaT90L<5KqsD!;5Skh=m~ z#?Toslp?1KfT^d$i+#X5A?6sYi99T*04rwg3~}&gcKCWdRcjLbyF#Fld57AiPFcS% zP+Qg5$#_VQ8f7tE8zX<2ve@=)VKSNeORiF!1m1iqxw#5$fthLs ztEZ_8%R}g&Qu}N9Q;>5&E{tXnS^8*6LBoWYb2z-$)sd~paJF1YiOK_WA-DiX?JLs% z^;A+p;@#kcpOF5i$u!tVLO6j11M^9>p8;n8TG{RWzR7>1hDDd3>9>)S*c8h6pSMT0&|Oc1Xp0@gl^Sl7Xg+0$8TmYnNP{B|F?KtY6>(ZFKZ?tW-ifwXAr8d17wyt)qSSGyF99c-Rfv#l#xeOUuoAb%YUsp8d0E6;nr!0?6|y^%X+iGu$DKiBBPB*(667nZ2{Qo zA|3iS2jA-M&yw^eNeLiA*FeDb=V8@950${JKdF?v@*@P^Xjr$qCOdU~zeJ21usG~c zTnjTkl91$WQRs!p6gnWX%+8>Jbf#w_f_G7GmA(A~bINhV%ka_F)|Jvi2@%nPHKM2M zwW%Xs=vsL^3cxns_ly40wWU#i>ostm2?nAWojJkd4lC*WTLXczwCW#dMwy`3$k`_~ zj>m5FRW2*4N8v^jQ6cCtd{D}vM?Z*ksx)!52xDPnZ*zKHC|r#&zY+q-3JRfHLTC{l z3#hMz_Vp;o z+%*)%Pqe#|V48WE{4))P%i{JK^gob)(3^czp^5c-VCDGyqK9 zcRu^-Oz{p%)tx|WE`Q|iY=8GI0-l>|cVu$;1?6)s)_fxUQvg`thYN+Tv+@Jk+?bj{ zOf^5AMb(4daL)x8R6OsGAM+KfMlC)t;D~88DZ3;P^G^BcbNmY$8T4b65Na3-tE|AU zVp{O+K@sGJf{m-`7 zy)MSjXOx${df#n_UpyR?Xv*oHXhgx^Xpn=R6l*_MUH!Tg6b|(>jxqR>JW>$W6ZDqD z1?gdiMl}B;-9n6n_83}FfZUWy$00B3?ol{ziO{@3Q}4IzYe!g?ya@#ho(TOr4WdU4 z>K7KmKPzZ-z~qfOtbT^k!j(Q&bAS0NS=JE92Ed#VhZqt?BlPR zSM=zMigFa|DP|)P_D|LRDu*hN&{PhdvRT|rk)bUq!A~yKR91_tkyJsNcGEMU?jF`d2cm$lBvwh+%4V7mj&Y6 zQOj0=sqrrV$r*FgUi1!LD@(-_Z*kv%q8u36VFW6B^1b)-lB0IXT*uj*weasXw->5A za9^zP+ai=6bFq;p=a^IF{ldBnuidZ@CbkNfKK})?)kWLZMH+DcrvLtj1dMtX&3@>U z&vt$>U0!;4En!xm1tad%(M}Z1;JBGNV-DPg&;DYeQa~?sVeo9|=6J|wgqtHrizAxP zYj!~6dV`2nMWA*7=hAPi!-VBjBWQ?Mh5LgT%MvR*iCZ2Q^54x$t)de97FRQ!8C!>8 zXGaauHR&y5`iA+7?>2v|8x+g)Zp~uvp8K1ArJ%?QSjr_M}$~tr`Qfd!t%ZafLjf#9vPo0xJ*YL<7 zKX{&{{E-R}*G)<~V?>)5OqAkIxODjKhLf%LUNX{;4oLBMVOAVDlR4vI_PayvYKOoW z`MRv)+o;QEOUI-AI1SAouj1~Zr$tDhoWMdDgl*fv$=a)U4ck)aQ?zDg>z>HjF;t;U zJ_xq4LTqSlF?&U-{0i5uj$;`RERjUKe>vj!dXv&6>T_X!G zn?NfiO8MNY3;&9s;TZC#|KK%#XHwEs|9Re(U16;H)B4+I^{33=wSPUN4@c6t>=Kg`Y_QBi!i8j2C!9oAH4(BB}>Azl`TX0;wzcj@Y2>|(5m695O3n=~DNskBU z`giCh5dZ`S`#;C)>+fmB)EX*)IFLd}S6en7`mO-MI-9t?2bvktpG=XpioHNusm1I= zj+PTUAKbQlO)7*`^}Uc}%B@>7+tP-BHiO1VGu5@YFY-#S{Qi|Zdn6crgR_{QK*i;V z|KyJ}{W=gp}m0V+AGP#}+(PG-< zr|%ZQ-4nwBlsukd`dobXu8+v+}Op5>B%^ducaivL~q@XKBu9`(osWe$St* zUkaj$n37sz`(3DLX@i^TqA}mZRa@D>JvwzmV}Bm!eIC6zsyd(rUi2$ABr0H5;wxKm zwKJsg(2N84iR|CW<$-wDeefG9PdJAG@%pagRrl^~G*gf46yi)mH0clnOwYWo*b`n{P&<}8VvPeNxlHU$49 zP$!}5{AOrFM-X@$AH|lhok5|N5*)jRe`I>)qQnCh{0Rge#z>0L81gK^$;!48_Q*VT(|Z3_Abn*1x>mNlZ%j9;~Qx13MJSX?%z{ zWAFqL0k<*)0O$vWTw3>F)J`e;(VPsFcL8MTSW&d@9YAN?P*z%URkb{1B!}C#(j0A%`G*?;x#G}Bq?grSE0riX#tieau$i4NUpg3apN2* zQJZ7FzBw69NhU}WGGS7#2*%Suv&-AzMJGlvIb0GuIT!4)FZOVzz1&`0(#)c{BXn8# zD|{ql?Z7p;v-a@yLM0fptmN*XX^ujkk9!&9J2JTTg5cr;F2--tK(t^6Z^JEtypSva zuPh`rnvu0oc`7rmdHFnB12R%^O3Ocd4tT*k2nUK8BL%#3i2Dwc4F31$drAsf zR~3|m;U?1>?sz&StK5y8a8VpX#|1eSD_}$9yYuu6uSq}k@$>S-bYurKikn17-UjnL z>{K;wCW(eZk1MzjYYS(CiVGtUv;r(C`gE#8gq#XFQ8wJrbUsIUk~802&`lo8ZZ*qO zfG$T~*;mT3#mtYCU9MsCNJ zpcxC(xkSS#zxmeR!3mZI7~f{uZ(LZH?d$B_>s zcT(k$;(mUn@sqU$Jp>+s&ObBR+cCVGzYWWe1c5KFUcHvH5fbGMNud^_suQ&s2+4F_ zN%M}4XYVNqJw1_jWLDGsx3o4TQq***Pxjh57_aV7U&k-S9;75o+|J#p6 zlvRGzMT8;uMLoktFSnd>Qn;WFV0wywU~%BIx9OFcO(gg8yUAME{%5Nd4JTZN=R4_c zgT1#zHiYs98~V__?uzGXU>k>c=GM;)vbn*rb8}?)9Gt6#kkkD4IEGk1UGobC4Ca9# z3j&D7J4}VZnOgC~$B1+0-QJrlpCX}sU1W5x*u~lt;faa>@_M0 z`qn6v>@xC!W6yeQcMG3;AUEVl^*xdt3XX|l{O2oqlwE+}Y|48CNER*K>sxeh*OV{vO>OwR+~N&{aR)2)7t zF0CEe>O{!S5_y4!MkKwMR|n#C3Ma(7%_C}vdN5R)wSc#T?_WJ@fmJs97pHbzZ}(F> z2X&yRmcvow$gWnr2Dc7jc$YQ1@V?KGDNVuxykNaiuOh*{@F^{MeWGhYPq!zx?*Gv|fE$@07)=ArRFdxW!7>e4G^-aEaI4 zkXkr@aIU2ZHfZh80DW-2zPak>a$PeB>@9r_OBhPsC0E#=)imtixqg^gc}OM0hI z_uvxZ`P_+>;g>>N6R-usOhYrAB~lCN1qs<|Ph}^hdWjx)9@NHl;k#oW?$}1pr%s`g z%x5BDI4m5Bc>&p&&Pem*mpZ}lC;#4#ifXiRUDuM+N@Gne;$_AK%`I}{2EHR?H2`&e*#}#Gl1m37+#nqzzpg? z`^u;bzI`Y#uy(Y+C;gv2(9PV$#QH<#JE*Q@x5k0t`%t^x1fIw#Vcw2;6!k?Yv{=wT zA7Qn?M^ec@o+`7N+>-oY`TTk7fl%qY*5sl=4b9yF**k`SnAA20bUf;x_NnWEbl~kKyEUI5C+;9AA zB})%z=is{!D__*DXm4XUvzU3O#*wB>o>R1apyji7*6YUA%tx*O1B2FoVr#+3#Rrgw zxU7;;eB!^X(|Hhu18qoYXjNCj>(8OfjjfpwA8kn-6dOvhQ|0ceEsW+U)#gWue{5$?^8>=`|=OY+t^M zCwGeHn#p;7P4n=0#l`b(a&BtFqWQE~lkZjSB3p$U^rl$)1pL~j^$VygL9KKsnv$LY zgiyxr+#&UJy1q%>($jftY<=Ly#EtYXYjPmKi#J19gti)uT5xi89MUaQqT~4%^!=r4 zUK>wkP-P$m()@U=NOhFl@JvIa#97NUvBHOK1U)E#E>iqD9Nsq3W!dt=KMt2RnK0}j zg@<5dTgt1S4){1<@gkd&fH&FE?9+zI4gdU-Wsx0NN;s94Pjas&Mq7PCgBXVTlZ+m9 zNi;}^fKJ_>WjdB+F2vDG8m~!z|LeZLJtf=y#>vK`UrzbgY`5hS*9`KzP_`a;vBP?Nb}?&{sVI|K5*h6WkdE3!EYr zYa$Hoo9=E^NT>Iwpcf{4PvLgx5U4Go>(9-Q6fVgHxqW7wdl|1Hnj3}TT+HNKd#`U~>V)>ty1}yCcDQQBXXiwJXZ|{9*~b z1842YUmg-y7-^FzRXjr{7+o_*s9)IN!POG%+kyJ+P%m6=NI)5lCKLoTSHfOyS&7eH zx{f8vudTV-v<7=opEe3w2eJum<61|>5auz5mM6@;J2A>$8)|dykem*kG+z<1U@?%S zhm~afnBaRw`)7(eJANVdq6x3_NcJ?Fy4@q1R+rPRDxk)zSnmm^OiX`iDdxn^+u+)( z{{g!%>{}iw}hP4Y5n3F-%-Z;OUPTK1q6yz9S#qQbKrZLy{y%9WxF|;;Wyg z(zkvx388lUnu57McqXgtf*ai2*ziFN(C3i(q>CZdr)K?8Z35J>9-(#Jt#)+iRKC_$ zqe9j|Y$!zGlDJ>7N*N2}A&Dqb6|)z}+~Kq)YnH^Pc#yOe_!2ylS@x2*@4AGu+eCwZ zJ&)ly$GmKJ-?6WikElv^@4|pEGvmGO6~6)Z+Ox1j-%;-zs+qDDb5g)7dKN7!bPW`x z#;~Kotbfq=9I!nRSNp<9>bkT@_|iyV{=_-eHG)?x@snR2+e+g@uFa`vnjB%3!+%9z z7QH5p)#etMs!FY_J7N}}q<_g=%96iu-8B}p*U|B0?{>Gt(CYp0)DKLQU(%}~b)|LI zN%qXs6VAf;fqE&{&$?-E2EwxIk@><&?}=M4FwmtGDsWv!+JYI)*Zh+#fHZN~+Cj9ELA*Vm82P zLU*L+>Vz88+3)rss#hKfu_rA&>zlD@*p42{6}#cp48KNcN)C@x%i|lBr#J-0NVU1< zN2Q6^x_Zl7%*KtPExEetpgEJGOrI{F&r@MNvP>TZ9k%GFh|U{WF} zHsUdUCl>ws9X}9HT!qXa^Yi9nne4uK0SVn?!PX5?ScYzq0ksot1d0MgJ-|T0yu>|6 ze{}L~Te_~nQvLJZQ85HD?lxL>31&EI0PwR(qfr=>0t=@fBNatZ-2+-KYt4$2?QVpC zKs`vm=@YLOPyq)uy$;z$&y|9=7&ToS#JL3q!^r9v4VW*`q6owE z2Kw|{sR>FKk@~$7WuSv` zlRuTjS8Ek-(0BC*QajMyh6wvr1DOSP@U`lj-`Ehr@}69uR-7nYakQG`+&b@yNUVG* zwbXGV+FocylY)NDVA^Gg-6G8iX0bJSNNoF&GAB76SQ5EV0y*4E;7q|tcObbvQ^xFa7WmYaPO-W`Sg=Qav$aZvJyT{)jEzq27Di7{_nBAJp?;GBLn+WXU$m7aR8nQVl^LV6u_I>yrHBnx?cwn%oL$A3CG& zaDm5HMWyx~;jKacJEvVaEe`!QhmqYNnOION!|vn&pMZYt@sT3^SR9+8Ac;x+rRjT? zYOIOkbyZ+D9}xcf8VA2~*ZM~Qb6%(*gc?&)(5*QTES5+@6(axOi1Y@Z$Ec1Nwk6d> zQg}rm1lmPfysbLhEFP@`hb3CE$O~7qoqp=+HJFXXLZlD6{I`+Gv6I_E#<&EPry1HOL zZ#fKb5)cw$7lScx`UxL1nr^Ws=LOrf#W?q9S^o@F5>$rWv1c>$lLRD$G1p!}&mz0K z)td|S1Wcx$HK@X8RLr#!6J_2NFDFRx&(+GfLiv8p4k=uqpI^;4OJ|7Oi^?-%LOU|N zJb*U&$XePn`r%S9C*kW2GbyX;;rSY$7uW=}J-*D~F}#Q4DZ4N)V`Hx07_)YRE|G?y z+I-TJCrfLXt*{vOyyv+*=Rz-L0NU!0^|4LxCWHFVib#cRYWe7~OAU|&XjVFELbeVoo zW9&R<;70K?GCpZ^+EqZn`Im!m-!{em{F?;tsI^NP>(>HQ=gz|opxlcf$X235;rHA= ze%-CX;nF8z?b(g@=m)EaHk%z(&zGj1x?iiwR#K_$R*iw2@Ms$hL$>u7403d(Co|dx z>Hw!}=Jj^-4E9k-yWTJ%QcYUHN;{P-wYy&08sD{I9Y#Sir$+IVd;kV8)pR!?*!DJ0 zq6o=YLK@<$`9nyxMgG zIYA^B>$(+U=BAIVd~E3ZEoiw`54?6Q274!gp$J^q8Q40XcD&hJxq70wGp7;S^YuZT zxk^YIqpAlSrXao;Br*?_nLqN9@I{KeL}%Go5~|txrqyd@2}5|}htsi5s7s{(GlYdp zM+oaRS?QI4!I{M2LFxBW|3ZhxoKSq*%Sbozwcd|$wEc56tC$~h)~Ds3lXacd+F(9^l+mbhqpz5=TW1un=jb~tS{j6 z?RG*@#@*Fa2C(*B(2-(_myv304^dqksnAEZZ`GZP0{H@~9*D`GBe41*{%OT@&80MrJ1#j!s^Ch9jN>|NeE)y) zoo~C&UE8q1z}Th!C)Z8wb^*YG&I$mN*nj=Qt~LP7Kj1Lh1AzI9Ha@h!U?1w>kI#Sd zVB}i>Lh4&T;GYT303ZP7uXWBi!24fli)axrN$_89>eUTE{O|bJTfoBKf^EK6KpEYS zIb%NH1x@NsKY$=L_Z@%?l70qQ{Y{$&wY~yc|219T0WSa8$0Y!Q_Fpd%6hzp+W(5p{ z;9t0sdVv7p_4jNxh!7h8#>bE$Y)St1@-ji>{JpGuK_T<&59RV7iBxdP4^{FjD+DgE ze(Uc0_Dt>6KH-GS&8i2X%e<~?KN#i zhOE)LSOPcc7|d&tUgQW0XBuh;vaT-l8CZuC+~Xd)RgGA6EyDg`HOYctyT#>8CKLzO z!{d08He5Z@nsX5#dOP*+2Oa*$mAqP*CNo4wB>IL(snvab7BxXwFykZo23|QpRr<-+ z-Ks<;KE^M=Jaz$$^O`bso%u)YZ=>+qhRq?ZgQgt1b}R@VZal8Zz zyhRtgcZOTIp z-6hb`4K3%NvkgKo90OqJpgiMs<$^&G?iTyM33Q|Zpow?rD2Keub>{e-j7RmLi`Nam_EE+f3;eiM9dW!zuIEwUI<`yzj9m~d*T&1lW)KEBq( z9lBUU?Zt9hwNYFxxwAR%_tM->3>JaAo-r|tVJ@rOqR+_+ohz7_{plTC9-g6WPz>@K z4Gb0dUMEi7Dw5KOyUO+dadl47nMG~7P4dOIQL$~SV%xTDe5u$rD`v$N+qP}nPFMGT zE>8F59%HYyZ`Xd;eC7jeDF|VH0$+M&--MfQ9DCxEE6gbKO3IIeXwmOaYV6M0xDA3Y zT(wQTN08|y$8sA3T4u?HwmfhL>7cZ~b+TOIwbYBpX^bCcOK$XoBS5v=FSpmieBn|s z7T!D^9o00CAC9k^J>&_?c0@yKPlAYk(b33zL?W!y%Dxa+Ymfjhcb`U^Q1l4=2_KmX zEetF-c2pD$`|w!3H*T72DnNf$-CD;ArMDf+*=QE{Px>Ju`}BOy4sKMHp#Bjz`{&Y@ z-U>~S=@Vk@|IN_Az8!&DAlsvF%_l`oDAb~q>`7KKM`ULiqT_P(Iut2bWDXIkPqOt( zdB9k=cY7Pf4>b_T7;QF1W}9O45hxk=%N|Z$w-=(tKib3<31F{f7_BnUU;`T&tlryx zQjbca?{CN(pMa^>j>colk^Pd;fE;MM72XzlJzz{C;{re-Wh0J5bs#88ja?B^>F(8$ z4oW$*Z>v{5TOU6M`#HE;ZD+#`e5^QP_e=rIsF4?}?mYq*ExKPXnrj%Az#8&W4eYXP zk@6>D`Jf%_iR^V!b?N``cYyf3h^BXhH+t$V zSR*y5NM?=nbeY?wsczr(Ln?SB6U;VXE z3-r)G{BoflnlxP7f-8Caa{~kS9W3$J-p0B>79Y|desPpj z7oeOxeB*Ob+6s7F?OLe>`@tzn+ABJ?!BtrFjIR`Ml>SA2bKhlRWEk(e_JRP+4EDD@ z25So+g|H<0(!Aa;?KTBw!d4{Or?l%XcY7|5Du;CLVCnXg*)*GpzLwJSSf7;VMHx2r z+C{aD%bV|iCIo|5i@2M}oHJ>dRptPdEI< zh*`s_T&C-$2z{6$ZaLZn0;7PAOsE9BYGy0oesXsYS^5)VE#(h6$@qHuLq~J`2@d$C z*u&th$z8tNlXAx3+5J4MYCk@C!u>;9#6`jw(LqISa0F2gvqtQ@lqQt;e2w(5DZMX{ zKx&)-EF5_MJ2GQ-f3UklQa*23z8wszxtxM%8f;pzN}Q93TjCSjv)R@_cF{kfu#hmo zLiaR~1Vd{&Va8`&?Im_CP_=Hs8mx0lbgy_%fEToe|@v=UQFyBrQ8M4wFOUzGna!hqr8$;xQ#smn< z*tXjHys;uqn%|(A_$(Q2yw2N27HI-NM#lZ#vmSIV)6lhR0wzk;C^AZ4WWA&|)wXf| z;@8fu$|C$tG}V}x2ej>i0%eu~qJbcRDWipJz$zYoET4*7ZIPlBZh-$x6g_w%m6Y#5 z3(~hcUpwPi&}2aOcURXs7%{4P^U+B(^Ie-|*SCN=szt>c$o#JY+ z98MF9?y#TWr=28iPbCU>&5v73P)gATf<%#>E|pG0hkt#skPz*C*)SrvvDirYSXz*& zJ;c|8Ezy=Nu2iG(PXT)1=BPl#ev(7(mq}fEI~7&0@WO(_0J369ny@Kg;~Upqc=-p| z>)-(Gn2(EcCoEXf(h|%R#mN>rt%F0@tl7_lMXYgsYepDWDb#}8(eOzN>Krr&R}Xkb|!$~!7Xm*`iNMqu4B23|3wrks;xSb>~uPd zu9?qhD0y4sXrV>KT6Y$~&$y%CV1l@hm>i%!VO$L5maX{6CHrvI5MXruO=*Pu01Du4 zaO-EXM*~AZn~v0!#wG{+7S$Hb8v~G>arQo15)8?#^oE7rv~N6La20$cscO|7{rQKX zk!&}kkjs!$wkCc81_(-9O&&ro#Y)ixoz0>=6j6*2d6ZLFfb98QMQf2g$kgxk;6h^h zh{V35+B1+p^lJx_We^MjP90ZS-@CvP6u~>|+q%=9#FNy@{OeiDDRwYQkVo<&K>LM@ z&@uN>pv-1cK0U~B#u|jCw_9VmXlI4{!cTtXEqSynQw-}=RU!TLou}zN)zyolnsh{N z1c*x2+$$Rff?Y&e4p)QlWjja0I%sjZ`bWb8QY*ru>cui)Hj6l}Wgwfv4FXV+A3_B) z5P@Q|fInf%Mhy23m!7wTm^mMt8Ly!gF5DaWdE{ux4hpBSoe>(PF*q{Bu<;|VX*LBX zZb8V)IJ{05wSyFHt*8y>+DOq&UQU=K3%NtFyN6^xbGiHV1BlN@ODs*)7GE&1Imq2_ zadV;v>8m!~RIF)cR?&`|YXls5GUsEZ07si?fhx_sbgbch9eDWs)n}dyLnYVbVI+M0e2x`^EEE;=(4NtN!IpOhpo#?NBaFc?et0Z?Xp}soHrwNkbn+iE_H_S zPLchSM1jSSOzpgp6qK5LVFT32D4d*$ykl#)XNL|+vGigyvqm9b73`oO7!}mF(%12}e7rdzi32$QI20z0;V5IEU|28f=!H)zqfRh!3VQevZ@hy|6}slD{@Xf( z5&kvNLoCqZ9dNOABR>1H4qHs$Cih@afn1QiaX znQc=-5;6NZr-;dsP4+U^v&Yny(GZ?VMaL66a|2AV6{_gt`GvL4mvXM=31(b0`(Nc_ z?;fmTQIJMr4_j7OKz`kMjJuj%a6MpExsudtB}F?NJCIYam_vwdRP-l@*W!IE2yX*~ zM%{AbRagO?uojTJr1ekc^{2-5Y7Ouc$8E4~(E`Jw){M2-jyiI;bvi=OTD_WH6UJ zP8>G-Fw{)C^;$WTAWk(HKDEpF@&=4~vuqaI>><+Pl<2urTHu{$tFIqQg+3*xhi^az(=X^558WfW9G6V<4nrbEwY6R7 zThlz#XnhCq6HOZ{anN?!3#j-UI&WI2xOz&obHInRb{^rsf2TMRjX2VWQny}uEju@U zE)sMFVxqi|dS|6~BbAK6F=Rd%k{i<+L&-e)a>kxFMzik9;1X;TZDbSJFv?jr>$5*x zTL(aeim)w5csPo!p#69T{>G4^rnwcc~71naiH z)25Av)Z<@5py z4fnsgynF9gj8QHEh7?kd%k6Irn*Eb0>3U~T7_lVWB}>%vT_HU3Fnhx*1j+-w-F;s~ zqSJ)4%+CCQ9E*6IbruJ7uFM+?oRX+dnANp0aqR^s*I&r+sZ4CUpw>jXo30qIn!rV! zt+LrONsVcC3Xv#Nv<-D&0moJ$Bmoe=g-aa?q{vR|eIqwof>LL3T62Q?a-S7xVOPGNoUdY!67NOZ7S&HiG6Z^y^dASb?TQY+8FK>ZD$#MERh*qLEjt`1nB!l(LZ zQlzo|nfQue!UO#q@wB1M##-26^Q6e=0leK1Y<@Xu`;=%xp-* ze785WiZiRQdDzJ6MXX64Xbg*>l?p7XUeni z1Pe=w_>=eh+jIYK?6CZm2RKUP!67XgcZ3P|vl#+@m+&56eAA@exwOwd(7d^D)}J-4 zrXmSpj`%6LN(~LJqZz=*4#{#kQ<_=9graX1?l<^2$kU;PN-%y5T z4d14uw;JUW4?~@boexflY^A z#Yx%M_s?R+#<*9H8Q*=|m^q?KNr%+#sx(^(01>7C&(6X(TgnLk_2%VUhr$zinO)5i z3yFuesG`YKU4mvXQ5S>B4~n#U34jca;QtN)I;+I8vH$D35t8~3kc1?Q2Msj0vNik1 zBX#n9daRGcbf4FxQ(kvUwzK41G%aKOUGrHTSbfVJ=vvuqI&Oidk0IkgAKi~vf9Uwy zhBNHqCS4zWj2&$lc|S2GJbo0+$m6A`{ydoMmbYtd;YLcKXywzA_ob?9PJo+Bm*92iHQ-2RS|#l z9oMTj3sQ?kH4OFbm;9n;@gUdl7s)2}Dr10jR-yMKM(u4d?~)(vs6e2eF2BH!GUjjR z2#f8=)_@Be(^^(P4HP8~Q!{vb$VH_msl9XV73{B{5;UXDWw`x2i#%<5YD2RD_50wm z$yxxEPy~cpcDq9$jT{&xoC%gcmpr+07_UiThcAs#13A(!S*5vh7p-;a#jl_R#U~qputivU9hWcKpXBwo+^9^6_2b=gv+1$s zMdBkekTn;Pa^=93&(rJe>GHNcO0s5l8~FL73y+9w+n*J@ga>Ho(BR$`YIT1{;ZT9< zWX!3Rv_F6-)(-g9kw047VXDy8>i6FKkcM@wp#Sl3#O3Gy9Bg;*KDovYrPzi?+kjx< zvcqBMq`PN5T2a4JS6%JJIxTbpy9Jgo5KMokh8SqT4jsfVl?Rfo6h;e4w|L{!$FRgr z6F|`ii^Yn0vG}-{u^Y(SxK=dyN zAt9guIehKkyE=SwM`QsEc>R9a%|dE^Ay9g`y&K#G3iA8r>icniIdY17=X}3jTs(XZ z-c~+5TY!4OYiNw{4*XJ=B?q3D{7$F%#Qkcut9J$ZX^oEk z29rY6`?dR1@%YY`iv)SZnxYhpoQD4HPGtqk+$kqbs{zj1@z3+(B7(u4xxt@I)3zz_ z8`CNm#U+j$%U2RT4ecDB6ar|Q(dN@ci{FO%_ZamZ6=rsW)lTgwU@K7ix~L(v2(tGE z2Hk6w1#Q5oNYzeAG_hcl@zx2Aau6+0YE-s&NA2Mnc?L<`Z;kt?7>FX0d|k&`0bzvD zdb$+hY`)XV{d>4zL_3K^%WT7GW@v|gn&fHA(n=^t79p##xX_D0A=8<_AAc%kBTNU^ zIaN8NRg$0BAYKV4;0&R}X}ouB!<_+OYW>RbogF|q6)TLHWY4xGVKQRB_6XH_K%hR9c z6<`aipnr-}w^+$3JysxNC3QdjHoEzw^urn`k0Kf8YZ#`_w)Y7&i29pNxR(}n(KyYI zKLzKc5!S1o)XXdpS99;O&aUM;{&%ffL<4TaC)8>S4k;DsJ<`zmv70Vsdlehp!^Z3FT2Ui@b^@v~*U=5jB z4_1*m-MzcjDN`Wvh&wkUX8snW)K5{TDKQdmPgt}m4#b=t?(v@BkQ{JZdN#EnP#|h^ zDKX_E8#+6H{EI2E=OMcclM9lEc+TUN>dKAdfx-yIYGwEz24Li5%e$_4q?H0 zAj1-Z%)o`Msez@*tQETOJ0`D))#kFXrzwMnoHSxDT{}};NuwTzdQDC@-lUbGB}oM| zBMbl8Rg2N@DM7zBB4~C+I_3;E9oTacuwJkOZgDW0!rJpw#ic}!<*z2|EAuQIze*nD z%*tZ$RLf3rvfBFm!i(fmBmG}!&JKH;9a(0uWNkafc*hpRVw8aUwh^6d^Vz+R`15Zi z&>Um};%&T0(w=%5+$QBdNdC|SlYFaE{dm$_cEjKRBq5zt0&HsjI4n3PI$*Vu6u5k< zcl6N7r@0)j564ySuiS89n)TH?$#!40K;HDg;vauEJ7Zptamzp*ILn`;`UxY|n>7DK z?Gc7yB2w-)mzyyA)|nR_Zkp&5{!joJ-*!ZW(nU$fgxxdq#cNG9OKm%!C7&L^94&~*(EYILDGQT(V((Zf3Dt_A8E!*3rd-i0l3H_41;rdUp5v8o(ozZB+_}!|2ckI( z{!%y@MntOPY`@Z8xdH0R$NS81Fv3PxO2%|b;!o}=PcgbZMrxz*>J>zlgVB#>d8zf- zo3Kf1^iN<_&!D9GbB$t^d5%coo%vgVXbvVhZVTz_4+uZ&7#YT;!R596L{lc0QAJg{ z;krt!f?Fkl-3;PcYSXw;XD&DvB^4UYjg_es^*c~Xe4R z0z>PAr?Pqb#T~MhuAl{Fy;I?Z*4_d8Bg=bF`QM3^qZ2B2n>~0fYB5p*usner!h*;> zRTYeM6VNH}dcJO=$VDo#( z1_%a;au<{tJ`SS29F`D~I6mU0!Kg^EM`KRF)i4lYnF4(9#qw3vB6;VM<#c|XhJodV z@@0Ltb!dc2()yn1`E9&2eX%U1+GFvB10`Uhpz??gJ2Bx$0DcEZePl~#1hu;LtXZ2Q zCTa|1-_H*{HV6dSZN@M~_*~ zI}vS3Kj`v*X}ir9(EfhCth@^<7oIzt_G#bA`SA? zzjZP*&Ph3Y5|0IJV^T2;lQ!wGuLESzB5g{NdI1OCP4uC~^HK#N5kV7S5NmnGMO+sj z1z$SEPK8KDM?!9%QE1foLT@YW7+UU>!Rgy^kJ#h0LsJAOAW3^9PUzuU3q0{JUklGK zAW0*l8Pk~XPFFc}OW=Rzh+18O)e^9ib&8H*BlXv{vs(AbQ(u%wM2nhb*-~OXW!_00Ih|Lq_B2xH>`hHmUALnrTje;7n`2qVF z9G)|mR5H&tQ~F`twXSh4luAq9ky=v*3x*Uks0-+L>dpKzf@#7AjOYrl4LK6_V zCdZR^)E2J)x$Zudkf(Z#P3dR-SNqWCGUEf~F>+6CqO$Qrq^Dw3!>|tPE*<_UO5amXO@@>f%ZbV)Mu6GfES_$cHwR*(Iw^KenUa60h7(TVTS zFFeo>0?RHg4vTzceax=BA1xG(;@N#ZX>FTEcgVB6k_>cE(PC(T)Ihubpm>?OE4Rh% zSS!Df%05g6ftn%2aC>+6+nm-mTD-2`==Zu=c^ubuleuDOk=i!jxcVaS(N zQyk2A9|{J4U!bE{Zwmr-Pj+oYKGV!D&PsS@oDT>2g`|fDz`I+5>d#I zrB5OE^2vr^EwYT9w*us*7T~GHnm%f!B$JS}$zeR-kkVq(ubni5abRz;@Dg&; zTh1zjK97m7I3H-a$N}g?h&lYr2F}HjS{<7hx5<_Pqm&Tq3gSuf`issGjdeUzp(BCg z+C3*|;x~a{O=d}@nyflQbA&63i)tQM9ayV!B3h^|7olZt!*FS;ooVTKIbG=m8C@^G zu(}rxqiV9^Tw2e&aN#a-Rm;_ZhEUA3ZX-`BLC|J;Sw0YP9D0ju=uAp)v9MIX1nUR& zq*pLg?urLm&HS$_XbYlqJlB0mKAEf6S_DnZ$l!tl25=xdp0_s)@1wnS3ypfsmQT*^ zahXicB@Xy@XRbJrxCG9w(@ZATU(^Vk*AwX}RYm8F$zH|LQ8xIXbMXqYbk!6FHgju_! zMOb*RT&`tArj^u*jUw5PoEj+N&{{x`m}dIeGlE8%IOGK-2Jj1eiS6&B z_igSD;YMcIbYv3L3+tH}mOvt!C2=PgwuE^F^v%4rx4apxlSVbO(OtKGq$hu3?J7>M z#d6)EgtgM9GQq=3p$?+x8`szqu7of(E>@Rhp9wAiHYWAS>0pP z1RzR~aS~@C6EW6p!%A5_nbA)mIW*AzDl^}rfB9kIZiYuu$S#2m@u-FA8`78?9$Ls4vL(O%EKmOA-i}+OeejBX zaP;cXEhFkhs^(jL%y|s<~jZJB$ zr^*0-%7cG?@}fkdSv-1Bvfr$_itIy%U>!yBf4OYft`+?0@xsGfasLMWj&IaJBv@h% z*{!%^(lv$4RNP}FZHhDJzNe+dUAzG)GYb!Wy0}>vrTBN}0{aG*-AIv?TaJoZnW9^+ zvMTcv=CdQUo5_UX!*6g?U@`=3g0#(lT`)CCfZZ2|vOZ?*9)yH^hEyB)+e$W(o*YOD z8W$UHC{)UsZuS25F-QWC=u+B6HfA; zY{()|5%lWgSS%2Q*Z{S`^juTN(2E*IBOh*Ix;W%Wcb{e~otbVu*_I>DqksrzTH12& zi84*yd^;TfBe>pWhAAMu((1cy?YeG;b&^%i|eczRa^|29)MbjSV`5 z(Chsxu=?kG{WqvhtC7WnZ>9 zZutO-|LotB4>0<_i_?fd0W@g_^8Z%nq~XB-&(_(XyGY3Y*v~w)G+;h}C~ao}0M}gB z0U-WQu5}gM-Dw&X1cX>VE#MmrJ?(!!{on5ZO^obKtxSzv&0PLXlrQ;g95y7Kw~sX* zlr=3W(#@89xX98?5s!6j971eu2UA_Ru)!vAo-AAT;`ulv?y`S>=XyUR#nsu4kL;m> zwqvetE-o%URu|mq>9PNzsyILI=*T_zC_}Wax2njoL}Ks2e0w}JV4O-M0t&p}3QidS zzq}Z7)52O`%FDkP#yRVAqVCl>PAlSFZY%8XD`cZuTQ-(o_UvG$UFzi3c#THf^oK|P z&^1&eow{;ym`R@DML+$?)tUo5-z9aBLedBRQ~eYWL9L%?|YT6 zHBu>OznXVfWLeXvz*5X8J@RGfA+sbxeXBHCr8b>LOy zhFtzm`fsYsg~fBLkp0qvVURaXZ62`c?+?huCkEID-#_3En>}z%n7K1MX=L|CyJcNu zk*tmtq$27#4D2|uB3h(X{?*dLRhMJi?mdtzZl%}n)yv2bEHO*%7XuUYS(zGyByOBo zO7caMJ`X$@=;5GNelgtn9EeK-!q9-Oh8NF5-u|@(=6lQs_fU-5vIsZTQT3RjUV4BF zcyC7* zLYRuK{WM_sPEV4o{m%;2jv!Mz$LzIj%qwy8y>>y(!)J!y3mDr%=wfLB{tb-lzLX)e z%!}gS4JPRl_x*B7ZV5Ex82F)wU_kK*fo2tNQx8$l-PgxxGiy?3F%jkJ&iN?`#Y}p- z5%H$?5_I>m0iV};nqmszDMM$%X#By}&FW2ah&tz=jYWuAZz1`Jv(M*fWD<$JMeQGT zYJ?;#*E>~x9kCOymtZ|p1W0ahx*(Pn<$}M;Az>AsO7^6TXJFv5j{4e#Q`iyI+ho@I zaZvx(oRg%j&RyYlxHl{>%F}?Im9%+)E)=CcUgv$vfGBsn+&ilQchj5ey!NjnDtI9v zj<5eISiF|S{z^v`8QYv5g6H zPSJ06LILc%axuG-iFT^S3??0XuZANeTDNO=G~xpaH{$kYjlNMh5SZCCNj$zu>uFb> z^tRSSDG$ayv)TE8Uw9VJ3I_|O>1wQw1Q{?l&0^CzAE>FHx|`=Uq`RjK8$X}J?Q8*{ zcQ%9rM1y{{$gi)&xXUM`j;S*Ke0`_zKgrnLJQ4-d@u=-vB~1d8}GB?a1fr_nWQmILb!gjWe9TB&m&~Fg3XRpSY-m zI@Le-0qc#R-`Q->{}7ApdZID_Nhay|dPli*ED{KTl5__3ta|NFThsO}Fzpus&M6bR z8Gf-~W`cmpr4`Jm5QAa8VJm6@M4t66F2ucBHJMq!pweu1I29HDGTH~jdECD3 zw$agN8g6%>umZMY|075{jZie39;Vw`5w9IGiYQAjduG!F9S*VWwU7j&Tbig4G?=jD zJt0Uow3v=*u78x@fa+g|C6?122}OLopKCdm#gSAS;jdlnewr!v9QB~4T=-t!gu6eC zbw)YI5?a8#uTR%b$R$?J(W_aXVl9`{-$~HiAe60ul85x^{i6COX!B&n7Fv=WSjgqp z>|iR$+v!SGNN$M!bB}Z!*@E20=;_>Q#;*v$*QMxeRr0eWOmG}Ok`CL0^FsyFlIYh=SVI;9l;bj>7oNCc~(ZIsV+)%M@-ob6) z2*MHc`k1L37-Ifo53%1BH2D0O_V6kGKjATG7!p3At0V(-s6raEqV^p=+n;Ml@ZOU7 zVTCjF7+zbAL-10zAWWhhKnM^u!s>BJz@MVZ9?u;lC7?H$8D0gQwsnM;V7?W_RJ7qUN^ zXq^?jO%eP~7M29gxEpr41ri(T8uFlxMRta@Q*ml#W0^%rA=DZ>tkP=qJNg>orFgJQ zA$+R;VQA7Dpp}Lw^(hzCP(9kv(#no%Ywf<5o4qjAYsFAbY4t&}_RIsA2s9o#$euK`_23be4OxN_Bi|{%hUS4&*x|kO&?c#lb7nkQUPD=M5dd<91d$Whk4UT0g?8D3 zu51L$v|*~`Eu65A4n?`gDWmf|z)4;>TuCq|93z4;!YVox4R2w?n*Hw4(kY<>sROs^ z8OR)&TA7pf4_YfC0|h>iTXNs(664)J^N`LNLT2X6p6oguW&y#!2?~UA@OpZ30RAn<(xz%&Ymv4F zSijAgitKq`{56L|d1O#J6MieHFVaI@b%^03;OFnh64s%Q!0^|^qSB^*zSZ|0LAc;X zFnm@*v=(F&E+9Z$S5*R!r3Tb??rzt5Tu!bzL^1GehtyY1bjc)wLgxz5kPqW!!iz_r zpl;P=xs|(peyR9Yq@Ghp8nI^ibnHEu1nk$UDyxvsh4H&tTuj{k{QOtuF~y;Y*EapR z;yIClIA<)p>-cs{mJy59L%_0nR~qpdXO;o95%xzOfSTpS$pHr{KACvX^|(k8-wu@$ zrgIY$wIB-=&9)@Td^%BRyq{Y=sOR?;hGa}3Fc){L&2B*bV?452Q7it0B?W%KMH5j! zVG8?=3opCT*6c0i<3N_1BX8OcWzS`+;UVTj5h@2zGPV+%ol)#h#Fw}?MGScB{Zzq? zeIJ*-%~+!6r*Z*CbKImkWJ0+fTx}wE3Df^{D2NrF$rk^DweXMO|ILnNfwlL%{atA< zisE4KjhZ>OA#S^0wHtfh$K3fxp!D|8d;G!aosi;7({dcy*WoTYyih{)&6ANn0(^G% z!2f}oh#XuGvVremR%?VzukQ^tfL{2*4viPGn0&yZrDp@!4YihhsC@n_?idtmW>+uP zfZHxb&BIKo80V4Dttj(Xu)LTeE~_Br9+p>*$i#3gn*o@YlNLEnh#hP$6d)R?Mv+Dc z2IC|gx_xNqK0_dr^~lkk!X}bJ4AL$vx)#RjS(VT5$EXBBmHtaG|KM*;a#}yuwuQ}f z+FF0dDcuz?i}$0~E>+BMpQnt@udy#GY@gvhA-joE=F@>Ie6QhRxLA8B_053u1$`B^ zv$~G3vCh-{_jy42vpHA}K~cdm=IIR7IExslN8{SDSV?Nyr2bUZ_1t;bo9;J6@7K1I zL07V!#LFY;A0~qD9nPuMU;P`0*5jQ`MyBaNg3?$Z$Md80R89r1lld_iBn`tbj(btV zenh%Q6?_RALPnkwOohfUkMa#rbn9S$%w+1&DY!2WO{E;8`zpmQ4QegWq%;XOa_@$B z>^f$Ir{^I3InR%G19qctZ-Ob84;Z0<~Q|fk~u4wFwKR-;4VJRDFU^VEs6#OI-IqiP?HZ#2nmLRU8f$X}A||^RsLZ(o%OnL=i9s z#W`M~==~n+?l;iGj7Hq~Q8OX(bmV!pg|f66o(>Nx&A|W4hB!h750$^@cdeIz#g(AH z-%ckTL&sr3v}u_zz(xB?{XBBALShTspX~teq1)}o*(dOZQOJ^BFaWWX$hQ6wXJ1qZ zq(WugE!E}Y9t4=C-X4aQMAhKRJF-iS#`x@iM`9}#J2H-Vy zWL0=ev>OZtPPE#W9>V*!t){M}>yM@nA^MNn(b$C98vjR;v^Vc&nX4pX&WevZPz8B2!eS>_pVP8*oLu z30u&L+eQ)f6fv(f)EBesk&|GX{4!UebXq_uKerKbydnv4VQtPzEGPR`go`g1rjCmd zaM$&~b}fi#`C8l`m{+GQVlNN@ssw;8q;6Qm7g#rove8lUx7Sk-TiiYeHxs1M(52^Bl+olc8VuE)J!(ePwQ|l89TI~j4qP^?F5<>FFtqNr zKW|bHAmI^3W$3#eI?A0D>eXwxcG>&gp6ZtU|(-nhP6y zppwONm|=>7`C>}oDDxLGes}y!Nc{DO;}4nN_Mhi!{=;HZoQ>ETWWGv?%n4ZEbbZd8 zMojvoo9MxHRD=<1gcjkBpv>JK?*09JkT_K&sINJ`Fu8p-(Y2~A&IRMm(MHcxjd1z- zJ42tw{a!pW%3npUI46*Vz}oG2+wkrm$T?5rB+lYxC=p)5oP-`9zgEqk17K{gN6&+t z>{P>(%cXb{xG|CHH?7E?nbXUVcPES?v@3JONiw4>I$7LZzi+O-cBMB2e=@%hsDxrn z7QQUg98(FQnGNaiS^bXSVz{PnL$;e@7kkw4e`zFK^zR6*J^q4#0#1?|bo(sqbE5^% zCB-NqtY^%|A`6tHJ>2ih8n+Awhe{MoP}&f&%kB%jeY#kp&2S<^mg@s^ug|4f#F25Rx>ku+2Pc0J>>qtyZ$k3+t?os)-f5UcWvt`te9>tGnZZa z9vnMxiBQ=qgB;8is>*&zq9OP{b#3U+mw0BylWh5PLW78&K^2l%^9+J=<4r4{iwPZf zgucCu0%7+5YCVCIlyvjt&xkJmOZPihkZ00WQBr^mp3ul(43MD~}YOJ6~kYK=73?4NJEQ zfCDjx;O0-RX?KrRT~LN^7Z-&zA=j!J{5#Od(*NSW7P8GFaxto`+CZOzs6t`9*KE=I zdo04hyy;1#p)3Hf!6Hf0Xcqvaz{+R7ROZ`VOu?|j)4EXcyn?Iyf=|R$Cw?kK$NFnF zYvl5b`kkCKr%1uqLherq`zru$R!KRfbK>y#%hYk2i2%V-saL(h8;nv|J-~p(f3U>j zEBv&Q{WDSe|0?K0kC=hXKR`fIfFK|Y|Hf~QR*sC#;|l;gP$~$tmj-X1@dqO2VEvKm zR;(WSl5@@%(>R$MSVBpyersp2r5=5LI)yadB>*1K==6T$-yzD+Pn5L#Dl~1gOV5hI z`Y>Q4%t8O5(}??VZGu>!Y3gMK6ke5N*Z7w@c^@T)xKoqz;jh}d6Z zgK*f_%*JV2J}`0SPQG=@j&g|G{bU}C+nV;kwCGhi%R=CCdPStXVaZ6Y4xELX2Q8f!fEImKY4aGuFI zr~a^oU>KRX7AAiLgDsZB!+r74dORa<@_z9Mfh*L=IA9(JSjR&)gC4F-q!UID7lruVOT7p%xRPFKI} zSsUnCP{@v)cU8z;$u^A_iXZ#ld#!CE{sJlqB?TBZ`}EySwy?wO?amDNqV zT>cj(9~<+;E!v~Q<_6eMfy3v`c#DDneZ8zyT%!=-jZ=Vk)9>#jo+5Y8CUTaGeSp`Ueo~1>v0%#$EJ0qjz z(mGZF%#e>DHNHqkY4@uD4lqRAX4*9XJSZ4Sd>Z#U03XaKGEHM0&<4h=+l;mWa0Z31 z|DgV!V{fv0ZcTGYOV|VufvNJO)o%j!z(6C@Qnvv5P=BInfPJ`_Y42MAejqV!=`B;& zkiHE@vj|^NjA|Ja&TB7XsoqRus_;c(!q+Xf86hhgFBioLkHxKD;Zv70eW~mM_#i-%B?^Be;H6nhW8caJm9U( zISHBalBo(o8{=t#odN01ljnvkN%GAFpbf4@C>#Bf)}T2Pa~L{<1fs-J0aACaCLfmS z5)dAUJqE}Y_id;RFImrCk-u>jj{3{qPkpgsL;~ zEfXsowVMPKW$dH(Tl=TvDh%EF^$#0uNI$KMRhNJBYo@!n=;e{O*QZN|pc654<^1w!!qt z12kx?FYtMG<~E7-T#D_qfp;;^Si?LyFF|=Uuk!~$EyEN(5RBfHv|(jJi-m{eBjAdz zl?Up($$YVR8d`huIti?at-Y9-IDSK=#JdaZXZXZtRs-ADufr+LwP38lK6wu0hC3^y z6mf!-WS199$`w<(O6XEEMQsZy7ttyB83OE2C@qO27?4S{8WW9+*{h&L{scn6CosI20|5GVY z22L`*J_VFTka!?aFAk6=zj;vhs%}QRQ*8P#s=hKPj^_IsS=^oA?(V@gxCVE3x8MT= z*AP6oyL)hV*FbQ0cYFE&o_u*fY}M3G-`ZQ}=6jOVtXTZZ)u8me>LI8GV=UD5fGm`0+XbQ~PnoP8=ExBq z9}GUlcx|9${VBvh=z@ne1RQQy{RPS2H7{f;VwZ zg;Uhf!oLFO20PNEM&^ZN&(pWp4IICxD;C#Ge%GYO>q`Q!gA_JF_^R9WEfO#Bk%lH& z8ZaK%p!ETJL>j|{ylW1<*G&Ig$^z5Uo@w*bS(xJ$GM*}x{^8S4*Q8+libfaW7>VrM z42~Bb7pV_nj@-F}HWAIm44G2@9^?h}$6r)gYKLTiGZCCpsoPRt4T&KUojuH%mc4(b ztX#*$k67Gfp*b)dF%3(Ic)FO?X48cy9pON>v7>zG-2L6l9R|evl|-$dY8&SaJTHyf z;fPD_o}mW>Y)7l)-tkMc>yB&^9QQ=*M@}p>fki|tPT4a3$$rbi_=frA&B<`^x4zX* zftPfE>)T4QmJEdo0U2g&YA*C%(3ub1LTEdtjFpvjD*5?oyGmut zrF;wphGvy-t;H`FahcoEg9^l%$fjC&LAMZDUrm#dFbT?K?1wbUM7chImxF>)HvsM%_ zqgyojz&BPL7Q;Zi_~q=6w)e#d#U7XflPMwEVvAvKbJN(>n%pFwoiDnFa(Y$h5CoAI ze`I(OB7N)vF(vOVt^=GpZ$5o$g~vRCfy8+j#x=1n8p!n*^1V(R6nqK`r90{GMTbj? zLZEM}fP0W8Y#$PI$oXK?NcaQtn?ytoo#GP?T|8YoP7nv*1Czp!uqBz~vY|J#=g5`h ze7nF-ej&wp<9($Tp(-oTReR81w=bruYtJytErcZFp1(p~@bpZUe*njUand2QPdJ31 z^;c8fm*EEwV#I`1z!bqO(yYy~&MF0U&F!ijc-MOpTz#o0{~b2(-;mft6>6Om{ktnX2H>9FK{Hl8<6 zIPSTBIKYtv{dC6WZy5k@pV)UOs6KWbF^1(=Y&#cLCmw~_5J*`R3e5|slkQT)bb}RWS#O~g6{b0JyBE5R$zlWoWHG2a``C1V{pUCjrymraP=c9MB`gz zOEn1<;CW(sW3hkojsFlQY*pq`ssriNqp`|!sj0OW=JFxeQO*NXw3Y}-s&omn;cMn? z)m9fnsf9roQY`0UFDqez(vU%<8=i2H)rA8-TLqtX>v$@y1oM3Qk=bs#KSM*OKZvga zc}O6(lheaF?sX6Y zZU=M>oz!{FOnyzuwPl9FmGSM0iODL>t!DN_!61t3L(~Elz>DUir@kw&&^rdPIxWF*=yJ^8nX8$-@*msDR55!HHkjys z1+y3C_1*+*5x!_4RX+IZeGaXFITMY2DXC-WCPY(Jkvuf<+mM0k!o*+Efn-iRi*;7-LMfkl`R{@#eK)2BlUobX!a658cE7EICH31NHBrm;@;l5< z3Gqw+8hHW>v35fGkVf<#<`I7PDusy8_db;NqmR1%VO|sh*c8qDdh~rVD|L7I6Aq`h44nrj{mp=3F4XWR$p>Ow?W}|ZS`Ml3lUXG&Z9g0!gn?f}zZhco=xef6)2n&LF zM=jwG9)xij46|8oR-RGAS%9<$~FGrPG7V5x*pr>xuri!`tcyS$x^qM&gV9UVBDNn zD31Dhh|&Mo;J2NfoGs3>FXkD%P8Y&3$avj2xG=W;-+Ov>u!WhD)8JLDVg@zq*1^4w z_{iRck6v?*J>_8y^UfvrA0@4j)8L{)%~t&`!aloqK8c%oB2_r~6=Zs%4uUn%0&zr< z3^7gR*XL7S_8I=EC#Z^}`ryYoCS-D$BqFs3cdI*aeidY_lM;f+D=U7rHpmY1G~ zYiwIW0P{!R-r1dQ!R!`w!Q3h6?_VMG+}%RX^u$_Bnnpwiq#V^({xy=ERKV5C>r&8k z(=R;!+2&Z8HEn6q*GzvTsj9E5pmvxz^Yk+15aLZc=Pmw``Rno|1UQYz?( zU&SblC31)MweJ)CRT@pr1U4?D+ibk>4zaXkSc^??_LBM!rh<8Y>iP+z=+sKqp*U;K zWb_(@z+AAdSNZjXM8N2K`Gx9_lZWPGq?Ec~f050MU*%cgBO}h_5$R~raPz-+Z8Xs1 z8Q+wv8Z7n%2^(|G+9*!KF!tC`bygg(4gEbK1w_!4e7nr!EOQLQ0b^#>B*)m{!RjG1 zc0|6mQs*#4k%6zLuLxMMHmhaPH=iAYu;vquYm+tnL8;vZVyEH|= z*E9p)y=S>n9|ZEd6d8Q_&0GXl&%X*Tp&1r;adN75yVaxELhf$(Dlzbw&gG}$gAwvm z-wCklOp%sh6niRp04VgYtr6Hq9^4%CJY1ImHwJN5?*CKo0Sf=vMV(p??EIfTtBMu#zC(LuZ^@yZCM(GeT>pvC~wyI%M{iQ`^Ng56n79Nik)U?Rd*9w%52G~`d z>h1PKRKK^XOK<?qv0Rf~hae$1(T4g(qUG$ncn|nc_cP7R$ zwhD6mU*4Kb6of4n(Zs`pPtiqx7I86riVJv8M055=%v!_K%J+WbhG}#6tWNZifQPzs zXb^ezF??F}F1hxONS&Yl5HB!6jgMu=VE>vdY9#nw()Yv?b2kTp1?!I-ieGf>T^y2P zQJbj@j1@3xWYi*5eyJpfJ?BVJaxKkx%!(3jv{^MoY)QL(*3AGzx!=mU?oCOZq@94- z{WJ3F^B5#>4kJRBoWS*Q)VNna{&uYD!tYy0qC6e-IQ>yl*2{qKLH8r?AksP*pdDf7 zRmRWvl;KJj$o@6XEEJ3er0(V`I6ue=gbu!qI{@^g-9s&Cl(vdD&yLfR!_g#_Z1KzU zCM!wF&{1?L@>uwI^o_aEl>38JC`45EbT|mt^B}@2^4~nTrb#^AKWXyVPvF$Qf{`d6 za;>G*lv35mJ%#BGEMa5RjIzQI2`Q?b{W>GqX^>PuJ}PyrK&?(G9(cA+69dU?mrYV- z!2$#Mgi^tm!vaP1E(6L6hwEK4Q66OWP zS-e-=shs*|qhbTGuxA2_Hc~dbA*CEXNl4!1N`Kill3(=rE0VJ=b%i$mzFc~$ z8!&!gfdxj5Xgls=-_Nzxq4H}XN&S@oy8&qJIwT|^N=*{fQz$JAet)M_h@nZwj`g5f z<5r^5DwgHAE$Lto`aUesw)V>>z@)&(6`OhoK0KxqMPiWFM5RB+Hj2CkUgKpoKW-(? z$_MMMuL`c58hM7p8>DnjtMK#|B;3V*&c`@!u)^>2fPKAut}1#9mbvrO=O{`4g)8z@AaySPf#%0!l9ar-!lwgFqh%)Y}HLuW|?DTZzvP zSX|>?8Of;nOQTfiZNG+RE%q0JYf4|UxT}Y~K6=ZzgR6d}?t>|;w;0xe@`&HwRLd5c zxb&eGVohbqSE*?O1K&vSK8=LHehlQ2=P649&FO-%Ng!ylf2t5el zpQfx5BWM!he`IFlThBk0ATTfkxc?Kqz)PM|!G~*7VgWUS{%0H1QgM7$2Mq@1j|&Dy zn+)y_!bxV~1YrT=nsy)lJg9GH22Lh|a-xL01$N7Lj-htAArQUVw%r{bAtO@t_HK`S+pKi>zFgk@pp_7DJd_=>z&svzdTVKGKRW!?v*vkvFxX(iPQ+|n**)`-UU`PU{8sEqoKJ`A&NU2@eA||_~ zhAYq3C759vM3Skgsb1}{8*FtAkvMbn;)44L+K$O!0bw%aLrYwnH{)V6wIkwkkShZ- zF^<|vrfG8N*jl*CiHTk3%^NLCcJ1!e2{MCb1LLAMU`|RK)^HP#6^~TCfvB>FD za=(%p)35_*stjS7!A=(zygnw7y-sN&TYzU;2Y(65;+XNN=})`bi-6ar~pk ztOs(<_g#Gsyq9PU&_*bhWq}`)=@M06_Sd4PIeLNbCR@Q_EH8t=jTEHS0)1wN?EBGhczJ7@Pg*~f2hIJS|dfge2G+jBJs=hqTJzS2;jn#v-eaZhJ z%Y^W>8D8RPu8ca19F~+=DoYsjDr~&yJg5NfMN>_)iF?8>5-j!&0t3%`;;C@pd*>(_ zS~Yg{)*>$KpI;6fG|u$MQi73~84(DwnWyOi`WuPUI>KD8xHBqGA<^J`JyMAE!-b^YD5jRK9RrN+F+5UG&~~m#Z{c|jRGu2sSi}}v ze3pbHLrH_O=NOrX#Z)kUGkUcu9p$Aena1LZEvhKwqLRrNl^YX_wurs5lx>Uv7-uV@l)&ISiIJ(*G@GAw6cBI+SZT4a7@{Zt%dhkl2r*rrL49|Uu|id)i8 zV+=LRIqzMXH_J$C_5n_BGr1CKYU*R)me)F>L`rQmUR5_MA$RV^%_pKyA?7Unj|tn| zQl9%?IrjX#;3mW3H61EueFH-_L+&c(tw@{``z_k`IME<03_UE5GWU@Ut*W56X|mAR z9v*L4VN(>?{Trf9eu~6d1-f=&f)r|*-T6PHB?Ra&C-Kv>l$S>*H9vV)7JAnK{nYkD zb6UA%=gc3L9ULX%2oe_SKn>)yY*z9Fg2B#=jl#9BY()zB{qXa-~eLj%P=&&o^s=3SVQBC!`VE&eH_Pz%-s1+CLZob~g#q3+Mi#<^j^(9W@P_xgujIyaaAndD87WlXZ_;hgEkq))qscGUbD@a0Qkua{i&FZm5b6oqWUx zs`#&lrtyQ~{uvLkh=S<g{XwoqP-9i7aRfvGe8=eYNOX*PLUg1#aB@AmXVFTVJP4bqWL@|zoo9I$a&;rY3KOV2VkpE@#f zLq0qf0b^OOok4k|ub9~}a7g0hKdl0h(HQ%h_qsi_G+KHePz|`%Q8Q9<9eym;VNAz_Fk~| zoZ7EHMRcVn_dv9B$AE;OB4gL@F~deftVEfZJ+m52X;ld)Xk2MZSL){o@3CY4$_TQ$ zQwFrcm8~?`M{=6oB3{N_mA%A*(bm1yuBq`-2ERBb zET)L90U+kFL!oZR8w{cS4FX9DMT_fenjdKwEmk&e2=WOBj7(P`q$iH7b{o`7sU}k% z|7S+o?0BB`?U+A%gEX;~X3oFX3(exbIW}C>lEr9m2wV4<-N-73jBfHt1?A%>(52n%spm_N(cQGN{oV>rV5OaeH!m zmD0mxmvyRi)e91c&g+x&trI2EP(Q7=iRo8r82wDzlh3yw(>Op5bkj)P_f%%eqf^_lgW7DCsH?2Z<9hLz7;e|cPrs4Jn0+K=f?+8n2nM9a4yhuq( zqX$5`ou;&W8X}+f%5_>Lg%93knsS}JK5rSMt&}9pQGpC8e8ky)-HTd-B!(J`aFA^_ zbkEdwd2qw@VFnM?@x`;XZ(#JCoKg|VTVG!MxFt`p@(W_rmu4`~iRHuu-})e=?A4=N7_S^_@Z({8U10^r}vb6KyPe8pWbY zu~!3lJRI)~KA(Jh#T+0eBoe}kJv8CKqjXl7fl9Z}A0du>-8WPjp|!(nEVr+WgEDl@ zf!N91NG2Qiy#|wSW~}DR-gWv$)q?;L`yTU6INTgw$hQc~9sBt^>Vg^59+7p9w+hXYZg+`jS^3IlDWbVZviiu)XBN`+mJ5(Te(8BfH>MIFsWf+YZLAUA^e=MU+ z9At`&crF<>?cS1fx0iZ>YWDdQhr|}+c9{jH8fip2@AtK4=(^DCQmEnx|6x|BJp2H` zBeKV`LL<^XK!SE{BZ#F+dzdG~!5?5K)FENQR_Tq-Bk)Pkq0RNlb7IH6L~c;pK#ppb z+TSvPS&t=CV^QvijfcTbyS64Bb&H4zSi5@@HoTPpb%>I^aQpzz5kl6^SA+{V`x4Xt zZEJXLV%`d?lMn3;qeh6w8PRx)SRp0AtP$z$TJJ*fw*ym=Vx=}i%-z~O!8icvJewg_ zXP+14iPW?jM`xjKCxy13eh**#cMPAai~~*n=1_$ zetmB`B#|Fv8^VuHtm4SD5Ye0;We6FNcErYLO{uV+Zjk==aJOaQ3Ph?vZ3$fTz zG5vpZx1O2lFUl?4C>ywgkMscn$k^?e4n7YhpG~kE%eCnPwC1pbJwVE^0!hk^3r9xu z<6omAxp=#%-Gz9kN*>M*^kXTVx)BG=cOoiupTu}-jGCC4qa79xE~!+s;~ytv^#$0 znB3n7tPGK2=qTAyxq!eJ=`IxTzx56C-7%A8rkJkO?J*cnd|Y)~9ZeivE^{mxPOkj! z5-!N_Z!j53&F;cXI==Ya)UAPKw|7gC z^9+Quxc`C=WwRT=4+$vyiyTZ@A?Eh(1X~NKgXAY^0TWKj_Z{Gv{uX5%4B@ihUt~$Q z)*&eHvUfpSd~}|t0*~(;rX8RRwlI&H14YKh0W?NtdK)67+OYOyG;Yg8b02A5l|>0# z*U4@!7u+>?z2Uj}jS+{;H>@w}z2}dfe)$ZT+6vV^arlHE|An-Q-X&Vnb8Q5*ZZFfB zA4d1(7z1xkhcj_LGf8p=5 z3bUTAaezB_D5mbO5~L19vg<>Zk~D;?_zL2)aAGdkb3JZIIUHoo_Q`J>XQ(xz18qvnb^8|f9+DCk#9J;Ua5Kiz7&g`N!%5Bm9AbxbH&774 z)yUY`RO^!JN%<#8MuS^9h(+zV8^gO*>4S%FYXzPb1$NFpG z-{{JPopX_zM(@`$+mVJ_{fIk!+??FspnWw_RLRT}eJmup7?3dq&VN*mwEs=)#zS1g zHY5K`S`>N(v16t7fz;fNZ}8Rbp=wn_Q2@#~9H`@X!R~vDyL0edL~P_`C_gsXHf*;9bP0v_KT~t5enD)fCUewzbB-0XX2K&0R{{EY<;J&@8w$3k+`O~!T5<%69;6teHDN0Qo(!5pTjMFAUBPk@n|n(`&>W1VmE) zmMrdnMiE~4iiDOTp(ppvZ#MNwKqX9+ZxP#y4R>TL-eAtLa~jB-L{PL~K<;V3D9(>k z9bRZF5L^%}J`I9MODNLbNwCH=u_nk5`}3QCH7(!T&pfJ7vu>q*f?4^s^tTOX*s=6X z6qpSHq9nws4jD5yl4A4f7Y zG&G@EkpEy~@N9ZXDq2ZBH-EX|0-AP~`H8q89; zN{CwSOBR)hov`Un#CDZ=WAO7T@e$2tsKEjYK2PvjRy zo#)V?yos*qEgMd=yo~HTO4rmClXj2lEN!RP+l%M-yfrWLkMI#q}4lXOs3&nI@)ule_me~O;%_Z zzX=-$yvUtw1)ZoV(DOBBP^6?{i^bUM8ZMtG@4gL)S`6n@3Rq?o_Y4-S~gF@e*DZ3dTK%xffL^9$HMn6N})07WCv7Eu{-;~H6|$it7( zoGpe$v?3Atmz?`bmxwBDH`?kKTIE<0tG}Q9j9-lGHt_oqX3msD0(fQ+8BoG{qSz?( zexaJTo4`1WyEgxztJCm3l|ED))SHK7;oNRQUf^N5S&sMK78K`j?1ae9nO0C@G<7>d zl!8p^oN!1`08+aVXA4sTHNQnr5yZEhl1olF{)vc?Rk6dkx_xxWOZ8JQOA1q?GeOmu z63`6q`9v{caQfA+EQM5B9El(yeD<0+urV+4*b-Y(3Q~oKzsu|)%zE^5|7xDSU6Va@ zyTeHuQqGrEul=x7IWQvQ60+9BoMnbOOeyo(^)T(pTOfCGV3YJSbQ4v@fo{RjEYAp) zhYZF2X#$)FK6^@jWxhZIegl}h3TOlWyEaSQfY>_y06(z5I)Uzk9*eaw~ab3iK6$qwq2fKNWvo|!LKz@uG0ESebi zsW7w`GWqNncY?t#|L^ajb*)*$1=`=E&1C;DvCC(j<*v2!lh^~{O%lj%DGID>L?QU2x3k*m9^&OJr0`|j$h{KU62j2s6M@`j*>U(+n z_yf@MbW|{5g3gK%eF?GUaItsw1cw)}I6fP93+ms_Z zVX8|6ytagmN|p*5_#Sw=v(v#(OZ@?xK^ef}uQ?lKI8(5JCws3#cmiP>^6{_99T%)K zbl{_VT}lv>peK6IOp_n{sWgU1pfK29EKD?=@a7Rexl|=Z?eLI^aE@k0ckH(7E}dCe z*Sn-{A2E2X<)|(^4TI+gW`=HV6UX)z{E&(4c}IIDn9xoVTruAS^;D{JX?jx@W%U3< zW#-pG8NbqLq5cyP`-sV0kaRDds&L;C4;0 zbvgO669?u!rh{C6^xq%b@L3pyqD4`q@c#O;OXs2Hce09Nu%vk1Pa5YD&Mr5VST9@SbZc>*C9Xd+%6rp z-EYA;Zzc{oJ9y??ZwiTK{4Z)>iNalO?iNXK=X&U*d`p$r$7L8;K^oTMMHxKfe^yqi zPA&1k&vL$b#u^Y;@+WJeCeE%L3T!=WG!&~Qf5H*AcD@XyN(q!QqCHiHA-o0dCwa9g z(iXEz0k8XI)acFI2I|fj1V?}0>>*rw#F*g`PiB4-5XbA`so8#oY-^ni1F1C>TJR?e zDK?7Ou%94ZF(t`T!;vH5QS|x}(J6LTq{kdZ397-~n~g44*7|(y8*p^qnDxeABktP0 zoRy}P+WbwC#no{K*{4gYdc8ncG1b&OV;;&zK*z&H!S12+J=mqNNLC6?Sp4xhZ$Z7z z(8gSPWAZaL>5TFx`+6p*u6}ZaX$B%}*3qDKH( zWqg0n{sYnRtbaGHM<`PMTtJN~?si(jH&eQbsd1~qzhBMu@Uc%&UXu#{SQG;zbOc;KwqMEgk;v^(db0sYB3^hb%nD}i=jdxlsOV5Y> z8KK!4DRMB;+JbPw{%{V6q2_x{4NnQJE};&7Ec#tc!RqL;)xH-vTWX>Wd$e&e|633E zi;gI6@nO(S5m9Cbu`+vkzC#yjoFpF{+Tl8;_=t41#EBmlaZA)I6#Ex21dB<5W~*}N zeC`oDDQqTZcBTLAkf|Rua|+uye8;PP`ouqsbHSpW;hQU!`B3 zvr_=OZ&- zAj*A!dqA=kQ9jS8sBkWekvL7vS-OVe)p~9`h9@MKH3|p1k_&w-{MUBaGZ@Ucp&kLx z`3feOQwjXM83!@|jp6T%gb3Q-r@Q*xH`~>lZea)&P++XeQfV_lQp`Pq5o(#-C?osl zX8V)vZYq~<ulg>7EiHrw=bq#a(J5v7 zn|sesdfVz3;?}tDyiN2|@r^Hd1f0`m$H={&cB;11FzTj2iGhjvQUxo=#wy*COurgJ zy%2{r|EGIGwsu^X{u1&Ef$8ThK4CE;f^d?;Nz#}kkNLcx>Up)dViWy>yq!H<^~VF7 zA&1*PrrZ>PMjm%P>Sp$ZZ>+)+Ysv($?ecr(kq`qJ+M@@SeE&O zv-p{+Ln%CWjg<3fYQyCQ!phDY!$2-;1xE)xa!xBa}rvLqe7k^X*>E~rmHd~JveuJbttDm@*^DK z(n0>Z!3;&*=fY}S6iSnnpYBqVu^W`sXObUADIuDz=pm;&YTqbb&Rd~7ng=D6-m6AJ z_cIX?0c}B;NOS{ed<-|e12Nqn0iGF`e@gRtAG-pWgse6&lsBgB<1ekRmb?sTV*5NS ziPP4msyAg>pM>ii40=2JNo>+qbgI#}w{Mu35AN+8HO` zZ(wOCxpeB2{j*s$FK=rtPE`rkxd^AOn1<|m>!KUPZ-J+ag4e(R=r#{)Fx@}pp)TwD zcsIHNy|_n)4O$W~VDBVqrAbE{2M;R_(hxK%iYi!(GO6e~RFbg7$Ef0zrer~~!A*aD z^$ag8#0}5fuRm%JR_ZtuXE0vEZY*IhI{;a$w82ToEPG||Qcrh;JZ&tY(iY1w{FDvs z#D{p!Tb89%E`U(B9{Q0UrdMznZ8LjnAEde|sw&urNA35x01l$r_o0l4No*PjiwF;b zxu!%vJkn+N(baR=A^K8NEoO=%Tv3+FQFNqCTR#YJEK5jvOUv;?BIM_X%NqxrBH(=2-=3!spWH-}OdEbMHmmlRk-x&q`dA7Ff(=H!S->nOmJ1*k| z*TXFIH*e5Pb!}*E*ZFyy5`6WrFHb;G4NjbnXpQ+izPGL=$Xx(gt@nbU_c|@`;`A6v zN`s9TTGiz&@`i!!6E9ZXn_)CI6wvv*Nyp%MFeWx65L{N?h1*x+*;vO=Pg%{*$3}y! zA$#TCo^%AUtp&e{V_(YWK7&Wl)fh*Hs=l(uhI>Ua48yk|ZFKQqBbnX*>6;BiLs(3f z@9AtmJcK_d$?6yDsc*fCu5h%EUfK6{Rw{5S5l(k)f5_6~lY}K)6yRpk5r7zllP6x} z(9Gj+)UHNpUJYhmXme#CS*#2$mo?J`+evDbQpfABdUl7HhFfqX(=#s=V+CTWbRz`( z8NxqkywkD%q^^90UDXJ!-XP!bG9c`2qP{t$_3`G)yot){#)!P%EbDJ=kZGEmc1;N@ zEE7m8nc0i!D-}O)l$OyGb_60B{N|%v!(66i6hBu{+h-vM`{f$qQj4w!qzgoX%!5ZT zG5+9EyM#A-N`w=Z7f&%SJsG!XZaZ?7fu}P5>?0T_B8&l7?z&MTh%DN&x%57W0u#~A z471q6zqCUbJc8voVKsNoCn&7E){zvfgnHUOyR^C9Yc8RF_&b^V&wb@^o$XB>RBgsYta z0sQ<3uj`HG)PUoyx6+CLD*Fg)-sV<%M*k$gy+hhY8YB89KQ?3=xw#%$n_?gW@xBFa z(?jI~*0j;Cu9&sntPLO>v1yi3$8Dz#rF(c*OOM)m9=@4h2sA*N@}Mn){jUG5mQegm zBAwN1>2)54kiZ)}Wi3}k8&Sz{M(;)%F;0y5G5(Ey(bL8u0OI`jawF8-Lz+XkgSe8u zmIa&`$H_Ekj_LB@-DMBk`Q>gbe4BZ>G@svR@)xNlmD}1Ku!Dgtg#>N-B2xet!Nmo8$6BM;>k$a+*24{@roUwkKc<)64+4lk8$R)G}fgr{Z|59_?@!0s24qDL#? zH+d~hcBPC;e3eh3pU-W-9&$xLNE)>`k~7Kdux6uW4H$n3X1ckQn;5W)5S&pGGBndt z-k9t+s_?^BQ_Tp(IS+cit_T>`nHBXvVk_z!h)tXSl468MwQDM}BOl`n=X=nBV<^*E zm52?)CIl!^e1S({5i=$JKmcr>)i_ zK{Ln*Taz$4D`v*GRIs7=>s{pFYZ)W)^PF__)TtZ&^&nH#?MrY<9lC52$nvL|3^jB* zhE+s1Kjtgq4GD1*W9|wjpwayn5wylRj`B;f_zFn#(=gr+q@!eGfmkL%6sVuD!J3|& z;}DpnV_Fvp+$P~Qt)d-fC)t3gYU{~t>0H@JCG6j(Lsw&Sd)8n-klWk@sraceR?iValhi+FoWi}NGZo9g)3~~hU)mK4XknZHM?TgYswxHaYD1wjsEvf z!ex}IF`H#pF!xLdo(>yKd-{v~<5g6gQKjugocZ(KeE!Ox6<+ddnR8UnVX6()1YL3* z(jR@vz2=Y0)S&?6a)#x=__DQ~F-;!+?^bj5JJB1i%%PO>YkbXaZV5C#l~8|Bs?o9b z2(UrgjUm5%%i(Xh)gff|(6ji}NgN%LG9`KCsgij=#h zuHTcpsIG;9zIJw*!2eGvXcEkX^8E+zcVuU@BOD$d@uDJ1s+zC+iq~Y?+)bC?yEE|J$i^ zbFh;t$xk~_bXKzTBa>=VvJ=cQYC~g;L(Fu_QWKN((&O~B3(7Q;Qj9XYTM@B}W5eOG z8r5oH>VeX9hcq++1&PK1S7s#={i%=@O}OwyL@mF*1D*$w;JJG22e;4tOGN}qL?9(6`s&+MR}su6uFEUlMMvl)o` zNHT1qO&1lXI)l)>w`+C^2zQWl-y1eHvFM@Wx_)0HK37?m$D-X1BkVoQxD>w38D)iJ z9@s+Zjcj~!M8}#)ffSawWYUPi%DCOM zSC$qzEKjYnPOUK_2eDHkg8A}Wxc9k2y5le8oinjDQMD+`FEHD0SsPWa{4cXmV$-3J z{XZ2)hhh8@{7$wj+fjFTIz}nzcnNG0USS6_iSz7W5F%c55k7PARljJauSj4e5FoKy zJ_Yy`N`4!!#OnkByedO+vmO)%fJdIIUt73Xjjt5gpHQb?@4k<_b<@M*tZncTkP&!= z?fOVqd2n}uuboK-o$R>~5Cq3g>v+oGk9?y}?{JTl??{jRLS1~)Ul6w|A&&0TslY-Q ze?*?EeK0JRFXkr0XXo+iu@weTFPLl~Qq^@|&3W|GOm1ZXaZ~uphvXbxk9Hi=Y+bY8 zQ1iiK_WAb|`CcK7b7ysxum+E=BGzgd3HX~RX?XR2Jrb#oTuaS{1Y{>@dI_dre0HES zvT#2hfqtEl^CoXP9j(nYGr$q^wsXwqRGvLgl;){8f~%u1CPz{a&$1`kap%CzuA;RZ zgt_<~u2``H3?KA|MMef^G`K*lTrts|40w@h&Ms%pmeoHMt$OA8h_aw5iqPC6aos9r zC{jh`d}XLqCf{?x$1wq4pgr<|49bJcAMy`}$ur>vai{OiI=yb~} z&8FqRK;Qm}^?u9Yrybh!w~CbB-?R*0VKGq5!&K;i-51ubYbyrojT4bWaqMHLiEa5# zkt4ef-kjD2o^SaNY@*iDp2^V^PhrW$~8#n&%@ZRt9 z2$P=@7V}J57xu_K_}v(Z3LQsFY;j%iCMcOuTCdm?_UEFM47qBx$DeV1)ASpt0?$>f z+jcF0QP%ap88)1rQfKyPKbPDN$(*B~MWZuE`*Y4${OSEUzART&s_b_i#B?99=hs{72AB;GTZpLMFPDE8s7L$*<`UohH z44Uj*n_TAy&hla_wZJIfan2mZz80V>(oREuJMYA#Y{!KvnsGoq&)kF_4a&uzKW&rp zGF1&Rxukp)1)sv{4Zqm4iO<^fK2b~YI~NTk$UeE$5{bNMKa-5>QZWX3P{LkYXCFvnGBKfV<=OqtK9`M27d%Nt{N;b9^XZe~`?Q(^| z-MItH;HLt4YqVoIi=0QsaEuUP`7&BOS5SO5jYIOt{`I?Oi*+phw(aCUa>bwfPyY03zZPmF zax9L))DcuoAt*v3I8H(+MPtbRpD;n7D20D_#4CZ1QPE>rKRPB-kuUqD>4#nPkyC#t z^4a&qKf9^v_ak4SW8{iHr~t=g)-me^AL~&Fd^DV-(J^v$C@ku@>MpzJ56k_NvGZeE zJN0QA*)>)AdG!MtpB*z@$Hr@X#JujJa95Q{d_36SFpVASa|HD1V1_;tFg-8?XmV^w z#K>prHa_+dvOfEF6$(!Mou<1ARb^BIGI>KcEl#Qu=?v*K>Dh-|OiadXIvFKE> z==U)K-G3eN>LBpb<$qC`z#%h#@cDj+4EW#z_;0E1!0&JYI&nHxS@WiYj$XKEi#JDz zRQd*KdT9>6sPMODfb`w%_Evc^fiYDr{-nc5X=+TvfiWzUl1=w2)#YI)Ga^SCG-M>$DPZ&TKZBCbb_eo}@Ab^wm;IyG}VtbNmwYYLf$4;V0Rd2ez=?z(e zIG>b=XZEqfItc#+HX_%gyF43^sNY7Kjp&GH1c}z*9=&MJ3v$;cNmGA*ZRh0y6oapKr$-K*h2vdfO`&*YOjmVI~uQF;*Zj!?57Z8~K6hr5>? zPmSZFnjQ~`V|zEFj{V^XIrcVoN4viy{z*-X$-{A@UnVx7qnK0iK?gYYkjc*oEp=>u zP{hBnKc^25N0K)F3n@UpEf*~-5K=m$U`aMJ%7)eU-O1VFw~&9kzg=2^qqhFd()ueW z%&dp!+`g99P3QI1R^X_u|D?16KRNh6Dy_dJ{X+Y1*3abCoV_aT=IdWB^=PTf<&4~`u1i?#j?b#t@7qEH?dLIwiIl zxk`;e6IVSEg6(~x&$5d;r)~wPkk1fo9E|E&=9=z6iGk)Yh$tCjEUCJI@e@nw0ZqcQ zgdxn;TU~!7^-^q#jAu`x3Xn9|d()-~0d4>CC?)+gcH;_bCHLf#6Lx)Wfq@W-5cOm? zUm(O>u1M)=@3G{R@?zZqs#ANGBWtRh&2wSjdpT#dkW_Bv{+g^p$aRmfz1;Zg z(wws0_TAa_a#Bd$qk#S_Y*6y#p`^~G)R7FX1Xq8OF~LUH)N@g(>3qu7XTHW)bt2-% zd0ee(@=08530H&>pk{&!6`{<2;2iSk@0WK5-zg@_&^xU01uUIlrCCWg2+Y%6 zG$V>`m8(2%ws8l*74+Ow7rkVL{FaXQ-Q?_V9P!v?A#g8X=y7|amI8Wp>*J}f>hUG{ zQyzcNR~!%mw0Oo@p?j`R3H8Fws0u6i(k!F%y%P47j@RkSqwR6{_3&+=72jkhvFBWC z!NKpTV6_PDm1DIea=eJ%!!qj1lbtoX^(g64>tnSJcfSUUnilqB4bUz+RS-j6r!j*c zUQn27@Py87xrOy~tNLs2KF-J$YU{CB`pSQ#o?06)aA2nrvDcJcDN+zQA<)C@2s7zJ z-hIE@JPVc@izjSi>CsBoldB5UHB=1r)s7x`3QY$Z8p^re`4kYv=z)Yo5uQX74)Vq~ z+SsfIBtF&bu*)GGO&QQvJ2Z9q4fC=3)_GHCyzKJo$XO2pTvx_o?Y9F4PUpS)xp059 zYI$9)=1g8YYm8{tgfEQJvfvfoy4|9dcU)uX%^$Z&gGXRdWsk3u+a$wWUe9`66L*C} zeaCqx3nO1njUV4`x$3p7%}Fh1CZR-WKs z8~44Yk6s|UH2<{7_zE%@Lsn=(WAODvftmqU1rQ=6%7p?lKa|uzY4WI}8+q4qAzix3 z&jiV@j6x^n{Sw@`Mv=fe%c(WjXa8g<2D5?JXf_vSM(@v4hsj-vxifwu189H$GM6;; ztP^5A4I_@Sat1XN5*x0Kf-UC>*qK|}dkyT>rM4Yzm`=e3qvS;;(3cFyy5R=y0RIg- z-dT2Z#&XQF;L4`KXdg0(X?p*g`BxyYyHqPmpbdR!!_T3Vdd$!NlKHA=O-G4EV&R_StdNM0N z$vqYqU0*S5pLIRxcD{c=mF1P^1H{JyyJ)gJ*dA?{4V{ZTe+iq|-P7*IbiSN*Pe;Cl zO(e6v>C4Z@ivMpv!k@J2Nf)pggvddcweKkUmIE2B3#GpiPyPCwuDX4FWrDtlgoX?-QV$Sfj^q@D8Vy-g=gxOUiYt*Hk?Vd?bi)W-}j$wIq>o2iuJG& zBe4`TP)>$Rvf0{2)Ig&#_5*$J^S2WCO}KZOs}4D16|92-*Ma@UeG>oI@rc?KSS-AbKT@BbH17GkWU)H?y5>{NS2UJ* zJDIs1t1 zp$_M|zsT-!Gw5hIKG0Sljy&=mr-x=_uxAs@x8F0L{zp-g7 zf_jr7c6rYq@Zb%E1z=FJIm#xjLEV|vh>XLs2y$ zcVi3=n}@!KWjO=UJ84Sm{P3xZzNm&BrsQQzhTGb3c$#4CHmYZNnz<{r2s+0{M0<|? z>6(8^Mv&fyNrQyx`_u z1rfBx`2-Z`vvi!IRi2M1z|`V8hEo@Ilx zCaYQk#?V3O{ZdOwo{U=n zaTb6yPc*Wh&A955!&El|eoNSruktibrmvmR%6-*(rO8T|I8Bw0tcE|_+9as^>+FB> z4B*n9o-@l}Fmqk6*QG7i7d^ggmr%;nHr?z{V=;*fDc2=c%7Nrw9HLcT6~n;PVZT7* zo|el!R4kB2Zj*9G7>Mp~p}b&ay)xj`&iVvW=Nx?Uk3>c0o6Dd&!p(4W3VC+pfKuW^ z_wl6iyEqT#;7g?~ZjoaV%;wB1V`G25Q@#3|1F-gWtm!?Jp^Kz+Z5<=_3#>xqg1ec-r6sh1#Y#V!M4b zHYNpr?WbQ?|8bT!_F98sWIC1s@sB=Z48KTz$TI*K(Y5w(#gp#?dD9B%aVLKs?jtr5 zWgjd!v-0)=2x{SMsK(E-8QU3j)22?cq%ZYyqWzSZmvqHBC+qn=lw4-*2Fug zJ=o^FSC>?&Sg-F+E&O=P@$F5M-c)o8kfVfa$fUxEWKwHrLdwj!w`G4CMZ%GrEtFn% zx5$e`iF;S-p<&O-JlP%if_2C_FR={R59reEA_gisu@R_ZZEt74X2dN{eI~lHl^BBY z{i000TXvK74m5&R;P^_S#u7mG22gFg5xbvwr+^-6>HUz5c~D|L1@GOB>VQVhsK}=l?2j@ptEbo9<0g z6p3OuhQcI7A_u8}I0h(oD@+nFfj|UIA5lIBADPC!tI-nTXvEt+B=ONQ2WS&HX0b5( zm`H`QLrv|9>p*`F?Edrna}{KCY%%Z8ML*jiaC~eVA9#X~sKUqt8nF9TDm&b0h97p7 z_&g`aeyq`;PorLpA1Ch$3&TEah0iYXZr68Fi9m8en%Dp(a4%SUnZ(>DOu6!s2}0Bk;W_ zNT*-vwB_gKKAzc)=6wc?-On2Q?F$|G>%pIn>1W|LxPsQ!U453n$Sze_S{}#(rAl63 zKnb$YJ`#WNJRO*O?K$5)$tkr$NOgAj(u=t0m#-)@^<@J(PQX}(AXPY7Po9LhW`wwX zvsguv<8+5_DWJeQIuOluuF9G`4>>g5s@w#>1xUJ?Jg zEj|XSz=IaY#S!)o$BjQNuK(Fo-S4ByzeOR1#;yyt+0kG(tf>o!Xu@{WvijbCC)W!2 zEST@^-0I))exq`!ht0~|jNPGWd=K3@Yde3WMy49e*UIeHapdkqPbcghD*G#;r9fTV zW_@1X=#?O!mHpH%jYknUW7DHm#+fKiGcyVz+X^QlY9@I=uX6Hi6n(+^%|?Wc9NI`zu;E%Q({ECBl2Qnf&QV)|I4e!Q;`^3_xv$h6R69 zsSMUTJy%24DdqUUg&F4W{8rMPXDw}Rx$i&~dKpW)1diTbLdN&zIa;<4;Q0Bvc&z~8 zmj+4LiU>6oVnA9VbsvddMJpuAYvMKI^rqjp+>q#L%>MNJKe(A;-x3yal7>hM!(oI*XbdH39NKSW zFnP=dq9g^O6!BT;rST(#{d+ev5dJ=i29SDtz0EuDuH-zVmRB4l(?!+T3PTW33E@HOlUK%pD}6#uOOfck zaFp$(yH?eHGgTKOORJ$4SAb}hCCcoU5H(Yr60ljz;s=#-vzccy^k&?9Ol z5lJMWPw|<&EY5h}X$2_LqBGww8WJB10@kn!5nNf*wFL4rDs00#O5OCbMKCsnQt_M+ z!#B}kQ)cq#HeqZ4Vp)GGru?fLyK~(3QGN^I&1kruybpO;Tkq0ZK=Ql2d|7&j&lp&#wi!Av-M@bLRgZ4a&02J}ksxCK8<~2Oy4uQSGMD&8o$^uT9?_O` z&dq#8?0r2&2>?^it(Z`;#vd^6hfN3u{&QB#zSLWl6-)df&&+>igrfzoUt#%f!|PkR za8R67bY>R=00kWqy4~6adtt{yC_TqKou%;Qc^}%Gt{o!0oZdv{Yjl<0r9hX#%4pZ; zh217oW>~=0V=1*fvDXd8b#9N8Ti=C9!DKjGne(vAq{Zfw&ea!wQOasW(MxGy@)HK1 z!O8J8fN8HFi>iNq-VLUF0bL@OSX)Yzy#j{}SKkilseri|$v%Pt?H4Co7n#jw# ztAqB$X&&R%DglaMehf!cA||<)V%~0gIorWRFhp@v%yHSZ((AkkIwSyn2v&~I*tZf_ z?MUVk=WJy~hP$997MoJ1Zg{L$pP03*i})T$`8C%OT*iN=0`o~Z2C|eQA9Me_X$`a1 z+dChbfmnx!BB^>}6@2HmwI7a|NWJttDvQT0Ws3 z%a`hLP#>9o zO^_uHWp<|YJ0mL1UUdAl>vn-ebgv=CDdUCluE62?r2)=W=}c+WCTr(r+SB#%L8gkn z((qs}PH8W*&UiK{^(~QCKYhx`^F)YINIpUKWafYV3aD5pXzKPBFM;c6#)G97LqbUR z?ifk^*4-OsS@i~LFB~bS=ov6*eDvo#pH&HrYA6C1!zrAaJSY(nro9s?ZZg#X1m^_3D)kJ z^%#GqdY$9GmcpsN8D73vf!%iz1C|Dpc+)ARp8f8pN*j35L= zp*W1;G)C?kjG!@^CI}pcF_Iu)5<9vkAp(D;V3?$E=(`*0FnZYSUB4vQv5XKAhhW(q z`mS`6&yZjA0T!mnA#*VD`)%kSNkn~MGW$up`oTX*O*ws#9f;mc(0L?qo7&XD~%jtN9KC z@tEJl+=Hd3(NQWhG1tA_8thA9aHtle7#f|FR2!o?!V`b zicKxfU`vDEircylaFari$u<@-N1~D*fhZVxgh?9RZ_&uChApRR}D9!A`9p;B0i?B5I%puyFN>OkOZ} z3m+!qyUA!Wo=oB0Sbc&>f0#ND+R7wo8%%*6aDni8;=);oT*lv;5T4z^rkagl@<0NA zE%Pjs*&otGX)a0u!PNYI_DX=>e3wg zS?fbtzKEX^NnxjlWmgG_9L)d*P?OGoD?J12WJ58ex@Kn&S8}iK9Q3)E=!k8km_gCO zUV~+J3xtWIwD)<5v)^kCR)+tlNC-9K$|awj?hn6(f>Mfd&b6~B*J)kL@69iV33B9B zhk0>qb%k;4_oP6l>1EmL#eHA>08mQ<1QY-O00;mBky}|^N#!pyD*yodp#T5@9hb2= z2^W`7R|ro8>mP|Em!ek)Vt*m6LS^(dVKQg{3LAN zH6kh!aeVgb;?3z-Z!gZ?oa2wsZf91Nb1|LHmd&zCr&E#57i9&_uj?{jHtCeV@9fCm z%UXS^QuV36T{c;+zpd(>ou*nH?Fjf&Ki2t9`YuivjX0%WPO7S`j(>#M6^kmmnMX&W zC}A@9X+_IB zkLj}oEYGeLr~tlJDa=2;2M|9m%ZBDNrB48$P#>!Na1k}PMKn*DP`*ExR9OgW0mqlW zSqN7F50@8O2qS-PA!kimHD#IWrI*2aYk0-*r_F6=QC_EQ2l~qL0O~i5?m+>7>dk5q zRj6#m4D@PIK8!_Hh&aNv*N7rblNzL|URKBl>;g~ga-NEZXeEJ7moVQ&Ro*B)#y_K& zlj!5);I^zADayNIFc`E?hWPL0(E>#zx%vY(gl{mBtKol0?C*am>;}WJ7@BQD04BlS z{^&2XfsIFFk678>eK zA^pO0Z3m|xkJQ?vZ{ZEld=VUs#i42_A0u*Ofe?0fQsCGI#h;bisC@X^)%EbB56%TN zIX(NXiWYwhEpJ^-?^Er)svMS6XsPpHgFbh3alewFKcDuuw62Rw#d^-fhSi;A8cc1t zg(Xmbwngx&#EmdMQe_&wf1T!ZDb!J*X4@34g4t49jMjGe%%ZD@Lr}WV1_jQemL0U9 zk!j2<-E9E!DsxANqi$y5+(LQ-tPPt-gOrqnlcpTCswkDE;0#mee2JMA?%x z$P`rsNu)Ri$e{D%s7aZ$+q$0wJK@`RalHaGXUiJt zKQE;XY@sx_Q6az_>2U>Ggc(W^MqWZZ6W|xzrz?aB%QCvov-&no959PA&*GJc<|Pbs ze*O~0IH%x^;=3Axs`3FML2x%f2(H0paR5|lRF?%nPepuN0^*^~rziu<(h=Z}njC+C z+yL2%l|e^zb=r>N`Kxn*;(H_p;u9EmQGryCMlG{;!K{EwB$f+ULUWiAdrA+F%ND3B zS3O*k;stV)!}P0QBqkHRe$;Q~$UVygzAmppyUfKwXtch7pjv9e^RLg|zI-lTon45i zfrbkrG&?U5Xoa+fR>*(^)!8gVO;~@3hubW^H2`9it_2~!jjAX{eT5!U1q=X{DDvn! z%|!_69G&%Nilz2K_MmpL+6Rd zg`cihx+3! zS(&3kP0$Snzvwmc5Y|gAAETBAPXv4>#?c(4CAw>2aLJJENx(>oS(N2VAhI}v_;?Ax zYLEs*c(yEPsXHXEaa4cwfkKmhuI)eyIA(*aUF)3%16Fwyyqm^s?C?#-@{t%=@H&43 zG|@Hj0fFK-%)CNWNP0n}8R_>;P>xUDTujeiU!0!3diD|l(GPD<{{8Lgo0I2*Rsy9H z>G)(dXq5>~2ZbRRf`a@BROYk1c?FF@o&!TwAj|I3)mYpkStx%)5joBr&=XpaodF~7 zSQ^>D@n;E`SI{kf5H~xI)U4E6CSW6%y{eU~=TPg*8KabyMZN-6odQo1)Z%1VL2fe? zB9Xj0N16ywK-J0tgru-2XFW%{!DHnGS(IiHcjxS(_43+JnqBez_uqG2d|a@+G|2RW zLlvXQLX=1jRR=oD7TkOZ?ZH7@!kP=cZ45TEe@4>cM^Co@D6Xr&9`38Z%~AjnWT0A& zz^y;JRN}VQeO8qP z8KME=H5d_QF?a(YD@gw;gAk=)R|Kd776JL0MwNjlj%eU%Nz|@5MnlRjY9z^l6H|jk zW>KSM7j{_BfQ;j04DlbdsC(`gDdP^9b^0%qygJ>oJ;)CD-L>(&HztS z=Y*ytM4c{17K&Jz0MT)S>IBXB;2|rX9u9oIYlrTliSAIe;cE)ZH%^UZ5V}ML1ONc^ zrDv#Tv;~({ z@iJ@J>hf@d1(_vS`{}?11ArI%Ee*QXybB_A`gHHZj`3IZZKgu0c@k02$YlcP$k#D||T7DiD9cymmmV$>FDJ zF4rcG*QGrE8b(PH$kwASZ%WJ&r$ma37e(!lwI~K?k)yZ+K#o=SE^LXZt*qs?lwVt` zKdB)LGX}L(_Rg;O&usC6u&!lM8p;#+XweOSC(aMU&p6K{DRdZqy2G_+f5{d+U-ml{ zAaDx40&2^zR0Vb$)lt(_f$=-UT+=CLc&q7jIO_LJ71W6Zbc<4gE_NsH8V5o7iy0rZ zzXo$X**UXkFIj(f|BbRvd7MfcHv(BJRh2oI~LF_yK(bqWpcZ4m8T$GQ$xfzxbM17M!Rn2s7L%wP3Bp{rOlgWq__6J_~HnC1FFOW!Zj&>I3@wb zHah)+I}@X^?1oGP=atMXH7C?S`ht<(kl@9R0pJ7g7J#@`X_Rx;Mnfva4CW5&731BK z%fCbMf)Y_6$&#^X2Ek2=YZ;z#O!v0P-r)$Fu{x4j0wTW5HP>Q*KVr4r|M~C#p>P7? zMGPk-JS*4SW*N}KF7jy}6*s7V1%uuYQ(6t+)vWOe*YI~=4Gf>4Ps$SkM9JVs8L@+?)oP4%j zaI6}DVP1j%?_bfXk)7c6LeZ6m>mjL1W`io@c5<6juvm_+_Q5EAV)T)J?pX9lKG^0I zH{#in2)qs25SWfkLh^$B5JGNAf-Q)-1xrGS-`^`C-IR5CmloMyw6~e04U9QesDDs4 zR;qa*fKGycb@t8l?Zu1FIr+3)NUsY%XX&&`oz3$B4|;htx%#2r3oiG6cnGgP84V2n zPho*iF_?*Rnp03#*$tw9Yn%Dgc?PB%$mTRho2{l?g|TJWG04OOBF2Hyb-8SK+c>Kr z20S=yOEir555`41B2ldU=IS z_H!Y^LH7zi(u?J=n3LXG`JwDwYxi#`xbdtH(WBb5(pi9 z7OcIYvqGfeFq*if@{lNjY1r5?O>2A1nesch017jU0AC(TyM||YTCC9RH9Xb@II`S; z#>%NeEYijPlfzG+BE@IWpAy;#h9{tURcgGZr8tKgA210*BLObhYm8ctVpITK!KyYdhyv6&!xJl1sF>7;7>AHxS7)0WLazp1nMb| z7`5&Zgk4=Rs*et_qC<&TEMd7kJ3l@>C5IbpHf14y2aW6jhIPh@0}6p|!3SbFmGSh1 zz9}cDb1u#x@>@Pu$J6)75dO_;gg8*^50IW`HI+&G$kE-`&t|PC%5A{z#*RJM@cl28 z6Mg?r)i1-43*`cMG}e&1c}`XbhBCko&i04eXqdF#Ply5oN!Fmj&7wUu+h1RH4c z#wnPUgfJPoiHU<{aaWWN?W*BI@{aM*Gw^O(tbwORR4xP9j z4`ZnyoU>8BP~HgJZ!)L3?+%2cL%akbcsdrpm2$T%xH-_MJ+24QuljwbUBVr_bQ=eE zBU7xi#J5pad=o7`CLhrO_6_gw0=R{LUWJzRqmEckXX1r8(3 z&Umg)pm?~V%<)tW6JY9BfAdz|EUIa>EDD*KrCsn&E2_-n1J1r}HT6f8#3D<7xXqYy zI<#*S^lmw07dqV0qOozaS<}pK0Sr*IqYgv(hxa;CEtr~htVKbdnYR;Y9;|Cy2hl(b z;$A%J(vO^uf2iuu>J|l3Xjfe|8g_ASAthzJ0SvWR3xl(vYk_c+wNRo0Obef# zTmx*a*Wv#gIh+8kw6XSD`(heoS&GmNc&M@_ ztreMSPW&Zlp0Zh^TCsA0`3hZ3Ob&#GCNT&tw%T^dDegupbdAv|w8`jXAt0`W;d+G% zp1cxCe?7a#Sx($uz(b=0|XWT9x7b} z1dX&L1=n&(^t)QW*SP3gO$f?muhxOVi2$+IfAd3WEM?armk&!{6iMF=bJ)vKllCJ- zcNBOql*L6YWjno*KC~;nTyR0c@|x5Yoji;%|2)IIm;uA4I2MO$N{`h{+}eHzrAs1A z>pI|X6o0DzE>|I3Tw4v4Q_W06zA&2j&NTNln@1xq^;zN+rB=I*>RWY81M8AYn5r(5 ze`vADHWejd0}BsxSQnbCS*X{^yDXq7R)LZm7GFznJCMOu$k*bD0Day6;Cjp>2Qv9T z>mU!`KLL3o37Sr|@&6@wfAGtwKR3Yh_nojZ=x5?d1I)qJm5GHR1`|N3I*4;TmyBs; zDlgsh)Lspbm1We*Ro3!LeTd6Zn$M)&e{xYkLvOkP#tpDvs4;PoaJUthiT5B#glGZ)F$37-*yD zE>`4);Rky@fYvm=&2kw)P{2rK!q0z-ikouCXRELbdaO0p z;=2@+X*EsN&kkpv?|(6;WeOA)@yCmX+>=+qn?I!P#Ioy~Yr_b;qz;Z8TqwP4}9&Aw1@c7-ics!|hU*^vK>s zK>QuD0he%!-o^GNotO8ixyKuke>R_k3}ltTKv*B*jfF9KNoxJkeG=eAIXqssIc65@`=w>{%o+>6SrgLK4=c(@b`iCE{w*A5W{m z!1eD`=wk4Az4?~mF+Nd57^7!=FXI~5J6C(-cge=zgFXB@@1 z=@c7GWswD*65_pwFDK$@_}dRJ0`9=X3pj4k3%p+5Oy$YN)O7~YyR7)AR(mjJ7%o=! z#ZNX6|DK1_W*Mx71A~q{9tQPV}sTa5YVy zqr3lMCve}tf3GeC!`-J4eI!yKVY|Mvpu3#GRO{l(!$Lx*TgW{bSjb(!unfpe=gVpl`QA;)pR?6 zJ=jd6Yh+U=WEytGGu&0YO);U7unR?DI@t#B5INv+@6U32$UH%9hSp;hk&Ue|hEpZb z$_3e88pJL;XCMgQfBgt=zBW62mEG*036;)nGQ1^)^6Ef&v%4<#iuiez-YoN|YV#L( zdUmHXIl8kc*MV`gFcTgYdGf5dt2yD7l*{X!s<-em5=wtLfawe(4c}=hcq5UBgX&I4 z8F(0?00%0~Q~QQ4c^8WF92{X#1W4bS^HBglpu22qJVAlge@eWe9OXA9aPW3MGC`hz zt|qjoyouvps#a6=X~5ANI{aOwcxvkM^_!D#$Kut=_ZMUFr<4D<3fCvG+OsOjhGdo$ zRViUi`cR1T?52qDmU2YU;jZH{cR9_6&wzD!d#J7xY;QUO#aPbar^LCbPbJu4JUS|9 zEhef4s;;x9e?kn`XTjv1ALNU4uQVaFos#3BKKmLqd@IaBi}+aFVC``-+~PJ5J?<7Y zCQ|OJva~ZzThy63-EkY3|GT6dmloGTo&K;U4^1zRF#Nd0k7L3AqD8;z8wD5VM7;l{ z>j6!t@|>J4b=!wYV-g6`o$^l!j;d=!BCd+q%K; z7E!I_f4qF6IIkOeIp2a&Y{$44Siib*8ULI%3Xt=7a1gjfS!U!v=Nnte1`C6Q4w~0e z8Z!3+M=C$9DDQB|biP{07OVX0m*%C0RV8r}Z8-zZ^EX$Zb z7U?_YiN!b-iS_hlj_dy2M))fWgYL6^;*}XBf1gX{P!_gKMoyw-z5L?IP9>QKw#)%z za=zX{)iq+P?h0Aqtwq%C@~|uYasYaKaOKXhLfc-a$+}q@ZRAYVFTZNGPyW`keR8#J zObpYML9N*Tl8gi1cPMi+=y}tTKXS&Q=@yBDnG}AVFK3BG31RQotz&NSWJ7j&)ScTF zf12GPhXrVe{04z1RX#?2GiaztfzEy_-0RxtI)hw%t@8mhLe(a zP8q@mZcCKABau#DV+@t9lX`D$o7QUje3S^k`qf3{R7iZ>mfeA1ZXeavvQ^4>KR6Dq=5T|=7-kE9fhzK3vR7(8ErTq(JW99% zYBUs&@PMVnXDpno2%R^lD+=N9M`6k}Ol_`41W(k^_E1#SGNFN7>%J?#!GdCZeNv^1 z)E-j!4Xd5&<$S>#27EMnK!tGji7T#+n+V5Qw0JR@_?V%35?+pBx6k5JOAeU(FGVKp zfDQeQbZc2A+|08@oEw)vf5|biPO5e*w0)zhHTCg>doNMzT==}@6uULeT~Mg(^dj>{ z13g>yD(!_8&HMpVLa9}>rT4;Q3(Ntb3|&_sUFhSeysZg#9#wZF6MWlkuzqt`)p)6X zeKA9DcR5b3NNL}XRglmgJVq`$hpOq)(Rxu9bP|NOkzJ)LOE~q$e=Oi*p6W#rrqyU( z;b-pE%hSjkRhr><_%@_vWx3{7r-|}l{ZH-EaA##eG*(?e|aWpUZ(4hLrk4R8%~xR4~tCQqZre^vl!W|?Es|QFtn=F!y_=( zL#yAVf{4^T*qmuu8+Dt*J_4;rHrg(E(zSwMv3pU5zK^O6z3G9}t~R9J(;c`}dnVtN znq(QLJy|+=-x+Pki>%%d?{X~pwOL0F_C#D>f408zmF-4VN`H=c+nlrd#!jmBW~^2&Csa8n?Z@N~*WxmIafTJR~Ym zXd~)dzA0AKNcMzyo=V7HQ)tS^%X|uCI6QmaR)wBlLR;3JSSr}v5arDqF5{w?9b3@Q zZp!#E{doz_e==_8i-5Nf%v;9^lMTiWPjq74sz-cSp{VJ3R!+a)qqJ}5lE$C4)+Gb& z^&Vuic9(53!7bwBa=wVFtj3H?2}EF5_Ut*mFNDeoYP>(VanIh#oVMLt?<4EO0160h z14}TQ{e-T+Y%I0@JF;_m%OiQ|_{FOl!v-!p*(7v^7M1*!1Rg6f#Es?E|Poy}T&t zQYM9we^c3(mp3<9OUf5m>RZU7I_3ABFDbJ`Ix$ORY1N06yPZBid3AC6;`HQ=`(EP9 zX#X$MEByD#{uk4$z2C@peHnL`8G~AH9G?TM7O;H(S8Wv@(k&pqgGa^-sD`iTEeCv6 zin_r;zk}{bJgU%3G2lv?(lr4)ylSw>=U5*yf5+DbsUQxQjXY_n-&Bn{Cc)R&$H3795co^JKL{bc}jK#RZgF*a)l#NWYL)JDh}no|rVcJ7;+m>BZXF3pMd zUeY9+(M_aycLEZcHd}Gi2#fYyGpT!VH5THsK7aS&35_Kvx^IymkLVgcn*n2kAuq9B zW@8=^|JptmDAK(zKEqK%J{Tftxvn9HaPY5Bzq;qbKkPW2#eaXd{}q6L906F9XLFd} zzxC;1{D(7r8&>@-c(9rNThYFk?jD-E>KhRa(6+5n-?X#&S5e$lM*P2u`yYJW;-9^C zvzNAg2sHvr7nkjQ2p)fzyR$dXdx7D7+dn*fGJ^k&E#v2B{lotd`um)|dVcbKf3HiU z*AG|DaHoGfT{B?vi8UV*(y6i~bOZl;J2M9MV|YaWsb)i41czqv>;_xFf1Vbm&=ymiMhO zoamUi5ufbQ*TGT-YV}wcz>+BQ`&1&}R>GLVkAH8twGO256_@aS2q%C1)_b&UPqsLQ zqHay(q^4vT-sO~ZH-F3*$m1Y>6-8L!O^_kJ5+2)oo2|VsOkt(&mXiC+^dfq1r!7l! z)!#O={U}`2rE1v5dbsZVp>8u4&9&e+dZ>3M1tUCz+-Zu%s%8@Gm~PHe;wv6u;;ZKE zIar>fE~59i)q)4EaD#sbzcf`8r}$PCx=w;n>CTRlZ_c3rL(j-%N{s*D72471wd>-rEa{tEOWJpOoJn{n%Jr1ZOr>G zkL@Hm2X70?7#f*GdcU;rI5Pe^8i_alcR9zy-oeNtR*CI3K}&zW@(iT#$yK*G@8%#( z|5DR5F)V5?Nleo8uUy11*@Ra=89JC*c6%dkoAIL-37${4a9rQM-LVfXXF%eEvB~-o z@sBA3ZPyRBo-XQdt#&s5@NJJ-vEi0s^A8Z*sx4g(1!&;8(_)E7tmTal0Tn3Xj!NEh z+oSu(lquHJ1^<7flGa6s+mT=c;n&N{cI%RmTg$lazDQSPY_8+ff5S(ZpO>2_fjp^6 z>!SOrzS_KPpAK&Lly~A54{V{Pt?$y+Q@bX#?QFg79>cP*cVh%1CI>BgQ4O8s;~f(t zY>jd{VL(?pgyLMfceD?JZ}X%#rZ`TfdW+Y}*z0ijQP6+;Gxt(-m!w?p`AH37>~Kq# z*#0l?PaCbg3^&f*den*vw;j*gV`y}1uUl=l(xtxZCV-*x2Tj1q5B5)hvWb8D32@x* z&OkPE6D9rFa$@Dzqua%S!xVZam>b#PpSFok2rjKq4@Uj!EoqHlLd8zrRvgQd3LWz2 zpa{aaIP|e~R~&!Si`3D9=OTc1_uoE-$?tBJ`!&HO zmexr(_fDN~!pK$?QP`CWccZJGEMpw_Uki)ZSK=&s&cf1rF?1z5wd^lN$G=(%77si& zA$Uc_mm81jDJi1$X7_EAorY+JF?fJ|#gLcGdngSKw^w4NpS{})h8 z0|XQl0000800WU*S-`>^mW?m~0NBTup@Ik}e`|9i$C2Q7{)+ZYOmu?=G1BO<4(`#n z;}NBu*m>>D$kGNq0XBgG*&@&lbvH=DzWwi)k9t2EASLVUyFr%3@Hl(Xtha4-dDUmdi&6IMv(KL$J^Sq07um-vk-gjY ze^*VNeP|Z_ZP|+K+h$YG%f4#r3B371i0swN7pHGNoKE_?J}c{a_TufEkMCdp>HCjw z-+#a#q20lwM~~i}zRSM&m#?#GwO)#qsCxziPYw8NHci`So4SGl zi|MlJMO!Yrg9G{CqU^-iU#f4|X4aW+e|0bJ`ek*Yez_{UE9>jBxx5480qW-RuhRGtR!RyUiMZ74tuHtJAh^TKVEi^d+oAsopGJ%OA$sf9una z&%b&8@%i-Im#-#vfvU*VIH>}JzfOWnn~Y&$V+#m}3n zr6n9^vl2!-pRU_xE!uuN&bUoouEZ3GVJhc`SSjaIafg7qadz9nlA5nCKK%JTJQwZw zAPYb6^apI;jt&l{({i~43OUKnf2e7W_;0I=4dOl@XZfFiG+x$S56#5ff0%r5dU^S> zUNrvC_V;%{82Q1cg9D@=(ZUEMAx&V>UeRyGlqWugfu8>O?(O@JA2dRteZJn#0pO9G z_T;AydO3LU_Vw%MZ@!7P1kzan7FE-OZ(e@*NbNpAqauI#=EKM5uU?(Lf6t?fp1(hR z@%H^UIsNsY-=BW?cq+eqc>DeP7pEWKi$6?w{Ndl9zlVk+?(XHAZ{JQ&fBcA}n$Vys zKopGSV74r~E}OnU3MiV3pTw*m9n+%Vp2mNlXC3W!rjl$`uGfIC3~|&Et1tjF+;?5p zH`(06d8fhAA9Jw)E>YE0e?OfTomehpe|Devc?m75a#?i(ddVtW^m-;H$j^X-Rb5s$ z?F#5%n>Dq_7EPN87+~hF_9O}%`<>tv03(02I z|9n2rN@q=R)OtE*w8y|W$`!RdCc)#s1Kq{vRxPM4BfoBd)7EBI#|}f$KcDG0KEcHB zOW2Ok1=xnUmYZc?&@0yhc-+~i(FAB&)N}fAq&I_4LGf+zUaUbz0Q-bZfXkUR3zzDd zWRXt+fkGRaSd)2Ws2f}Rrk)$ z$w(IPIL28+a*hVVAdwoE;b{ZM9qi_iwI=cOWBcVUBGru@LWBe%ytI`P>Qs2LFPZ1^fy%8(MX#E+t7`O#;`} zC34Ax)J&rsDts_i6UPBU3!HbN1)v5RSlW&~c>O zktaL&=}rmK5znnaHEv<+`ph>F6$~{l63qJP=LSvNN-XD7hscM<_FvfCRs&!&J%v3r z0q6z&l4KM%n8(=yZg!1Z&(0e{CBe6|IY+bBCL#7ppES#N=|q555r>Rarm%{$f-28(7#DzV+P*@e9fYm`FCH?P^)o z*RaX2Do`*$C4r6JV9RV#Ed{a^S{G5@RBcnENN)AB zdcG6>e`yLYPqBSL!ozt9&?VoC@)ROmFsuM6!g+xG@Qc(*k>>$iWXo*^u9(6l0_!e~tGC6Ae0QC49 z&_jgnq9~yuO+dHkZYx+STL&M-Vc`dC*RBHoe=tS5Vg(yaq+i1l{FLky@vY2I-7g|4 z987xP_|ZU=bW(=+pd6C9pSK+!j7}-imX0Nx?)A0K!V+q9Y*zt1#+~hjhN`R_0 z3`3JovK5ko<=Ftn3n;2D3m)O5?54mYMY$?QBh)4M%YH})3@O(^ftUrA^@QICTZ6>v ze@V`IO`b*=+r*Q(xY%44Ir)gPCmqIn&+C`7RgHX!OFk^NWXD2v$W1>+dMFfBxTe^su#Y`&p(7tl&+64CvD);&ebqj$M3HIgXl|LAa%qw8W@+-#L29&lrn9SJB?YLj+3+pe}PoD z5DM%F-7Cya0`+tYIc=?eL>0cs_5k2jrwk~v631E88<*HxHUe;yu-)yqO0!yj`UZxt zt|%OYaH5Og8z&Z&0DG~41c2y`f1_Ou+v%#AYhuMwAs>R_wJ86J*%G!P{sm?T`&kpT zi+1!OHasMHIFzjqGqQOF7zG^>ep-DYtsPSzQ3TF^hbxXH0J#qq=Kmjcz7n74^JqJ*G$Se=oLjI(U8% zBQyFSGTIHWga*~f`Uv#?HB4}`5^XiJ(L_F-M(!9{W?@Bxzv&7gUMj(c1f*urudak7cI4uUMCd_tHb-9g!12|Ox5 zBq?;Rz__p0L&$;;zln36e~Y@)b0#d)Lm!hGQ$8};GteDtSJRfTZZ*L7)qD1ilMZ6? zA<7+4z$$_UF}2hv>3M($tm&RPoB7iy`+a8X|3+@1t6*;<`(4}IRC98{*S^pO0f#MwWcedc;o2F%b%pR}{~?^ibu`<8Nt-!j{8e=P+?Y7c73L?=qA!&lyNTPp6nlaiC*o4N`TfHfLN#)rv`JG&Om^B_%juvYHXP zEwy)0JCflWe=r76kWhsu4Vuqn@hbs^alJczcl5=VUjg6POYa<1q-^?t4rW*6pLSRd zYy=$(!pSj+aL9mD^kT^qB?=aZps=P^k-?YIKEe=l(x0Owtyocq|8Hx-^V;4y>% z4g8BQv)j@>OGdUbZ$ww;y$A2Ayb%mdDvG^4rp+dkNx%&o3aP?2(vZ*9i+O~dyAH88 zP4-B&ess*9vCx)}+wp48OO8KLa6-2!osy6zTD}q&AnPfw${NFz=u|WoyHujd z!$_TQp2Hxz8Biy?jVrU|ZK@pzjImBl)t_zyX*#Qi6USdjEy%95LJXyWjd~anFYKlx zn1iUh3gtjX@#AgPHI_4u-d6gu)thesP`hO_BL|wNanrMTbt$^Q{-;Ocu5ZguKElzJ z^LfRgf7wEm7^>eHign+WN7dHLe^!VKXd3M`&>9+uEh%vBkYJB3n{qzgw976CfU!p1 zai}dl`ZpCur72CyQ~)yM8%2VVx&w+V#JB1{`~LkaS`iBV+f5&K7@1xWGYYu}tjSSG zi+YSW`V(xtTXf5F$^cO5vVs{UCK%|c1Jit-VNfOj)8S^u{$4N3ZD-CUhy=2FWjg%&?Then5h#lymLtr9~^$%1zIIN_M#uHj18qS z!cSAQ;4EaX=KgFf*gw;5e*<7-_O0d?1l`KD^qzFb*(C;1S)G$ojH2HP6ln8tX5mDE z9doC_{E!>0=96Gr)OwsT(>k#jm;UKe&>oz3 z(_OHJ^T0mbm(!hq>d`;659i%<7jtp*&>rkp?NDI0a67xT*$%0&e~)sDJJJmRmw>Wj zu~~w8wd_V@gledPh62x6Ik6g{9!Y>~oF=Fi$**u%>WOjD$+LS-rrfeAaB1 z9C<^pDTxXU@Cfv1l?FvtM9%c*fRkz@{5}BzU4aJVpB*Hzz|MvP50dikp!Nx~^tH?b zYj4S;1Y>~UN4wNG>R5_7Pc%KqpJu#Kzf1YXqVcs+Z?GPHf6SW|v<@9;_n{SNLrymEL*RX0fR5P$S9Co^+p3 zAMx6oO%ooL>6deV#`*uS{REj*cb;^A9MX8k5~3ZBHwEdhY(uh7Q(RdH&6OQ}uwqTN zBTW_+LxK|Ue`ESJo@d7976d zMH&J4u0pb(-8wJ;lPXEaks+T(pW#6GGe}?1WRe>}#<@>4@o7Jz>nBQPJ5uDldP)}af|VA z5^b>;nua#_0~)#M#kRK`5fTc|h2gLUim?^U0iDVmD4wMXgq{>xL?b1#>_DSQc6wJL zEDG7=qj4)n;`}`CuFB8z^YbJyZu0Eem)J;t`{ED$4gL?Gef70^wwiw>V}ysnef9Y> ze~hB#*eu1)fG({ADBg7ZD80YT>A2jdJHisxW=O$PsmLm3#0+hYQ6Q_TW{c}WXcUjL z*WY}#10E+8GdLnaMR0*4(J?tF;_W4gO*rmG4hMIvxC2{cR`r;JK9p$9kvDu;$6!^6 z4k)#t^1-k2cuyEWvZDyNMYBXFIniN$f0Fz5vTG}QdX7P6c>bnE8u0|L`+eV)8)E`w z=o&*bQ&(LMRVEEaxz^M^lTStom`}PBt-X5#*Dihjy&%3QUFMb}T{q)mIurD^mkTky z`1(sxV@aKYTZ|?x67#ya0Mr8(<1uiY7y3JD$K6u@apF-0flrJzPiE!oW< zXCDP7yp=$-M>OFdu7p@-pG}^9p(L{JJ{br=@_SFD|Lz)tEbsBl`%l-Kf4T?EfK))9 zKau(*F0$l6ktAm#8@I1iYHhoBR_%i_X+2fi@a4C9}7^B)Njg1 zc?z~2u+Z9pF1pzoo-|yEgmYYY4sg*GYtJ1)3)ZX!fC4z} zMNW&eh{Wgcn&2qQd0|8se-*#;l9@fW$Bt-pye@(JcTS0mgf~yS!lFxwj^8I8rOvjy zykg37aXJN1$vz(eyd#b;R2@p*$Gh@|*P!YtI*@_AkTDmZegbXefYi0~-O3El_f1t32&}c_DElXw& z{RR01I<4kcbuh!ii*$A0P#sDahDjuRnvW4qClaB_&Z`dhb+9?k;){YG zl{g^-4T{*rM+q-%r;?c6;*gpJ$#Ba(&O^9p5vL^}dFW`>f4yTn<`snjqAJtqp2xZt zVX0s`@v9}h7UIS7IG)m5r&uh)PHJ?*%LE1Lf!(nwmmx6OuVh-BOM5N0JUNOC8(=wZ zmBAex$1n2eNZU5y!^7o z`rmO?|Bo!;e=pZ)^#I)!Ws$Or3Y^-m()yI&67)dTUFD_=R+U#SN*S6kq#K)Gcqn}& zz1gPX;JwHs3D1zve$=vvk_KXAfGmub+yegd+o+c8E|o^p!b>}F6BJa$%dV|p}*BwxaRh^_G?M5s*nNoxkC zT)emue|+-FiiJlzFO|-NEM=-&(rzAL{%8j&<%xc=N4cHK|}}3D@`(_a>Ml4?DRBVPCALpkr;|tZ^aT+%E#Ppr|qU5 zENe?brt>j}K-C$YIi>9|Ngt<;PDky&on+5ze`80IcLHDYpwW>Mmde3X5?m~tM=xp% zx6+NT&S|jdwL0iwr!xF<%QDes7O6mFbtvGvStM%gf{YXwu$Os8X2OQtxf(qFHi5+e z5kZyF_(2l7HaFZcNFz-Zsf~-Z&_tHub=aiHXLtyJsOQ3J2BMq8$3)?)x5Nq@7nNdd ze_Uj~u;EdGUivvKZlGMsv^3E&2FBC_RI{m<$rqghbL;JlYRj#+O|rJ!<80oL{kY!r zY<1#h=Z&a66-QtE%h%DjDHew7RGcWAH4mBCK>aNF&J$v4YGSZ*_#jeG)WIz~>)7w7 z{dMa!zjjBfNQ92%7i;Owix%yqL0Kegwg$BesQPp58XB3}GKgI=;e?g1u7u{d{JWxm|t{iSKt%gL^E^nXQ$5EH^vBg|# zs%kqau6lxdMmu|hQfDLaQCWoP`tJ-?ab0^>nEc`kj_4v>C;DMpm`dRQ#y}C33{hUK zWta`*cPyQf&fCPSXorj?JzMZ1J=5$Ac_ht@{3J)B+0_z1PACXBmO=Xfe`K6}9)#|j zu?$sdhy+~vpR{yMgO%u^Q_GV^ zdWqJ|+poyjr9aUTn$wQRe<`aGOEFrpPE=!|X~9ZbH#Kp8U3V;WmyjqaE%(;Ks?QfV z&e`|em)9gY(bWPHW>fc6$&%Dtq!SVfQf_Kkm=c~*M!Lyr&nO$7OXlBH7(_$27#*R7 z2{^mlP@2|glD(`QSeTQdgrJ3jjP6{aLElnR4M|bul5;I2M--4(f2C=9F2t$esq}VP zd_Oota1hSbplCkSRAjq~fx$^gIMcfApcu1#)9J+&3nCWNkT%%7#kJ*|z}s7Xb17ANR1N7~~ni`J^uf zG0z4(>QOGHT_JnBKzxqo5UkAW^T^YXW;A%+_qdnZ6K>Ad=gn-RLyH}5bc|JwkI((t zg>mxAp0{u1A$3$9T9b#3)MAN>~8u~!EU93_V z4pZ$bjBu54T(sppMH0tP7iCG$7^pCXwVTIT;al-8blp^TQg@aKzJt--?#bvDY$+G{ zUus$3m&On(e=-*MuokN8**AOMnw~N&WYGX~OJFR-GF`roU~nl_Ba4vekJJ8c`;$Lu zIlzhIe@k^A!Ngy?-Jzoqn{coA(QtC+A_G7u9V8MA6G<91KWSO)5IE0!A6lc)g$W}X zI(3~JF*;yZ$N+}F`FFDfO;f5%-V=0ZHp&(Du!`E((d-9G&q zOqohXSkp~tt~&OwX)wUUW#o3%1@GCF3N!L)r2*+vz;x(05@H%a>Et)r#KVPpODE-v z^J^HHZifDFCcXmX( z5`Mdx4?g%fsfaxfmh)ytZtO_$_dgnb&;VjE}mIJ@y^zfsT$J?mqC7psme(?`$f4>%$%yRl02|tBOY$!>UtbK#FX? z_@Pz!Cvd`8<1tKD{b(!s>hm~zBXssHI(aX|0*k=oMEp?iUovE$o9>&)L(_CIe`^wY z^uQ>^D8h*Dkzk}#M>Mvg7LO{s6&zbonLoQUR5v9kUiDA>Xzpj<^{fhtqS_#%g%u#o zAd;1z9XN*w`|w!tzMd-3QM$XilKKc3<$N;}^B6R5P@bRVXV0aAALVHY^M~wKd-ycz zvGQh8`fV(Cq7&r((m6R?t^$uGe`;~dV=1hAvSjlv>Jml00AD#q!0WcWT$RVjOlPRT zMfJ|)t*6yO4P0vj`B^^NAF^Le>-$$L6YcA`mQx$Wqes|7c2=T2fd-(9t(fe-MMvBk0wg*z!e}1+IT@|D1 zNJK6WRmhyMass+XpSUa*H=J_caW$d)c-?0#l<2*Epc)?WReyFq>^LvVhMoxS{OJW;`ye32wM-;ee%p1227j23DOe5`6<@+8Ue zt0rQ_WOp&Kl86(N<=tMsf8D2?TXOCCrBa*VFR4!Wmzi*sh6?hN_r?ZsCXooi$er)V?^?a!=bL~_yqrX;bb-0AAOIIfdz+gide+~S@SJ+PUU!qNf zOv;bQ1Te`;3IPHg@|9*KDwN>G>o?y;=NyUZo%)IfJEIf2&O zCujvE1L2`FV-Z_lz2kjF440Jib zPg4829IOF=pCl*Rf5C(zRS6URRvH*Nb44xvEP8R!kAh#ud#X8D=$aj_o()L>x{Tqt zC5q-+P|2Fwn>jtEi#j=`rCA>l$}&}~039_p9>*ko_*lpuhT3D%(=&dq{Hv;n16iP6 z#Gz~!AxsmDCfn?eM>G3=XORY}D9Sfna0ZN}d4z;un#sT7e-@fo3PQH^U6I;pVL6R< z6o!Zx;Qu&fA^v|r_WyeU+3{q6AXY^a#Stye&Vns=0!=(^W}Hpozk3B`%dV6=e=vX= zKSMV1{(;mUQQa??IuWM&Yi0jMmgVoA3TSN49f^RBnLAz0zltFkm1946dAH#xJ$aVQ zaDi4ehI>V_e@`jlRTNR%+$!Q%$PPx6D{-f*=D8Cxq3zM&D?Ie>%br`npVa=~*WGqH z2-Moo_t}aO``gatxlb^s?aoXH`hDD)__0l0tU*gkX$nK+AWIcMc{F+Yh%bue8?VU8 zCNCbk5dAIJ^mR%aB_NelRLlx*cFOz4-%2oK84RxdWh`1pKN$Vhih{Ub^n=CclZV861wWYRF@*sNzCBdm zD0u7qe;lPBmZYT->$0zMxC2Djw`JX7>@kg;3$(yQmTt__BzvprZZI+p482>a8j&+J zg?{Jubv;*#>oU`n*X>1Q;C_K1zqxAFT~}*)ApTFl=j90z#o$k#CW7y+X}LEK_@6=E zrS7W-KQ5iM$inle;ZCOb0OiJesL^L#K8T>h{UPIEphfK zhvb~ZqlONe<=kx+nUJ{|RbO%WU0bfN;+LboR{^^2rI^_zzM}OI=UN8IfT_;Ad4Yos z;qg_q=EO5oyRbytx}5)1&amkeAE!}l+ zjsD$=M{|DOA_%OJ2d&TUK4HQ5=QU4_f24{ByF_d?0gBM0~*3w17O?gGTOts(= z>-E+t9q63v;Zjo}Ao2xly`?`tmoMTJP31~C9-Wb+X<>*CoD*Mq;}(}6m?wd=uT{hm z^YyVF=_=Z{IEfWW<(HXuY1T_<?}d7rL!Qof#gEmjkB%fHIXYda52i{hC95Yb#Z^&9(uLFG`vIVl_QQcs%yy} zS}z>x#AA+*by>se z24AvPHgXh02P1UcLiaiF!3g~s9*hvk8qcH*NFZ-KZaewhC6IS*MInZKGd$SUBs*+G zHJcvmHvxa-@KZBh8mXI~X=`PA3q;ttw-4r(xtG}LfYo@XC0bz&+?@G^27`o$NK=;v z77_`x$DJ2=f;vJ9f6B8%e@0jKdnyq^Gxe&kZ!R=u6X2Fdi8I7!M4c9HDQ{e^JXcBvR^1*6FmC z*=MA}#}qnNHlgdadmj}shs7~^&9Q$O-v{Hs(Vw3mEvsvRp8d9T`{x&fxgc*re@lY7 z*i9|X0zWFl_R+jzbULc@-~LiRauaTtY+(y^iTyMIXscL3Agm0I?~Txc{ftZ=9qcf5?8v{-TFqdu&=8JNY9#1wQ&?M*p6%=7oQM`b+IIL33AQD8khz z?N^BQIMm4~IN%R3O1MV!+dq!7Kl&+;x^KmIUBdZWz!LNejLwtn(Kpr$kJ9ZgE@#cM z;RNP6H4B!KcxF{+!=&M$3z4L86p0M8lF1X}`fulv_p`;vf7USi%W8%-l3?2o9Xq}g zE&6Bi0MWda;alo#Tv|u!1*=3i`4GnPOdqSL2)U+d@E?R0l*Ceb(B&X&9CxjV+y z>+%{y6S^x>f046Uv)(F{YmViXGcQ9UnTkA&vzvP{JA!j|O~pyhtfXJSD2OJMG=453 zdhc%8Uw{aN8LgTdq08&E8#mjj$8rYLB8U{W2aLlgN_(6m7*3QQ;*#AYB8*gLiuGQ{ z9k+Af0BYtw@29vU1t%6Q`UBsMz7z}E^t=*9MV_4=f766UOzR#Ms85)ZfLFE?hIGLo zchQj)h>3Pd^p)uq#*ekiX9XBw?TGo-7_afE5d`cHWqaw#d&w@2*8dtb7(SF@ik9b< zXHJy-TY7J1ivB zJB^_W4gEU$_wac{F9f=;eQRp<^Vnq32CD>w>(uw|?o@QZc+Ke2#wmX(_#a*@M&(Ix zL@;t4smQCzF@la+DoBI72XREfbA=B5BRY^ye|dFeBE!ZmHq~-&*%NdaUt!oL5a})R zB_|iy(@yMc88ZTQO-d?<8V9+NUMz#lPsl6V=)og98O#6W zW48y1AqSXx&-NzpOO_YGL$N-OszK!9cGAZh-7ef&an-Epg4ENo)!F}IWKj}@|0Atn zfAH&E+)TqjV6LnFvz?FSg}BBdra1bHt_&a|oyZ^1i4skZ`M%aETYqK*C4%3%4gn=4 z_eXqN>>A=?I9H z-b~_yHSd6up`mO+dD<{*KQG&TM@6*8e~zsyu0%+Ms}yC2x;`wkrcBwawO=_y7!h3v zKgl!=Jv3`R^luR)PTQaR(uCg?;~?4$@6NiMKLC&CZu+(sNW^3e9ufthKEN&&aeO*eckQgY!PFE_)udy6ruW#lJ zst80Z!KoU(u27H49u=_Yu80Q$e`mpnZ|;-rE`(-~ghY+MOxBGZVFSa_9wt|4bekDv zxW-2FDR6dCYqdNg5;jA9E1eY@8}!hKKBEE_(#WH==94_J9@F7|&zIhyaEFm_%~U)l z#z3}41}x}1Th`VNl0t9(8*Cue6&`p0W9%R2Q*n7ZRrk$yJxu;@*=?xlf8cpQUr2hA zE3#v+#ZE}}*=-1@!*Cq#vj^3Io%L*-&KnvHY4HgR~e?@qO~5mZvJREM=w z*Hn{+-8k{NxHjinMuF(}yn`Uryy20r1KFlM;+U%KnR8ZAhZ`P$^+&5dHZ#EP92p4k zZS#~)qCDOG@bDURz{}1Hf1P@cVSPY_6(!7Ik=SO=Q9$K2-QmV`&6N5Rrty`mTH$mg zaCa+oo7D=VVNNpckk%xZzha>DJG@=X=noOI%~ou2Gb+!RQF6j~&~20+P7JO6#}tDY#3l%3hhp0hlO zMFLf~UbpVMZk3kDlb>_QM74ir+>gFM<+)o(bH*zm=9g-&JxklSZIrF@=;;sNzkd1r&p*EY z;pHoQ2<48B%H_JM+i3nvxjvfJ)iNrpe@LGFdD|Av^B+`^e>BxfeP2}bISf?&tQz%g zT{Y#~b=F?12X%4O*4xoh1Rr_SUe`s2^K?|aofhjhdQQ)u)pb>mqUa=A*V%lTjiOZr z1H3J2yK=r+F1KS1BFY*Io|O4zQBIC{G^wihb=kD=_!+ebQz);e)e?HE3MHF*fANp1 zTn!`mvd-$Jpl_R%`F@UrTV+f5rM{iR<6-pAO|dEPPt{_{RnbhdHGG?F%0)h|*2Su* zhcuGT=iAq>U%V{xvM#3Wx3E$RT-zr4bJi5z<6+bmZ`*OZMaVA;XtQaDRG(&V82$M2 zJNh<|@d3VM6M$n+10f7d!O;2je*#7`jF#C=G0x$!)L#~DhA>q9zsm2S{`P!zn=Q(m zT9rxwZ=t7jnoX~Ze7vq<3hH({i~z?sbun%hSpy9=>qXg)XXT>cNu3uhmi-5edCU#b z+>dJ*EX)MrcW@TD6v7z8RE+^^8XDrOqK5A;>gp{ty{hUZboLi6sOCt@f2tm14;tt* z_U1?E>l&XH`QNydJt{bf<@ma7*UjkR!}WGurd2(s zFY(dQQC`ewF0;jgFiIgB4ZFducJY0+Dh5m&j*pM&@5`dy)T;<8e?@ksh$=-ltLknQ zO}0SKq7rD}+mtGeVD+;lZqHHl8Yn01f~cAi5w%Oz1bY-ci537FOJFk$v)fqe^sAg9 zcv#*DJ3Z1Uhz~C!XIALlbWsAT!Yc~_6CxCCxh$$pd+|7ZG@zoIKH`V_DAiN!=Xjk> zZ?ZW|85f@c*H|p9e=1xyiKmOIDdGVXJ35-e?rI{BdL#jg;!XdPh-(51x~uA&D65g_ z0H>L3<}jC0Q!O=PdYqo8Z=u7B0>E0+MPE*EA?hM-OkG?KqD5-M&46nWK!POIk|Ld_ z^yEB(GCxi>t9BFpuqw*BoDS0HIjmarUB#FgT?6G825};Df7e6=;bAtJ!gg$-$#T&| zlVX}}kPfy{lWiO74Da$Nj-@^` zHuIqjvKg2qe+LGS^VSeF)a3Sgz0+O54pe}%j2>`e_6rEQ>HB?u%8a$vWj zilu@`7eEeUcMQ7!B3UG`zQ_Z{vkj0%c$f@^kq=tHUuR9$wsj&yhdHc^^&*=VV}9aK zCw`=C>XuAk*22vci>By>LX!=B=ZZdw3J{a@-YCt)!l`zKt8G7c>_7OQ{)2N(@d($e zI;kcoe?fGJ8<8I_iHN%3(oJ*pm?cOv_!@eY#A%z= z>HHVOcKSN`|(1$2LzwbSdA_$W}R45)~} z0yz(;7=Xe(#l?VDWb>?CH7$`oYQu;>(OubIGriobRw$q|Af}2$$~z556_l^JEkJn? zWw?)Hf(=A0Q>&(kHZ-2CrUgRC%xE`2`G7F4x3?%YXOj~Csi)Ti8FzQU1kP$o=o(XN ze~=Is6^OeqD0jxYi0}!n0xpzZ1*G-kak&CHcPv|i3C2Y%6KwBfg<|-54s}WpSOIBC z;Ng)P5-f5LLmNeZ79OY3dQnw3gy_qvK~-#uB8hNcm|U3YZCE2g!o`XxN=LMWifIe2 zgICZLq6rY$W?f9nSy?oF&=A0M0~`w4e}D1p#VK^9T7oPO7_0!E5_7$}iWkK^n{MN) zt3F^QqmAmJNa(O7VC@mJoqdZa^J4qrc^aHxT#a;0Dhe#-zkYRJD6%eHwD_i)X}~lP zZW=8aiO_k?5&9}qe1skq)EA;zA7luz>ld{UvIH)z!-PXM8J#29dYl2)Gn zFZ?&Lwj&Om%g~1G*?vkFS#2W$f5^n+I=hASni4|iVZ^G72KF^{;L=DdP#I|As%q^% zrp0pIZj-@&8O2c()Q7Osf(8RizR7^84?0D;ODX7eu`pOhI+14_Jt&SgyMc%WTVQF)2V?Csn&=e>qN~|G+&2 zvqLy4P|zsWUe`?EmQi+>ZCy07&}88EnuvzqX^WnuRLrh7HkJjyp3Dzd7iwebHEz8j zbH`4znq1LquCJdd`%5ym?Hd+ozoUvWaEoLw2`|n!XnTz2yK2{A?$!Su{H%#WrM(HFBFUVS&X;l}b zU^5z_<{QSMzX1NAc#V2`#((vMzZfZmWSHr7RRJEa>ta?Q=SQoLk$7iaWK_1X@FKUi zb-_{0QA?%8xiJ2eR6R`E6n~r2mcDfny{;|JTsC7iQD10~De(RV)w0CaCZ({g<^=1| za`Y%ej%7r(?4pL#Q^!!Ako7!KEe?bv8+EKBO29N&Ru?itql&Do(0?%znRHdOK(&Vc z;D)+`L#tCmJz|R>@oKw>bjF^bK4FE?1a)K-`|m2k6I3k$u_nMAB6Q{fZslbTe26U( zd58?5!V37*7}Fvmg;K=OeC-nL1j`j~GbB1j!w{=PblarSFXejR&@`i#X;Q_u!dZ3; z8c7o=^F9v(DGoh?Cx1iTKeGpr!J@Xs1wqS4>mfd5tzOv!*}@8lsV2W%lZKWST3g-DV@V1V4JKJH~jQW>7w1Be`AW0yyLSi$nO+smH*S(1LW0Mo*}4D%YRdBo9Gyab3BZWWonNNO*vLmcT7ug z46|_jCnNX{*+gi8b(cl|Ak;xGs4W7VvCwxu@TC!2L)VAP6$Z!z0x!-7M_t0;S_?!G zQjB6vUT`w2HRRK;L7<<3%+<@RVNvmYx~T5Z#*%{MSbw*|VvG6wB0fO1cX#81W~31u z1V)mVu?Zy3Bi@-d!g2phhnCP)%c0DAP2!e;PA}cr%@*@&2skkZg$MvF(|KKO*0%80 zB_v)QoY!2M) z$w@4SxPJnc1s;tzuHYh4gfFgiTj;JcwM8HeJXl|pW5OK>lX5k33njX4>Q03f`44=F z@vzoh0M7oUDM&*^wWr$xr@tY+Z~xU>1V1sh0?1=^V0U@hVY-Tn7};G*(LG&F^N`*3 zfMh@w6HAmNKIKtcr9*wUTr(HE4&B}WeNe#Q>5$`INCtglwBx4(DlBljh{ zC|lXEdOFgu9`5K$y44V!(o#%No9pg$7UEm2nfHvZyJI@!4+{4XBA0|h|EO%&v5p_D ztABgalOXFMn;ciJJq$_u)<(R8I62bfLqYeQBvY?hZ$pki31Dz1z=+#^$|sm;(_0K= zvB{vzpFOcK^f{2q;YU%r{Zxla8=`O!g`+wal{<{SQLX<{8u#nYw}|?fA#H?^UppXvLWEFUw^ho_jhDaXn!%5 z;gMAcXU$z4d5cCVcz3Bwzv<9r91DjwHP;#R2>I+X|11=VgUX(i7I8xTD!P{fgmsV+ z7Tvigex%BPn$k6EKahe=ftBhd?SC2DIz3>`*x0A6>a49x6vWgp6E-6oMg6*3Br#MdV+`(st>D|2i%sJK>j+@B8FM?1QT6u#g9g&v_Rsj8oJh!7O+kJYa{iZ1C!I+Q@Uw>UOgNmBX^t#)w zv$9j=)>q@W2bZr&o$*eJB-VF_n$`F4sgh&cKR(3jVivIm>tNM`8u@0hWgU&-MS^rl zm>1w=zDaPoJV@#^*p90_NnzBJqU1p{h=&T`5P4IP$ge?aj-)6^+EspGB4U)1Q>U)d z2lI-Wq^dHAzKqUket(e&kzA|{051AyW7WnjWPI+;XbBY_h%C zp)+D+9Zr>RIfg0D4JbAi>&3o#AN`n2i<(;D#zycsztF+7Y=6e)?QRv9R!W7R1-kNn zMkW0Ch9!zS;9-+btFe4q`zAw8?5^GlqEivX^0V&16&4_kX;L^5~tBwtcH!iy_1x)Hpz3V8>h+PVa@LkZ~6$ST;iAYG91O@27C z=1M$l_*-yJv_fi#-L9BdPhFC;5a@`1`QoWM5+Q%RGZC+?$S#a@X`-M0`rRp1Gf}(V zL5S!%1yO=5TGiZzX|_U|ph9J6vo#b?5G_j%wM^(>1%K)D{D@Q>qLj$Fyu)LGh#QXY{5#yryTDUiE0d|Oe;pPuPqLZ zKMhUrrGFV|Uz#2(CMU`!isWW3w8tbYCtA@ZQ1^MB53E+2InsOglgt%uA6cAwHitqxA5 z9-Ul$ly0uIa=!p#Fb$_%^$Zq2`$xbXy59h-4u)(J{nm&OfPI#hes=gDuYUOczWfmD z#Z81&VOrXvo@KyPfD6Jy*cDq4#g?T6pwBidHVR@q8^NOp2X(?0xg?-Butz%0^Zs1V z@P89)MDM{+>|6{y@4p*X(H~Dvnzs(-mV-wIUi@FjKis3d&SVbJZvGH+q@easSwJ|R z*-U;%`-8UEY76n1E&9{l07CAue2TeFk^yJ~c$zjDpxiklrR=UF4P$Ro6kwaAOYz7; zdN2c#9^{uX?r)z9G@mHZAXk(xAn{+C`3aJ5 zn{;b9UHW|}_p$Ywev)f(szxgmJ_AFcACf-K5t;4BLb-#@%Rn!KQZ^0sF1Aof5 zZmAH$S3bt;l7~tp2C=KXf(fm{he#&XeNf!0@LqUsjq-h5Eg>+6BKy(NN#7i@aChRj z;QN&9nd}rkNK6ga^01;)=zy-`=YUS`p8j2=W+$lo(i`7$iOIV{r=sM5?0VBCI*nIS zcxEiI_7%p{K$7RIpztSI2pdy=j>W718l^UCfT7q9j^gE|*1KW^Dm2uhB)A7rDTz+_&6S7!an6ihquQtREYw zoa4eY!Z|18)R({mF>8_4%BYoB8x%Q7y2IoYFj)PQE#vCPsf+~JNRH>w>bUgM8lfhR<*jxu59{h0O;UN$Q9z1a29VG~{r+1%rdiR;% zyU!hH&@&ht*zuQdJ{kBx z`%`pq^11$FgJEN%NqO?)szeE$c9B7RInBhDM?3w-6!|ymGCLAgD1RZ`j%M&RI{MwU z7A`dv!?HjnF_a|HP$9P#Dfv(sN5o&NFP{>LZ7hoe7T zeD&|?$%FCFKfgPDqw~=bgn##P1nMP0nsA89DKpxrly0=mur4Qzp(SW5px=DH8&)V3 zgOg3F4Vkvf+9wr5K7XWFfcC#ES0;T92yk?YxCMa@lu{#ID*1y~+$~HwDG1}rF68l(XxNe5UnbXVv2bqSK>W{pS)Q;;6JYxlv&Tks>?WmjY;E4&ng8-zayox~xg z>=;ShTxJ*8bO95_H{3vdET`JcDf= z#Sb1lIDd-<3eb)dwUHkU2E7qPBr&l^0mkiQkonJoyql5=furxPD>`bA(I_>2@d9}| z0VpTRn*yY7)qe(1g#D)qJ~~ikIPEBEFCV?Zej(K2!Zp{2C8Ag4m3k%HZMP-xi8cfB z_GQ_qF|tu(yU6r@m&1IW$UG9c>dmS#iTOBjZ6hfJa2B3F{NYa+ZA8Qg*$JK$Y*C76 zki10ms$xk8zOT!5j4~eiE--8gz1ou1tEz8El_l{i1AmdS+Ca~;=2~~hP1J}?tTrdz z^CDX?oxIKJ66-!?26p;v#VL-3vNS52A+kD3xMSkiF}c+O<|ZCdLSC|1ElJohk=`-p z9fkt3rjrpRB2NDT|9pc?1f7H+z+Oly;$#9cJR86)7%L#G4vY!E{B^fkRe8wx*xG8d z9OJaXD1R=_9=*4#QN8y)jdfMEzPqtY^`(~djBCn|AyY*VBy!B$Md4nQqLo)nQkgWV zvxn^u;h(5RgmOAQD*>@pTG5%j@AoH#&FIZFHh*sL5U{Gw#n^_@D}uZS(60+JyM64EhgYRI`=i8R4hklY37Yy-p|h!OH6P~YN~_L%9a z1%C_(C!K(%9XPFk50)!Vh=>W;$iIV8;0l#bsc$5?O;N`4JBHCufS`qBB)8B|YzFJS zQ^ldZk{NCc*g@rKalCmvJ3F^Xn%D9!G5NKOh7wQkFgO;2X5Y?cqqD$q5*wCxp}Yn) zp|B5}L&>&FTJ)AcQ&b3OPGvKHHm_DvejI|DJ{hH5C1w#!Sj-|uRg&@KkHIeSmm^Z+OEs*_MS5TePF@atbW8#1|QgQPM$Y0nKSg zH75ZbRMSDSpi%B{iqv}_fGwYi?NC}9!^~p+wq8VzkFv-^V5}OTm+eRwaE>2dL>;65 zURPzWo6^h%vLv0xuKU{Xvt5NeDu3netWZF#8}CTGj>9YR4!n5t4B}izFUF2hRq6 za3|isP?0m6(mGLcB2-Zq_%!Yc2t9oW_rs~+s1)8=4{Mw2<6FE%EkdSt{=(h<2!3zg zHWr0;DIlClKulNSg;u$~>53S+_)6tg*5=V6r6NQ!Q?|x_z<+KT@}?+uYo$WOUE^g& z?D|M7wHAmi@o-GIzQthN>x#``o0V-g2-6(S$Bon93FX#?bS*5-3tz_z%B~zo+?RA^ zuG4js5P!-EZc@m7+ zglu!8BkVr+)qi{F&Hh*l2YMV_D!-#ciB6~9l?4fiC9*h7lSgkH8~eM6pI+5OZA!fz zd)GBQaz}aDKYEEc3EjbF5JlxzI_T6de%Ais$Z%lGK}Veq4|wU-xiC=f4)1EpIbfK~ z-q~#hLxTN2Z=%uZUL7x#j2=J2QG7;tb`p=N>P9mEbGn3CERJ?t|&rpuXVwf$B_ zLg3ca(0^71?oBZZ)*CB@1)KfHQoYCiccPNcu3>)Dwph^pA)8g%Zc%N1_;qpn6hp-8 zhtINR`y9KlSe(eYo>RI5?i9Gk{l(3Vm+H~VIgGxkn8-`jP)g>sZ1S?E&YzKwn6qE{e>uVo1NhVH3>x(v+>1AiWpCbusB3Eh*6Hd*|HWZm_XY=2zECu zGk>5CB#>SnE-7J8ME4_ohZ{%SE06MPco$O!us$)Ub7!TTkGG-k;NQew#Dhm2o+Fws zdb*6C?s1FWqH6K`MyLGcJ)@HmDk!^!5b?6BRaZ{;OI7;~odwD8?p5Y)lxS-=NQo$8 zP=Qk-J!6gOg5!QWB!-*GC8f%8=d9MQ$$wbxo&~EHRwPAk|I6;r3q)TkDA%mm9t z65_Y#;^KR>952und3qM}u^!-Ilg#p7`X5a{DbSY#7B#l__rAjxbe+KU3f_?QRl|W8 zXZ1mZPAT^Bql@U%N1ygDKsVO;8!yb+<~;$lQ41lr9^XSg{Y{$3k8d8_Gwqs@k$;}k ztuIhqa6z zL_M$rQI*zYo8U?^00e?7tuR0<#(xq>?!HjFuj%eNP*e^$Z_70}l&1R<4j?Oi=6JSa zt06VoqZ-Xt7V`7e)YQY-DlF${tA#!Tz!nfx-I(CgjT@+0`CAG=4u7~9|3Bza_3q^a z-gB!!Us_uH^gCk1K3D;&P0gAZb(=USjqUGKV)_3_`r9KZ1*yFsl3IcnpMmA93co#8 zioEtdsZl6qC0p?Q2N)2ca}$wY#w6*GOPJXkQ?io*5gD+lq*Gh^%tIR~SMPL-U91)x z69)A<1!PFU&&3Oz7Sk+KVeZ*6r=PL4#kcDll4Z&LCp;lls*}Pm4 z56fCrqgkkHh#l$kzk5Uf9&@FLdBXx~a#}g^6+Z0}6P@isr|2NU!Wlh+9xw1`?NpMQvTOPSsW9Bz(jth?^F z6XRoxA{RikRWXBV`Gz8J%!UYnFk7VavXevG&d##`J_ngJJ!J>fkeRsX=2ZbS zd9lc*1!h2(f$EeihX6hx3&xI=-=@gndAd&6nZ`E{_!*}36zRJK^wk1P;;efFLWx@N z<7QY$C@KHYtA809W$KVJN!(78ZRG+ECAid$7H`*8-MV$Us3;MezHRcPaASih%hpab>=k_0fZrF-$bira)f%CSaxtx{howeQk&li3Bl^{)e7enklA$5s2I4Jg zh+2SR{2FM*8qJ{%;Y@{~ABBH~cW-yk>^BQiMtnY0NS82Ybgngjh=$Fg#^6*+hKy3A z5()S3!+(!e(cf$%Du8S%^n3KXFc9)|k#UfZmwDDfw%ydw^JX)}cnzR|{k)lnqXJX5 z$}p-&Y~TKg)KBUN^j4l=AvIXxThL>hfV*J@^H zAsO;b+`iAK2b7$1=6q)QULc7ccg7XXdV#3RfzF{Sjwc4@wg$)r=Ys+mcUgnBylY9D zf_8=O#cK?VEK<#8(qLTLsx@3vv=_{~Q##iGL5n@G?r5je*p$=69wH?Z!4h=y9)D&t zBQ2b7H*n0pGapfzg z!pSi-6_&dd_THV$SpD8NC#&k+gCcGzxtC_g?hW+*fU9E;9)|sKEy!L62+}@Fc4S{> zu^asVb8eHv#D!oinm~Q$N)mx#dVk@nEbj+wzTGCAuzp`JBWot^O35&)r4bvLX4XM{B zj%xzw$cccZUN;Q#{Bzv5=;F=m?2c(cIN1{)O2bg{?Yc~>dj62FDtQ>Ymw#pqE&1~z z<^iI)ToOKA_>t?p=!G#Bd+D)5&O~pY zK*r03JcihJ6->W+WtLTaqx^Z!jJY*>??!Xg153Qm^4zuZ7!zC196ZT$FP1^4AEPx& z+3r9ID_AZv8DaV}2Hss)Dt~$b@jh!iDt=CvHNEyp5OUJI=Wv=Em@NiKr#6M~<<8Yl zDhoSWZ*HvQlG-}fj3-;7Cztq7$AoLjUCP}fwjpTHDNna?E7x4A=D?*u&c&UPx}=Zd z&po_NCM~n5|h^H*m z3V=6oDwFbZbaBrvr5ycT?ye`#Yr_$n)P0eRv32p!K8)qlzG~)_NX#){&c&)8vLQ$b zk~F1EAvyrUWdM)NbANN8sNZB_C)KS2YMyd-sHgw|kp7hcT=f|LIzpIrx29o3=7LR} zDqUX3{WqKSnle-VjaxnN2*3#)(!<#1tUX;~ggmUP+@40Ml8`EdlJm>Xb+aE^^ku!SOHJbZGQ1CGF+;lMA%D+7*kfsH2jEXrka!xn zDcJ5u+t-9WDsLw3{o|s8x^qEPFT4^RmUx;qc;v9bsKU0qwQuPQM~ch7^=XA6{xfcg z;|rJ&IZN+cW1*JMF3u#OOFMc`$FT9_!n=@E5#z3nX!pL@*#xV>A=@aG2v@d(qttlA zwy=W~OPB_X-+!u$HHIjt5ORS#WP1fYn1H6$=O=p7w#9PYGJhpNm^RQX2d7V25wKLJ zE--h)J4p{IFCT?=+&U2;q#htg(m7<=_18#ZM17;RQTUQSM|>%@GFd&U zq1X)N|51bCTfDEX)OfD0pbrg3x**5sZmq@|3+}?JD}Nd}RFl2fbjg5%&7{E094DuR zRT3w>nqQpK4kw~!IuPOzfNrS2Eb&N3yW3u@AsY!uP?I2LlDztjCkh^#`ff=@x2Mx! zfrK_Mc7)GoQMiS&{jQl4^l?2|f%*~2v zTOKs%P*_Oay^ePWYiNQ3n@d2|n6y~irEa=kMBExDXhFYotDQ&+Moo51ntRotQ(j>u zYdkLMbjco&n_uwitv1ok4?N-Y;QTu$&XVuzr++M7SMQ>Vz3KM?i@k4It=6Ents$D} zu(ZS`pk8*25n;X*&id2CmrxutLYUf+Ly9gO^Nq@qz1q5=n@!!j1U63{#jTG7+zX3R zfw*Ys3rcL}#(Ph26GPHg*_Ax?v!9+sbo3DDEU6oI+))4NENd=M3{-I!_&AdLr-7MW zqko}r)E2Pt!)P?wlnc=1vOR~Rn<}!;muMcLr<&Nr)fFx!QYi{l!S|<9z*s{m>+#OU z6qAWgd0(K{W+;YEK@Y3touD?W1@LaVUIf`5Gv|yFeW*xaYeAKbT#^1z5Sa-eW0#^T zY|F4rQtaeRzFMG%X!66+(x`-nc#Y64Wq%PibB;;nMpuGd`IVhyu4p-nIZr>*M}mQl zBSXuTspaa*LQp8Z*1Xo$?#%hR3lB=dYm5@X> z>o_u=aCxuS-t21W!px_V66iQr!)dJ<6blNv{?%2ySvAmdg9hIida5J3=lcS{q`FYXV*UhAiIVekqu3c*Aza^n0z}8Y zED}R|M<0(UuGc0qt~_8~C^HUKa*6&)G{S;JaX=8-fE0u{fNqC!TH^g#avUb_1CIV7 zio%PTh+#ankTLq27q=sfowa*!1%G2Y+{513{!J<@HK}U=L#7=3cu6*SD?PwGLUtAC zSmm0;x&ndMpkwc6kAvHHo6lL_yTLZS;hp%|f2>-(9egm;>cK99A=i=QDc;D*Rw;Kh z6dk9l-pIZv+E#fb4=K>oMo*?4W3@l1Oyw0~g%6rhg&xO;zl? zaL)GZ5wK_b3(J{9SSUiM zQ}+fl#*7{`Biv24cfjjcv6I#Y#`liA zg~)wn>f;BEo)Brw9X$?D&5f+YJ2kEE1Z+obAX}QQ8E~*Gi>bmg&yE_fO{tU*s>~so zp}w!ImNiyqiAemZVy$$vc8RxU`(u#)<2$Uy!b<>K5!9)wY^(;YPRzMNToddwk?9i(S+ zcBA0E*|9Yk&6d}@mlH1qDNF?kixe(R2_@FMHU9u_U+-emtyQ z#k@g7F|&L0e*jQR0|XQR000O81Cd)SIQA?4m-D5$2(0g9994iWA@IVB@upd)` z-qec2x0N8IBur^pXM~`m`QhyNY?i7Ag)qy};fLe%)A_F-&p(`==|R8+J3BkU2^JEh zEkTCfmasc2IMb3)iN!4u5|uO)e6PT4RpS*wIayK$L@7fjvlH}c|8;64!N$j2kqMgH ziI=~;N{q~Z-uiniy>=NdE70ktAPJIIZ!8rEDtTTP1m^1^M>ho3&N7u|i>OM`AN-!& z5s`QfKt~B!l>v}fL}0LrM6%A-AP#o?J~d{TPN(R8O|vxuqq0yLEex3iF_IA}sRBl9 z1@_J9a!G`?1gD(nwkgnNG2Ui#>T-?d$iA_CB2|v5L`suiKR=#xN3{#eX)=l8p7>@7MJ(9kfcqH zU+!P){llwpC-j@Hi1IqgzBXTuE}}AB30_x!GKyh!Y%;OzDB--7LfYk;JqXeE$_gwc zn%&`|*1;a}o6jUuPQFe^{dvBo5?LfX_%tGR5pgMw$OD9kGz`;bxp}auq$jjD8v}&X zX*fXzE^l&-9ul;fpa;k;v`N~KpJTp10?{^qKyN$PCnMM=U2$)Qh&Nrp5BKY0-wvUF zT|#gF19=F|Ay~(28^pyB1G3r>%7ze#l{UnL^9an2d+0aoUmc-78X`%GWnzLMF^3Cz z@Zr=BDgB!H0K&r%a}$hLfPMMwxS}EH)z(0l+3+Lkqlxd2#?k=(F zbWssyOWso0_li>#K9#BYGm)ubX^B5`C;|4Fveq*+>s#u#R5#6bN|1toV9*%)?xJ0T z4F*o)5E>L*^lGXn@qB7t4_E4$z{Y92`aVi1+z)@UNf=u7tLhHE`3ptb?WZG4 zwbUVNg9;q0vULQj?37u5?OM!eKMp$K+iK`WNI(lQGMYTP#y9hWWp1L~=}5l=muXL` zR~0fmTf*69l>c>RZNEiZ;c6?6=wbcOQ?=7y1W= z+27|7RfDnx#jNO$1_ALm7g(~r#rWFSTwEht=yhL8vf9Lx6EQvJjP&k1bH8lcnd-B_ zk;Xpsb5aqef2~1~jji82Qk!!VIMQ+H1We!()!dZe^3*W1P3c6pnhg~E)0QycY=yZm z_CBUBd?x1$&Ts2~sx5V7d5NnEcz2XmVzVtdwzUI2b%M8lL2!n&C4f9+q*7>RKHP5y zt-3YR@O)&tGwm3_8$}wN?tgqEw{=<^`yy^AS!YP4&jEd8?1n$wv}T|V+-mi;6{ZXA zu^cO`PkL|ikzMr;Zewrisp)p3UbHskhL&z<`720W<)-Z?>LcTJS~Nl3>eD*+so-Bw zO9KQH0000800WU*S>HYG3K1m$07RFULHr0CmpWt{3YRbx2?c*PlE3?};M$u^iw*b?|ojwjOV694{A(vTEue z$@5@tG?*vwFxnY!4}+cY4*oO2f1W;>jCTl?$#^mtW9NSx7gaeA;`n0OEGrhrK{iK_ z!LrDJ8Z6GUhE+*kZ)}JHd^)RnGd54MT(+3Ax(4K8EQv3&oXHmdtjj`v&&$h8AhG;e zu?-GsETO!}>L$<5r=MnQf#ethZa1u|;cFa=y0db=NE+GVxTyf*!JA=F)3>;}Td;Z< zH0)DD-$j3`c~V^iAlWP{U|@@iHKKUg=%GN%Dw#F$`CWX??uNl7YhrpP#yu7o$@*Ac z&#qt+hd4FQo^8k9Pmhid-WI=Ir=fwe?`xtI4+VokbSVRu`$b&x>oc4 zI;(4_JFTj+irQ2e>}~|`f%)498veY@Dwb*n$m)M!&RgRIw*fydi;Fy)H7g-E4Vy2T zpedn?Bn^NKZ!6#igV8dUr!{aZOa`uinSi`Z^0BYycSXf!2Rl3a&!pU2$EM zw}tLgQodNu&spW|=AgJq@+@6VISn+)mki04@unQ=R09uW(Re)=$-f$p8-ysRAkWj7I1*?z^1ck=Ix8;IeEc5&>xXnO5oWlfN zCB-F6p*l<|$b_IQW(+wtc>3&19DmIP3P68h0Os!Yiopu)MjufC`2q;UuMQ5URN>%# zyc18Lq++yC0r@EWPz3z*;lr=tz^)B{`dS27fAVZ6et9r`_2L++MT+7h!9_^qLs&=n z*Ld_cPZ|`4`2Bb}2LW)0Uth3#R%OHu`13n zS6GXG8s*J4_}|-O3GkiQ^gms^zt%E zNAHea;qN!+b(yn<)t-LeR^?5WGV1q;i=!fie4=JN7zMR~@3ZakM*QVh#^NxS$`?R5gRMtkK*GqI(FxerZMkjAb1mp` zDiFLm6+IBK`d81M+STvCP|km52EUJ9f}s$~x*Bt19A5+`9H_bf>XoipvnCpt&&JCI zkex+_x#2I@O1`69sV9HACa%9+55Zrq2MoiXzCStI2S39$psFwo$z}OaKi=Def1=Ik z^ry|UF9w^xhVU(fZ{Ywcq34mZi$Ho=6SC@aVDd;j5hinXp^Wc6vipCw!(Fu?!H-&2 zMPN{lidgQn+VQl~^z3Ri@wHM^c3Z((iJ;k2jHZ;Sr0&6zzS^WxycXS0ZwdUCRxpb@6jpYPK?r2 z;J0t1oqn4&S80`iV}ySa1-ns}dpIygD)H6~*VVs|z?#iAG+Ha2ImtDWug+QBNal*T z%cz~O7a$*I4aqgEr;tk7f)zABC6{`_*F+DAJADX%;9n(m%zgU^oON*gg`+=k29y+c z5ii79!OApu`jKqOp;HBL@Zc}iqfmfw6$^pT7{u_rjs~ z90C^}mIWJ}5!^)yO8Gozk|@*(t*0ShAVbda^ha^Yt^E+h?SOdz@Q zTanyZ6Um+Rk<>CpAUXN1NKV#7aMQvfgwHD1X?qt@mAA zRtE(vww)nJ8dbn8EkG@~023^@0(Ajk9rvVr=o5#Dx`%&1xd$T|W{?>EZ)Bv&nv68* zW2CJ%nucX5&|E1wwtA7=wp3mhiXN%4;fIZJO!Tqp;OAwMqx+YZ+r6u-a?gWwNZBXWYtK=Nu4<&sCPvx4u;Af~7SpTK`4;f~W26cC*IGz;Cb;3~Nx*EX14 zmEhCi4%PM$_Zeur3Pm4$hqj_c0PKz0A4UyE&3RQ`vmy|o7h&U^!*aMSt7~o{)3#Vs zmU(SK*g^h8j~U$ns|2z91b%=7ir}y}aJCy5Qj+p@X0)OGv^2$ifeMUNmf$X0ZB>|1 zcQAj-9DKLBk+VYLkS`5s!wc>5$i-r|bU^9?eGqDy; zWziGJU#%vDFzbe)*o_9|NI||)VAh%V>P*Z!6Ca$3gtMh;2}oN;9e}f8x56hITfxZ{ zNhj3dd|Iky4pW|-moVAjFBdgN_0aPm`yYR1pX>f}VsHR()ijHG_sNsn+uQMi;#}jh zx_pwdn~b{glre8#r?>4xWGS zpG?hIs1x4uMhA^>;9x^e{IM5~3IXbhW<4E&qwS#M6Qj%wt=b_>YwuuX+^GZep15UC z{Mm_)c7%f0id(utM=O%qif|EqPTswJH8qK3VS{0?>8t7M>EX$-E! zyfA_2u(KUz?g(fjkk<#t$9(s(JV$>7B7FGr;MMea|79x%6`uaIKl(>9`q%d8&*QT% zbf^jU%W2;mWSa^N;Dezww1&vfltqA#_g*G>&2-e@h%ahfy=jKK{vfDnQyA9_Nq)Hr z%7wteg$0fTakh6 zRb8U6FGfkexJruUoK+y4p;b5z4LGx_1XB($K>@eYg=9#D9t&_YA2d)n3dcdPpQag( zH^IGK=*9q3FQ8Q|L&Xvmo){6FGng4>bxc_A1!@Av_3}J|UWQbnZABF<@>P|@mf|c7 zka5Q0U|@;hNA(Eo(BM&EPqlweeR#z#li8iLG9u1jde$-NCZ{UeDlIX-QL&sQH4~Gq zl46vt)XIZFUjQdc=EFqEvMEO?MWR?b7zb$3%o48V!3}7VqRBvab5n&drCHGt6tInw z>T-!WJarIJ=)I8aItm_xNp$siNX_vp*&b#VMb2bR{0_r@99(8#8u5R!QJ!5hvDkRW zswpU^84sOH0P|$AfT@0rES|vP00Ch%m$i7Vim0TRgdWnoONvWd?c~jiH$hs?XoP%= zg7-tI5lBlB=)#CxvdkOQokoZ*&Wfyw78Kb#Yc=JeO;*e@Do0H18e$^$1O?1d6Z?oj9yYW`ClE-|2Z6}$CiHv6POcm>h9&9p{%lE z&t?Ooub8r$_;bObimQa6!oaT4vnU=@!wBRWI@liyQ?yYFvlG;LXoIO$K=ReGZV5-I z8gcP!w68twUDQl4wE!b)nb1;}_hCcCh=p?CbOS*HgyecVvXw(q-Pue4(Cz8b@bqe6 zl#&&IjY4bDw@`m&nM(~BqFF)CNLta>ss#bvHKul5vs0_Kw^wxQT(jNlM=3FjA3%(%Vs0S$j_u^tpBf^oSTj2DExz|sHe z;z)}()XaIi#rCK6V&Usyzu~qnb5_Nc(9~~L#-ezv5Ja0BvjGk6B^8xi*yc5Uq}_|3 z``X(0Ik-@;*S592oy&RfIt)Z6p0IN^!z(BbnZ4Gr^U&2_O^mk!F`7Or|g9U#;orbde(Tyz8D{CwG;ffVB93UQL zrt>JL-Xh1Spm1J@8kn7+BSIZoi3~(agy6e0fQVfIKd5xGV#)k1Z3c5&ZwbtJ*q3;m zCo&bx-8~bOCyJnU!*pw&JmBt}IT)Cs67tA7uuhxR>GYJRcF^x}y#P}w3Wwm%5;0W< z0Iz?3=73Vh7hxq-MQ!8lsvJ%t;pZb!{4^0vLZIEQRThFVR!suh;*?t1PXaIQ1C#$S zTl~wfzLIffCi4F&gQHCEFwNXbV>fnAhk%~}DY;3qJUP$xNC|+R^F?xp`HGRfgibdA zb3ly0jgZtPt{Q3vL#Mw;SzkS)V|xotoO3|0hLR?K8tWtt-#R1L!wj>mN;D*VwcXRcz>WX7M2*2=PXJEW^GY>`v6fZ{UMUIHo^~(yaqJOxdJJAA7bd!5OlgJ zAi_`}rAsWYoFl^6l8$Z)9JeZ5S=}-_mE=(Vn@3imO>2zT5>05;>SQ6z9XeIN+nwQO zwJ7d?G1(P$EZ5hZ7qR+5=#BqbWo$9Ru%d@h{rt zBFo-Bdg5#E7vA@U{;LPN)<9CZ^y^wf)42#~VD>zAs4;sbyEPujLv2S%#D=&mC^5}a z#QPpUzP?SW%i5Lz$EG|s?J*Pz7$t?7$4qE{+;aX%;6BpA;;;;#IBx5XbKDarbQLGy8nkdd(^j-Lh0ksacM*+)Mf8a@lq)=6;P1k{uA;EWRX2NtI1`#UpA~ z^bh+-hX;q>w7OsLjcqgfETcTOj#B$1`uKHZY@j&Cmm;Z?0HHmkULVn(X}<-4JGpFj zt(_vFvru195UI(9=v}&<)@%4hSh7i?Kk8pPB3D+C*f}`b}?z+ z&KX&g^c@5OK?017sS7bbvEtE2>yt)?`J_qNPb9vMTta!r`}+)6IxzpPVOr`}j?l^~ zaU_qD*Zrowlpb6^c(w`J27nbzqgc7LxUG=4rNqQu$ezq$vGv(Ezg2~QwMQ+y9}`oD zJaWGrrbc4r5=T~&ecO9FE(eORuc&t4NwcTIq_D3OPICFs=KU_WZ_OUeV3vQGxO-3h zX=~pdKf0IoTkT(ozQ)M{H}sK1U5BpQRm4oh1hc5=eixn0wW=HJ2Xp|f%+sB- zfp_XL2eo5Tdg21>&&$1k?Fo}x3=?UiRqp9ot!C1zVm)JTv&I)OdQRFmyRai@879ii zq1&Wr#^~yC0Qj8tddP<5du&FCvM2+zJJ9U>UM6*c8ej0_z4YF}rmf)p`}aY8g*m&* zOkg@sDH3Q?MC%swj>`o4(Nq$*x(ov$-8r8REt^Z`f%1Sz`#Af5V3()KiYsHz@8s&nR+S zfuVn_1NZs~&nIeIx5HHi>tLuG$u{fs^srBdIob9Xt(dsaZo!YGD=zhh5hdRFrrp0U zg+KJ9^cuF3iRBvG`~mMx5O5J^Zs|U%H!%;(iar|b+`lw`klC9O1A|i0V8C8f_Ng0@ z9U*pT5}9;q#O7Wa=gZYSOx$<`DF@4bS@Ru^Wr61iXJy4kl<_l5a3ia^Gxo<&>C#nP z7s1ut0(91Bo_zu+R5i-RY#dyHK#NhJnU$548|auGor9nlWw5|wjQ2X#;Lp}rZ^uPu zPTps?#Slk-C_5?b(p})OG;%tOZIV33ga%H-Zd)Bc7}TT$Xn6+1o7ZM^D36s&mugw% z9orf>EQ$`xh({mfZllr!qoe*y9;8~z5t_iyoTY&<^lC`bG!{CU(woJ)Fdw;TTmI|@ z=lTcy$gF@+gr)I#meP@rK}0+b=tu<}*E)4tJfZYzI?09PrU?IIkX#j7tA=2rD03?bR?Hc#p8G5)D{~Dy z6lrT_4ye8ffR=?X$bCmNvy#1eysHDxQ?)_T0p76pdAzy<4&QuG&<3l)#lXf3&oE`S z;$I(s)dBtYpOnYTB|%K-{&75(_cZc8$2^`uUyV}?ucs&bFZNIN>4?PP{%brA6E5yB zZElR0V1^q%d^?@KioNyJr9ZsptLZoU&wun+l@CMb>O<$u1pPfRT_NklgwO)^1*D*m zYCPCTZB;wE3s4;rBqxfllMoMvFkiuKl`K$y1=2!Pa=l#(? z&LZ(89*@o*%ZG!%{V_y&H$D)MNc{JLGhy{Xa>wDhJQOP)zkB_9|LDh#4#&Uj3@6)v z&;ImTj#;ug46cNA&>t-n?v;!`eT5ft7!ZznlJuhsJ(U zD<{NN02WtdSjVBvS!+G6#ep(-9P%?fcqWZk5UTv(@Wu4K>?I=LDnyy{195=>V_(NW zURw}af=P7C%VK^{?X@@!7c9iqkzp)<&D1f&+7Brem#2{q7j%9xeLDrD51;?2(dO60 z;=wPeHi60U6oUG7zRdDe|Mc}Hx@0%Hng}}7v_|yfQr=Y-gDc++O56@q$E>)?z-%Uk zB!_YQ%@!pd%EUWSz{x(x+Z$5m?!HC zJ_$(8+EUOTx(P2?!K$PwE7?wIV7I~N7TJ7`p1M3j#o!S+LLDZKWKR4clG07=yHABt1HyWChr` zV8&8@neH@*GTf(0+`H*J;BXUH#QAyH*bCT*#@GPRU^n{5Q`<(?o1!|fHtiTBT?49@ zvl&H~QMiMjO{WC{F%@WkJ28Ym#G>1z=z_vi8A>!kz*d4e?3v~+xh9pJysV$|%S!R4 z02?BXDgjC6V5EvG`Y>CGTa2iL-qY&^7|u zhSx^MC!GMHN6~#Yj|fRuehUZlBusMo4 zqa!2W(oW*N2d%dF@t-88tp}0AFnt?5`|{5nG8~Ty0RJ0*x5li%k~i=hGVU-?GV%L! z>W-v+G$Fh5=EMwOj9QD9&e|5LDMvtTnix~pK~?!7n^<*f3as9KQ>V)m7I2n#jeEWE zcZ{l!JM=jEPDA)nmQ1}8Wn2<#pzY&``*!vFQzyHSE%4PUf}^{8QP4d(Rfc%ra=pFb zFPipCb?ah(PJ-Jli@U{P3yOPozEjdT`98d^p#YVeVBS}t>8uRKLw&)HptKqMcOqJ? z3}c`StBRqFaqugc{Vly3EE3TSd69%LU*!yGu%1K_=t=ZHrmTmkgMkF|&pX7qmF{A_ z@n}=#dg4ivLZo`CP4dl^Oy2rzqRT-b(f(&ub4UAs>tZ@^Qrp**ShpZ}4~eu~LO$2N z)$~8x)`|bS?Hrn9@NLx_;uxRf-k{QHetqT$5&X0T$?tAw=mjtLpnXVm9DH8eo@mK> zU^o#awTysa@XO~;Lu(B+pPo7z-9I3Uvg@gGt`AMbTbkUDJV&dOvfb3}?NiVDJ^Nfo zFR6up*CQ5sREa@V<-U7Y(!KLh@gog(k(A1h^K>clo+BR~Sd_%};KQSC_VP+;VhMnI zF21g1OBMevrM{B!-g{Ww4fXCjTRgkxL(173bag2=zuH~h-+(!7-35Bq!+kzO##%u7 z&e2ojXdl`VpfA;yYS)` z+zCrCxW>|$_wI-SMgOp2e@H>oK)sAuyq}2Vo7a5p9lcN#WCo`Zn6N6Gf9CRky>Mr(^pMdQtR`+rX z8@v6QB~k1>xhBq<8HWuK@!#p#nngEppNE`JFM<4_H9FI89qkgS+L^kHXI;kjok6rh z#QdBl_vc!3Vw}5>t=;Kp9bi{`tGj9zfV8@M@p2;vt-iRzIw>j6VYt@Wpa;oTK_UUh zrcsZ-4yYyu_Sd3;@r;WQ16)3!rwvBPMvyS%G6q^QaVK{pQml+ zGbu}9#p`UL+0MLaQeEM*DsiON@4`s!H^=KppXbad!3GSy!s)sdDeMRo7S};5pm-10 zfEr&rMSR9i3knhgey7)3I$z)NXIxbnZx1mI9J+A`@jng2)>&SEYH!^HO?~O$9rk&B ztNY_wGf|`r)i@PzV6oC?@R(#+V=_$aRBWZq3~ZTMg6J!*-M3kafs}HVh{ur{<@K3M zPK#!zzl27XjA--O9kdnbASRVhRMjn+yl%ZmU<)L?d>M;f;#tq~oXGy$xBRUvZhpQv z1g@X!HK||2qe@$UQFJ#nt=7h1*Z1ymBO_bCMn;#W)*BW(UYFj1gE&Sm!+hW&)pvm{+JRB5%OS^_8U)yfb%S=CNWgp#RR_whQ`^8BF=Ch#y znzAMSRYxLJIAb*)7HBFof5l(ts&(lgwL{&w@VFz$8+u%SNmOX4*eu`QtybI^m3m$8 zN~G^G)9H0;A!c;+o2qw)R8ZMr-%{}retjGFK#6gZrcw2fn7@iKgq;UC$hGcA!iFRW zyccXfsyERNr3by>i<=eEiuHmTHXaxRCo+mR|3EMD14ZQ)Fl zZyh)LLf??99vXq1Nf(gT!88HJ%r18BBpLfcebNAGWeAfQL@&&XyzzM1tbL4HwW@a9 z%DxO~v&qD~wHwb_@6vnO_!Xh@!hG72=`*t0w|RG-;^K0EUlh^0-I`pIo?~40>8(Fl zFA^qyv?x-bPX$Eb^b^<_`JH?Z8NC|{#gh4^C&p5iwoh<*&I@5SipP0fx$n%M$BrYm zh7@p{YOBPF9QcnYDG=gSOr9Io{kNB|ft7U)x;$yO254^dw>x%lmcr7n1xoxpQ6~haWP%L8#N# zjtQk>Z_~4l$(!?CPHSh83jC9$5TZKXDy|;Hi?w*W&MY_u*YdedT7P!hn4=zpp#z40 zTLhjM2el64R+tmO{TklL+D8k1r4s*q+jyJp44nkct&~asy%gqclZCj2E{uwjU&X0C z1^s4DGr5FnLuKjex3!zT?t=1E*17Yd9nw=*L(6oQ{{m1;0|XQR000O81Cd)fFNE^v9RJZ*N{IFkQ$3Pc`1Qi(*xNl!N8ZFP^6$lKa+Y(LxS&TNv^qa;W| zOpzQCwCwE1QFiaKfA=JNldUQMBtTM*lWBFoZixg6h5D{S!Fz1*c);e#Ld2^>R>Gx)+Y7Q%Y5%*3pa3H(}RoNst65!NN=>}2wKe0n(! zSZubHfbnX1pxN66sta4aLMO# z%40>;K2AIaIC@^j^Q6e;JU3I90*RvE7E(m!g^#n&Ql5oCraoJ70D6mW0JhBT`bfna z4nF~pwRz9yg$!pASHIIJl*=UBfApD%r#C#l>2*3t9ALu8P$__cC-lspPUCRHr&Aa; zeKS5jdUtX)eS35|IUZkL!359qIzRq=yNMVqn*%>b-Gkt1mzk}Oy6>)z2QRxoT;N+6 zB{3g$?|9z*`KQj0VV?8NEV^SbKh8(pB8w06`I>LSe6SJoEXhG$20+!re=y$!HwRs| z31hM3x%|~$?57SZK}{Aw2qEtrbnu^UhoxBpG|rRkD4VYZa-_%roA)nYz)RfasJoxT zS9zDh*R6=3KkE*E>Hzddg8@^JmvC*kFKofk@>N zW#oZ-d``PDAn`jwg&p(7e|aWufcq<+JCDc2UqIx9-|&b<_}@`C%qQ_pa?P_YE5y+p z_dV(^!zkytCHCWR2iT##^svMpm^Cyc{t0*=Ce`$kg5R_=@9d;Oe08$WUtD6r`KdD{h#mvt< ze~{0CSn^|#-fjQ=e`5d&iHP?>cl!36UI~QX3hD3r%Oalla=+K>pq2rp&oe$)ayefU zSjpKO7EMz>;Ey6d$H{ zX*f(pIuv;h!ZAE}_Tt40oc`OIgP~5*V#g~6Bl>L1VTVWyf5Ih+7Wf!U3IqEx=WNEo z#(WE}Uv7=Rkb z9Hwst?0-fiSr+Ja!kmVt;ru#Waol;FfN_h_%7r(fh=@!8SYZ_zLj#x{!4UH54 zG!%~joEKsne z+o2i1T^yaCk1sA^=)che{A9GnL-_v;-EjFFgo0%#C5nlDZMj|mW|@4O-|hCwSwKhy zFyQebM;qdIQH}JF|LAl&3%&%O^S2_A-12yS^;OdoKzZ;FU{Jj}EEhtVy5=kgzks|Z zaA3tEe`WM71%vtXFz2Xx;6bhVxIum!Zc-RDEb?qP6Y&s+uQhob5=2OXFl+(&n$`pmu)ag zA{a@8Gq0kvJsAZ(PNeK+SE0bc(H+(i!j->&VY6!W zlqO^xq6k}>I%ui?!g*R6MpElA!;qKxC?IjN?e(>d%E&r_C5m_mUJ~LXj8i^CaKeh5 z42*o#nKnfm8PRwMYtJL_)9jKw&RY=X%ui+rP4BPURl;(_)Icx=a|r3tFwHX_g19SZ zf0dKbV=68!pW!Gl=jG<}l+VRd2SVUz>=o3UspK1sI1%5PqgLj_+0iL(Uu#jm=Cd$f z^A*WM6=h3pSahrl#fL{O~3b8GH2M0HeLhzkH+%MT^&aY{^l%sU zO_+%g4kK_&&BrMR7{_~Sl3=r!DMDddW+JBQ*2Qja9N*1i+H!atWeCVKOj^M%SYPefeYqPT&- z$%6(QozS7wb($}i^dgAB-2|5e0`>De0}^HO&iAxU@f0^`DeqqX)nbH_Z;=~?MadTY zbFYeOJw;E9ZQBBpJ@ziIf08>GWRnE`{SAWZWSj3|;ts6zTQ?2_!Ej@p$^^~|5iO?L zJ-66Ba0(L4CTL%3?ZMWUR|o<1PQf7Uf^1M#3vxlhGlkcFwW&T@cXvt&Z@U(dI%=7a ziOTdSSTRbhLgpTXR2+e*CD14pkxKmFdkK!PQ0oNj%*4}unoI=Bf7d3#wD(QQZt9pf zd{Ma=jk7`%;wRXST7>KlDkFF~#sw~=>!G@qLUB-EMS>N)LMY>f;U8A(AiWRcYYOIm z39}Grdzxg66(n~gAe8&ZX(5A3_OYl6I-ML+9pG>{+-|plhzCWq2^M_#pPMkJy3P>2 zc~ay8{87U&E#9FYCF2u10YY9%E&$3Vuh^}@c>?QjEU%(B& z{KT-TND2a(3CFkH;C=?U(P=aP+G9tH1$#~ci4G0iJ_iq?QbN9^>R?_h;ZbcNwZc@1 z9hRtT-t-AQf3b}YJbK=6I#wV;R(uhHR>v)7d=uVI8;kz&;91R**Y~$`>cO*rxSw*q zKf_cRZI@G)P$8jT1Nh^pWtpB8BI9PAB@S!WJ})8+o@c~`Cw4IO#J1h=Yvz57y?c1- zz|xk{o?(r70)x7q=izD|>waxr*8RiNF8t@u-FxBTfAPadtNfu|nHp1z+G`H0Jc_ZF z9?dXU(II+0JJi{B-PV|ZrmdVr)9fg^HnLV}G4M&1P-7rLFQ~u@=EIaYC1iV8e9Ex+ z#gmwQg+_guL8oXFo1uJ45E9U ze38QTYJYmOGMZXW)jL=P9fry9f|NiH{m|vzK zp#|>b=xTDxULT!Lu8vOF$@uDOe8Db%Il4G!mq65aPY%X^8uwJKRGMO(Q|Xy51)0NY$Ze^LR^XLlC3l0G@Zlk1x>!qXr;!oxkHz03n! zLMEz?0@f;H3$Z{VshY|io<-RbE+hmg6cWcAkDfz1;>Vn3`eS+6hL(AmQ?LNr0!f|I!B9l#%f_zgB%BT`f9)&* zxVYc|fv{0wJDo>Yf$pyJ6}7PM(Qwbk)H;BgKx(4=Q6CRqA@GN6f?`J=6Ub$TtOWm) zViCk9o!lwcttx z4U%Ze0Q8JIS>2x97J(=DR0LP)WfLMWJ4SNOYyjI#NC_rVowd^ewQOCtl0FP+EC{r< zN(>t{Oj89R04;K;3z6?)f$!hYD9RQI!Z z#`c;PO0y5UOh|#qszO>12{-^Sp+EDf8e~mx(!JOJR+3ulmkY@x30#Y%UtoDd?Z>5i zYcaXT34!%@`+e>5U6fhtqs z(N#Ob4VjTuX_eZKs{PE+@K@m${=^Z!8QHq=a{YapZxIpA2-jrPYm)EpS2ZV1HR|P1 zr>A-Z5Zyuy^r<}IG`8721+5)&*-AmK-U3jwL>2}JT1(^;=f$_@e}#a*I>@|h$qDOQ zA#pPgeNWcU%UV;QuK=kZy5$mF5V&H~zUsTLDLB&2qrMsoxibL4Anwbu#c1dgY)VJc zWWH8{qbr)~81nM$-Nozi^v%)Lcsf2md;N>oJO{!Ir4Fk72!!5a$1EO=!~cTS2LI=S z6ZRV*dc6;aFFv)xfBB*hV|9cH|&6TaLiof4#(w_tiUZpGxECT=c`n z;8r(F9I)CG6sM;%5knS3&&)2qDnH5>kLiDq+P1H?$Ml&ju0t86ol8MphshLm+|$tk zGNXCEiJ#p^y|e=tC~RFtCJ%An;J`6dg2*G{;5o4gawX<1RsuhZrNsa<<329nN0sPE zR`{*RW$r65e>)@qKQKPy8<0LTR24C#I$%>9$Ab=rJyz{JcmJGE(#dvbIYwGVK zAo$T-Tku%{JUc?}P#&V%Xf2+pWaJ^i*2DO;Q}|nn+dA@L0*;>)d(H3^OJW&YNimA{ zD#k8hI$(N$FSVNoVp(<*YHC}@=z%)ekPpZ=%N;w0e?u1%OFkm3Hgsx2Ys_1Tn%%vTA5=I>#PhICJMzfoAz1^m3nS z%}FMt46wH$UQ~{PhUu2FY0e>I$JQ`p)4+4%W{rOd%8F&3WI&%;VQ-pKNAjp$)oEdC zJMO}Wf7W-|fRo>U!)&jtRBOuDd(iMUKn;BG*Kb{*5@UOnIwjjzZ+m+1shN^BPTH^; z(ak0F#Uv|f*m1ySSAMYYOrA*!(rc_nzoUAP=Znkv;)b?fK~3h8xa~xd@vwd zRYxVT4Jp^ysFuoIos9KDEFudD*7m-Wn#$!UdsBROrPrIt`)hqEh`jX4(9 z;o@^ad3voI*ATuLK--1Fov0Q=b!8_~*HVnf$H1(}I33e0 zvbzCxu24VnVBpl!LcED{hqsM9h#P=BES%4a3@bNF&KI*#-8|b;fmBs*-6E^P_ns2x zk_-rsOB#9EtXbjI4VDk8DU>|W?aNI&e?wKa1{P=z?@IkK=mkOpKgm`CbCK8oeDwxT!$vRs5Ks*m5uZ2M%%Zk9PO{gIqv30V^(vLeI20m z9Xr#878m;={$#mUMP0wwbgng0f847R^y<&4Zl^BYvgSHDza7>3nt*6X`WFhn)P$|W z>oY2>)i3wd-~q8{Sb1IH@42pdFVpwfxXR?qf}TE+4Xj}&RjEAF2VSPHb|&Pkm|t^A zZM8S}2N!}I|KP$<_xl;R!&;-hQ*l<*xfb!Fr8A%Y075Viqj@gAK=^pBe_GyO(&k?L zFaQ)9e5PwgK!g`R)GjHs%C8yy{Fyu2970cZmlWoAVYcy@>f|l|YJsnM@V6qy*RZB) zhV@)%RVGhqkS+uIxa&Tl(62ApG*SpcpJ1CSt}Pv(IdyP)@6<^X8xc9T1V=q zP`7g_t=Lr~(OFvkMr@0Vf32U<0TOKiS&8-s@&-yM_Sktbi^QBAoln>@p80t8wHIGtG?)@KBwQyK9s^FS-*xMC}xKUB~HLX#eP*XB#5( z@oKh>l~SniE1=93$DX=!U`$^NIIEpz2Po|`)w-sc&|Ej~1$82se>9gJ(YYji$JUvo z%Dm`yL85NdYa~=_6TY^Q4k%_r>K}Wr3!NKw3xCHdjl-4|4vYI;m0Q z9yR^~iSKZr)~AD0fW0U~wbMN^&Q6-E-4m@SD0T&6ckQ8(SDTwxW~i$a(@hac zkw&fBvAd*U6Y@$)O^#uQ3xRx!x_fS4zXdhe^zT)q+-7mxb=>cjhW@um1KrnkR1Zs4 zE}lDrQHUlm7}aOgXntA^PqXw?aq9m8P)h>@6aWAK2mk|-TUoblTnQh&1Ot&9; zQkiy=rtNyGcD=6K_%w-qZKv%X*;Q$Ywz;NAg{17bFZ)BMRS`}Y4A9SkJEoNc(uQ~_vUynZr(RRQp|$ggEuEf`+t9Xa&UBv524(nY`!R~CYYA9 zbXq^UsLDBf&+~MOfa*YA&(e3xv@KgS>H8+n&h?Y}hO1uY<+-Yp(T}7K>Si{fAF6m( zs&D_S%R+t6%gf8GxKuyOT76sGO{V31k>whLN`I@%>2-hFJZh@D?MDH8)Z;pTl)j&) zize8oCwo;@R@*_a9xSTla-M7lMF}0bNh_)b<%3c1rYu^(%kxE5PSaYWQQzsWO;TML z=rrkkVgG*L+*ZlrQ3tQ)s!Ed?_VPopQ-iRa&+jH01d_Iery9uS=_4MCSk?PFt8uXQ zs6`l6d5wQGO&V1ws+$VnOq#nzS`VoU^nDoASIZ{Lhe4IxPO@ULY=*%xmEAuW2GeAE zl}-@gq%N1$6v{8Fyj-LOefejZ!I!J1SpWh<>P+YJex6s0DZUS0o}3)M1WwJ$+dv2lV^jLN77-ZL*ZzsDi-@f^-Q*3{HS|c%j{XH5y`FMT%ufxr+KKj?sfBUb; zKmGUUw=cdt9iN^dnE=eAN3-;T1}dG*lj<4bb41`K$@uC1-n-$N`IBmtKRxC}|t zDs7fk0k38m3CpCqBhd&fB~|t||uC>0KSHm5a4uu$F&c z)oaw!T7};($_m6nvC*W}JS&nMgmXdg8i3a}5?ofv9GV^mr9!ukgB^vrG?dPuc0g401OGEM1cby=mVJ$xSOQPlJh(T0kfQ5A;hw# z`7?+$o#_jXiVOtQiC{u8A!R)9vmSq>8FaP^NCadTS<1b%G1SH9z$NYUiRVc(y)xkH zav3zdZOI5A+Q`RMLf-Y{x_@2a86fO%GO;~_|pa3l>F9H&~;lKb|r#6^(78(w&fWbS$0mdgh4cC9d?T$qB zppg|MZw=Pk4j$KG@Hp_$5I-d%LGa@$UF69$jouA|FdRI9a8I{wlwp20HIx{?v!CBy z!G!OlC4MxIXcnDbEsJa7lky$?d57FCv#3cs5P(`HC4ym{K)#v#VG?d##!2xH@|p~QOwW6` z$4e1w{(T5>x)ZUVJjiEZ7^AKdQS04?yt7oZ&`f%&dguVKdi2hn4I*h)AkaJfagOaS zq5-mfeVr|!sT$;QUXl_*qWDn@g_bLBaM%LsNMD@qUh!+PwXA?PlZSs%=#!&Es|T{? z`a3dk<(AdNN6^IJVZzHA9iSnDqUj#2p!r-Tp?%KjRbi*Oszg0%ylz*iz{SkZU*_jmscf>IyO?7+re zUhf-AXL9KBD+dw>5fp#m)x+06blqY5kn!jni@u(81|kF+h4+tzklZGmOYaY&wLLZu zC-uP!UGM*b(mnm?61uGZ9G&Hr*Q&AXo~kuj0kd~KCQoGIzjSF=XtPXBDeyFJMba8YA}Sa(EXFvjZ07@=XnO^M75lyF>NTEFG}2h`0VMBzdnDl^&(cl zXJuL!p$jI-ZYYy>X7*!Io)S0STJxkzD%2m65SDenfTNr^-(LL z`O)id4$BIzrR5@3&T@tuG|NSf4!H}U#T_z6*ZzfRj?T2%knp7W7(b|aoGz`;S>}t~ zk4_z9snQeQ{B*r>o|@yX&4C}5^C#7^#|eU;2bh05MuQV`sIA{C%pdhZ@^t<94X_*o%xgldYHAK2{8hY*QIMXhKN8g4g(6`=nlRfQrp7!V6KoD~b6`SF{?4@0$g z6)`{S!Ep(4Xpu~>lS`O~SIG_P*0A(tIs4;rsRhQJUIn)#0SP4(%f)5A3T!GOK3ISH z$>)C`M6EwVl0P!#9bEo6FM}CTBjt+b1K7Ex0P$&mu^Uveq20JG-F>br*E?pm zX&a8#y3o@-zc16Lzz=K%-ayf#$m`Dj+k9&HS)tyy)cqheUwzht9WqF94NGz`uhhCn zo7}SZIs`Q&FK?lodRr{#=VGkd(31E(o}z!ot2+pjmTlgIDUcD{QyF_^)37#LmDbPQK zds=ze3gj3`tK~6TLjPf;4HYE{|1}D6DLi}h0oDx)iod#U^nT0?zsZVe_y8+Nm(_o6 z1zRLp8|Fq64{$PIm)66To)crsQ?HD(r15zSOm|FIrdLRMW!=j+W8eBs8I`(P23Ux85(R2Ljd-@rl;U`dqT+K|$f0*qd& zt*v-&B%dsj225ariC?YV_yVjj;KE-}Lh67B3K<}-TBNg$&5b$*){!NnxoQUjKq5E7 zAH7>#)-jfep$ZJfrm=C1kBJH4?fs?ESBY_B^tSZ^Vq4~%ps~Y3<2)_+Z99J>2%u2I zAloSTm0ht&zw@NV_^9Q@MfQG3<&a5;^evedRSK`6qQaMW%pETT)#8T0lk<9lPZ15&*PpUq3Y(%K_ z^JrWd>~&wy##XP+NO(&-A0ssQS7B<3BNK#(jI03tpty--WP!q0Nsa#bsJ^3phBN^< z#9yH`#c#5zStc+)ZUO{g?y$+W8(P~QLAy@6*C$&q`szW$vCNH+i0Xd^I!JPb&d?}n zNnM6y$i(!0I$bsxY^3_RPO(;#$>Be~-+S}@EA zk_iD8m4oBpM|s2JLY;rjlLkFpWnpsjKjqJu0r}SeY zDntg2!5RVF5UJf_9s6qS83`m6H7ce1Ig+A>(-}zZa=vJW$_#&)04r6%;}j$_;g=&6 zSGa&&Bv7AzNz>@7;xhEp=iegJN`>Y|3uDc+>l%IL7l zgf3N%whhI}fU-LLz>Nx%D%~mz(%q)06rL8Mz)fvZ4yDW1xJ+e8NDrGflk>aDb$S=U z1jlg8Rwf#}fG>ZBff*BRFarf?j_6NZFY>I39CkBw1Sk|pT&Jb<%k!BpU}g+2QQFVw zOD~6E=r?MNB`7!;zMUrXwlB!>qGJMUT$HGYe>n=CTlyRDr-Xi@OA5#nFqoFP=qI4U z=L0YZ8e2_KWp6GvJ`V?~VI^;2{ccc>CKNsTKgS1ehQWUYumWoI=gIUMgS|2ltV!o}0bm1?@y}KK1*xxMnv9fjf;Bx_ z3@J$?S@M4n#|b_1nd_nni(XaJ?DzV%1iA4w@*Nd-6=g$O%h?5epkUkK7f^T7>u75j zYzx^<&$CKh03tjdRKPI+rPY%R< z*npxRluWZ&tfvPiNi2A;Vf6x@J?67CFKOQJNe_RQUKp{L8e&v zy8fxL3f=oe70|1e<3CYn1yrI*@xKP3fUx0vljO@(fHA*Ay+L=WvDn?H>bN=|$ng*2 z_H}+Aqm_;#C(SQ9jp0l{Z0yP4lfkzYbWaOm`Rg$Ee^MG#`#sY5K^$&LC`P|4p+K%5 ze0_faT5t*ioJwOg*(SrZb9b?PohL;C_6l(#9zuVcWtAdmGa~`Q2h-yD^$frJq}pAU<})bH z+<*s5a^o!@{)($Pppiz+>;Z^OuMmxy;4!_Ov9=D(3g3Mgz)Mxf#>$V9E)L)xfDWG! zoZ!K@5)@=$%(9r(qo*$vf-vJoQVNk2?N^oe;45Y8PFaEdpkDL>0erAm(;TE3AFqF# zp>DeX$#xf&=l_I>HP~*K)d|RxteH$A6l9=kflX>mDSQ~?Gqhabk1?ak1q6#N&PKE= z`Ai!!?qo7AXUkmwnw3-dYKa4eEhalPj9-V^jK{XrGcsoeCdMeo6~fS?VKB{W)9R5~ z2e16|Uj(rwx_QMJwLL~!wIjiVizj~*!5Z49mUZ!1QJ}K|tz%_)jYqa7lX15Ot`he& zueJ`cl&l=UDzG9n>}SG%=unjQ*h*wasNRIU2}PlUm!XNGbqDd?WR80VwhA*xLdGe%;)m0}pYd zt#V!ug;=;f!2XlGoF+NXUwl>IVgm(%sng&V$|qodPSJCf-vzuqm(CSF28Dv)2sa~m z`T8D5hZHoV5FWKdj5f0RD&T+O6h&iK780_lVy@l0p6(_gZ*>-6=8Lbglgt#06y|5kBJkIMfUpDC)tYn%i zJK#5-{vr5yoQ+5W73~Jt+W|joar5J2F|M_*l-(aF|Cbf8BJa{d6~lkojz44eC`Y>B zz@=r~A*3$*$bQ&5)SpnrRy5T3({X&)@9VV5Kgr zbVkypF{}i7$<4sDEUQ^$N?G$cmUJ8CR{)eya#jqSArn+Uz(n@93#6(iQ_xKs12eBxdhDo_h3D+8x6qBQR+Y+*o_Q}Cq>f{ zTn#GZRzo_0*aJ$HQK6I`OfGP+u>N@o(}?QYRWXY}lR_m|q0esS7?)gF!S6ZM|1_8z_*FvtUV`!kUQ&jDG+O88tz*Tu}nP zqY#e-34>&uTOme6I0_L3Z1XYMzOYzy(C^UN6q-&8w?hKFL z8)8Bbf07F*G-#~8*q|-DxQ87;H;OEJxGr1#bnN2}njI(UgPDnabmtjn+c2dh4)u_H zt*&mgf+a}*_^{D*CcmQt>5gi>wHszYIx~$9<4j|W2H{127tVz^jvQyPpIDAI#gwA` zPcNNXesC$)rEyy;rb=m~>l!VB-iY1?)zo>`P()OHJ!E~s@d(s0pPd8owMBPaG6uoJWC;-S?$}A+iJqQj=?R+)>%g_M=}eil+6Q}(P;L;{Kkq#mC9cwDam%|0mh6Kjr$e57Aouxf!%exLTe)1;z4JDO4<@%w55M`zN_s%`j!mA~QhVz=qA=ZZTIz z&Ft6q8io2c>sO&z+}?9+tJx1QnqOm6-uk^ZoJQ8P7JX*i`5j0PmCnhOIwh#+^X!+D z4d)?iqv{9y?j?HSDyh*`DuJ;S{nW9xXENNKtYsptXdtDS(PZ@H(t> z@A|-h8a8HY!cuI}n!vo`f?OHYfB)p3Wyz)V*1zG~D;9d9C(Q_~6^-e5N)@eW$8F0P zPp)slm~plbrDvXj6n7wR4!7w5VIe%co9-J0UxPSsrMy8fBf!Jc%FxI(7<&NssN+6- zNB4k=cVF)9ez*7a+dftpzcR}J-`4ap!K22Y;Y z?NU}5HV!Dl=007*;d~X0NYRO|JZ4R2*6S6zUz%Emo0d!-gNls0o_QoQdzPLrFQf1X zks|X~ySZ`KD@dAlg7>Cexqtb#x6*ontrVtGMuqKmWNZKFhOQXy)i!%h7IiG;9->lz zYiOX7W&8nxhboZ;`_O^nIQ=1N1b=dHR%zb?=z|Bwa$epuGPa}BLPgJ=j0;eJt9Rn) zpbp!m%WiYdlu>sg{vK?gn4y=+6f>iWJb~XoOb)*560IBJ$Fa7Cies5oE?%lMuPP4- zA=HbI-m+rMt-uXMPds{=HLi2qbZzZ_QVH>9gR&=Kz{7xDb{ERgO=s!36H49cDU@KM|89^(J^M$ zQ7+diPXL--=dd!(7Y#;k-wss>)*`L0k_8=bajH)yi#yi*CYatAp*bb06oYhsQcjDI zG^!K^iKj`W_7}n0%PQe98v+%^U;^B#j5>ogR1L5vwnJ0$iem+jRiAUX5>N-fd9;3^ zG8J5@*a@gnfU(`0B4N+@x|w^h1Z@hyPcrY)LEN8YWHfTgw zvbBnSt;-y^L}C>eXIp|~^Bov7^vIwyJdiMPc{Mg_N#Y%A;o=ID z38zn> zHV%_@;HYT$g+IidH$nF(Vr-9s@$TINB*~Ce*t+QBdw{L480%?Yp3h*O+~D;8S{5Z@W-49(`PNS7*IRMP)Je|~QRdiaGw z(md4@qB21BF67B=a-HtYr?7rHXvFp#Lk&>Z2;ZkAWu=<0X6U}TK# zh*98QsI^u&rq@ZGCIBeco2=Z zPvbNE_GCrf=yWW#sYhRqPj5HQK8{9M@2hAC@8FyK1VH%vZ17co4?Msem#6sqy`#S$ z9PbURb5&-@Eju`;WN!*b;1+_SN?gNAiD$>Ha!Me&In)$qSS||OcOHi%s!bs1AqmgA z&mXqOtJ3<|AiF7TJfAfTVZps%PoHdVpS5S!FC?{io%!0O`Mf9a`=sRc7R7alC(RgKt)S75g zMTvSKDt$F5N*WTr_3o_wDbD*prjF{gks7Hxy1LMXN~CCPP0$vQm60UjkGQcS@v(G7n&SS5cBC(VGo9I;TgSmZ$M>}E8w}?l za5|)8h)0Vv9flGIZ)*uNVWt9A;3h*;58>l;YE?tzt0aumbLjmIV?iX8qstiv?`TjG zEOSrU(8=v$#MT@G?jKpUc*6(0;R8S?vD(L?x%Vcik~1R;4~ zLyCGx6S}b=WGf$Z3KbR%Wp9%LCyZ29MjvG?q~whhh9si^*0&khYWsTS>}}hvWlejx zrf*7r*)JXMl&B$G#TJj^X1q-*%rz2)Uu(XRD82Kgj&4(~xNUYpn#X}{l6PVxa5F8r zPSMb}P7!xHqmR}TPZftCXO5gyT9jIGQIUs*Z+w4F8%)#Uc%v;~A4i93&I^^P`IzU7c=Gox+zH6E?(bqv=;z|^-zjd-M1G!WLf^Xy3#KiWEbk#sr zc4#8awOV~zx6dP7*#{7e=H&XUNIf!+3ovlgsim7!wbUbPjJpUbN*Riz+|M>yVvLG9 z_hznK{9>zo_Kbn+NB8A!$ZAQOKB@8IJ9LNCI!$^v^NE#k8-+v$(ut3J!%~ZX(a%P8 zgDnkjOMkKft4Z6{f}eH|MBKYs=j5x~!^5M4|JmC;nY`I~y*Jr;^Yug$z}XIsFd8Qt zzie&%Wpeg$G>$jU@aN=AKYTKHGT7+u)cHRxu$ZnZV_(Dm;L+hfPF^0o@ncYh8;iT> zbaonlbvpa1y}OGzbfS(KMd}NGrG7wX4f$YwM#UcIe^6(X`8+P}`cwX5D{)|=k1+*N zQ3g6!fcVqIJm~;}uc%UK(zjXcT}KC(HTg!h*G>)fXwZsGI$5d&BKloy0xIu|uBoP? z;dD_gi=!ekq>O=s`a0g8a}-D<24Qw#(V0|NjQ7w@244mo|Irp2P!>mj-OQZFS*6#G z(|VdL(oT&kJUtJGf!&vGfACXKe<%r{f8w;=Db8Au*>xJMo!r6?&L!$3vii3G&I9RGA$53u6kznuH_=)5E_j7nA+ zEu0y;6JU%)*4zd26ei`2bt%xr@W75{H)p2GWfVL!zrkl|d>O-wL$<){4Rpw`Q(sDL zF4xS!`6lJFdx-&9SjOQ%l5$MtDQ(R~cs?}k+BlX5{S50FaYGsIT_J3O;|znHoZ zF9}(uHEm%gH(<9>iX~?`Y!8X)((<(Z4YF}8+lCsB6l#APg;4Ez5^|Omfnh3d@Xid?MBTq9V)x@cs>jXqlzX!Q~)s?L>ds9CA^ zqS|R>d!v=KIkg1keVQkgd*Orv*@>snZRxBveNi5YqFqp4k8$;H#J=)LaFg;KnFvyG z57%dO+kx0fD0>Q?!KNEFQJUc0tHjb1;c3(^^9dG=mR0V5atY#$y}7I# z5N)c7;EM0bjZKC}3rf(We(85tlzfJ>FxLwXWo_S1vC~onQy}2U78v!S**F1Z)ZT8O z3qKo+=My}C!p#=_CZ=C8(ezhaeYruS}1?8ON4D-hg77+F8Vs!7z?b~DotD@n}ZgDI|d>! zu!fU==a>DeDYI2hZl^XUf@C>hZbc2Mz9R7q+DMg9>M~G)aPNd#!~Coi#LH@!(MCym zTeZ;3I1q2D&JmJIcYep4@e-Va2@$bHMCJA>O>=qfxg*#KDxt)={^-4ZD3^i!$E(PS zK$+Uc*=5lJ5d>>@_GS-a!r@**ONmxGmu)D2^N^3(?w|6DGk}Nt#_{7EL1rI06J}-1 z34Tmxw4H<)pz5PR^hTc!`foaFGr%3H#!0ynAJGiFX@0g)g0%xB?SSF9Sf_(suJROdA+Jl&X z@!dQNn}bciGD;N-+=mEIT}9p7o5ZyLTgY~kiY?UR;N~+d+;Bi$60B-xN7{Qhv>Qea z)o2^aJ_3E=iz3C35g+Qbhac;-HBW?INOnNJ3#~uNp@*dE@*5L~482jR4V%M^HLtVx zK))V|PPr3mlIX!=c@E=pwOKFEF^SH9xf0a(2}d`mZlVEHa`HykL-m>`OnO6G&TY}5 z>=Ue-Haj!A5?k3?YY}nJ~g;Cfk+XCeZMkBKSJwv@eLYo{TXmIxfx65HV zta4gVVA-kffr4>=Rj`3W z0xQb`R8c|U=0KX_nmeUVDMA_N03tjYQyEGwi>h`sZb6-`Qnu@N6jrGLxE7$$s?+oO zotheLLk~G^qU+`9MPt>~JS$S5hi!W}^@x+r|6ehy5*PoeA@1aI2;YP*mLoig_F|^6NDSOPVZ=cm+z0Y($kJT zq+$m;ii|Pg)F~{NXI*Z^k5^OCDgAWisD}wYP;cm(`mIx7wnU$<3@VK%J61fmMJW6_ z$9t8_jODJA&Cqtn2+xo&K@Q|ThMwuuxsU5%OKWmA2nm=1T+R;JU<|r0x?@&mWJ47% zOj{Ri=vekx?@goDQD|U)5uQ1Rh}8t2PQ5P*uwQEBtmZpxX6lkuu#X7fCe^l-BdVv4 zG1y0e4Y=f`EZQsv?JDKg2RhC!)4Fp&oh-Ros+pJJI!m$9pa|>2%CCUS1VZl~+FCGR zIkUy&BLT=bq5ShK#e7JOPb5nBJCJJ|GEwk@Aal9eb-l@YjfaANvb63rt1=h22hpTc zlES$EDELj!vH3JNd24)q_K-HYyMMk-f`e^(6m!G}6`ZM=-&LK}M>ow!BYNwbB1W3o z2+Ita{|B6kp)&pZW`~Sg(t2Bq5b06IJ{Z-G{8ba%915&qkA|A%Ch@SW5dqD@_`CFu zqvq~)hjbOF$Go|Jkx*-CU8AW=cj?j%opcu*kz#dU^aQHheHkXT*1Akk|1s=Y2^3Z! zlGxKIpOk9mALk4bd7S|yZF`XuFo>N$_9kaNrUd;hk$ zF3Q_NX}w%&r4rGUv(kQ2r=Ap;SWMgeHdH=sjRhRBjWig4aZNs$=h{#$m3+s=*U8M{ zLg;%2hTZ|LQ7-ibNlc7`k7Y+8da}zN^Y9>$Fp@ z$1Y7J52+u2@O?n>L0kI#M(^x;etdhl*y)?8h zTS^G(QPEBBvW`<;4xlV3s{^*o3{PI{S*kDdnxo?htU8Qmrj1-EYR_(bGR8XSda)?s z-fXJ+{jk#R%i!Zt@YInzKw8C-hH~2Wa~Iek!>v@kM%Z)DpX5)M#WTZ5ZASP5Z6OQH zxT|b`waXUyJ5*t>iq)1C|A-=`Ur>NaqAOe_yf1N=ViIf+d^Z`G%BlZUsm(gNRlk_& z4Cg#6BKzU6Eu?{Y&eoG_+olH&ZC~fu#iC2M+1P2SQ9>n(B3FADMw<67Fg4c$J=X(0 z*MsPIclS?pp67oNr0BS#JUKL%$eDx zq(`zjaz=f8H?x_ab|gkJBT)zNQ_a(A>qK42Y!-t+=dfFTeDLGH=-uoo#kEBqe7eme zkCc_VG{Cql%KX^NqXErw;wTH4q)I2&h~C~i!9C)=lXBTS@!ef2XJscfOuN#Avy4}N zm~Vq$L)Qg0ojRKFAF*vNc#mNw;r=d=E;Yjd(*tXN!CXlx2 z@09vI>}Vz7X%U)db_U`KdRt(Saz-hftT-(~@0V;rIo#o&%U|H1bNJ`>D#sYEoul2C z``_Aotc?2SBTByeCW%qnjC#ERO6E}=ccYxswP@V^ znQIqjD3>Zs8?uWrO#Xtd@8+{O_gPznFXrn7Wx~9KR+(Q5<3eR@#e=#=fC^%N`%nm@ z$?X?1M9xVY9-MC2Hrh?jn6~GEqLw{~9l96zA-)w=mA$TML^r2&azV~F9=c{l=3M`%bCD&nh4ORE&skr_g#nq57_ECeb z$=db>MuSdiQfz3qL){F$5AP8euk`3Y(4%&&K9aHGTri&N^u91})58yDcTVki+ozvB zeet}_6M!Zg2`#)fECH#ER}i6`9Xf!7co*guQ^K_2ePnCP{5M!|*P3kPaqrorml6uY`P^l~ebbWGc)CA_) z4pfZntenD1#aG0lFXZ_q2Swg(s(E$Q%=7gY%MEzgm`*I?{$b==ejPEnJBb|egLi-} z3q5b)uT&b6_l;#D=Ps9U>Q+FSTcz9^3f#<)VbO@=I2pMPM=U>o#mHz1D}Hx7LBr_t z28hDfMb_@2&pDv#d_(2=<{1o)en0gz<1PfC=0{L+U~r6L<_@ue=Q_`Ns{w@!or6ks zt|(|1N3YP;7Z$LB3Brq$b*m7_2;L_7b*BqvMJ4Tf65U@c z^V|&~*QeAxUu;Vw(2>{6*c5fS9mq-+!z`_N>7+yoBdCoD za|a#_3@%WA87xfrPh{yMR_DE0q#W`9v=thfLoaN4!-8OJ%oWp$;`{ZLIMb?2Cwz)S z?oi&KF?IT5u5R4KL5F;OVHRdp7=VtMk1tF(<-(Iu)*KvlI^9DFtF6RHH*c~}dx2Kh zZ3C6E`EuTqyph|GspnutEJNulG^_Nq0l)CBx8$;alOs~!~sUApn-TRcoMXOy`g8%AlM8vb6Ems$X%i_@k8x&h4cY{c&h%~P=t!g5N1Ly{+NS?n@~ks)+qTR@=<81Pjg4*k zZxwZa+oU%r8$kKEAo&nJe!2bl_4eaq5dHM#lI~~Iog8@f>sGlQ_fB>m&R9AlYWOw0 zvn_6&Mp^`nqZD%P+F&s||117O7pkE4V@kX(5!wa;&%kc*URG9EZP=Ss?Ih5m5cq;F z_wliS$HHi=#m0~M!+UK)y~xX?xqr@Z@l9iYMQuxZ;YJOVcshWI>K!8GLzQEG;?XtI zyE@aY8T9Y^F4DAf38;_YJ=_lBWa{A;q{D&X>e%1nby?^|A=LDKO-aB!t z|1|#T*Rv<5zyEgnE4ADvSja8`cXB9C@LOwK=%dm2_}p~4s~qPGoDX&Ifn; zA(-SKJgk^s-#vwVqY*djU}@6vkKs7aYD(EaM>bN_u&ZmZBg0?m+OhEW@Watlr#;=_ zQs>kC!&qh0tBHOH*lLzE?uepyX3{3K0qvTYo8@UoWAv2+Y4CjLw5#j2a;PzXva$9Q zrhG^Z-@aYrjrTgis3$&EuFnuMgtB|21s}rEiQjyImUmg2&j<{?vV|2TlX%i5(Nd^( z@zD4-vz`&@HkzrUv)zVGnpMdxnkvpq62Q&M`6W2FIkCgA+jzSg$DO5Ex8<+e zq7ph8Uiy~K+f<1Qx_@{DMEMqf=bU6jU*Y|*(x<0Ram5_ulJIyW)MZm$@+8*%Zu;z~ z|CX2bETjy(tsn6I4wmxYWh`Rn{|K$UlOaF^WRdXrX|$g~cBrfuzdlR(46 zSvg04w7{W1?6+`$Md%C7v-8+_ZqQ+xOr|N{T0jcCj-kr*!4H*NksOaymK=>yyhx23 zL3uxbF%x?afsyl)Bdjjk#>{kQhIU`Tknx4ajX-!&+OA7d^G5-#>Vbr>Z95|@7F%@#I@)d1hjtydh$@D6JQD>2LeHn%8lrJQ; zyS3u}Iff$K)!#VHsylTxCH8T5@8|?{qyP7I|7h>))ksTal?b(trU~LWvfA#-CzDz< z7%z8@C&zF0SFlan*>MP~Jv6Mv3Ed*68Q5kRliL*Lw^g#3@KlKKPu~eBmxir%Z_aCv z3Fq5cz>h5jBaIt>Zdie7Q(-HSnsr#LFB;7}`t-7_8zmZNl1XI+0NJf@1@Qfw*By$+ zchl(9yrubx7-{5O9(c%v+yU;+yzKl%@7;>X>87*pF~vLn_eOiqGU%D1UQ zKp<5Z>w6d6mCMj}r_k|6s~V33Zo!rl+;-=UJ1}`MEj?z4Po~Y1piu`qvG55);Joa# zUCCR0)Qnsf5eGXpFg7N9sZl*UPp=ZNsi-s_5^z@mP_UM`btAF(Sa?Wkolb3X@Ez@u z;*KfiiIi)9%+!@w7Cfl;1Z}n_y7P?hZ5rmerX<++MV(xvu5vcmuz-(iJCFk3tSMBDm zH@YA+^i!71cNAuk&iLvL-0Q`JU3J-)(SvPpS4Nxp&;=~7gr-6qJT#RpeL_yaMfvK| zcYRAn?@gD6uvV)32^~J=)8dz?kT<~`6NFq6^TB{5VDwIT6PMUAh|>27Zco;j#PW4g zZ0r|*8z)!kh5&q>&1SrJ`TkB~LI@JZ9;F3^u8ghw3aPymJ!b!{S3 zt&NMn^!Sn$?q#xmnE{D{~&HQcQMQ;G2H!X)bo!FhLs|oG716+l>p;)NNY_13!iT-@n-U zixRPTJP}J#q*-K7b@OPV0UPHN7Nmo&&b#rJbI^bbP~6F+&C{4(c?uaVi~_bgO{?5A z*1fy579LN}3?GHT(#Nn?`-azgevblwdH*m!V5sfkwwiyykblsy8$+)x!+QtcU;s&e z(V1<1W~Q>pq|2=(=A*&CgUKGuXb)yK%QeKNdY?wLk^@x^2wad4aj`O4u6?>frYx(> ztML2T3%+qlI)S4{K%5PR1Bov6z{`PnUZg5`uAED7)*?^tIOfwGwRN;9^aVnHrnFE< z^hQCf2Q}z)6d_4&VGO8@pof&KVwQrAK$!=;Nb!IcdzwNsFhenJdlMH}1qGn5RW`cH3i|v_iAflLB{JB6zyaB+ z3J`+4M3PnX0xQh|s-z2buv0G>J);G6?NASu+N7+<-=hP>j_i|^86@>}li@7QF_1Z} z!fmo-a06_p#0)$D^SM&FQQOR*G{|_0=BACX3+ZwQ3>sIU)&vy%(AF_9)6U_35Mf+8 z>$j-Xw?J@MnDUsEOF=q+EkY7B!b&__em5m=iU*Cm`FOmcU{LzKFF)}U1Q?r zxe+g`se8l;orTUT)&P(AM~jjnllkadqWQI!ePdO=litoZ9ljj7Ck~h~am;FcIUl** z8Eki*Rn7Nju;wBjsio^WuzMm5b@6ukt3KnFOnBy;X`xDOhVA-)Mt(#FG^9E^1BBzP z%Z9Uu^GQKF5pF^8z37**nN54exO5JJ$c;Q|Q@6d8r*n;*0ogg~z&p?P9dTfQGD>Y zwB@Z6aP*Mjs{EOM0MzgSQ15_!@L&-@87Eo^dh)*$PU@H|mUfg|3Kp(>G>kPpkP@OE zP?F(`>~bmD5Igr2$gmrQ$bD}X-6nkYr(t!TF8pxI$8N!axB58DiYYIK@I}4o zk4v9Y6P&|&i*=<^oO$ogH)V<-p(R}&87ksaHmTVEOcDU zRC*DW4jb4kQx1bDr~6^)%)4)QzYYFGmAo88V+A_nTXZvuNN_SYP-LUs5Dt-F=!DUL zFaBI5UbO4ir9$~ZE=cFH3-?2r&Q{>k!Wdtl@g^aY8Gb$_kxr*CGDr_`Vo$j}=snwT z(ZF*@g=~<2L{o>RCH1NRAL>Pr|He{|*RW54P|mA1owq9=%q{@_b%@3f|yW@tH;2r<>J*)GVPuTp(;M zq^{FDpITu|p)nM(ZU{G~tHOfjEMLeA{wLWt;(qPPNi&_^S21+fHFpb_s z%n9D)fp)gKHcfXrl>RA$1SybaWJs(1(xk=%j;v-aNBA zc*mz2qX#UIDrYEn&c6s7l;lH=uv&eH640q%yB13qno;K>U)EO!30*rLpAow*3rrn< zG*1eZ%yc@Rc`X%8XVUUzd`NQ>D5(X&4QA8=>*@Wq1vtOI`$-zJ&W;8T{t zRxRg=3P!k}Rjp!ChzE^O^$9Vuz+kF>_N0!NGrJr~fKH39@w*U*WI-`C*)M!Oqaus8cC&A&~Ven$>xsoC4fqAu+acX~--fS+?MUDS#Y(b69b=~-E zgYr{6G7zlN7}yHbwv9=A_Ay_)D#wb|or!cMr@mMYFV3o_n$@8f>m=CLgKt%TDnT$Y z@Y0bwkV0%Ypid3YrNeqd%jV(T;l8$VI6^Q6DEcN!^6)W$Shqo9T{i%#MwO~aW4u$c z%FdSv$ybuKLN1GKAMNfkbnG2)wOJoJy{;%^m5pY`nP+-IC(Z4g-e2#1v-9>9hDjbC z9PghT9Q`9Ot|9}K7nb=L=|}^A#+RAO#oTSxoma2178dI_PA>{c)3mH|cLBzy1(kT2FdR)Vp2i$d_n78N__A7lkn7x+wI=|E%ErN853SJ@=S*>-h zjHYb=m`-5Swylm-c88%8FN`dq%oo~2s^X*MmJRwt`t2;9V(IAqw3s=6a)uL+wziRa z(p`*0&7>RwBn5q5*F0^)nr_O&$)WC8;5Z*oDp^XKDQ{a$Xz#0SbBKNrD7Ya7J!`80 zW6WRGwW^#9j^m87!fsKW_#k(CrqI+iG1pDl&2)fAn{;#NBl9on82a9*GfP7uOoM49 zN=+Z}-37?Ne&^VQ%&*mdboY^g>vhrZS3_({DOmUU9dLR`NHcC<&=Q%+FTWcrAx=X!Q6+)hAPqw)iT+a6yTlU^3ZOb>BySIf&R4_D~zatc23f zH2v)esaFjj28w|iRxV)$UZf=^`M63bAK_X%G;7*^UPG2%TLG_DAsH89Fp2=B<1c*L zg+jI>Sk37wsjL25qSQH_0fv6{7Q#dHGG|6=EtGp^wBScx>tU{;RJo4{)U+`eR>!J% z7Lh(Mq%}qgm`qxKN-b!h%h-F`vx+?k;jUkkFp!ov^70at+WVH2GM`CO1CNu6Depk^ ziR}J4WOlN5L&;dhebUMV@j>2SS37vXV78?7!fYky_C12tFS%OzyX}#`o$_Wza<3E5N^_&AF$`3{tR(CYNmB5Cp-S3?jv7~*nFES-H}eid z)$0_Hwgx4wXE0Z%?vaGIPtYn&cw&T&--}E>a1*)Wi(#Nmq za29Lz5ov6W>yW%?D9y=2OXw`2ZKz>eaz>W#^lI%a3zB6)k)eck3bl!v`ao``R)}G8 z<XBZHO z=~#oZ5H$W8q?a-Ne3cbT2`sw?K1g$oSB7Vg2ncKcou)UQ7?;6mfXe(Z}lVPx5G--}s_FjMb z$;mKCn|6B-Ks|p3#i1>V62o+xYRGX&hvdC~Qrv(Hrur?Wz&E%7NBSEk@5FWTN6kF- zP;n~Il8!KO`p#>>Q zs`=m#K&s}?pLHR9`pF-IWn!gbfeiA<)psTs>HN=IBhW{BC27uSe6y*w(dHw0< z*I4B6aF;kbeh3Lq*y1+@;tk9}OqzOskta7GzG-T|Ei%b-20h{Bf@8g_G*5Y7kB1kN z5nw8mbifWWkyxrZxjEaChIq$3^2C(j@Qpk{xEUH5Z~1T|h2R4IsQ{}N3Em_hAq%V> zA_$}g23^-zYdoJBSwe*}$O`kpvI&F$H3^!5aS_EsFb_uRTU#u^Vw2FVxS`B{f8qgb zVZ8lXJxZZeNuVHc{HI!<|xG!=!w$&Su#${~_9T|CvaSUIC+k9C{0pt1t zD;={m5A37-dPG8z_MsyP2r9mRe>{sNqZJHk)HXK&f&5%^-uT(J6G^fj{2;N>ba*V( zDuFq%B8+nnbr5ahKsYbU2A1?>fn#x=r=U;#KykN}fpyv_FB#rOi^r~<>gcRPWv5=& zpa{@xx}wmq+CEAOD^EqqHWTxc7vigz*ATF55A$2jfh$@@C{#khB8J-EOXuDPmMi6}9%V=+sr znT*he(04;YuJBYrjR_64f?;vWbLNyJGr690!U;T^sEjaTvfv{viyRI$--%&jwe%^s zG`+io<-%yJWi5GS0L~|WRocn2bvol68+b~IuvPl9SCjXE@YXMwI-E**Ewcu@64#WFwSga=(2LAcAwsJA_CiY-d9lx1})uN(P&~A zo5lgYh%_jA#a}0|pwyUnp%1Faoi>%-2K^VBBFa@ z6aWAK2mk|-TUogby-u~I82|vUTmS$bm$5ks7q{VU3{)0>qEzE`}QR4>-<|+3+ zw5?8qs`pE*H8>zBXynEQp`R-d+Kq6h(sGQMvs2uF_1swjRi1v#QeL}PSv!GJocn#r z7!OZ^P=%}Fqay{|M$$M<6E+r?nP9JHiH39#NgJV_Ynr)fanw^yFWsF~ftyw6^Yi)# z4u!@(KluhUPSZ79GDaq@{->Q#px%3^-}}86#RXV+?oDy6?YKirmuK5MR`1Q0M+Hhu zDFPJpD6hw=!vS@&TGi$lcAN=;nRUTd&3K%f>$>fK!$3tEmFU#nl{i&=BoIR!O=oua zv(NsUzCL1=H|FuX8shAd=k#ICL;7CHViPR!)Sv=rzNHXC4;4FIIg!Vql);~2 z$1GfJBKpQj<;Gy`8z#j>1(n97y&%+WahFdV|Ex=&+ zEU&zOAMryJ;7{Y9HEsTe!%=x_Wpp^5s`$laLgzu~Am0iRfHqH-$j{cOQx3YsCa*n4 zLKjjnbiN6r0P!i;m>lGA+C`8~x1sJC);+Ndjczy0!RczF6#A(0anIkN=PO&~_guEo zKUXoJ?_4}O#(CGUy`TQ9%&q#R&vW_?>7Czy`-EwA<*h3GJc&5F;puVZI=ij-R+q+Ca(1K`n?M_mDhoq=cK-GsC*Pc$mjQz^ECOD=DIF>y zlWzTXT2fN`uFrU@rO9Mj@1{v z=}SZMgN6jyH2Ne)STpVXA5cpJ1QY-O00;mBky}}}p@$4xv;+f@TUmxY4YoWEE-nrO zky}~*@S-kG#Q*>Rj+gNy3>vpqY7Sq;5d)E1Ss~Nfp_VED0L!ZY034UGISCh+-7gOc ze{FZ$wvzC7{R+0eSyGL}*iQPgKG)rK5~uZUn&iZ3d+&988A^g|#uCXxQdX4R{qH+3 z00@vECA;nJea^EyZ7fm1U@#aA1~Y@fo;Ut#>`k*-l3pEot7<;}4&My+27BJKEZ-E# z)pg|s&xYRN{=wt%;r`)c@0TQvH{N;te=*5JDE2a$inJ6nugbjYT6k|Z)peG7=h?hk z$A$1-WUF)*R|&j>52Em5XfLgbWU{I<_;ytYu@q^Au+D|>UYP_c}Yg@U&fWf@S5>mm-!{5VC6>9_?&pNRGOnS*Gm36SQ38ddXyiRl z$_j8h{WKLhQeBpvW=m+?tJ{DEP$30 z29PR7QYt8CX<5aKg_vQRG@x~ROHsvGUX}exejj$nMQOYQMjs9a zgenwzm8HV-_Pi+|2cW$5f3--xREU|F0o%`!MdPX}0vPF$=jWSzqnRX0=b1k|!rFNe zUoGP!FU^34@H_SX?58);o42Pg&i(@J_<8OR!~!4!q)>G?gn%)B!pEdjvT*D;kUsrr*EV4pI`7R&F&$MHhqk4f8!$X4YH)!EUWw> z5--gvuLjVKlhug-pnOpJ-UI5GN$ZQF!^^>&zd~W6=f?LQ8Z`%iJpW|$!YVL0dHd`~ z_}%2UU>FtxzDz~nk9`>7$T!}E@(omdde+wA;KE;Pc&9l@^f3%Eb(%q9 zDcznfG9u~^!!idMe~g$7FZM6xKvCtHn0paS&E!@@@gxZ(Onh=|5+Gk7h><~nOI?Jy zrlTuwHqrCbr$7JT8!$E8FwS$4&H{f1oi)IjoWrbRSH4Y{eC+`>O93D#_-8M8Jo3J4 zG>^|ZU-pi|uV?RmjNbh9r<0d2Uq3StG~gqMq@-!zhF`bwf38@Gj_U4eHg%Tn#&zc& zJ35EYs_g9_49(B4&Yrz~ej1&h{q5Azh-?Vq9D7eZPz(b2EIUkWiG#3=Kgl&7i|v0p z*na^}2TtwYt&D~X0lGu#`F{8@OVWS}4hIH5w}Eb%^EUoZYNfW}9N(%BEMUcWtkc5;5|{U?5hY4!B=`6+aj zFo&<_XRlwidT?*#cWL?j$J3`LuYPDXIw}13?_XX%{PI8FpFbQ9-QhNZ|!Iy{oXp~@oC=5Vc!my=oSWk+6StViwwT3#~95ds`i8!Z8|e+d)rF$0sT z1pF~te}HdN322moKcM}=OqpIMsVFw?pGn^w3`iQ|WGz?odGbk=N*)7FQ23}hTP{k( z4AvhH<|ZjQpa0>m&cMq(41ZNG&o@xn>(sdy;8@%FoC{Ojmf4aTvYPs0sub@_q<8hg-im4c*Dm?~G zPE4!Crmx%B&n|=<9WHY*g~73@9pc-1CjlLt(x#{d3!h~+TP;Kz2ES)02rs~Y>S`n+ zsYrQ&U@rjzf46X>zK9|ep8zBNJ>Wkr@hEG9+PR3!()$Vaa-d8H+2kV-ZD_9Pz_&>i ze?>tl7IQ-&qNO@^x+H-CWvw??24OHlI~I2i5Lm2l;2Aran2jiv))EM{??}49IPjxe-C>W(@GMgJcz*?kwG35t5Sg(RU0?XV~36$qF@A~ z4^j!~{M7{k1ErSf$=@Zi2g@moskHD5=SIXO+muU52`(-Vi>BwNOBocr#@o#V)5$M3 zT0l_td-G{jQg09gGLda_8Lc+8_z9G~;*Q5>gyJOk7H_??6q+ZX>qwkdI4U-apj#vm8@J{?_;)ry@*u)~Hur&I zp(@xqW2Kb-IaJHlhD|9xT()o+VXYy7>C?i~4_+MxGca!Q8mrhX0u*8<&lV85Ug9j`Ct6Kg`Valp(v>Z+rT6dE*iG z@nVm05wZHmc;ce}c1)w&0zUB=i2h#9xVcY4E(2q;aRg>$Vm0bM1~VEl(}TBpkbXbY zZLwEK&N9aA z&FPE%-knK%Su4jj0!XD&>=tB~FDWv;V~m(uy^hhXwbn|>AoXDrF$Cj&5NDI2YL?Ja zWQH#NUdFAZ=YY&Nd~BI!T7k`90Y35-^Ie>~MDvB&Q{2Uy#0B?rv>W6wTL>Zfyh?u2 zpYF95*-dyiBzCiv{Z7`Y!I;j-ymNrc+pA(ah1i~sa4zdqFIM_&UutZbZE*vMl8o7Z z#w>v>Wc%9iEEI`pcF7g8Kxh~yL3%`X&h`IlAJ=>4N07xPbbHl{U1^*9EF|$U-^dh1^J0#wdY$8Ec8%s}8p{PTYThs5OfFo9)T z`v;6Kg+21)2}T@PwRu>rq$!-xy7M0F{sJLY9Ql?$j*?i?TjgU^|T?f8gE|u8jSv1dWDHi1a%C{Zh zdWoZBE&}NUAnklPgTYgZeikfeC`V=zv$b_ye~~w)mmz-@#kRKO)(Tpt5)LuSHqpxQ zmlnuzN*5~QR#M=``pwu8`+k!vuFJzQ8I!~+bv$Ly;`4;Ya6%Cw>=m7|hJOK0D0N7M zk@B!JnnJfHnTl>9I3o)p0%F~Sze239pIE$?KQSnEfx^<>ghQ|(rBmOSTUSl^Rn&9! zNv=$Al$v)l#;`E(dLBpl3k>0=aE7&Flks+mr?~b;Ao{50-a?tor1U&TV68fQvFd-y({1^%GMw)Ws}1kkx0#_!Z_-E zw0O|G%=bub-F&jaB_t#`Av~;DyW-}O;0x8L+xS#tDFz=rFBFxyI|@VrYN|>MZpaKE z@-3=*!SMV9;$*~D9iqGHIK&u)xB5tlykO=!V$vX&$o8EnM=N;T{;(vZA$2I!_s%kc zrJ(zr96|5bhc*^UBl;?ER`809Jk4^e5H=8Dhv^iSz-K_ys_;&J+mgSJ1vAE4Wd00u zXy*H5SgKQ%qh)3u6KaR2mIkic$sP~So6Ea4)v=9afvX>=YH^H-OX|CSwM~-!E}+_X ziIjR_%0jfEnA?S)0|7nGiaAcla;1s@kid>V`$_%Z8Jn_r?K%3qDZp}S!k)pgif9@uIp2uUhYo z7mW{!@4bSiwlkbVh1s;ygXzZSpucTC;bW%lMQD(;rBC7Sw+3hFheE0Ke->!jE9Ao8 zaC|!54FA<=>nf2$#y+3vM!~HH@;@5N~AcmzM_;-o;4h zeOqbdW4boxfqE^W&HT}Y!wAttag5v-@<}nF5e<*-;!@rw-vz?XRtu&a5(#NkykoQ; zKD8pBUyj#eAy7 zd`k_HLv%cFJ?)WwyNBCtDIpLPQLli+2j@a?K)?Xb%1LOvnt?dyC< z+yKSAM)-@e?ys19ZHG2ESfi!j0 zFpdMIzf#x|w|i}dT({Cg<-}IFp5bZ64wy9nR3t!6=3*m{N<1V{^#s4jYa~ zvg_#St=y){c-SP(dw=p4TjSA}K2xh|_Fv}$3!c%>?&0%%zPV!nedGCiy?;T|l>+^n z^G8Q&W5!D!Ch2dx*O zup|@~qPg7wgXA}YTlo^b1BR>Jr%HmJ9}4~Pl_ctC?N>z{xeA{<+~x|L)|r7?uPY_y z+e4bG%dN}&I*uqDpt0Z0$BM*?T`xS?LQS)I@yTH8TFAfJf22xpT4Kk};1>1z2w z<`{*Xu&)^F8c5)mi1D)V=nq zSmqN~E?reJCLSOmduJ#|VEPj{{H$@Aavb_f^mabaA7HE@xj0d z@=@(S4Q6O`ypvXNfg8SssONSS!<9$=EbetryXCk?KY-+c5WHx{Z}2~db;-s;;#-1c zP6hZMkRN_n;v|m};1z}lSHpe@1)#@iYc~9zDR%p!LOGNPz5Eafoy&{1@iTfvU z*Y^L6na3}<19c9I48O9Z%gN#7G_wEvrZZf^3cJ2MV3j&6A?kMHY&q(Jm^Zv~1x2O9g!wTOs`iLJG4D?zO~Ex{ z&GOK4=wU+THm#2SYCs%mdZU)ey-wyeJ7qoCv%D@O^RVT->c5def^sSs7@ z5-9NF6?cV#(!}6bd!*jkza~eoibYpq5r00u`u=^hZQOn5QkU{81D4W{?}V`Bt&M zCkpW{O64xGVDF3047B>UAik&!Fk^f8+3VI(>C5qDxJKw6d75bO2H~daS1_PaaKA~) zt|NDOR8uUEY zi}X5o5j?^x`?&@y(vY;fUPiRAe%-yFK+>IaSC}Qz3}i?K1N^pZ;WGDUPRz3M{R7kn zYS0f4BHjV>pA2VK9_2(R9Pkvmi0efsccg6?bN8X~{2ao()2weVX9J|Od1iDM!R!GT zcd(v)Z0TMHj!zc@hTP1O@}+Gqk!Ujft5Pm+hsS|z;Uh46akB7t)tpp`U-#m;O~M)+f|#V&Jc!8=jlJXQ=X}>s{6tdGT#oUa;$J zKOhu!xL_E&^jFgWW)wscgf_e3+?|g~YsT$WUze1b}Qk zzrf`4oRR>#P}Y|uu`~um8cesQhQF$lJKUm9V` zygtCOBr_3@EUUnnV^P5!vpg(@-v@W2|J!_|ml7&(5ZlmF8xEE!LRm426)D5tmFH)i zzBLxa+$RrF+OXSZzN)H*_6x6R9c(tooQ^*)D}qj|+z#rvhN(fPZq>&ya2zBIFMGQ? zLe*YG;zV{R2yBi_zep8FeqQk4M0cBp<5WiCq=??W^q5X#XdJ#cT0MLT zZJK~oQ*jMjibYZf%Ua@wPYiS)pY&aZAy@`M6kJH9R5)}>`!WI`xa9P`Q4Qs=i5hbR zroKG>sA}Z4HsUm8|C9OJCCMN%HE&3j=Ub6K_jkMMDR4YBl=*CEUmqoABI~^3zP1D6 zwt{8s(A0DG@`zk2cX3CV)?>$bJD+wk1R8d$^dw-m9KAycThY@~B_3#5?c{7&1SN)m zan$Rjj=oAQWUqPLKybOg_-fUS3X<6J>vtR1I>`dwn@U1^&YSZvZmD0Uwm5XBhCxgmFf0r`+!00015<@gi zZyr^0)+os$Tgf-d%^^2^Oy*HJ67{7tisnt5lq$#GGVVUgj!(7*{n{OCk)=sZxh15b&J%xNP$&j{OidiDzM3n#K<=Q>=J3kLUqTFQk62uk%Z9g+)6_wr) zLY!DR=;AGP8}m2?WTOAaCYYUzIHtl#4oF{X9gII8wR@NLAa3VE&fePnpoe(-G&K4lEL8Elzbxu9-cB`Jv`#zs9|q2G zj>xL~)L>PC!{&hDvB@2=qdR>tv{U?K(cP24|Nan(t9Psec)p(`=|PoKKG~i1K_?K|aM~(9x1M=|UdvPc|`x{5407 zi{@#j5#(>n$UJPWRQq_&?lGSe5cT&Q1q#(N!lvj zVdQ>=gX#+apRI$C-*9A17Y{Fz?je#-`?KRrBI#$*=fh30)}t=tuej@=8zfFFqa5D> z&XDyOH-ij8etcwJ5|(b%VyiJgo3GQa_@gAMZtSotS~ZwkK7&3h!uS8cn4h`M$9qwu z5S?4cJVBEY88lX#8SRp#fqqZyl{Z-?3G=8N^uP7W8<7A>Re=sYQcLRvtE6ik`h>{0 zKOVH~#*{D)u9|7D$3u{z`_0dsOk|Mb-Mv-Txn;YCCbxgN)uqLi9NK1)rs)DvE1JZ$&&QwXwM~*mnWLWu6i1}pyr1p=!}Fp zpfsP3LkmV{MS6Y9URpV4gfg1#*U90H_~dB)Za!@b8HLe{wIqE#PBNmk8%G|YKW9kXE4qC# zYNMgt%(#6_HnFN73kwM1J3N2S+b67BIJmR!-RejyNZ-YK7rr#}ReH~NyH<*PX>*kZ zx$S6-;aXwu6WU&QCY|-~HL%;cnEc_T%>IdL&D%9nH@xELMM>?7`w4zP#qMq}Ux;W} z{e7mR3z^%G35Tph&ps*%OXm?sgaZzneX|$0AlA6+j_E77`(Am6EI6gl6YY(`+tJ)s z6@NMMd5@FG>SRqdsiiW63s+uJ1zOLNK!!yEj8#pYx8St5@z(973fbsV3t9WJ&K3De zCZ*v6y>iw=z14~NV!g@b5q9O&De9y_tjM@?Yc5-(Hi6C1vXRS^Ah)Jbs_TFn%LOLK zwj%GDtTil;oeUKRg!W?^dEVQf8}#Xp7Oa)iW$rlNc*!#Tquy5eHibOu?d@kyKyDqw zz!s)3gb;Fgh^sObN8%=$)^A0Qb_?mDVkH@y?w;*V<8dEY08KmC&Ha_38opd5)fK-N->tRo>m=9TWp*CVrbm+7oZCZE`VILpd8~8`4r{K> zW;IQ$D{lK&^5bDOp$b%y+gbPbjvXe|C^D2;IXTu7ojH1Sw)^)|a;~r{AjF zeq%Yw@#Ev|U~nlK1MrxOLHVkFSGtTL498;AzQ<*yy6Lq2_$!}6&91D!fozNT8;ejHA5z&Jd`gc_j9WeiIkc2wC`r>e%ew2B!u)!AS4VGb%1GlIVQmX|E&gG==Y+8et`U0I)Pj05)<4q1=NVQ z(T`9ek48MmvI^^r=K`@c(nVr#9($0{36g`Oq++RO87-CNCFGsm3Si@R=qe$p$i{Y> z;w6ZjNza10Z(CW(;>O8i8{99u{a4kY@w|aY?t(#g8z>~NBB8O(#Qf_{$HzG^F_)OK zt*WrMuPC@%2Oz&WVz1Uw&)P6{^X~U&)r%%3ZArLj(kC50Q7HDa(=-f~8I5PM4>z5js-JYrc4Hj zdZLsK;ALHMOX9rGGo>s1TrDF)St%DAa45YUb0uwEwHnc6m+%WwJb7IU2J$Mh6oN}^ zdI7wA(Ur4cll-1he7(~Io(=T}gRaX%W?IaNnMYoGiH{RG9tTo2>#)`*0~wkjxFUPQ zM`L0C`7fX^REa~9RkV`Z5nio%>M^B9&g)qL_+lJFK1!S8xKdH{d@i)&l~eI1d$GJ4 zeJuHVj@ca1bfywc!8w)f(Cy1=Z`gdnvVrjoXQ-#R>Rnp2=rPD5s*H=M|2N(tjg6+U)Pg|>!j6_p^?OlvwoGDdPBy(a~ilKWcm?!xp~ z6i$<=(bjAx=&zyA!|9OqxCyn6v;R5Nr{4wejn2FqTPyBS@e6^7Ggj8CN`pMX(c^Od zl(sLoy=SDgvYe$g9wsZ!KWdI^G3b{XzSin6e!c~uFxUXd|xJ_c}{UMDI>S*e&6P1q( z|JhyZ>91+ovG8W8mksinfU_D-rXkYvrB1|7Gs|#^v-3Iarr=!V07!S}!0JL!-mL_r zy64qb^Ejts#DTHgi76*y=@`8k;szNv4|~S07VqAv&}Y?n6QJfPgTRmQhL|Xu!JEBR z>?5~AI1VmJ=cT%=3$DhYDSCg4h$+8WdzE4wVrd>MkHc6qSGIJ91xPPpuV+u^n-?)! z14!@%RK7|FMsSDhw< z>Qoom@2XifjV*BFIa`OgYl+ z@SR+d{2`;0V0KSqZ7(WdvygJFlwx$3p_+^%Tsah@G+-D1)SJQYX6E>%%$X9T`I+sE zjX^geQe9lBLwjWlL0jX#R!Gy@+|Dl9g~F#<+`^p76hS!K|I56UbyN1U>agoi5#5`@ zW9ap6iMFpQKP{PYj!}o{3I&T}J<2rm%BdLKr=)v=vcj={ zXT8MYu}t%1Y@iGb<8XdHS!3Y>IsFQd{QC2eu9R*6^-nkXVceF`P5rRH2sEaRn0RR* z1KDIp4RvmmjlF62jfRnLGHff8)B4A(geiHgAB82;$hrxiPSA2py)6&KVn26 zN*QX{3p9*GLN0DGeny%ULl;r{=u3E(QR^T#iD6qjmtgN-T*zA*#8O8}ifhU-*PGM5 zKf5&#;j;U}UbctaH`k2yR1oAIL*3=F7rp!h;I}9oM5M*dskd+$+@4+`!`9tORnT&j zXBHULrou{GVukmlj?QLIAQ6MF(==K;NTCA#y)Zl-mh;m;jk43QcNxco$e0)z|LnfL z{9uOPo{0kenEIY;47&=yW1(w4xdH3!ae#?4GTb%XEK1deYw8!62>0m{*l)RoUwpX& zK>Bm-zB9}4?Rn9aN(+2GC~IV@VLp3ycc$c5cX+pFJ^AK{uOAo*0Mt$=P2Wnmwk48( z;Oz(#cNJc-Nbw`)e0G^u!C`!O>S1{$Z9HP+?{DMOsa;wuk}nc-z?+S)X8mNSrl4~m|rq}E$m4)B{xq*%#+MMw~&scD>NpCxf6?vOGFyK zO>_tCj0B_{xCSt&OmtZ|qd0+GkeRu07&xKOIcp;5lpI;3R1F%S)y1*JmR-Oc_ECjH0ct2MO2H?wwDqiUBw+o zc8~6Xubn9?$Q`a@_k6-I;O%&EkdX7~u5nSa1aA#zk(*Vs(rCUyaw-wcB~$2RK8hF^w3M!r5)NH zo0#z(KI&SG@~mCciZhk@AQIH^BYJU(5_v3T{oc0oGdF;QRWf;k&>AxRJ)yY*9<$p$`YbYH5#M)~pLs|bwayL|X@P8zW2kP-hC_*pPclf1~*i^R0A7)gq9zEsP_2(jMTDFt-$`%yv4mk*nB) z9V6AD78Ne_I|&*b$kKUZIAQ0R&Ma>o{Wz|c`eiL<`Nq4xlA_$zM!itCLS2M}rEnPf zeI27_jW548www(dl%(|Qbvo#EDE!lNa=JT8`WW2YC@FNpg4jG_E2s^_({9yn($p;{ z5j6B2HExV3zclAE!FaNVwzylZhP@6V(A2xs4!H$pqeaex(n7j;e65Ee&y$?npDv%S zj$cpW^_h#TB~p^%ISrJq_!ILdBRG0>OrSE&EBJp}CaDrD*|upg8n$s_W)DJ$ z=z=f(QukcB0WWUjpb8J(mB;DwO~g#8dIF@73<`gLoa%g+?6Afc)_|F0`QuvyzePaI zC4N1moPKwK^*5a2IruQRTE*o9^%Se>euIXWHtC5-P@f2L#R?Z3ZYP_Oi?_p{xAWuB zMB$q8qYTUbk9FjadC1bxK`Pw%HOe3s^+?gL?Q7L>(T zPXU7*Z*n#`=slpf1n`S?Eb!q)%KL)ck9ZRqI?$mVzne!8flv*MkP@tqU-nSt&$REa zLHznxknaPc*<_-$tQ!`?BT#9k;1L425+IjD+s1~cA}ObV1x_tSMo>4Sne~aJZE#&J z1uagszI2yly9}6XmTPC!R4xkys}fDdbHp5@>%^-q*bx?xXfwvU_%&MwR`A?*Gu;;dYsljLD(hd3X>VVN(GYjYYs#Q)2ewqg$=ZOO+jG< z$ge#rFr`7IvK6AWGotqmz(`qYk|0ebJH{BOH5!X+Gfk{tj|syQB}D=cepr*wAv)9t zxPhlT<=tdnD(O0R@pqn&&YvuOw<>KP+}ow5gvDgW|s#` zaLF5$2fWf6&VN_(OMZ@Eo!%3{r|V%Eaer>Esa5_ON+GFfU@`2hJV~cqAGi>RK^fMm z1?ZFxAb>>ju$cYRT&&%ivXOZh_ptHf%64xwM6Zr5tKxn#PtMB}!)mxM3MpzJ{!-qc zj;}6u58+pF;MT>{@a5Du&Y;$N&?e^W$Y#$VU4Y}nTc4eHCG<`=G&e-TWN92fk@dJuW8`SrPAl19GUXi%BdbTNknkmh5{6)6GG>;I)A;m0@b>YVC z7p)bNkzhrN0^0#0y0o7XEPPh;Uv)e3LU=AdBiaO082cC*>Ba@j6Mj1Q+6vTD60#Tx z2Mb9pT-hRFRoJd?N2Qk}UEN+49Al@2b(k(ffF%Vo=ILH}#EMQsUy$i$TmKzqLus6$ zC)6R3ooP{|HkP#sru(Z3weQ>wqU6&~zH}uCrpS%TI5aRAgL(e%fODCaJ`!BbA4?j!UxJw&5pve)4ePP&_HY_}sEVrvw)Sv^pS_3S$I21Vq z(~$kJDB>vNSU8R6>il^8aj2M$0?3@c<=JEhTaftMhBeHC`F6Kd1kc)`h9utipPO{` za~xgOWlWe~fr{ZG`@AhAn-m({>ydYex}L9fK40kfg(^V?1P<|6^xmm>5GGRw4Olza z5(!f`u*yyXE*6?sXL4KD%uP5_PuyheR{cVs_!`zI`4JLK zpm@Z<(E^o32BHGx&3KB3{E58PQ`$DYUtHjHs?5NIL0<5lK6mWc&#I)RLk9~dcLy$! zf&+TM!|VMam&fPGqp!c#83q!ho0*YsT;*xkRn6xld-G^*hTXf{--hj#(4kLFLtJJb4Gq)t3$uYRV2 z`s8)4&p{fIUdLEz&PhO9B~n+7gLH~Wqr)=ce$ZLD!Y<$`ePw|xoQ7jn?qTo8Nt&A# zZZ5gGTA~-PMD}iu2i|W4hd8bb$`&q-LAxe~+&t7gG4!)vQLDvsT#W-8_zjmANC|y_ zIb<+HOFp|v?%|AX&LMY?F<#xlmiQr?nH2G{(nq8QmRpEn!S{P>J1lr{kIa}WIcmq6 zeW3VcUYPjyV)s&kN}Wz8GAaV;Ap!P41Ski@M$aXR;j?SHRr)_1-kx2a6kdBUNQHxy z_9U=)mk>c`M61*x#OU;Yxs1_d?unv^S!!pYrX gx3|@AKQVU@M(P_h086>nKwi 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

B)!DlVs#jyfesv&)w-I0m&Ih%s<2A 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 PfT8F#cr;~5+)Di)oD8oq delta 235207 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 z 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

^2TP_ws~bFCRzM?n0-cJubqPgy>f?cg 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 BiE01< diff --git a/Misc/NEWS.d/next/Library/2024-11-13-20-03-18.gh-issue-126188.RJLKk-.rst b/Misc/NEWS.d/next/Library/2024-11-13-20-03-18.gh-issue-126188.RJLKk-.rst new file mode 100644 index 000000000000000..bb13662e6ae62ce --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-13-20-03-18.gh-issue-126188.RJLKk-.rst @@ -0,0 +1 @@ +Update bundled pip to 24.3.1 From c695e37a3f95c225ee08d1e882d23fa200b5ec34 Mon Sep 17 00:00:00 2001 From: CF Bolz-Tereick Date: Wed, 13 Nov 2024 22:39:10 +0100 Subject: [PATCH 50/57] GH-126606: don't write incomplete pyc files (GH-126627) Co-authored-by: Kirill Podoprigora Co-authored-by: Brett Cannon --- Lib/importlib/_bootstrap_external.py | 6 +++- Lib/test/test_importlib/test_util.py | 32 +++++++++++++++++++ ...-11-09-16-10-22.gh-issue-126066.9zs4m4.rst | 3 ++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-09-16-10-22.gh-issue-126066.9zs4m4.rst diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 1b76328429f63a2..fa36159711846fc 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -209,7 +209,11 @@ def _write_atomic(path, data, mode=0o666): # We first write data to a temporary file, and then use os.replace() to # perform an atomic rename. with _io.FileIO(fd, 'wb') as file: - file.write(data) + bytes_written = file.write(data) + if bytes_written != len(data): + # Raise an OSError so the 'except' below cleans up the partially + # written file. + raise OSError("os.write() didn't write the full pyc file") _os.replace(path_tmp, path) except OSError: try: diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 668042782bdc5f9..0bdd1b4b82e5447 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -6,12 +6,14 @@ importlib_util = util.import_importlib('importlib.util') import importlib.util +from importlib import _bootstrap_external import os import pathlib import re import string import sys from test import support +from test.support import os_helper import textwrap import types import unittest @@ -775,5 +777,35 @@ def test_complete_multi_phase_init_module(self): self.run_with_own_gil(script) +class MiscTests(unittest.TestCase): + def test_atomic_write_should_notice_incomplete_writes(self): + import _pyio + + oldwrite = os.write + seen_write = False + + truncate_at_length = 100 + + # Emulate an os.write that only writes partial data. + def write(fd, data): + nonlocal seen_write + seen_write = True + return oldwrite(fd, data[:truncate_at_length]) + + # Need to patch _io to be _pyio, so that io.FileIO is affected by the + # os.write patch. + with (support.swap_attr(_bootstrap_external, '_io', _pyio), + support.swap_attr(os, 'write', write)): + with self.assertRaises(OSError): + # Make sure we write something longer than the point where we + # truncate. + content = b'x' * (truncate_at_length * 2) + _bootstrap_external._write_atomic(os_helper.TESTFN, content) + assert seen_write + + with self.assertRaises(OSError): + os.stat(support.os_helper.TESTFN) # Check that the file did not get written. + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-09-16-10-22.gh-issue-126066.9zs4m4.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-09-16-10-22.gh-issue-126066.9zs4m4.rst new file mode 100644 index 000000000000000..9c0072304ded638 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-09-16-10-22.gh-issue-126066.9zs4m4.rst @@ -0,0 +1,3 @@ +Fix :mod:`importlib` to not write an incomplete .pyc files when a ulimit or some +other operating system mechanism is preventing the write to go through +fully. From fd4b5453df74e249987553b12c14ad75fafa4991 Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Wed, 13 Nov 2024 22:59:32 +0000 Subject: [PATCH 51/57] GH-118289: Fix handling of non-directories in `posixpath.realpath()` (#120127) In strict mode, raise `NotADirectoryError` if we encounter a non-directory while we still have path parts left to process. We use a `part_count` variable rather than `len(rest)` because the `rest` stack also contains markers for unresolved symlinks. --- Lib/posixpath.py | 18 ++++-- Lib/test/test_posixpath.py | 59 +++++++++++++++++++ ...-06-05-19-09-36.gh-issue-118289.moL9_d.rst | 2 + 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-06-05-19-09-36.gh-issue-118289.moL9_d.rst diff --git a/Lib/posixpath.py b/Lib/posixpath.py index fccca4e066b76f1..db72ded88260565 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -412,6 +412,10 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, # very fast way of spelling list(reversed(...)). rest = filename.split(sep)[::-1] + # Number of unprocessed parts in 'rest'. This can differ from len(rest) + # later, because 'rest' might contain markers for unresolved symlinks. + part_count = len(rest) + # The resolved path, which is absolute throughout this function. # Note: getcwd() returns a normalized and symlink-free path. path = sep if filename.startswith(sep) else getcwd() @@ -426,12 +430,13 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, # by *maxlinks*, this is used instead of *seen* to detect symlink loops. link_count = 0 - while rest: + while part_count: name = rest.pop() if name is None: # resolved symlink target seen[rest.pop()] = path continue + part_count -= 1 if not name or name == curdir: # current dir continue @@ -444,8 +449,11 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, else: newpath = path + sep + name try: - st = lstat(newpath) - if not stat.S_ISLNK(st.st_mode): + st_mode = lstat(newpath).st_mode + if not stat.S_ISLNK(st_mode): + if strict and part_count and not stat.S_ISDIR(st_mode): + raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR), + newpath) path = newpath continue elif maxlinks is not None: @@ -487,7 +495,9 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, rest.append(newpath) rest.append(None) # Push the unresolved symlink target parts onto the stack. - rest.extend(target.split(sep)[::-1]) + target_parts = target.split(sep)[::-1] + rest.extend(target_parts) + part_count += len(target_parts) return path diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index ca5cf42f8fcd710..b39255ebc79ac19 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -695,6 +695,65 @@ def test_realpath_unreadable_symlink(self): os.chmod(ABSTFN, 0o755, follow_symlinks=False) os.unlink(ABSTFN) + @skip_if_ABSTFN_contains_backslash + def test_realpath_nonterminal_file(self): + try: + with open(ABSTFN, 'w') as f: + f.write('test_posixpath wuz ere') + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN) + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) + finally: + os_helper.unlink(ABSTFN) + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash + def test_realpath_nonterminal_symlink_to_file(self): + try: + with open(ABSTFN + "1", 'w') as f: + f.write('test_posixpath wuz ere') + os.symlink(ABSTFN + "1", ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "1") + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "1") + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "1") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "1") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "1/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) + finally: + os_helper.unlink(ABSTFN) + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash + def test_realpath_nonterminal_symlink_to_symlinks_to_file(self): + try: + with open(ABSTFN + "2", 'w') as f: + f.write('test_posixpath wuz ere') + os.symlink(ABSTFN + "2", ABSTFN + "1") + os.symlink(ABSTFN + "1", ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "2") + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2") + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "2") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "2") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "2/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) + finally: + os_helper.unlink(ABSTFN) + def test_relpath(self): (real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar") try: diff --git a/Misc/NEWS.d/next/Library/2024-06-05-19-09-36.gh-issue-118289.moL9_d.rst b/Misc/NEWS.d/next/Library/2024-06-05-19-09-36.gh-issue-118289.moL9_d.rst new file mode 100644 index 000000000000000..522572e160ba7bc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-06-05-19-09-36.gh-issue-118289.moL9_d.rst @@ -0,0 +1,2 @@ +:func:`!posixpath.realpath` now raises :exc:`NotADirectoryError` when *strict* +mode is enabled and a non-directory path with a trailing slash is supplied. From 4ae50615d2beef0f93d904ccbce44bbf7500b94a Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 13 Nov 2024 15:45:08 -0800 Subject: [PATCH 52/57] Add Savannah to CODEOWNERS for argparse and the JIT (#126814) Add Savannah to CODEOWNERS --- .github/CODEOWNERS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9162f9c7bb1576b..669844854b2fe5d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,6 +16,9 @@ configure* @erlend-aasland @corona10 Makefile.pre.in @erlend-aasland Modules/Setup* @erlend-aasland +# argparse +**/*argparse* @savannahostrowski + # asyncio **/*asyncio* @1st1 @asvetlov @kumaraditya303 @willingc @@ -23,7 +26,7 @@ Modules/Setup* @erlend-aasland **/*context* @1st1 **/*genobject* @markshannon **/*hamt* @1st1 -**/*jit* @brandtbucher +**/*jit* @brandtbucher @savannahostrowski Objects/set* @rhettinger Objects/dict* @methane @markshannon Objects/typevarobject.c @JelleZijlstra From 6a93a1adbb56a64ec6d20e8aab911439998502c9 Mon Sep 17 00:00:00 2001 From: Wulian Date: Thu, 14 Nov 2024 12:58:06 +0800 Subject: [PATCH 53/57] gh-126731: Update outdated project information in `pprint.pp` doc (#126732) --- Doc/library/pprint.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 1b3498e51f766dd..2985f31bacb47a5 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -267,7 +267,7 @@ let's fetch information about a project from `PyPI `_:: >>> import json >>> import pprint >>> from urllib.request import urlopen - >>> with urlopen('https://pypi.org/pypi/sampleproject/json') as resp: + >>> with urlopen('https://pypi.org/pypi/sampleproject/1.2.0/json') as resp: ... project_info = json.load(resp)['info'] In its basic form, :func:`~pprint.pp` shows the whole object:: From 73e34b680852794d110cd806505b3d74d9d593db Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 14 Nov 2024 05:01:35 +0000 Subject: [PATCH 54/57] Doc: Recommend shlex.quote alongside pipes removal (#126570) One of the most common reasons I see the old `pipes` module still in use when porting to Python 3.13 is for the undocumented `pipes.quote` function, which can easily be replaced with `shlex.quote`. I think it's worth specifically calling this out, since being directed to the `subprocess` module would be confusing in this case. --- Doc/whatsnew/3.13.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index de4c7fd4c0486ba..664b18661723789 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1568,6 +1568,8 @@ and are now removed: For audio playback, use the :pypi:`pygame` library from PyPI instead. * :mod:`!pipes`: Use the :mod:`subprocess` module instead. + Use :func:`shlex.quote` to replace the undocumented ``pipes.quote`` + function. * :mod:`!sndhdr`: The :pypi:`filetype`, :pypi:`puremagic`, or :pypi:`python-magic` libraries should be used as replacements. From e0692f11650acb6c2eed940eb94650b4703c072e Mon Sep 17 00:00:00 2001 From: John Marshall Date: Thu, 14 Nov 2024 20:47:24 +1300 Subject: [PATCH 55/57] Document that return-less user-defined functions return None (#126769) Co-authored-by: Andrew Svetlov Co-authored-by: Carol Willing --- Doc/reference/expressions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index decde0d297cf59b..3eaceae41f7eaf1 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1156,7 +1156,8 @@ a user-defined function: first thing the code block will do is bind the formal parameters to the arguments; this is described in section :ref:`function`. When the code block executes a :keyword:`return` statement, this specifies the return value of the - function call. + function call. If execution reaches the end of the code block without + executing a :keyword:`return` statement, the return value is ``None``. a built-in function or method: .. index:: From ff0ef0a54bef26fc507fbf9b7a6009eb7d3f17f5 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 14 Nov 2024 09:31:14 +0100 Subject: [PATCH 56/57] gh-123832: Adjust `socket.getaddrinfo` docs for better POSIX compliance (GH-126182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gh-123832: Adjust `socket.getaddrinfo` docs for better POSIX compliance This changes nothing changes for CPython supported platforms, but hints how to deal with platforms that stick to the letter of the spec. It also marks `socket.getaddrinfo` as a wrapper around `getaddrinfo(3)`; specifically, workarounds to make the function work consistently across platforms are out of scope in its code. Include wording similar to the POSIX's “by providing options and by limiting the returned information”, which IMO suggests that the hints limit the resulting list compared to the defaults, *but* can be interpreted differently. Details are added in a note. Specifically say that this wraps the underlying C function. So, the details are in OS docs. The “full range of results” bit goes away. Use `AF_UNSPEC` rather than zero for the *family* default, although I don't think a system where it's nonzero would be very usable. Suggest setting proto and/or type (with examples, as the appropriate values aren't obvious). Say why you probably want to do that that on all systems; mention the behavior on the “letter of the spec” systems. Suggest that the results should be tried in order, which is, AFAIK best practice -- see RFC 6724 section 2, and its predecessor from 2003 (which are specific to IP, but indicate how people use this): > Well-behaved applications SHOULD iterate through the list of > addresses returned from `getaddrinfo()` until they find a working address. Co-authored-by: Carol Willing --- Doc/library/socket.rst | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 0c7b9328648f668..6358d140484c780 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -928,7 +928,9 @@ The :mod:`socket` module also offers various network-related services: .. versionadded:: 3.7 -.. function:: getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) +.. function:: getaddrinfo(host, port, family=AF_UNSPEC, type=0, proto=0, flags=0) + + This function wraps the C function ``getaddrinfo`` of the underlying system. Translate the *host*/*port* argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. @@ -938,8 +940,10 @@ The :mod:`socket` module also offers various network-related services: and *port*, you can pass ``NULL`` to the underlying C API. The *family*, *type* and *proto* arguments can be optionally specified - in order to narrow the list of addresses returned. Passing zero as a - value for each of these arguments selects the full range of results. + in order to provide options and limit the list of addresses returned. + Pass their default values (:data:`AF_UNSPEC`, 0, and 0, respectively) + to not limit the results. See the note below for details. + The *flags* argument can be one or several of the ``AI_*`` constants, and will influence how results are computed and returned. For example, :const:`AI_NUMERICHOST` will disable domain name resolution @@ -959,6 +963,29 @@ The :mod:`socket` module also offers various network-related services: :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect` method. + .. note:: + + If you intend to use results from :func:`!getaddrinfo` to create a socket + (rather than, for example, retrieve *canonname*), + consider limiting the results by *type* (e.g. :data:`SOCK_STREAM` or + :data:`SOCK_DGRAM`) and/or *proto* (e.g. :data:`IPPROTO_TCP` or + :data:`IPPROTO_UDP`) that your application can handle. + + The behavior with default values of *family*, *type*, *proto* + and *flags* is system-specific. + + Many systems (for example, most Linux configurations) will return a sorted + list of all matching addresses. + These addresses should generally be tried in order until a connection succeeds + (possibly tried in parallel, for example, using a `Happy Eyeballs`_ algorithm). + In these cases, limiting the *type* and/or *proto* can help eliminate + unsuccessful or unusable connecton attempts. + + Some systems will, however, only return a single address. + (For example, this was reported on Solaris and AIX configurations.) + On these systems, limiting the *type* and/or *proto* helps ensure that + this address is usable. + .. audit-event:: socket.getaddrinfo host,port,family,type,protocol socket.getaddrinfo The following example fetches address information for a hypothetical TCP @@ -978,6 +1005,8 @@ The :mod:`socket` module also offers various network-related services: for IPv6 multicast addresses, string representing an address will not contain ``%scope_id`` part. +.. _Happy Eyeballs: https://en.wikipedia.org/wiki/Happy_Eyeballs + .. function:: getfqdn([name]) Return a fully qualified domain name for *name*. If *name* is omitted or empty, From 3966d8d626fc9adcdf0663024d4ae6e6be7ef858 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Nov 2024 09:50:00 +0000 Subject: [PATCH 57/57] GH-117759: Update GC docs for incremental collection (GH-126695) --- InternalDocs/garbage_collector.md | 138 +++++++++++++++++++----------- 1 file changed, 87 insertions(+), 51 deletions(-) diff --git a/InternalDocs/garbage_collector.md b/InternalDocs/garbage_collector.md index d624cf4befd31a8..377a846428ae0c1 100644 --- a/InternalDocs/garbage_collector.md +++ b/InternalDocs/garbage_collector.md @@ -108,7 +108,7 @@ As is explained later in the [Optimization: reusing fields to save memory](#optimization-reusing-fields-to-save-memory) section, these two extra fields are normally used to keep doubly linked lists of all the objects tracked by the garbage collector (these lists are the GC generations, more on -that in the [Optimization: generations](#Optimization-generations) section), but +that in the [Optimization: incremental collection](#Optimization-incremental-collection) section), but they are also reused to fulfill other purposes when the full doubly linked list structure is not needed as a memory optimization. @@ -351,38 +351,90 @@ follows these steps in order: the reference counts fall to 0, triggering the destruction of all unreachable objects. -Optimization: generations -========================= +Optimization: incremental collection +==================================== -In order to limit the time each garbage collection takes, the GC -implementation for the default build uses a popular optimization: -generations. The main idea behind this concept is the assumption that most -objects have a very short lifespan and can thus be collected soon after their -creation. This has proven to be very close to the reality of many Python +In order to bound the length of each garbage collection pause, the GC implementation +for the default build uses incremental collection with two generations. + +Generational garbage collection takes advantage of what is known as the weak +generational hypothesis: Most objects die young. +This has proven to be very close to the reality of many Python programs as many temporary objects are created and destroyed very quickly. To take advantage of this fact, all container objects are segregated into -three spaces/generations. Every new -object starts in the first generation (generation 0). The previous algorithm is -executed only over the objects of a particular generation and if an object -survives a collection of its generation it will be moved to the next one -(generation 1), where it will be surveyed for collection less often. If -the same object survives another GC round in this new generation (generation 1) -it will be moved to the last generation (generation 2) where it will be -surveyed the least often. - -The GC implementation for the free-threaded build does not use multiple -generations. Every collection operates on the entire heap. +two generations: young and old. Every new object starts in the young generation. +Each garbage collection scans the entire young generation and part of the old generation. + +The time taken to scan the young generation can be controlled by controlling its +size, but the size of the old generation cannot be controlled. +In order to keep pause times down, scanning of the old generation of the heap +occurs in increments. + +To keep track of what has been scanned, the old generation contains two lists: + +* Those objects that have not yet been scanned, referred to as the `pending` list. +* Those objects that have been scanned, referred to as the `visited` list. + +To detect and collect all unreachable objects in the heap, the garbage collector +must scan the whole heap. This whole heap scan is called a full scavenge. + +Increments +---------- + +Each full scavenge is performed in a series of increments. +For each full scavenge, the combined increments will cover the whole heap. + +Each increment is made up of: + +* The young generation +* The old generation's least recently scanned objects +* All objects reachable from those objects that have not yet been scanned this full scavenge + +The surviving objects (those that are not collected) are moved to the back of the +`visited` list in the old generation. + +When a full scavenge starts, no objects in the heap are considered to have been scanned, +so all objects in the old generation must be in the `pending` space. +When all objects in the heap have been scanned a cycle ends, and all objects are moved +to the `pending` list again. To avoid having to traverse the entire list, which list is +`pending` and which is `visited` is determined by a field in the `GCState` struct. +The `visited` and `pending` lists can be swapped by toggling this bit. + +Correctness +----------- + +The [algorithm for identifying cycles](#Identifying-reference-cycles) will find all +unreachable cycles in a list of objects, but will not find any cycles that are +even partly outside of that list. +Therefore, to be guaranteed that a full scavenge will find all unreachable cycles, +each cycle must be fully contained within a single increment. + +To make sure that no partial cycles are included in the increment we perform a +[transitive closure](https://en.wikipedia.org/wiki/Transitive_closure) +over reachable, unscanned objects from the initial increment. +Since the transitive closure of objects reachable from an object must be a (non-strict) +superset of any unreachable cycle including that object, we are guaranteed that a +transitive closure cannot contain any partial cycles. +We can exclude scanned objects, as they must have been reachable when scanned. +If a scanned object becomes part of an unreachable cycle after being scanned, it will +not be collected this at this time, but it will be collected in the next full scavenge. + +> [!NOTE] +> The GC implementation for the free-threaded build does not use incremental collection. +> Every collection operates on the entire heap. In order to decide when to run, the collector keeps track of the number of object allocations and deallocations since the last collection. When the number of -allocations minus the number of deallocations exceeds `threshold_0`, -collection starts. Initially only generation 0 is examined. If generation 0 has -been examined more than `threshold_1` times since generation 1 has been -examined, then generation 1 is examined as well. With generation 2, -things are a bit more complicated; see -[Collecting the oldest generation](#Collecting-the-oldest-generation) for -more information. These thresholds can be examined using the +allocations minus the number of deallocations exceeds `threshold0`, +collection starts. `threshold1` determines the fraction of the old +collection that is included in the increment. +The fraction is inversely proportional to `threshold1`, +as historically a larger `threshold1` meant that old generation +collections were performed less frequently. +`threshold2` is ignored. + +These thresholds can be examined using the [`gc.get_threshold()`](https://docs.python.org/3/library/gc.html#gc.get_threshold) function: @@ -402,8 +454,8 @@ specifically in a generation by calling `gc.collect(generation=NUM)`. ... pass ... - # Move everything to the last generation so it's easier to inspect - # the younger generations. + # Move everything to the old generation so it's easier to inspect + # the young generation. >>> gc.collect() 0 @@ -413,40 +465,24 @@ specifically in a generation by calling `gc.collect(generation=NUM)`. >>> x = MyObj() >>> x.self = x - # Initially the object is in the youngest generation. + # Initially the object is in the young generation. >>> gc.get_objects(generation=0) [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] # After a collection of the youngest generation the object - # moves to the next generation. + # moves to the old generation. >>> gc.collect(generation=0) 0 >>> gc.get_objects(generation=0) [] >>> gc.get_objects(generation=1) + [] + >>> gc.get_objects(generation=2) [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] ``` -Collecting the oldest generation --------------------------------- - -In addition to the various configurable thresholds, the GC only triggers a full -collection of the oldest generation 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 (that is, 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 -of creating and storing lots of long-lived objects (for example, building a large list -of GC-tracked objects would show quadratic performance, instead of linear as -expected). 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"). Optimization: reusing fields to save memory =========================================== @@ -588,9 +624,9 @@ heap. be more difficult. -> [!NOTE] +> [!NOTE] > **Document history** -> +> > Pablo Galindo Salgado - Original author -> +> > Irit Katriel - Convert to Markdown