From 60d90ba2382e5462eee66d4b8171cacd9f0b5533 Mon Sep 17 00:00:00 2001 From: Seth Sims Date: Fri, 10 Jul 2020 09:53:26 -0400 Subject: [PATCH 001/486] Added __next__ to _TemporaryFileWrapper --- Lib/tempfile.py | 3 +++ Lib/test/test_tempfile.py | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index ba04be8f9058e1b..1d10e6a7d2d47da 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -500,6 +500,9 @@ def close(self): """ self._closer.close() + def __next__(self): + return next(self.file) + # iter() doesn't use __getattr__ to find the __iter__ method def __iter__(self): # Don't return iter(self.file), but yield from it to avoid closing diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 8ace883d74bb24d..400c9788d6df4e4 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -886,6 +886,22 @@ def make_file(): self.assertEqual(l, lines[i]) self.assertEqual(i, len(lines) - 1) + def test_next(self): + lines = [b'spam\n', b'eggs\n', b'beans\n'] + def make_file(): + f = tempfile.NamedTemporaryFile(mode='w+b') + f.write(b''.join(lines)) + f.seek(0) + return f + + with make_file() as fd: + for i, l in enumerate(lines): + self.assertEqual(l, next(fd)) + self.assertEqual(i, len(lines) - 1) + + with self.assertRaises(StopIteration) as context: + next(fd) + def test_creates_named(self): # NamedTemporaryFile creates files with names f = tempfile.NamedTemporaryFile() From c614cdf41a44d401da36867adfb925b734740f2f Mon Sep 17 00:00:00 2001 From: Seth Sims Date: Fri, 10 Jul 2020 10:09:11 -0400 Subject: [PATCH 002/486] Fixed spacing --- Lib/tempfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 1d10e6a7d2d47da..1aa79bcb8a2a510 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -501,7 +501,7 @@ def close(self): self._closer.close() def __next__(self): - return next(self.file) + return next(self.file) # iter() doesn't use __getattr__ to find the __iter__ method def __iter__(self): From 937694ae6ca87dc1343ab1e84fdfe5bbb6c0b5eb Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2020 14:33:53 +0000 Subject: [PATCH 003/486] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by?= =?UTF-8?q?=20blurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst diff --git a/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst new file mode 100644 index 000000000000000..11b51dd5b87c5d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst @@ -0,0 +1 @@ +Made NamedTemporaryFile its own iterator to mimic file objects. \ No newline at end of file From 1a9ddc1eeb17a17808553e43b7575e0cf735cc84 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 9 Jul 2020 18:52:43 +0100 Subject: [PATCH 004/486] bpo-41172: Fix check for compiler in test suite (GH-21400) --- Lib/test/support/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index f8f60fb6c27b912..b21978a61cd2f12 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1673,9 +1673,15 @@ def missing_compiler_executable(cmd_names=[]): missing. """ - from distutils import ccompiler, sysconfig, spawn + from distutils import ccompiler, sysconfig, spawn, errors compiler = ccompiler.new_compiler() sysconfig.customize_compiler(compiler) + if compiler.compiler_type == "msvc": + # MSVC has no executables, so check whether initialization succeeds + try: + compiler.initialize() + except errors.DistutilsPlatformError: + return "msvc" for name in compiler.executables: if cmd_names and name not in cmd_names: continue From d9e44280e081377218be34eb04204f897480b4d3 Mon Sep 17 00:00:00 2001 From: E-Paine <63801254+E-Paine@users.noreply.github.com> Date: Thu, 9 Jul 2020 21:18:34 +0200 Subject: [PATCH 005/486] Remove trailing >>> in enum docs (GH-21358) The >>> as the last line serve no purpose and are not colored correctly by Sphinx. --- Doc/library/enum.rst | 1 - Misc/ACKS | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 4b4f5eb1944cc57..b327a0ad15f96c9 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -113,7 +113,6 @@ The *type* of an enumeration member is the enumeration it belongs to:: >>> isinstance(Color.GREEN, Color) True - >>> Enum members also have a property that contains just their item name:: diff --git a/Misc/ACKS b/Misc/ACKS index 641ef0cace00e2f..b585769608f4e98 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1266,6 +1266,7 @@ Richard Oudkerk Russel Owen Joonas Paalasmaa Martin Packman +Elisha Paine Shriphani Palakodety Julien Palard Aviv Palivoda From 138ccdd4c02a564d9928525ca6c4a15165e90703 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 9 Jul 2020 18:08:33 -0400 Subject: [PATCH 006/486] bpo-37765: Add keywords to IDLE tab completions (GH-15138) Keywords are present in the main module tab completion lists generated by rlcompleter, which is used by REPLs on *nix. Add all keywords to IDLE's main module name list except those already added from builtins (True, False, and None) . This list may also be used by Show Completions on the Edit menu, and its hot key. Rewrite Completions doc. Co-authored-by: Cheryl Sabella --- Doc/library/idle.rst | 90 ++++++++++--------- Lib/idlelib/NEWS.txt | 3 + Lib/idlelib/autocomplete.py | 6 +- Lib/idlelib/help.html | 85 ++++++++++-------- Lib/idlelib/idle_test/test_autocomplete.py | 7 +- .../2020-07-07-18-44-30.bpo-37765.umc1o8.rst | 2 + 6 files changed, 110 insertions(+), 83 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index b1192e7bb465523..75b6fa3861b23d0 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -147,7 +147,7 @@ Go to Line Clear any selection and update the line and column status. Show Completions - Open a scrollable list allowing selection of keywords and attributes. See + Open a scrollable list allowing selection of existing names. See :ref:`Completions ` in the Editing and navigation section below. Expand Word @@ -469,52 +469,58 @@ are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands on the :ref:`Format menu `. - .. _completions: Completions ^^^^^^^^^^^ -Completions are supplied for functions, classes, and attributes of classes, -both built-in and user-defined. Completions are also provided for -filenames. - -The AutoCompleteWindow (ACW) will open after a predefined delay (default is -two seconds) after a '.' or (in a string) an os.sep is typed. If after one -of those characters (plus zero or more other characters) a tab is typed -the ACW will open immediately if a possible continuation is found. - -If there is only one possible completion for the characters entered, a -:kbd:`Tab` will supply that completion without opening the ACW. - -'Show Completions' will force open a completions window, by default the -:kbd:`C-space` will open a completions window. In an empty -string, this will contain the files in the current directory. On a -blank line, it will contain the built-in and user-defined functions and -classes in the current namespaces, plus any modules imported. If some -characters have been entered, the ACW will attempt to be more specific. - -If a string of characters is typed, the ACW selection will jump to the -entry most closely matching those characters. Entering a :kbd:`tab` will -cause the longest non-ambiguous match to be entered in the Editor window or -Shell. Two :kbd:`tab` in a row will supply the current ACW selection, as -will return or a double click. Cursor keys, Page Up/Down, mouse selection, -and the scroll wheel all operate on the ACW. - -"Hidden" attributes can be accessed by typing the beginning of hidden -name after a '.', e.g. '_'. This allows access to modules with -``__all__`` set, or to class-private attributes. - -Completions and the 'Expand Word' facility can save a lot of typing! - -Completions are currently limited to those in the namespaces. Names in -an Editor window which are not via ``__main__`` and :data:`sys.modules` will -not be found. Run the module once with your imports to correct this situation. -Note that IDLE itself places quite a few modules in sys.modules, so -much can be found by default, e.g. the re module. - -If you don't like the ACW popping up unbidden, simply make the delay -longer or disable the extension. +Completions are supplied, when requested and available, for module +names, attributes of classes or functions, or filenames. Each request +method displays a completion box with existing names. (See tab +completions below for an exception.) For any box, change the name +being completed and the item highlighted in the box by +typing and deleting characters; by hitting :kbd:`Up`, :kbd:`Down`, +:kbd:`PageUp`, :kbd:`PageDown`, :kbd:`Home`, and :kbd:`End` keys; +and by a single click within the box. Close the box with :kbd:`Escape`, +:kbd:`Enter`, and double :kbd:`Tab` keys or clicks outside the box. +A double click within the box selects and closes. + +One way to open a box is to type a key character and wait for a +predefined interval. This defaults to 2 seconds; customize it +in the settings dialog. (To prevent auto popups, set the delay to a +large number of milliseconds, such as 100000000.) For imported module +names or class or function attributes, type '.'. +For filenames in the root directory, type :data:`os.sep` or +data:`os.altsep` immediately after an opening quote. (On Windows, +one can specify a drive first.) Move into subdirectories by typing a +directory name and a separator. + +Instead of waiting, or after a box is closed, open a completion box +immediately with Show Completions on the Edit menu. The default hot +key is :kbd:`C-space`. If one types a prefix for the desired name +before opening the box, the first match or near miss is made visible. +The result is the same as if one enters a prefix +after the box is displayed. Show Completions after a quote completes +filenames in the current directory instead of a root directory. + +Hitting :kbd:`Tab` after a prefix usually has the same effect as Show +Completions. (With no prefix, it indents.) However, if there is only +one match to the prefix, that match is immediately added to the editor +text without opening a box. + +Invoking 'Show Completions', or hitting :kbd:`Tab` after a prefix, +outside of a string and without a preceding '.' opens a box with +keywords, builtin names, and available module-level names. + +When editing code in an editor (as oppose to Shell), increase the +available module-level names by running your code +and not restarting the Shell thereafter. This is especially useful +after adding imports at the top of a file. This also increases +possible attribute completions. + +Completion boxes intially exclude names beginning with '_' or, for +modules, not included in '__all__'. The hidden names can be accessed +by typing '_' after '.', either before or after the box is opened. .. _calltips: diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 7ae29af0b30ce3f..1c5c03da86efc57 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-37765: Add keywords to module name completion list. Rewrite +Completions section of IDLE doc. + bpo-41152: The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE is now always UTF-8. diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py index c623d45a1534230..e1e9e17311eda1e 100644 --- a/Lib/idlelib/autocomplete.py +++ b/Lib/idlelib/autocomplete.py @@ -4,6 +4,7 @@ pop up a list of candidates. """ import __main__ +import keyword import os import string import sys @@ -171,10 +172,13 @@ def fetch_completions(self, what, mode): (what, mode), {}) else: if mode == ATTRS: - if what == "": + if what == "": # Main module names. namespace = {**__main__.__builtins__.__dict__, **__main__.__dict__} bigl = eval("dir()", namespace) + kwds = (s for s in keyword.kwlist + if s not in {'True', 'False', 'None'}) + bigl.extend(kwds) bigl.sort() if "__all__" in bigl: smalll = sorted(eval("__all__", namespace)) diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 424c6b50f339e1c..81ce5100bb8ad5d 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a4 documentation + IDLE — Python 3.10.0a0 documentation @@ -17,7 +17,7 @@ @@ -71,7 +71,7 @@

Navigation

  • - 3.9.0a4 Documentation » + 3.10.0a0 Documentation »
  • @@ -201,7 +201,7 @@

    Edit menu (Shell and Editor)Completions in the Editing and navigation section below.

    Expand Word

    Expand a prefix you have typed to match a full word in the same window; @@ -465,38 +465,47 @@

    Automatic indentation

    Completions

    -

    Completions are supplied for functions, classes, and attributes of classes, -both built-in and user-defined. Completions are also provided for -filenames.

    -

    The AutoCompleteWindow (ACW) will open after a predefined delay (default is -two seconds) after a ‘.’ or (in a string) an os.sep is typed. If after one -of those characters (plus zero or more other characters) a tab is typed -the ACW will open immediately if a possible continuation is found.

    -

    If there is only one possible completion for the characters entered, a -Tab will supply that completion without opening the ACW.

    -

    ‘Show Completions’ will force open a completions window, by default the -C-space will open a completions window. In an empty -string, this will contain the files in the current directory. On a -blank line, it will contain the built-in and user-defined functions and -classes in the current namespaces, plus any modules imported. If some -characters have been entered, the ACW will attempt to be more specific.

    -

    If a string of characters is typed, the ACW selection will jump to the -entry most closely matching those characters. Entering a tab will -cause the longest non-ambiguous match to be entered in the Editor window or -Shell. Two tab in a row will supply the current ACW selection, as -will return or a double click. Cursor keys, Page Up/Down, mouse selection, -and the scroll wheel all operate on the ACW.

    -

    “Hidden” attributes can be accessed by typing the beginning of hidden -name after a ‘.’, e.g. ‘_’. This allows access to modules with -__all__ set, or to class-private attributes.

    -

    Completions and the ‘Expand Word’ facility can save a lot of typing!

    -

    Completions are currently limited to those in the namespaces. Names in -an Editor window which are not via __main__ and sys.modules will -not be found. Run the module once with your imports to correct this situation. -Note that IDLE itself places quite a few modules in sys.modules, so -much can be found by default, e.g. the re module.

    -

    If you don’t like the ACW popping up unbidden, simply make the delay -longer or disable the extension.

    +

    Completions are supplied, when requested and available, for module +names, attributes of classes or functions, or filenames. Each request +method displays a completion box with existing names. (See tab +completions below for an exception.) For any box, change the name +being completed and the item highlighted in the box by +typing and deleting characters; by hitting Up, Down, +PageUp, PageDown, Home, and End keys; +and by a single click within the box. Close the box with Escape, +Enter, and double Tab keys or clicks outside the box. +A double click within the box selects and closes.

    +

    One way to open a box is to type a key character and wait for a +predefined interval. This defaults to 2 seconds; customize it +in the settings dialog. (To prevent auto popups, set the delay to a +large number of milliseconds, such as 100000000.) For imported module +names or class or function attributes, type ‘.’. +For filenames in the root directory, type os.sep or +data:os.altsep immediately after an opening quote. (On Windows, +one can specify a drive first.) Move into subdirectories by typing a +directory name and a separator.

    +

    Instead of waiting, or after a box is closed. open a completion box +immediately with Show Completions on the Edit menu. The default hot +key is C-space. If one types a prefix for the desired name +before opening the box, the first match is displayed. +The result is the same as if one enters a prefix +after the box is displayed. Show Completions after a quote completes +filenames in the current directory instead of a root directory.

    +

    Hitting Tab after a prefix usually has the same effect as Show +Completions. (With no prefix, it indents.) However, if there is only +one match to the prefix, that match is immediately added to the editor +text without opening a box.

    +

    Invoking ‘Show Completions’, or hitting Tab after a prefix, +outside of a string and without a preceding ‘.’ opens a box with +keywords, builtin names, and available module-level names.

    +

    When editing code in an editor (as oppose to Shell), increase the +available module-level names by running your code +and not restarting the Shell thereafter. This is especially useful +after adding imports at the top of a file. This also increases +possible attribute completions.

    +

    Completion boxes intially exclude names beginning with ‘_’ or, for +modules, not included in ‘__all__’. The hidden names can be accessed +by typing ‘_’ after ‘.’, either before or after the box is opened.

    Calltips

    @@ -935,7 +944,7 @@

    Navigation

  • - 3.9.0a4 Documentation » + 3.10.0a0 Documentation »
  • @@ -966,7 +975,7 @@

    Navigation



    - Last updated on Mar 07, 2020. + Last updated on Jul 08, 2020. Found a bug?
    diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py index 1841495fcf1a0c6..9c113bd893f1378 100644 --- a/Lib/idlelib/idle_test/test_autocomplete.py +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -240,8 +240,11 @@ def test_fetch_completions(self): with patch.dict('__main__.__dict__', {'__all__': ['a', 'b']}): s, b = acp.fetch_completions('', ac.ATTRS) self.assertEqual(s, ['a', 'b']) - self.assertIn('__name__', b) # From __main__.__dict__ - self.assertIn('sum', b) # From __main__.__builtins__.__dict__ + self.assertIn('__name__', b) # From __main__.__dict__. + self.assertIn('sum', b) # From __main__.__builtins__.__dict__. + self.assertIn('nonlocal', b) # From keyword.kwlist. + pos = b.index('False') # Test False not included twice. + self.assertNotEqual(b[pos+1], 'False') # Test attributes with name entity. mock = Mock() diff --git a/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst b/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst new file mode 100644 index 000000000000000..f8b53ca482a21e8 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst @@ -0,0 +1,2 @@ +Add keywords to module name completion list. Rewrite Completions +section of IDLE doc. From 811b2f7a29535ef64de0132e7f62fb5d036e42e9 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Thu, 9 Jul 2020 21:36:35 -0300 Subject: [PATCH 007/486] bpo-23802: patch: __deepcopy__ memo dict argument usage (GH-21326) * Clarify __deepcopy__ memo dict argument usage * Add full stop --- Doc/library/copy.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index a8e8bfb1e832bb2..176e01db6f9faf0 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -86,6 +86,7 @@ The latter is called to implement the deep copy operation; it is passed one argument, the ``memo`` dictionary. If the :meth:`__deepcopy__` implementation needs to make a deep copy of a component, it should call the :func:`deepcopy` function with the component as first argument and the memo dictionary as second argument. +The memo dictionary should be treated as an opaque object. .. seealso:: From 0a4949f9a9da712e017080f3734af6c6d2025287 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 10 Jul 2020 10:12:04 +0300 Subject: [PATCH 008/486] bpo-41263: Convert code.__new__ to Argument Clinic (GH-21426) --- Objects/clinic/codeobject.c.h | 138 +++++++++++++++++++++++++++++++++- Objects/codeobject.c | 73 +++++++++--------- 2 files changed, 173 insertions(+), 38 deletions(-) diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index aef505ffc3f612e..c7395375e64692b 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -2,6 +2,142 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(code_new__doc__, +"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" +" flags, codestring, constants, names, varnames, filename, name,\n" +" firstlineno, lnotab, freevars=(), cellvars=(), /)\n" +"--\n" +"\n" +"Create a code object. Not for the faint of heart."); + +static PyObject * +code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, + int kwonlyargcount, int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *filename, PyObject *name, + int firstlineno, PyObject *lnotab, PyObject *freevars, + PyObject *cellvars); + +static PyObject * +code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + int argcount; + int posonlyargcount; + int kwonlyargcount; + int nlocals; + int stacksize; + int flags; + PyObject *code; + PyObject *consts; + PyObject *names; + PyObject *varnames; + PyObject *filename; + PyObject *name; + int firstlineno; + PyObject *lnotab; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + + if ((type == &PyCode_Type) && + !_PyArg_NoKeywords("code", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 14, 16)) { + goto exit; + } + argcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + if (argcount == -1 && PyErr_Occurred()) { + goto exit; + } + posonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 1)); + if (posonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + kwonlyargcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 2)); + if (kwonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + nlocals = _PyLong_AsInt(PyTuple_GET_ITEM(args, 3)); + if (nlocals == -1 && PyErr_Occurred()) { + goto exit; + } + stacksize = _PyLong_AsInt(PyTuple_GET_ITEM(args, 4)); + if (stacksize == -1 && PyErr_Occurred()) { + goto exit; + } + flags = _PyLong_AsInt(PyTuple_GET_ITEM(args, 5)); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 6))) { + _PyArg_BadArgument("code", "argument 7", "bytes", PyTuple_GET_ITEM(args, 6)); + goto exit; + } + code = PyTuple_GET_ITEM(args, 6); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 7))) { + _PyArg_BadArgument("code", "argument 8", "tuple", PyTuple_GET_ITEM(args, 7)); + goto exit; + } + consts = PyTuple_GET_ITEM(args, 7); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 8))) { + _PyArg_BadArgument("code", "argument 9", "tuple", PyTuple_GET_ITEM(args, 8)); + goto exit; + } + names = PyTuple_GET_ITEM(args, 8); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 9))) { + _PyArg_BadArgument("code", "argument 10", "tuple", PyTuple_GET_ITEM(args, 9)); + goto exit; + } + varnames = PyTuple_GET_ITEM(args, 9); + if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 10))) { + _PyArg_BadArgument("code", "argument 11", "str", PyTuple_GET_ITEM(args, 10)); + goto exit; + } + if (PyUnicode_READY(PyTuple_GET_ITEM(args, 10)) == -1) { + goto exit; + } + filename = PyTuple_GET_ITEM(args, 10); + if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 11))) { + _PyArg_BadArgument("code", "argument 12", "str", PyTuple_GET_ITEM(args, 11)); + goto exit; + } + if (PyUnicode_READY(PyTuple_GET_ITEM(args, 11)) == -1) { + goto exit; + } + name = PyTuple_GET_ITEM(args, 11); + firstlineno = _PyLong_AsInt(PyTuple_GET_ITEM(args, 12)); + if (firstlineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 13))) { + _PyArg_BadArgument("code", "argument 14", "bytes", PyTuple_GET_ITEM(args, 13)); + goto exit; + } + lnotab = PyTuple_GET_ITEM(args, 13); + if (PyTuple_GET_SIZE(args) < 15) { + goto skip_optional; + } + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 14))) { + _PyArg_BadArgument("code", "argument 15", "tuple", PyTuple_GET_ITEM(args, 14)); + goto exit; + } + freevars = PyTuple_GET_ITEM(args, 14); + if (PyTuple_GET_SIZE(args) < 16) { + goto skip_optional; + } + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 15))) { + _PyArg_BadArgument("code", "argument 16", "tuple", PyTuple_GET_ITEM(args, 15)); + goto exit; + } + cellvars = PyTuple_GET_ITEM(args, 15); +skip_optional: + return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars); + +exit: + return return_value; +} + PyDoc_STRVAR(code_replace__doc__, "replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n" " co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n" @@ -218,4 +354,4 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=f9f23e912a3955b9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=18c31941ec09e9ca input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 49011db1014e7db..4ca22fc5029b82a 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -442,46 +442,45 @@ validate_and_copy_tuple(PyObject *tup) return newtuple; } -PyDoc_STRVAR(code_doc, -"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\ - flags, codestring, constants, names, varnames, filename, name,\n\ - firstlineno, lnotab[, freevars[, cellvars]])\n\ -\n\ -Create a code object. Not for the faint of heart."); +/*[clinic input] +@classmethod +code.__new__ as code_new + + argcount: int + posonlyargcount: int + kwonlyargcount: int + nlocals: int + stacksize: int + flags: int + codestring as code: object(subclass_of="&PyBytes_Type") + constants as consts: object(subclass_of="&PyTuple_Type") + names: object(subclass_of="&PyTuple_Type") + varnames: object(subclass_of="&PyTuple_Type") + filename: unicode + name: unicode + firstlineno: int + lnotab: object(subclass_of="&PyBytes_Type") + freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () + cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () + / + +Create a code object. Not for the faint of heart. +[clinic start generated code]*/ static PyObject * -code_new(PyTypeObject *type, PyObject *args, PyObject *kw) +code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, + int kwonlyargcount, int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *filename, PyObject *name, + int firstlineno, PyObject *lnotab, PyObject *freevars, + PyObject *cellvars) +/*[clinic end generated code: output=612aac5395830184 input=85e678ea4178f234]*/ { - int argcount; - int posonlyargcount; - int kwonlyargcount; - int nlocals; - int stacksize; - int flags; PyObject *co = NULL; - PyObject *code; - PyObject *consts; - PyObject *names, *ournames = NULL; - PyObject *varnames, *ourvarnames = NULL; - PyObject *freevars = NULL, *ourfreevars = NULL; - PyObject *cellvars = NULL, *ourcellvars = NULL; - PyObject *filename; - PyObject *name; - int firstlineno; - PyObject *lnotab; - - if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code", - &argcount, &posonlyargcount, &kwonlyargcount, - &nlocals, &stacksize, &flags, - &code, - &PyTuple_Type, &consts, - &PyTuple_Type, &names, - &PyTuple_Type, &varnames, - &filename, &name, - &firstlineno, &lnotab, - &PyTuple_Type, &freevars, - &PyTuple_Type, &cellvars)) - return NULL; + PyObject *ournames = NULL; + PyObject *ourvarnames = NULL; + PyObject *ourfreevars = NULL; + PyObject *ourcellvars = NULL; if (PySys_Audit("code.__new__", "OOOiiiiii", code, filename, name, argcount, posonlyargcount, @@ -963,7 +962,7 @@ PyTypeObject PyCode_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - code_doc, /* tp_doc */ + code_new__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ code_richcompare, /* tp_richcompare */ From d0a9bd685e6b241918d040ca257e456aa747c68a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 10 Jul 2020 11:17:21 +0300 Subject: [PATCH 009/486] bpo-36346: Do not use legacy Unicode C API in ctypes. (#21429) --- Modules/_ctypes/_ctypes.c | 33 ++++++++++++++------------------- Modules/_ctypes/callproc.c | 10 +++++----- Modules/_ctypes/cfield.c | 7 ++----- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index ceae67ebb161274..0ac48b92bff8bad 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1366,8 +1366,6 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) static int WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) { - Py_ssize_t result = 0; - if (value == NULL) { PyErr_SetString(PyExc_TypeError, "can't delete attribute"); @@ -1378,29 +1376,24 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); return -1; - } else - Py_INCREF(value); + } + Py_ssize_t size = self->b_size / sizeof(wchar_t); Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); if (len < 0) { return -1; } // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, // when it is called with NULL. - if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { + assert(len > 0); + if (len - 1 > size) { PyErr_SetString(PyExc_ValueError, "string too long"); - result = -1; - goto done; - } - result = PyUnicode_AsWideChar(value, - (wchar_t *)self->b_ptr, - self->b_size/sizeof(wchar_t)); - if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) - ((wchar_t *)self->b_ptr)[result] = (wchar_t)0; - done: - Py_DECREF(value); - - return result >= 0 ? 0 : -1; + return -1; + } + if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) { + return -1; + } + return 0; } static PyGetSetDef WCharArray_getsets[] = { @@ -3484,10 +3477,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags) for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); int flag; - char *name; + PyObject *name = Py_None; PyObject *defval; PyObject *typ; - if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) { + if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) || + !(name == Py_None || PyUnicode_Check(name))) + { PyErr_SetString(PyExc_TypeError, "paramflags must be a sequence of (int [,string [,value]]) tuples"); return 0; diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 6030cc3d43670df..261ae5ceb9e48a5 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1300,7 +1300,6 @@ module. load_flags are as defined for LoadLibraryEx in the\n\ Windows API.\n"; static PyObject *load_library(PyObject *self, PyObject *args) { - const WCHAR *name; PyObject *nameobj; int load_flags = 0; HMODULE hMod; @@ -1309,14 +1308,14 @@ static PyObject *load_library(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) return NULL; - name = _PyUnicode_AsUnicode(nameobj); - if (!name) - return NULL; - if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { return NULL; } + WCHAR *name = PyUnicode_AsWideCharString(nameobj, NULL); + if (!name) + return NULL; + Py_BEGIN_ALLOW_THREADS /* bpo-36085: Limit DLL search directories to avoid pre-loading * attacks and enable use of the AddDllDirectory function. @@ -1325,6 +1324,7 @@ static PyObject *load_library(PyObject *self, PyObject *args) err = hMod ? 0 : GetLastError(); Py_END_ALLOW_THREADS + PyMem_Free(name); if (err == ERROR_MOD_NOT_FOUND) { PyErr_Format(PyExc_FileNotFoundError, ("Could not find module '%.500S' (or one of its " diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 3a9b7119201cf02..3bd9ae438db4402 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1220,11 +1220,8 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) "string too long (%zd, maximum length %zd)", size, length); return NULL; - } else if (size < length-1) - /* copy terminating NUL character if there is space */ - size += 1; - - if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) { + } + if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) { return NULL; } From f52e93976b15452cfa409f59670bd8929a48ce6c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 10 Jul 2020 12:40:38 +0200 Subject: [PATCH 010/486] bpo-39573: Use the Py_TYPE() macro (GH-21433) Replace obj->ob_type with Py_TYPE(obj). --- Modules/_elementtree.c | 2 +- Objects/abstract.c | 4 ++-- Objects/genericaliasobject.c | 2 +- Objects/unicodeobject.c | 4 ++-- PC/_msi.c | 6 +++--- PC/winreg.c | 4 ++-- Tools/scripts/combinerefs.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 2c92a8aedb5a884..85fdfa7e5ed42cf 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2040,7 +2040,7 @@ element_attrib_setter(ElementObject *self, PyObject *value, void *closure) if (!PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.200s", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return -1; } if (!self->extra) { diff --git a/Objects/abstract.c b/Objects/abstract.c index 3494f33ce380ca0..7bd72c9b5dcc269 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1382,7 +1382,7 @@ PyNumber_Long(PyObject *o) if (!PyLong_Check(result)) { PyErr_Format(PyExc_TypeError, "__int__ returned non-int (type %.200s)", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return NULL; } @@ -1391,7 +1391,7 @@ PyNumber_Long(PyObject *o) "__int__ returned non-int (type %.200s). " "The ability to return an instance of a strict subclass of int " "is deprecated, and may be removed in a future version of Python.", - result->ob_type->tp_name)) { + Py_TYPE(result)->tp_name)) { Py_DECREF(result); return NULL; } diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 4d511a239063ceb..87bd1ae5c1430b5 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -20,7 +20,7 @@ ga_dealloc(PyObject *self) Py_XDECREF(alias->origin); Py_XDECREF(alias->args); Py_XDECREF(alias->parameters); - self->ob_type->tp_free(self); + Py_TYPE(self)->tp_free(self); } static int diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 809ed85895f86fe..648dd15ca09f588 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3325,7 +3325,7 @@ _PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr) } PyErr_Format(PyExc_TypeError, "argument must be str, not %.50s", - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); return 0; } @@ -3361,7 +3361,7 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) } PyErr_Format(PyExc_TypeError, "argument must be str or None, not %.50s", - obj->ob_type->tp_name); + Py_TYPE(obj)->tp_name); return 0; } diff --git a/PC/_msi.c b/PC/_msi.c index f725c816206e725..504899d0757b78c 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -193,7 +193,7 @@ static FNFCIGETNEXTCABINET(cb_getnextcabinet) if (!PyBytes_Check(result)) { PyErr_Format(PyExc_TypeError, "Incorrect return type %s from getnextcabinet", - result->ob_type->tp_name); + Py_TYPE(result)->tp_name); Py_DECREF(result); return FALSE; } @@ -879,7 +879,7 @@ _msi_View_Execute(msiobj *self, PyObject *oparams) MSIHANDLE params = 0; if (oparams != Py_None) { - if (oparams->ob_type != &record_Type) { + if (!Py_IS_TYPE(oparams, &record_Type)) { PyErr_SetString(PyExc_TypeError, "Execute argument must be a record"); return NULL; } @@ -955,7 +955,7 @@ _msi_View_Modify_impl(msiobj *self, int kind, PyObject *data) { int status; - if (data->ob_type != &record_Type) { + if (!Py_IS_TYPE(data, &record_Type)) { PyErr_SetString(PyExc_TypeError, "Modify expects a record object"); return NULL; } diff --git a/PC/winreg.c b/PC/winreg.c index 7c3b2f4be85c963..b2725b857d0c227 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -112,7 +112,7 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type) +#define PyHKEY_Check(op) Py_IS_TYPE(op, &PyHKEY_Type) static char *failMsg = "bad operand type"; @@ -693,7 +693,7 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not " "be used as binary registry values", - value->ob_type->tp_name); + Py_TYPE(value)->tp_name); return FALSE; } diff --git a/Tools/scripts/combinerefs.py b/Tools/scripts/combinerefs.py index 49ccca73909fc8f..848bae5658ca3ab 100755 --- a/Tools/scripts/combinerefs.py +++ b/Tools/scripts/combinerefs.py @@ -33,7 +33,7 @@ if the refcount changed. -typename is object->ob_type->tp_name, extracted from the second PYTHONDUMPREFS +typename is Py_TYPE(object)->tp_name, extracted from the second PYTHONDUMPREFS output block. repr is repr(object), extracted from the first PYTHONDUMPREFS output block. From bd6919a3658190839c1f560fb3ae0d2fa6eb561c Mon Sep 17 00:00:00 2001 From: marload Date: Sat, 11 Jul 2020 00:43:31 +0900 Subject: [PATCH 011/486] Fix typo in docs: 'created by th' -> 'created by the' (GH-21384) --- Doc/library/asyncio-protocol.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index 3079716f03ecc0b..9dbd3ab46a3f681 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -993,7 +993,7 @@ loop.subprocess_exec() and SubprocessProtocol An example of a subprocess protocol used to get the output of a subprocess and to wait for the subprocess exit. -The subprocess is created by th :meth:`loop.subprocess_exec` method:: +The subprocess is created by the :meth:`loop.subprocess_exec` method:: import asyncio import sys From 90348f33a2ed31a3d43c00bd0b42462ca6161428 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 10 Jul 2020 11:43:37 -0600 Subject: [PATCH 012/486] bpo-20179: Convert the _overlapped module to the Argument Clinic (GH-14275) --- Modules/clinic/overlapped.c.h | 908 ++++++++++++++++++++++++++++++++++ Modules/overlapped.c | 865 +++++++++++++++++--------------- 2 files changed, 1364 insertions(+), 409 deletions(-) create mode 100644 Modules/clinic/overlapped.c.h diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h new file mode 100644 index 000000000000000..efecd9028b77600 --- /dev/null +++ b/Modules/clinic/overlapped.c.h @@ -0,0 +1,908 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, +"CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" +"--\n" +"\n" +"Create a completion port or register a handle with a port."); + +#define _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF \ + {"CreateIoCompletionPort", (PyCFunction)(void(*)(void))_overlapped_CreateIoCompletionPort, METH_FASTCALL, _overlapped_CreateIoCompletionPort__doc__}, + +static PyObject * +_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle, + HANDLE ExistingCompletionPort, + ULONG_PTR CompletionKey, + DWORD NumberOfConcurrentThreads); + +static PyObject * +_overlapped_CreateIoCompletionPort(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE FileHandle; + HANDLE ExistingCompletionPort; + ULONG_PTR CompletionKey; + DWORD NumberOfConcurrentThreads; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_ULONG_PTR"k:CreateIoCompletionPort", + &FileHandle, &ExistingCompletionPort, &CompletionKey, &NumberOfConcurrentThreads)) { + goto exit; + } + return_value = _overlapped_CreateIoCompletionPort_impl(module, FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_GetQueuedCompletionStatus__doc__, +"GetQueuedCompletionStatus($module, port, msecs, /)\n" +"--\n" +"\n" +"Get a message from completion port.\n" +"\n" +"Wait for up to msecs milliseconds."); + +#define _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF \ + {"GetQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_GetQueuedCompletionStatus, METH_FASTCALL, _overlapped_GetQueuedCompletionStatus__doc__}, + +static PyObject * +_overlapped_GetQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD Milliseconds); + +static PyObject * +_overlapped_GetQueuedCompletionStatus(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE CompletionPort; + DWORD Milliseconds; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:GetQueuedCompletionStatus", + &CompletionPort, &Milliseconds)) { + goto exit; + } + return_value = _overlapped_GetQueuedCompletionStatus_impl(module, CompletionPort, Milliseconds); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_PostQueuedCompletionStatus__doc__, +"PostQueuedCompletionStatus($module, port, bytes, key, address, /)\n" +"--\n" +"\n" +"Post a message to completion port."); + +#define _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF \ + {"PostQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_PostQueuedCompletionStatus, METH_FASTCALL, _overlapped_PostQueuedCompletionStatus__doc__}, + +static PyObject * +_overlapped_PostQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD NumberOfBytes, + ULONG_PTR CompletionKey, + OVERLAPPED *Overlapped); + +static PyObject * +_overlapped_PostQueuedCompletionStatus(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE CompletionPort; + DWORD NumberOfBytes; + ULONG_PTR CompletionKey; + OVERLAPPED *Overlapped; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k"F_ULONG_PTR""F_POINTER":PostQueuedCompletionStatus", + &CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped)) { + goto exit; + } + return_value = _overlapped_PostQueuedCompletionStatus_impl(module, CompletionPort, NumberOfBytes, CompletionKey, Overlapped); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_RegisterWaitWithQueue__doc__, +"RegisterWaitWithQueue($module, Object, CompletionPort, Overlapped,\n" +" Timeout, /)\n" +"--\n" +"\n" +"Register wait for Object; when complete CompletionPort is notified."); + +#define _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF \ + {"RegisterWaitWithQueue", (PyCFunction)(void(*)(void))_overlapped_RegisterWaitWithQueue, METH_FASTCALL, _overlapped_RegisterWaitWithQueue__doc__}, + +static PyObject * +_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, + HANDLE CompletionPort, + OVERLAPPED *Overlapped, + DWORD Milliseconds); + +static PyObject * +_overlapped_RegisterWaitWithQueue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Object; + HANDLE CompletionPort; + OVERLAPPED *Overlapped; + DWORD Milliseconds; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_POINTER"k:RegisterWaitWithQueue", + &Object, &CompletionPort, &Overlapped, &Milliseconds)) { + goto exit; + } + return_value = _overlapped_RegisterWaitWithQueue_impl(module, Object, CompletionPort, Overlapped, Milliseconds); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_UnregisterWait__doc__, +"UnregisterWait($module, WaitHandle, /)\n" +"--\n" +"\n" +"Unregister wait handle."); + +#define _OVERLAPPED_UNREGISTERWAIT_METHODDEF \ + {"UnregisterWait", (PyCFunction)_overlapped_UnregisterWait, METH_O, _overlapped_UnregisterWait__doc__}, + +static PyObject * +_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle); + +static PyObject * +_overlapped_UnregisterWait(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE WaitHandle; + + if (!PyArg_Parse(arg, ""F_HANDLE":UnregisterWait", &WaitHandle)) { + goto exit; + } + return_value = _overlapped_UnregisterWait_impl(module, WaitHandle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_UnregisterWaitEx__doc__, +"UnregisterWaitEx($module, WaitHandle, Event, /)\n" +"--\n" +"\n" +"Unregister wait handle."); + +#define _OVERLAPPED_UNREGISTERWAITEX_METHODDEF \ + {"UnregisterWaitEx", (PyCFunction)(void(*)(void))_overlapped_UnregisterWaitEx, METH_FASTCALL, _overlapped_UnregisterWaitEx__doc__}, + +static PyObject * +_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle, + HANDLE Event); + +static PyObject * +_overlapped_UnregisterWaitEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE WaitHandle; + HANDLE Event; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":UnregisterWaitEx", + &WaitHandle, &Event)) { + goto exit; + } + return_value = _overlapped_UnregisterWaitEx_impl(module, WaitHandle, Event); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_CreateEvent__doc__, +"CreateEvent($module, EventAttributes, ManualReset, InitialState, Name,\n" +" /)\n" +"--\n" +"\n" +"Create an event.\n" +"\n" +"EventAttributes must be None."); + +#define _OVERLAPPED_CREATEEVENT_METHODDEF \ + {"CreateEvent", (PyCFunction)(void(*)(void))_overlapped_CreateEvent, METH_FASTCALL, _overlapped_CreateEvent__doc__}, + +static PyObject * +_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes, + BOOL ManualReset, BOOL InitialState, + const Py_UNICODE *Name); + +static PyObject * +_overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *EventAttributes; + BOOL ManualReset; + BOOL InitialState; + const Py_UNICODE *Name; + + if (!_PyArg_ParseStack(args, nargs, "OiiO&:CreateEvent", + &EventAttributes, &ManualReset, &InitialState, _PyUnicode_WideCharString_Opt_Converter, &Name)) { + goto exit; + } + return_value = _overlapped_CreateEvent_impl(module, EventAttributes, ManualReset, InitialState, Name); + +exit: + /* Cleanup for Name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)Name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_overlapped_SetEvent__doc__, +"SetEvent($module, Handle, /)\n" +"--\n" +"\n" +"Set event."); + +#define _OVERLAPPED_SETEVENT_METHODDEF \ + {"SetEvent", (PyCFunction)_overlapped_SetEvent, METH_O, _overlapped_SetEvent__doc__}, + +static PyObject * +_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle); + +static PyObject * +_overlapped_SetEvent(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":SetEvent", &Handle)) { + goto exit; + } + return_value = _overlapped_SetEvent_impl(module, Handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_ResetEvent__doc__, +"ResetEvent($module, Handle, /)\n" +"--\n" +"\n" +"Reset event."); + +#define _OVERLAPPED_RESETEVENT_METHODDEF \ + {"ResetEvent", (PyCFunction)_overlapped_ResetEvent, METH_O, _overlapped_ResetEvent__doc__}, + +static PyObject * +_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle); + +static PyObject * +_overlapped_ResetEvent(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":ResetEvent", &Handle)) { + goto exit; + } + return_value = _overlapped_ResetEvent_impl(module, Handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_BindLocal__doc__, +"BindLocal($module, handle, family, /)\n" +"--\n" +"\n" +"Bind a socket handle to an arbitrary local port.\n" +"\n" +"family should be AF_INET or AF_INET6."); + +#define _OVERLAPPED_BINDLOCAL_METHODDEF \ + {"BindLocal", (PyCFunction)(void(*)(void))_overlapped_BindLocal, METH_FASTCALL, _overlapped_BindLocal__doc__}, + +static PyObject * +_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family); + +static PyObject * +_overlapped_BindLocal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + int Family; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:BindLocal", + &Socket, &Family)) { + goto exit; + } + return_value = _overlapped_BindLocal_impl(module, Socket, Family); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_FormatMessage__doc__, +"FormatMessage($module, error_code, /)\n" +"--\n" +"\n" +"Return error message for an error code."); + +#define _OVERLAPPED_FORMATMESSAGE_METHODDEF \ + {"FormatMessage", (PyCFunction)_overlapped_FormatMessage, METH_O, _overlapped_FormatMessage__doc__}, + +static PyObject * +_overlapped_FormatMessage_impl(PyObject *module, DWORD code); + +static PyObject * +_overlapped_FormatMessage(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + DWORD code; + + if (!PyArg_Parse(arg, "k:FormatMessage", &code)) { + goto exit; + } + return_value = _overlapped_FormatMessage_impl(module, code); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped__doc__, +"Overlapped(event=_overlapped.INVALID_HANDLE_VALUE)\n" +"--\n" +"\n" +"OVERLAPPED structure wrapper."); + +static PyObject * +_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event); + +static PyObject * +_overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"event", NULL}; + static _PyArg_Parser _parser = {"|"F_HANDLE":Overlapped", _keywords, 0}; + HANDLE event = INVALID_HANDLE_VALUE; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &event)) { + goto exit; + } + return_value = _overlapped_Overlapped_impl(type, event); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_cancel__doc__, +"cancel($self, /)\n" +"--\n" +"\n" +"Cancel overlapped operation."); + +#define _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF \ + {"cancel", (PyCFunction)_overlapped_Overlapped_cancel, METH_NOARGS, _overlapped_Overlapped_cancel__doc__}, + +static PyObject * +_overlapped_Overlapped_cancel_impl(OverlappedObject *self); + +static PyObject * +_overlapped_Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _overlapped_Overlapped_cancel_impl(self); +} + +PyDoc_STRVAR(_overlapped_Overlapped_getresult__doc__, +"getresult($self, wait=False, /)\n" +"--\n" +"\n" +"Retrieve result of operation.\n" +"\n" +"If wait is true then it blocks until the operation is finished. If wait\n" +"is false and the operation is still pending then an error is raised."); + +#define _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF \ + {"getresult", (PyCFunction)(void(*)(void))_overlapped_Overlapped_getresult, METH_FASTCALL, _overlapped_Overlapped_getresult__doc__}, + +static PyObject * +_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait); + +static PyObject * +_overlapped_Overlapped_getresult(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + BOOL wait = FALSE; + + if (!_PyArg_ParseStack(args, nargs, "|i:getresult", + &wait)) { + goto exit; + } + return_value = _overlapped_Overlapped_getresult_impl(self, wait); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ReadFile__doc__, +"ReadFile($self, handle, size, /)\n" +"--\n" +"\n" +"Start overlapped read."); + +#define _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF \ + {"ReadFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFile, METH_FASTCALL, _overlapped_Overlapped_ReadFile__doc__}, + +static PyObject * +_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, + DWORD size); + +static PyObject * +_overlapped_Overlapped_ReadFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:ReadFile", + &handle, &size)) { + goto exit; + } + return_value = _overlapped_Overlapped_ReadFile_impl(self, handle, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, +"ReadFileInto($self, handle, buf, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF \ + {"ReadFileInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFileInto, METH_FASTCALL, _overlapped_Overlapped_ReadFileInto__doc__}, + +static PyObject * +_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj); + +static PyObject * +_overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", + &handle, &bufobj)) { + goto exit; + } + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecv__doc__, +"WSARecv($self, handle, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF \ + {"WSARecv", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecv, METH_FASTCALL, _overlapped_Overlapped_WSARecv__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, + DWORD size, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecv(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecv", + &handle, &size, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecv_impl(self, handle, size, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, +"WSARecvInto($self, handle, buf, flags, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF \ + {"WSARecvInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvInto, METH_FASTCALL, _overlapped_Overlapped_WSARecvInto__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj, + DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", + &handle, &bufobj, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, +"WriteFile($self, handle, buf, /)\n" +"--\n" +"\n" +"Start overlapped write."); + +#define _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF \ + {"WriteFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WriteFile, METH_FASTCALL, _overlapped_Overlapped_WriteFile__doc__}, + +static PyObject * +_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj); + +static PyObject * +_overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", + &handle, &bufobj)) { + goto exit; + } + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, +"WSASend($self, handle, buf, flags, /)\n" +"--\n" +"\n" +"Start overlapped send."); + +#define _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF \ + {"WSASend", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASend, METH_FASTCALL, _overlapped_Overlapped_WSASend__doc__}, + +static PyObject * +_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", + &handle, &bufobj, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_AcceptEx__doc__, +"AcceptEx($self, listen_handle, accept_handle, /)\n" +"--\n" +"\n" +"Start overlapped wait for client to connect."); + +#define _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF \ + {"AcceptEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_AcceptEx, METH_FASTCALL, _overlapped_Overlapped_AcceptEx__doc__}, + +static PyObject * +_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, + HANDLE ListenSocket, + HANDLE AcceptSocket); + +static PyObject * +_overlapped_Overlapped_AcceptEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ListenSocket; + HANDLE AcceptSocket; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":AcceptEx", + &ListenSocket, &AcceptSocket)) { + goto exit; + } + return_value = _overlapped_Overlapped_AcceptEx_impl(self, ListenSocket, AcceptSocket); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectEx__doc__, +"ConnectEx($self, client_handle, address_as_bytes, /)\n" +"--\n" +"\n" +"Start overlapped connect.\n" +"\n" +"client_handle should be unbound."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF \ + {"ConnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ConnectEx, METH_FASTCALL, _overlapped_Overlapped_ConnectEx__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self, + HANDLE ConnectSocket, + PyObject *AddressObj); + +static PyObject * +_overlapped_Overlapped_ConnectEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ConnectSocket; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O!:ConnectEx", + &ConnectSocket, &PyTuple_Type, &AddressObj)) { + goto exit; + } + return_value = _overlapped_Overlapped_ConnectEx_impl(self, ConnectSocket, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_DisconnectEx__doc__, +"DisconnectEx($self, handle, flags, /)\n" +"--\n" +"\n"); + +#define _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF \ + {"DisconnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_DisconnectEx, METH_FASTCALL, _overlapped_Overlapped_DisconnectEx__doc__}, + +static PyObject * +_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self, + HANDLE Socket, DWORD flags); + +static PyObject * +_overlapped_Overlapped_DisconnectEx(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:DisconnectEx", + &Socket, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_DisconnectEx_impl(self, Socket, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_TransmitFile__doc__, +"TransmitFile($self, socket, file, offset, offset_high, count_to_write,\n" +" count_per_send, flags, /)\n" +"--\n" +"\n" +"Transmit file data over a connected socket."); + +#define _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF \ + {"TransmitFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_TransmitFile, METH_FASTCALL, _overlapped_Overlapped_TransmitFile__doc__}, + +static PyObject * +_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self, + HANDLE Socket, HANDLE File, + DWORD offset, DWORD offset_high, + DWORD count_to_write, + DWORD count_per_send, DWORD flags); + +static PyObject * +_overlapped_Overlapped_TransmitFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE Socket; + HANDLE File; + DWORD offset; + DWORD offset_high; + DWORD count_to_write; + DWORD count_per_send; + DWORD flags; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE"kkkkk:TransmitFile", + &Socket, &File, &offset, &offset_high, &count_to_write, &count_per_send, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_TransmitFile_impl(self, Socket, File, offset, offset_high, count_to_write, count_per_send, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectNamedPipe__doc__, +"ConnectNamedPipe($self, handle, /)\n" +"--\n" +"\n" +"Start overlapped wait for a client to connect."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF \ + {"ConnectNamedPipe", (PyCFunction)_overlapped_Overlapped_ConnectNamedPipe, METH_O, _overlapped_Overlapped_ConnectNamedPipe__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self, + HANDLE Pipe); + +static PyObject * +_overlapped_Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE Pipe; + + if (!PyArg_Parse(arg, ""F_HANDLE":ConnectNamedPipe", &Pipe)) { + goto exit; + } + return_value = _overlapped_Overlapped_ConnectNamedPipe_impl(self, Pipe); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_ConnectPipe__doc__, +"ConnectPipe($self, addr, /)\n" +"--\n" +"\n" +"Connect to the pipe for asynchronous I/O (overlapped)."); + +#define _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF \ + {"ConnectPipe", (PyCFunction)_overlapped_Overlapped_ConnectPipe, METH_O, _overlapped_Overlapped_ConnectPipe__doc__}, + +static PyObject * +_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self, + const Py_UNICODE *Address); + +static PyObject * +_overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const Py_UNICODE *Address; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("ConnectPipe", "argument", "str", arg); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + Address = _PyUnicode_AsUnicode(arg); + #else /* USE_UNICODE_WCHAR_CACHE */ + Address = PyUnicode_AsWideCharString(arg, NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (Address == NULL) { + goto exit; + } + return_value = _overlapped_Overlapped_ConnectPipe_impl(self, Address); + +exit: + /* Cleanup for Address */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)Address); + #endif /* USE_UNICODE_WCHAR_CACHE */ + + return return_value; +} + +PyDoc_STRVAR(_overlapped_WSAConnect__doc__, +"WSAConnect($module, client_handle, address_as_bytes, /)\n" +"--\n" +"\n" +"Bind a remote address to a connectionless (UDP) socket."); + +#define _OVERLAPPED_WSACONNECT_METHODDEF \ + {"WSAConnect", (PyCFunction)(void(*)(void))_overlapped_WSAConnect, METH_FASTCALL, _overlapped_WSAConnect__doc__}, + +static PyObject * +_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, + PyObject *AddressObj); + +static PyObject * +_overlapped_WSAConnect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE ConnectSocket; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WSAConnect", + &ConnectSocket, &AddressObj)) { + goto exit; + } + return_value = _overlapped_WSAConnect_impl(module, ConnectSocket, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, +"WSASendTo($self, handle, buf, flags, address_as_bytes, /)\n" +"--\n" +"\n" +"Start overlapped sendto over a connectionless (UDP) socket."); + +#define _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF \ + {"WSASendTo", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASendTo, METH_FASTCALL, _overlapped_Overlapped_WSASendTo__doc__}, + +static PyObject * +_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags, + PyObject *AddressObj); + +static PyObject * +_overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + PyObject *bufobj; + DWORD flags; + PyObject *AddressObj; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", + &handle, &bufobj, &flags, &AddressObj)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvFrom__doc__, +"WSARecvFrom($self, handle, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF \ + {"WSARecvFrom", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvFrom, METH_FASTCALL, _overlapped_Overlapped_WSARecvFrom__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, + HANDLE handle, DWORD size, + DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecvFrom", + &handle, &size, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvFrom_impl(self, handle, size, flags); + +exit: + return return_value; +} +/*[clinic end generated code: output=ee2ec2f93c8d334b input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index eed8fbf0393002a..9c4e2da9dfbd35b 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -37,6 +37,36 @@ #define T_HANDLE T_POINTER +/*[python input] +class OVERLAPPED_converter(CConverter): + type = 'OVERLAPPED *' + format_unit = '"F_POINTER"' + +class HANDLE_converter(CConverter): + type = 'HANDLE' + format_unit = '"F_HANDLE"' + +class ULONG_PTR_converter(CConverter): + type = 'ULONG_PTR' + format_unit = '"F_ULONG_PTR"' + +class DWORD_converter(CConverter): + type = 'DWORD' + format_unit = 'k' + +class BOOL_converter(CConverter): + type = 'BOOL' + format_unit = 'i' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/ + +/*[clinic input] +module _overlapped +class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92e5a799db35b96c]*/ + + enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, @@ -150,25 +180,27 @@ initialize_function_pointers(void) * Completion port stuff */ -PyDoc_STRVAR( - CreateIoCompletionPort_doc, - "CreateIoCompletionPort(handle, port, key, concurrency) -> port\n\n" - "Create a completion port or register a handle with a port."); +/*[clinic input] +_overlapped.CreateIoCompletionPort + + handle as FileHandle: HANDLE + port as ExistingCompletionPort: HANDLE + key as CompletionKey: ULONG_PTR + concurrency as NumberOfConcurrentThreads: DWORD + / + +Create a completion port or register a handle with a port. +[clinic start generated code]*/ static PyObject * -overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) +_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle, + HANDLE ExistingCompletionPort, + ULONG_PTR CompletionKey, + DWORD NumberOfConcurrentThreads) +/*[clinic end generated code: output=24ede2b0f05e5433 input=847bae4d0efe1976]*/ { - HANDLE FileHandle; - HANDLE ExistingCompletionPort; - ULONG_PTR CompletionKey; - DWORD NumberOfConcurrentThreads; HANDLE ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_ULONG_PTR F_DWORD, - &FileHandle, &ExistingCompletionPort, &CompletionKey, - &NumberOfConcurrentThreads)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); @@ -179,26 +211,30 @@ overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, ret); } -PyDoc_STRVAR( - GetQueuedCompletionStatus_doc, - "GetQueuedCompletionStatus(port, msecs) -> (err, bytes, key, address)\n\n" - "Get a message from completion port. Wait for up to msecs milliseconds."); +/*[clinic input] +_overlapped.GetQueuedCompletionStatus + + port as CompletionPort: HANDLE + msecs as Milliseconds: DWORD + / + +Get a message from completion port. + +Wait for up to msecs milliseconds. +[clinic start generated code]*/ static PyObject * -overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) +_overlapped_GetQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD Milliseconds) +/*[clinic end generated code: output=68314171628dddb7 input=94a042d14c4f6410]*/ { - HANDLE CompletionPort = NULL; DWORD NumberOfBytes = 0; ULONG_PTR CompletionKey = 0; OVERLAPPED *Overlapped = NULL; - DWORD Milliseconds; DWORD err; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, - &CompletionPort, &Milliseconds)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped, Milliseconds); @@ -215,25 +251,28 @@ overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) err, NumberOfBytes, CompletionKey, Overlapped); } -PyDoc_STRVAR( - PostQueuedCompletionStatus_doc, - "PostQueuedCompletionStatus(port, bytes, key, address) -> None\n\n" - "Post a message to completion port."); +/*[clinic input] +_overlapped.PostQueuedCompletionStatus + + port as CompletionPort: HANDLE + bytes as NumberOfBytes: DWORD + key as CompletionKey: ULONG_PTR + address as Overlapped: OVERLAPPED + / + +Post a message to completion port. +[clinic start generated code]*/ static PyObject * -overlapped_PostQueuedCompletionStatus(PyObject *self, PyObject *args) +_overlapped_PostQueuedCompletionStatus_impl(PyObject *module, + HANDLE CompletionPort, + DWORD NumberOfBytes, + ULONG_PTR CompletionKey, + OVERLAPPED *Overlapped) +/*[clinic end generated code: output=93e73f2933a43e9e input=e936202d87937aca]*/ { - HANDLE CompletionPort; - DWORD NumberOfBytes; - ULONG_PTR CompletionKey; - OVERLAPPED *Overlapped; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD F_ULONG_PTR F_POINTER, - &CompletionPort, &NumberOfBytes, &CompletionKey, - &Overlapped)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes, CompletionKey, Overlapped); @@ -264,26 +303,27 @@ PostToQueueCallback(PVOID lpParameter, BOOL TimerOrWaitFired) PyMem_RawFree(p); } -PyDoc_STRVAR( - RegisterWaitWithQueue_doc, - "RegisterWaitWithQueue(Object, CompletionPort, Overlapped, Timeout)\n" - " -> WaitHandle\n\n" - "Register wait for Object; when complete CompletionPort is notified.\n"); +/*[clinic input] +_overlapped.RegisterWaitWithQueue + + Object: HANDLE + CompletionPort: HANDLE + Overlapped: OVERLAPPED + Timeout as Milliseconds: DWORD + / + +Register wait for Object; when complete CompletionPort is notified. +[clinic start generated code]*/ static PyObject * -overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) +_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, + HANDLE CompletionPort, + OVERLAPPED *Overlapped, + DWORD Milliseconds) +/*[clinic end generated code: output=c2ace732e447fe45 input=2dd4efee44abe8ee]*/ { HANDLE NewWaitObject; - HANDLE Object; - ULONG Milliseconds; - struct PostCallbackData data, *pdata; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD, - &Object, - &data.CompletionPort, - &data.Overlapped, - &Milliseconds)) - return NULL; + struct PostCallbackData data = {CompletionPort, Overlapped}, *pdata; /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since PostToQueueCallback() will call PyMem_Free() from a new C thread @@ -306,20 +346,21 @@ overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, NewWaitObject); } -PyDoc_STRVAR( - UnregisterWait_doc, - "UnregisterWait(WaitHandle) -> None\n\n" - "Unregister wait handle.\n"); +/*[clinic input] +_overlapped.UnregisterWait + + WaitHandle: HANDLE + / + +Unregister wait handle. +[clinic start generated code]*/ static PyObject * -overlapped_UnregisterWait(PyObject *self, PyObject *args) +_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle) +/*[clinic end generated code: output=ec90cd955a9a617d input=a56709544cb2df0f]*/ { - HANDLE WaitHandle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &WaitHandle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = UnregisterWait(WaitHandle); Py_END_ALLOW_THREADS @@ -329,20 +370,23 @@ overlapped_UnregisterWait(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR( - UnregisterWaitEx_doc, - "UnregisterWaitEx(WaitHandle, Event) -> None\n\n" - "Unregister wait handle.\n"); +/*[clinic input] +_overlapped.UnregisterWaitEx + + WaitHandle: HANDLE + Event: HANDLE + / + +Unregister wait handle. +[clinic start generated code]*/ static PyObject * -overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) +_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle, + HANDLE Event) +/*[clinic end generated code: output=2e3d84c1d5f65b92 input=953cddc1de50fab9]*/ { - HANDLE WaitHandle, Event; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = UnregisterWaitEx(WaitHandle, Event); Py_END_ALLOW_THREADS @@ -356,26 +400,28 @@ overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) * Event functions -- currently only used by tests */ -PyDoc_STRVAR( - CreateEvent_doc, - "CreateEvent(EventAttributes, ManualReset, InitialState, Name)" - " -> Handle\n\n" - "Create an event. EventAttributes must be None.\n"); +/*[clinic input] +_overlapped.CreateEvent + + EventAttributes: object + ManualReset: BOOL + InitialState: BOOL + Name: Py_UNICODE(accept={str, NoneType}) + / + +Create an event. + +EventAttributes must be None. +[clinic start generated code]*/ static PyObject * -overlapped_CreateEvent(PyObject *self, PyObject *args) +_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes, + BOOL ManualReset, BOOL InitialState, + const Py_UNICODE *Name) +/*[clinic end generated code: output=8e04f0916c17b13d input=dbc36ae14375ba24]*/ { - PyObject *EventAttributes; - BOOL ManualReset; - BOOL InitialState; - Py_UNICODE *Name; HANDLE Event; - if (!PyArg_ParseTuple(args, "O" F_BOOL F_BOOL "Z", - &EventAttributes, &ManualReset, - &InitialState, &Name)) - return NULL; - if (EventAttributes != Py_None) { PyErr_SetString(PyExc_ValueError, "EventAttributes must be None"); return NULL; @@ -390,20 +436,21 @@ overlapped_CreateEvent(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, Event); } -PyDoc_STRVAR( - SetEvent_doc, - "SetEvent(Handle) -> None\n\n" - "Set event.\n"); +/*[clinic input] +_overlapped.SetEvent + + Handle: HANDLE + / + +Set event. +[clinic start generated code]*/ static PyObject * -overlapped_SetEvent(PyObject *self, PyObject *args) +_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle) +/*[clinic end generated code: output=5b8d974216b0e569 input=d8b0d26eb7391e80]*/ { - HANDLE Handle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = SetEvent(Handle); Py_END_ALLOW_THREADS @@ -413,20 +460,21 @@ overlapped_SetEvent(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR( - ResetEvent_doc, - "ResetEvent(Handle) -> None\n\n" - "Reset event.\n"); +/*[clinic input] +_overlapped.ResetEvent + + Handle: HANDLE + / + +Reset event. +[clinic start generated code]*/ static PyObject * -overlapped_ResetEvent(PyObject *self, PyObject *args) +_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle) +/*[clinic end generated code: output=066537a8405cddb2 input=d4e089c9ba84ff2f]*/ { - HANDLE Handle; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = ResetEvent(Handle); Py_END_ALLOW_THREADS @@ -440,36 +488,40 @@ overlapped_ResetEvent(PyObject *self, PyObject *args) * Bind socket handle to local port without doing slow getaddrinfo() */ -PyDoc_STRVAR( - BindLocal_doc, - "BindLocal(handle, family) -> None\n\n" - "Bind a socket handle to an arbitrary local port.\n" - "family should AF_INET or AF_INET6.\n"); +/*[clinic input] +_overlapped.BindLocal + + handle as Socket: HANDLE + family as Family: int + / + +Bind a socket handle to an arbitrary local port. + +family should be AF_INET or AF_INET6. +[clinic start generated code]*/ static PyObject * -overlapped_BindLocal(PyObject *self, PyObject *args) +_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family) +/*[clinic end generated code: output=edb93862697aed9c input=a0e7b5c2f541170c]*/ { - SOCKET Socket; - int Family; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE "i", &Socket, &Family)) - return NULL; - if (Family == AF_INET) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.S_un.S_addr = INADDR_ANY; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr)) + != SOCKET_ERROR; } else if (Family == AF_INET6) { struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = 0; addr.sin6_addr = in6addr_any; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr)) + != SOCKET_ERROR; } else { PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4"); return NULL; @@ -484,21 +536,23 @@ overlapped_BindLocal(PyObject *self, PyObject *args) * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c */ -PyDoc_STRVAR( - FormatMessage_doc, - "FormatMessage(error_code) -> error_message\n\n" - "Return error message for an error code."); +/*[clinic input] +_overlapped.FormatMessage + + error_code as code: DWORD + / + +Return error message for an error code. +[clinic start generated code]*/ static PyObject * -overlapped_FormatMessage(PyObject *ignore, PyObject *args) +_overlapped_FormatMessage_impl(PyObject *module, DWORD code) +/*[clinic end generated code: output=02c964ff22407c6b input=644bb5b80326179e]*/ { - DWORD code, n; + DWORD n; WCHAR *lpMsgBuf; PyObject *res; - if (!PyArg_ParseTuple(args, F_DWORD, &code)) - return NULL; - n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -538,19 +592,20 @@ mark_as_completed(OVERLAPPED *ov) * for overlapped I/O */ -PyDoc_STRVAR( - Overlapped_doc, - "Overlapped object"); +/*[clinic input] +@classmethod +_overlapped.Overlapped.__new__ + + event: HANDLE(c_default='INVALID_HANDLE_VALUE') = _overlapped.INVALID_HANDLE_VALUE + +OVERLAPPED structure wrapper. +[clinic start generated code]*/ static PyObject * -Overlapped_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event) +/*[clinic end generated code: output=6da60504a18eb421 input=26b8a7429e629e95]*/ { OverlappedObject *self; - HANDLE event = INVALID_HANDLE_VALUE; - static char *kwlist[] = {"event", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|" F_HANDLE, kwlist, &event)) - return NULL; if (event == INVALID_HANDLE_VALUE) { event = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -720,13 +775,15 @@ unparse_address(LPSOCKADDR Address, DWORD Length) } } -PyDoc_STRVAR( - Overlapped_cancel_doc, - "cancel() -> None\n\n" - "Cancel overlapped operation"); +/*[clinic input] +_overlapped.Overlapped.cancel + +Cancel overlapped operation. +[clinic start generated code]*/ static PyObject * -Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +_overlapped_Overlapped_cancel_impl(OverlappedObject *self) +/*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/ { BOOL ret = TRUE; @@ -749,25 +806,27 @@ Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -PyDoc_STRVAR( - Overlapped_getresult_doc, - "getresult(wait=False) -> result\n\n" - "Retrieve result of operation. If wait is true then it blocks\n" - "until the operation is finished. If wait is false and the\n" - "operation is still pending then an error is raised."); +/*[clinic input] +_overlapped.Overlapped.getresult + + wait: BOOL(c_default='FALSE') = False + / + +Retrieve result of operation. + +If wait is true then it blocks until the operation is finished. If wait +is false and the operation is still pending then an error is raised. +[clinic start generated code]*/ static PyObject * -Overlapped_getresult(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) +/*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/ { - BOOL wait = FALSE; DWORD transferred = 0; BOOL ret; DWORD err; PyObject *addr; - if (!PyArg_ParseTuple(args, "|" F_BOOL, &wait)) - return NULL; - if (self->type == TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation not yet attempted"); return NULL; @@ -879,21 +938,23 @@ do_ReadFile(OverlappedObject *self, HANDLE handle, } } -PyDoc_STRVAR( - Overlapped_ReadFile_doc, - "ReadFile(handle, size) -> Overlapped[message]\n\n" - "Start overlapped read"); +/*[clinic input] +_overlapped.Overlapped.ReadFile + + handle: HANDLE + size: DWORD + / + +Start overlapped read. +[clinic start generated code]*/ static PyObject * -Overlapped_ReadFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, + DWORD size) +/*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/ { - HANDLE handle; - DWORD size; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &handle, &size)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -913,20 +974,21 @@ Overlapped_ReadFile(OverlappedObject *self, PyObject *args) return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size); } -PyDoc_STRVAR( - Overlapped_ReadFileInto_doc, - "ReadFileInto(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.ReadFileInto -static PyObject * -Overlapped_ReadFileInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; + handle: HANDLE + buf as bufobj: object + / - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; +Start overlapped receive. +[clinic start generated code]*/ +static PyObject * +_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj) +/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ +{ if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -982,23 +1044,24 @@ do_WSARecv(OverlappedObject *self, HANDLE handle, } } -PyDoc_STRVAR( - Overlapped_WSARecv_doc, - "RecvFile(handle, size, flags) -> Overlapped[message]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecv + + handle: HANDLE + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ static PyObject * -Overlapped_WSARecv(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, + DWORD size, DWORD flags) +/*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/ { - HANDLE handle; - DWORD size; - DWORD flags = 0; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, - &handle, &size, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1018,22 +1081,23 @@ Overlapped_WSARecv(OverlappedObject *self, PyObject *args) return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags); } -PyDoc_STRVAR( - Overlapped_WSARecvInto_doc, - "WSARecvInto(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecvInto -static PyObject * -Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - DWORD flags; + handle: HANDLE + buf as bufobj: object + flags: DWORD + / - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; +Start overlapped receive. +[clinic start generated code]*/ +static PyObject * +_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, + HANDLE handle, PyObject *bufobj, + DWORD flags) +/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +{ if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1057,23 +1121,25 @@ Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) (DWORD)self->user_buffer.len, flags); } -PyDoc_STRVAR( - Overlapped_WriteFile_doc, - "WriteFile(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped write"); +/*[clinic input] +_overlapped.Overlapped.WriteFile + + handle: HANDLE + buf as bufobj: object + / + +Start overlapped write. +[clinic start generated code]*/ static PyObject * -Overlapped_WriteFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj) +/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ { - HANDLE handle; - PyObject *bufobj; DWORD written; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1110,26 +1176,27 @@ Overlapped_WriteFile(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_WSASend_doc, - "WSASend(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped send"); +/*[clinic input] +_overlapped.Overlapped.WSASend + + handle: HANDLE + buf as bufobj: object + flags: DWORD + / + +Start overlapped send. +[clinic start generated code]*/ static PyObject * -Overlapped_WSASend(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags) +/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ { - HANDLE handle; - PyObject *bufobj; - DWORD flags; DWORD written; WSABUF wsabuf; int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1167,26 +1234,28 @@ Overlapped_WSASend(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_AcceptEx_doc, - "AcceptEx(listen_handle, accept_handle) -> Overlapped[address_as_bytes]\n\n" - "Start overlapped wait for client to connect"); +/*[clinic input] +_overlapped.Overlapped.AcceptEx + + listen_handle as ListenSocket: HANDLE + accept_handle as AcceptSocket: HANDLE + / + +Start overlapped wait for client to connect. +[clinic start generated code]*/ static PyObject * -Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, + HANDLE ListenSocket, + HANDLE AcceptSocket) +/*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/ { - SOCKET ListenSocket; - SOCKET AcceptSocket; DWORD BytesReceived; DWORD size; PyObject *buf; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, - &ListenSocket, &AcceptSocket)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1198,12 +1267,13 @@ Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) return NULL; self->type = TYPE_ACCEPT; - self->handle = (HANDLE)ListenSocket; + self->handle = ListenSocket; self->allocated_buffer = buf; Py_BEGIN_ALLOW_THREADS - ret = Py_AcceptEx(ListenSocket, AcceptSocket, PyBytes_AS_STRING(buf), - 0, size, size, &BytesReceived, &self->overlapped); + ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket, + PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived, + &self->overlapped); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1257,28 +1327,30 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) return -1; } -PyDoc_STRVAR( - Overlapped_ConnectEx_doc, - "ConnectEx(client_handle, address_as_bytes) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); +/*[clinic input] +_overlapped.Overlapped.ConnectEx + + client_handle as ConnectSocket: HANDLE + address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type') + / + +Start overlapped connect. + +client_handle should be unbound. +[clinic start generated code]*/ static PyObject * -Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self, + HANDLE ConnectSocket, + PyObject *AddressObj) +/*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/ { - SOCKET ConnectSocket; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int Length; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O!:ConnectEx", - &ConnectSocket, &PyTuple_Type, &AddressObj)) - { - return NULL; - } - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1290,10 +1362,10 @@ Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) return NULL; self->type = TYPE_CONNECT; - self->handle = (HANDLE)ConnectSocket; + self->handle = ConnectSocket; Py_BEGIN_ALLOW_THREADS - ret = Py_ConnectEx(ConnectSocket, Address, Length, + ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length, NULL, 0, NULL, &self->overlapped); Py_END_ALLOW_THREADS @@ -1308,32 +1380,33 @@ Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_DisconnectEx_doc, - "DisconnectEx(handle, flags) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); +/*[clinic input] +_overlapped.Overlapped.DisconnectEx + + handle as Socket: HANDLE + flags: DWORD + / + +[clinic start generated code]*/ static PyObject * -Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self, + HANDLE Socket, DWORD flags) +/*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/ { - SOCKET Socket; - DWORD flags; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &Socket, &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } self->type = TYPE_DISCONNECT; - self->handle = (HANDLE)Socket; + self->handle = Socket; Py_BEGIN_ALLOW_THREADS - ret = Py_DisconnectEx(Socket, &self->overlapped, flags, 0); + ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1347,48 +1420,45 @@ Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_TransmitFile_doc, - "TransmitFile(socket, file, offset, offset_high, " - "count_to_write, count_per_send, flags) " - "-> Overlapped[None]\n\n" - "Transmit file data over a connected socket."); +/*[clinic input] +_overlapped.Overlapped.TransmitFile + + socket as Socket: HANDLE + file as File: HANDLE + offset: DWORD + offset_high: DWORD + count_to_write: DWORD + count_per_send: DWORD + flags: DWORD + / + +Transmit file data over a connected socket. +[clinic start generated code]*/ static PyObject * -Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self, + HANDLE Socket, HANDLE File, + DWORD offset, DWORD offset_high, + DWORD count_to_write, + DWORD count_per_send, DWORD flags) +/*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/ { - SOCKET Socket; - HANDLE File; - DWORD offset; - DWORD offset_high; - DWORD count_to_write; - DWORD count_per_send; - DWORD flags; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, - F_HANDLE F_HANDLE F_DWORD F_DWORD - F_DWORD F_DWORD F_DWORD, - &Socket, &File, &offset, &offset_high, - &count_to_write, &count_per_send, - &flags)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } self->type = TYPE_TRANSMIT_FILE; - self->handle = (HANDLE)Socket; + self->handle = Socket; self->overlapped.Offset = offset; self->overlapped.OffsetHigh = offset_high; Py_BEGIN_ALLOW_THREADS - ret = Py_TransmitFile(Socket, File, count_to_write, count_per_send, - &self->overlapped, - NULL, flags); + ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write, + count_per_send, &self->overlapped, NULL, flags); Py_END_ALLOW_THREADS self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); @@ -1402,21 +1472,23 @@ Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_ConnectNamedPipe_doc, - "ConnectNamedPipe(handle) -> Overlapped[None]\n\n" - "Start overlapped wait for a client to connect."); +/*[clinic input] +_overlapped.Overlapped.ConnectNamedPipe + + handle as Pipe: HANDLE + / + +Start overlapped wait for a client to connect. +[clinic start generated code]*/ static PyObject * -Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self, + HANDLE Pipe) +/*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/ { - HANDLE Pipe; BOOL ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE, &Pipe)) - return NULL; - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1443,25 +1515,22 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) } } -PyDoc_STRVAR( - ConnectPipe_doc, - "ConnectPipe(addr) -> pipe_handle\n\n" - "Connect to the pipe for asynchronous I/O (overlapped)."); +/*[clinic input] +_overlapped.Overlapped.ConnectPipe + + addr as Address: Py_UNICODE + / + +Connect to the pipe for asynchronous I/O (overlapped). +[clinic start generated code]*/ static PyObject * -overlapped_ConnectPipe(PyObject *self, PyObject *args) +_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self, + const Py_UNICODE *Address) +/*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/ { - PyObject *AddressObj; - wchar_t *Address; HANDLE PipeHandle; - if (!PyArg_ParseTuple(args, "U", &AddressObj)) - return NULL; - - Address = PyUnicode_AsWideCharString(AddressObj, NULL); - if (Address == NULL) - return NULL; - Py_BEGIN_ALLOW_THREADS PipeHandle = CreateFileW(Address, GENERIC_READ | GENERIC_WRITE, @@ -1469,7 +1538,6 @@ overlapped_ConnectPipe(PyObject *self, PyObject *args) FILE_FLAG_OVERLAPPED, NULL); Py_END_ALLOW_THREADS - PyMem_Free(Address); if (PipeHandle == INVALID_HANDLE_VALUE) return SetFromWindowsErr(0); return Py_BuildValue(F_HANDLE, PipeHandle); @@ -1512,29 +1580,31 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) // UDP functions -PyDoc_STRVAR( - WSAConnect_doc, - "WSAConnect(client_handle, address_as_bytes) -> Overlapped[None]\n\n" - "Bind a remote address to a connectionless (UDP) socket"); - /* * Note: WSAConnect does not support Overlapped I/O so this function should * _only_ be used for connectionless sockets (UDP). */ + +/*[clinic input] +_overlapped.WSAConnect + + client_handle as ConnectSocket: HANDLE + address_as_bytes as AddressObj: object + / + +Bind a remote address to a connectionless (UDP) socket. +[clinic start generated code]*/ + static PyObject * -overlapped_WSAConnect(PyObject *self, PyObject *args) +_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, + PyObject *AddressObj) +/*[clinic end generated code: output=ea0b4391e94dad63 input=169f8075e9ae7fa4]*/ { - SOCKET ConnectSocket; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int Length; int err; - if (!PyArg_ParseTuple(args, F_HANDLE "O", &ConnectSocket, &AddressObj)) { - return NULL; - } - Length = sizeof(AddressBuf); Length = parse_address(AddressObj, Address, Length); if (Length < 0) { @@ -1544,7 +1614,7 @@ overlapped_WSAConnect(PyObject *self, PyObject *args) Py_BEGIN_ALLOW_THREADS // WSAConnect does not support overlapped I/O so this call will // successfully complete immediately. - err = WSAConnect(ConnectSocket, Address, Length, + err = WSAConnect((SOCKET)ConnectSocket, Address, Length, NULL, NULL, NULL, NULL); Py_END_ALLOW_THREADS @@ -1556,19 +1626,24 @@ overlapped_WSAConnect(PyObject *self, PyObject *args) } } -PyDoc_STRVAR( - Overlapped_WSASendTo_doc, - "WSASendTo(handle, buf, flags, address_as_bytes) -> " - "Overlapped[bytes_transferred]\n\n" - "Start overlapped sendto over a connectionless (UDP) socket"); +/*[clinic input] +_overlapped.Overlapped.WSASendTo + + handle: HANDLE + buf as bufobj: object + flags: DWORD + address_as_bytes as AddressObj: object + / + +Start overlapped sendto over a connectionless (UDP) socket. +[clinic start generated code]*/ static PyObject * -Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, + PyObject *bufobj, DWORD flags, + PyObject *AddressObj) +/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ { - HANDLE handle; - PyObject *bufobj; - DWORD flags; - PyObject *AddressObj; char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; int AddressLength; @@ -1577,12 +1652,6 @@ Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD "O", - &handle, &bufobj, &flags, &AddressObj)) - { - return NULL; - } - // Parse the "to" address AddressLength = sizeof(AddressBuf); AddressLength = parse_address(AddressObj, Address, AddressLength); @@ -1637,24 +1706,29 @@ PyDoc_STRVAR( "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n" "Start overlapped receive"); +/*[clinic input] +_overlapped.Overlapped.WSARecvFrom + + handle: HANDLE + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ + static PyObject * -Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) +_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, + HANDLE handle, DWORD size, + DWORD flags) +/*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/ { - HANDLE handle; - DWORD size; - DWORD flags = 0; DWORD nread; PyObject *buf; WSABUF wsabuf; int ret; DWORD err; - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, - &handle, &size, &flags)) - { - return NULL; - } - if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; @@ -1700,38 +1774,24 @@ Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) } } +#include "clinic/overlapped.c.h" static PyMethodDef Overlapped_methods[] = { - {"getresult", (PyCFunction) Overlapped_getresult, - METH_VARARGS, Overlapped_getresult_doc}, - {"cancel", (PyCFunction) Overlapped_cancel, - METH_NOARGS, Overlapped_cancel_doc}, - {"ReadFile", (PyCFunction) Overlapped_ReadFile, - METH_VARARGS, Overlapped_ReadFile_doc}, - {"ReadFileInto", (PyCFunction) Overlapped_ReadFileInto, - METH_VARARGS, Overlapped_ReadFileInto_doc}, - {"WSARecv", (PyCFunction) Overlapped_WSARecv, - METH_VARARGS, Overlapped_WSARecv_doc}, - {"WSARecvInto", (PyCFunction) Overlapped_WSARecvInto, - METH_VARARGS, Overlapped_WSARecvInto_doc}, - {"WriteFile", (PyCFunction) Overlapped_WriteFile, - METH_VARARGS, Overlapped_WriteFile_doc}, - {"WSASend", (PyCFunction) Overlapped_WSASend, - METH_VARARGS, Overlapped_WSASend_doc}, - {"AcceptEx", (PyCFunction) Overlapped_AcceptEx, - METH_VARARGS, Overlapped_AcceptEx_doc}, - {"ConnectEx", (PyCFunction) Overlapped_ConnectEx, - METH_VARARGS, Overlapped_ConnectEx_doc}, - {"DisconnectEx", (PyCFunction) Overlapped_DisconnectEx, - METH_VARARGS, Overlapped_DisconnectEx_doc}, - {"TransmitFile", (PyCFunction) Overlapped_TransmitFile, - METH_VARARGS, Overlapped_TransmitFile_doc}, - {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, - METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, - {"WSARecvFrom", (PyCFunction) Overlapped_WSARecvFrom, - METH_VARARGS, Overlapped_WSARecvFrom_doc }, - {"WSASendTo", (PyCFunction) Overlapped_WSASendTo, - METH_VARARGS, Overlapped_WSASendTo_doc }, + _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF + _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF + _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF + _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF + _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF + _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF {NULL} }; @@ -1774,7 +1834,7 @@ PyTypeObject OverlappedType = { /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ "OVERLAPPED structure wrapper", + /* tp_doc */ _overlapped_Overlapped__doc__, /* tp_traverse */ (traverseproc)Overlapped_traverse, /* tp_clear */ 0, /* tp_richcompare */ 0, @@ -1791,36 +1851,23 @@ PyTypeObject OverlappedType = { /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, - /* tp_new */ Overlapped_new, + /* tp_new */ _overlapped_Overlapped, }; static PyMethodDef overlapped_functions[] = { - {"CreateIoCompletionPort", overlapped_CreateIoCompletionPort, - METH_VARARGS, CreateIoCompletionPort_doc}, - {"GetQueuedCompletionStatus", overlapped_GetQueuedCompletionStatus, - METH_VARARGS, GetQueuedCompletionStatus_doc}, - {"PostQueuedCompletionStatus", overlapped_PostQueuedCompletionStatus, - METH_VARARGS, PostQueuedCompletionStatus_doc}, - {"FormatMessage", overlapped_FormatMessage, - METH_VARARGS, FormatMessage_doc}, - {"BindLocal", overlapped_BindLocal, - METH_VARARGS, BindLocal_doc}, - {"RegisterWaitWithQueue", overlapped_RegisterWaitWithQueue, - METH_VARARGS, RegisterWaitWithQueue_doc}, - {"UnregisterWait", overlapped_UnregisterWait, - METH_VARARGS, UnregisterWait_doc}, - {"UnregisterWaitEx", overlapped_UnregisterWaitEx, - METH_VARARGS, UnregisterWaitEx_doc}, - {"CreateEvent", overlapped_CreateEvent, - METH_VARARGS, CreateEvent_doc}, - {"SetEvent", overlapped_SetEvent, - METH_VARARGS, SetEvent_doc}, - {"ResetEvent", overlapped_ResetEvent, - METH_VARARGS, ResetEvent_doc}, - {"ConnectPipe", overlapped_ConnectPipe, - METH_VARARGS, ConnectPipe_doc}, - {"WSAConnect", overlapped_WSAConnect, - METH_VARARGS, WSAConnect_doc}, + _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF + _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF + _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF + _OVERLAPPED_FORMATMESSAGE_METHODDEF + _OVERLAPPED_BINDLOCAL_METHODDEF + _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF + _OVERLAPPED_UNREGISTERWAIT_METHODDEF + _OVERLAPPED_UNREGISTERWAITEX_METHODDEF + _OVERLAPPED_CREATEEVENT_METHODDEF + _OVERLAPPED_SETEVENT_METHODDEF + _OVERLAPPED_RESETEVENT_METHODDEF + _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF + _OVERLAPPED_WSACONNECT_METHODDEF {NULL} }; From 14ade10bf3283c78eb824722a61ace0cc5cda7ff Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 10 Jul 2020 23:26:06 +0300 Subject: [PATCH 013/486] bpo-36346: Make using the legacy Unicode C API optional (GH-21437) Add compile time option USE_UNICODE_WCHAR_CACHE. Setting it to 0 makes the interpreter not using the wchar_t cache and the legacy Unicode C API. --- Include/cpython/unicodeobject.h | 4 +- Lib/test/support/__init__.py | 8 ++++ Lib/test/test_csv.py | 2 +- Lib/test/test_decimal.py | 5 +- Lib/test/test_getargs2.py | 4 ++ Lib/test/test_unicode.py | 4 ++ Modules/_io/fileio.c | 12 +++++ Modules/_testcapimodule.c | 16 ++++++- Modules/_winapi.c | 17 +++---- Modules/clinic/_winapi.c.h | 64 +++++++++++++++++++++----- Modules/overlapped.c | 64 ++++++++++++++++++++------ Modules/posixmodule.c | 70 ++++++++++++++++++++++++---- Objects/unicodeobject.c | 81 +++++++++++++++++++++++---------- PC/clinic/winreg.c.h | 14 +++--- PC/winreg.c | 61 +++++++++++++++++++------ Python/dynload_win.c | 10 +++- Python/fileutils.c | 23 ++++++++-- 17 files changed, 360 insertions(+), 99 deletions(-) diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 49ad32d5d199e15..615b4a971d5f47c 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -11,7 +11,9 @@ /* --- Internal Unicode Operations ---------------------------------------- */ -#define USE_UNICODE_WCHAR_CACHE 1 +#ifndef USE_UNICODE_WCHAR_CACHE +# define USE_UNICODE_WCHAR_CACHE 1 +#endif /* USE_UNICODE_WCHAR_CACHE */ /* Since splitting on whitespace is an important use case, and whitespace in most situations is solely ASCII whitespace, we diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index b21978a61cd2f12..1ce3a78fdbbe570 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -36,6 +36,11 @@ from .testresult import get_test_runner +try: + from _testcapi import unicode_legacy_string +except ImportError: + unicode_legacy_string = None + __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", @@ -426,6 +431,9 @@ def requires_lzma(reason='requires lzma'): lzma = None return unittest.skipUnless(lzma, reason) +requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, + 'requires legacy Unicode C API') + is_jython = sys.platform.startswith('java') is_android = hasattr(sys, 'getandroidapilevel') diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index d421be075ca27fb..a92870c24a1b456 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -250,9 +250,9 @@ def test_writerows_errors(self): self.assertRaises(OSError, writer.writerows, BadIterable()) @support.cpython_only + @support.requires_legacy_unicode_capi def test_writerows_legacy_strings(self): import _testcapi - c = _testcapi.unicode_legacy_string('a') with TemporaryFile("w+", newline='') as fileobj: writer = csv.writer(fileobj) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 716e6eb7fb127e2..9dbae449fb61d95 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -33,7 +33,8 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, - requires_IEEE_754, requires_docstrings) + requires_IEEE_754, requires_docstrings, + requires_legacy_unicode_capi) from test.support import (TestFailed, run_with_locale, cpython_only) from test.support.import_helper import import_fresh_module @@ -582,6 +583,7 @@ def test_explicit_from_string(self): self.assertRaises(InvalidOperation, Decimal, "1_2_\u00003") @cpython_only + @requires_legacy_unicode_capi def test_from_legacy_strings(self): import _testcapi Decimal = self.decimal.Decimal @@ -2817,6 +2819,7 @@ def test_none_args(self): Overflow]) @cpython_only + @requires_legacy_unicode_capi def test_from_legacy_strings(self): import _testcapi c = self.decimal.Context() diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index d39ea56ae9e9ca8..095601979130592 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -976,6 +976,7 @@ def test_et_hash(self): buf = bytearray() self.assertRaises(ValueError, getargs_et_hash, 'abc\xe9', 'latin1', buf) + @support.requires_legacy_unicode_capi def test_u(self): from _testcapi import getargs_u self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') @@ -985,6 +986,7 @@ def test_u(self): self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_u, None) + @support.requires_legacy_unicode_capi def test_u_hash(self): from _testcapi import getargs_u_hash self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9') @@ -994,6 +996,7 @@ def test_u_hash(self): self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_u_hash, None) + @support.requires_legacy_unicode_capi def test_Z(self): from _testcapi import getargs_Z self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') @@ -1003,6 +1006,7 @@ def test_Z(self): self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) self.assertIsNone(getargs_Z(None)) + @support.requires_legacy_unicode_capi def test_Z_hash(self): from _testcapi import getargs_Z_hash self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9') diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index afc95555db02699..d485bc7ede2b923 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -723,6 +723,7 @@ def test_isidentifier(self): self.assertFalse("0".isidentifier()) @support.cpython_only + @support.requires_legacy_unicode_capi def test_isidentifier_legacy(self): import _testcapi u = '𝖀𝖓𝖎𝖈𝖔𝖉𝖊' @@ -2350,6 +2351,7 @@ def test_getnewargs(self): self.assertEqual(len(args), 1) @support.cpython_only + @support.requires_legacy_unicode_capi def test_resize(self): from _testcapi import getargs_u for length in range(1, 100, 7): @@ -2920,6 +2922,7 @@ def test_copycharacters(self): self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0) @support.cpython_only + @support.requires_legacy_unicode_capi def test_encode_decimal(self): from _testcapi import unicode_encodedecimal self.assertEqual(unicode_encodedecimal('123'), @@ -2936,6 +2939,7 @@ def test_encode_decimal(self): unicode_encodedecimal, "123\u20ac", "replace") @support.cpython_only + @support.requires_legacy_unicode_capi def test_transform_decimal(self): from _testcapi import unicode_transformdecimaltoascii as transform_decimal self.assertEqual(transform_decimal('123'), diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 7c8ba37c4fe9409..b9856b3b6316570 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -270,7 +270,14 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { return -1; } +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS widename = PyUnicode_AsUnicode(stringobj); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + widename = PyUnicode_AsWideCharString(stringobj, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (widename == NULL) return -1; #else @@ -491,6 +498,11 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, internal_close(self); done: +#ifdef MS_WINDOWS +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(widename); +#endif /* USE_UNICODE_WCHAR_CACHE */ +#endif Py_CLEAR(stringobj); return ret; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 1e4c31fefb206f1..fca94a83a5d04ed 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1668,6 +1668,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) static volatile int x; +#if USE_UNICODE_WCHAR_CACHE /* Ignore use of deprecated APIs */ _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS @@ -1772,6 +1773,8 @@ test_Z_code(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_DECREF(tuple); Py_RETURN_NONE; } +_Py_COMP_DIAG_POP +#endif /* USE_UNICODE_WCHAR_CACHE */ static PyObject * test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) @@ -1824,6 +1827,10 @@ test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) return raiseTestError("test_widechar", "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); +#if USE_UNICODE_WCHAR_CACHE +/* Ignore use of deprecated APIs */ +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS wide = PyUnicode_FromUnicode(invalid, 1); if (wide == NULL) PyErr_Clear(); @@ -1844,11 +1851,12 @@ test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) return raiseTestError("test_widechar", "PyUnicode_Ready() didn't fail"); } +_Py_COMP_DIAG_POP +#endif /* USE_UNICODE_WCHAR_CACHE */ #endif Py_RETURN_NONE; } -_Py_COMP_DIAG_POP static PyObject * unicode_aswidechar(PyObject *self, PyObject *args) @@ -2024,6 +2032,7 @@ unicode_copycharacters(PyObject *self, PyObject *args) return Py_BuildValue("(Nn)", to_copy, copied); } +#if USE_UNICODE_WCHAR_CACHE /* Ignore use of deprecated APIs */ _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS @@ -2096,6 +2105,7 @@ unicode_legacy_string(PyObject *self, PyObject *args) return u; } _Py_COMP_DIAG_POP +#endif /* USE_UNICODE_WCHAR_CACHE */ static PyObject * getargs_w_star(PyObject *self, PyObject *args) @@ -5398,8 +5408,10 @@ static PyMethodDef TestMethods[] = { {"codec_incrementaldecoder", (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, {"test_s_code", test_s_code, METH_NOARGS}, +#if USE_UNICODE_WCHAR_CACHE {"test_u_code", test_u_code, METH_NOARGS}, {"test_Z_code", test_Z_code, METH_NOARGS}, +#endif /* USE_UNICODE_WCHAR_CACHE */ {"test_widechar", test_widechar, METH_NOARGS}, {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, @@ -5408,9 +5420,11 @@ static PyMethodDef TestMethods[] = { {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, {"unicode_findchar", unicode_findchar, METH_VARARGS}, {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, +#if USE_UNICODE_WCHAR_CACHE {"unicode_encodedecimal", unicode_encodedecimal, METH_VARARGS}, {"unicode_transformdecimaltoascii", unicode_transformdecimaltoascii, METH_VARARGS}, {"unicode_legacy_string", unicode_legacy_string, METH_VARARGS}, +#endif /* USE_UNICODE_WCHAR_CACHE */ {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, #ifdef HAVE_GETTIMEOFDAY diff --git a/Modules/_winapi.c b/Modules/_winapi.c index e1672c478522e87..ddb11aa5a820425 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -164,10 +164,11 @@ create_converter('LPCVOID', '" F_POINTER "') create_converter('BOOL', 'i') # F_BOOL used previously (always 'i') create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter) create_converter('LPCTSTR', 's') -create_converter('LPCWSTR', 'u') -create_converter('LPWSTR', 'u') create_converter('UINT', 'I') # F_UINT used previously (always 'I') +class LPCWSTR_converter(Py_UNICODE_converter): + type = 'LPCWSTR' + class HANDLE_return_converter(CReturnConverter): type = 'HANDLE' @@ -197,7 +198,7 @@ class LPVOID_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = HANDLE_TO_PYNUM(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=79464c61a31ae932]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=011ee0c3a2244bfe]*/ #include "clinic/_winapi.c.h" @@ -520,15 +521,15 @@ _winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, /*[clinic input] _winapi.CreateJunction - src_path: LPWSTR - dst_path: LPWSTR + src_path: LPCWSTR + dst_path: LPCWSTR / [clinic start generated code]*/ static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path) -/*[clinic end generated code: output=66b7eb746e1dfa25 input=8cd1f9964b6e3d36]*/ +_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, + LPCWSTR dst_path) +/*[clinic end generated code: output=44b3f5e9bbcc4271 input=963d29b44b9384a7]*/ { /* Privilege adjustment */ HANDLE token = NULL; diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 6022dfe0db4b28d..a9630d55998d3de 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -195,8 +195,8 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na LPCWSTR name; HANDLE _return_value; - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkku:CreateFileMapping", - &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, &name)) { + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkkO&:CreateFileMapping", + &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, _PyUnicode_WideCharString_Converter, &name)) { goto exit; } _return_value = _winapi_CreateFileMapping_impl(module, file_handle, security_attributes, protect, max_size_high, max_size_low, name); @@ -209,6 +209,11 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na return_value = HANDLE_TO_PYNUM(_return_value); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -221,23 +226,55 @@ PyDoc_STRVAR(_winapi_CreateJunction__doc__, {"CreateJunction", (PyCFunction)(void(*)(void))_winapi_CreateJunction, METH_FASTCALL, _winapi_CreateJunction__doc__}, static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path); +_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, + LPCWSTR dst_path); static PyObject * _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - LPWSTR src_path; - LPWSTR dst_path; + LPCWSTR src_path; + LPCWSTR dst_path; - if (!_PyArg_ParseStack(args, nargs, "uu:CreateJunction", - &src_path, &dst_path)) { + if (!_PyArg_CheckPositional("CreateJunction", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("CreateJunction", "argument 1", "str", args[0]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + src_path = _PyUnicode_AsUnicode(args[0]); + #else /* USE_UNICODE_WCHAR_CACHE */ + src_path = PyUnicode_AsWideCharString(args[0], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (src_path == NULL) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("CreateJunction", "argument 2", "str", args[1]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + dst_path = _PyUnicode_AsUnicode(args[1]); + #else /* USE_UNICODE_WCHAR_CACHE */ + dst_path = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (dst_path == NULL) { goto exit; } return_value = _winapi_CreateJunction_impl(module, src_path, dst_path); exit: + /* Cleanup for src_path */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)src_path); + #endif /* USE_UNICODE_WCHAR_CACHE */ + /* Cleanup for dst_path */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)dst_path); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -715,8 +752,8 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg LPCWSTR name; HANDLE _return_value; - if (!_PyArg_ParseStack(args, nargs, "kiu:OpenFileMapping", - &desired_access, &inherit_handle, &name)) { + if (!_PyArg_ParseStack(args, nargs, "kiO&:OpenFileMapping", + &desired_access, &inherit_handle, _PyUnicode_WideCharString_Converter, &name)) { goto exit; } _return_value = _winapi_OpenFileMapping_impl(module, desired_access, inherit_handle, name); @@ -729,6 +766,11 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg return_value = HANDLE_TO_PYNUM(_return_value); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1106,4 +1148,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=db87076a32fa7abe input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1f10e03f64ff9777 input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 9c4e2da9dfbd35b..4f0ba85d7983e00 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1291,6 +1291,7 @@ _overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, static int parse_address(PyObject *obj, SOCKADDR *Address, int Length) { + PyObject *Host_obj; Py_UNICODE *Host; unsigned short Port; unsigned long FlowInfo; @@ -1298,33 +1299,66 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) memset(Address, 0, Length); - if (PyArg_ParseTuple(obj, "uH", &Host, &Port)) - { + switch (PyTuple_GET_SIZE(obj)) { + case 2: { + if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) { + return -1; + } +#if USE_UNICODE_WCHAR_CACHE + Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); +#else /* USE_UNICODE_WCHAR_CACHE */ + Host = PyUnicode_AsWideCharString(Host_obj, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ + if (Host == NULL) { + return -1; + } Address->sa_family = AF_INET; if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); - return -1; + Length = -1; + } + else { + ((SOCKADDR_IN*)Address)->sin_port = htons(Port); } - ((SOCKADDR_IN*)Address)->sin_port = htons(Port); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(Host); +#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } - else if (PyArg_ParseTuple(obj, - "uHkk;ConnectEx(): illegal address_as_bytes " - "argument", &Host, &Port, &FlowInfo, &ScopeId)) - { - PyErr_Clear(); + case 4: { + if (!PyArg_ParseTuple(obj, + "UHkk;ConnectEx(): illegal address_as_bytes argument", + &Host_obj, &Port, &FlowInfo, &ScopeId)) + { + return -1; + } +#if USE_UNICODE_WCHAR_CACHE + Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); +#else /* USE_UNICODE_WCHAR_CACHE */ + Host = PyUnicode_AsWideCharString(Host_obj, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ + if (Host == NULL) { + return -1; + } Address->sa_family = AF_INET6; if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); - return -1; + Length = -1; + } + else { + ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); + ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; + ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; } - ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); - ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; - ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(Host); +#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } - - return -1; + default: + PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument"); + return -1; + } } /*[clinic input] diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a411f28987ee717..efd99544f5a9974 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -988,6 +988,11 @@ typedef struct { static void path_cleanup(path_t *path) { +#if !USE_UNICODE_WCHAR_CACHE + wchar_t *wide = (wchar_t *)path->wide; + path->wide = NULL; + PyMem_Free(wide); +#endif /* USE_UNICODE_WCHAR_CACHE */ Py_CLEAR(path->object); Py_CLEAR(path->cleanup); } @@ -1002,7 +1007,7 @@ path_converter(PyObject *o, void *p) const char *narrow; #ifdef MS_WINDOWS PyObject *wo = NULL; - const wchar_t *wide; + wchar_t *wide = NULL; #endif #define FORMAT_EXCEPTION(exc, fmt) \ @@ -1075,7 +1080,14 @@ path_converter(PyObject *o, void *p) if (is_unicode) { #ifdef MS_WINDOWS +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS wide = PyUnicode_AsUnicodeAndSize(o, &length); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + wide = PyUnicode_AsWideCharString(o, &length); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1091,6 +1103,9 @@ path_converter(PyObject *o, void *p) path->wide = wide; path->narrow = FALSE; path->fd = -1; +#if !USE_UNICODE_WCHAR_CACHE + wide = NULL; +#endif /* USE_UNICODE_WCHAR_CACHE */ goto success_exit; #else if (!PyUnicode_FSConverter(o, &bytes)) { @@ -1166,7 +1181,15 @@ path_converter(PyObject *o, void *p) goto error_exit; } +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS wide = PyUnicode_AsUnicodeAndSize(wo, &length); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + wide = PyUnicode_AsWideCharString(wo, &length); + Py_DECREF(wo); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1180,8 +1203,12 @@ path_converter(PyObject *o, void *p) } path->wide = wide; path->narrow = TRUE; - path->cleanup = wo; Py_DECREF(bytes); +#if USE_UNICODE_WCHAR_CACHE + path->cleanup = wo; +#else /* USE_UNICODE_WCHAR_CACHE */ + wide = NULL; +#endif /* USE_UNICODE_WCHAR_CACHE */ #else path->wide = NULL; path->narrow = narrow; @@ -1205,7 +1232,11 @@ path_converter(PyObject *o, void *p) Py_XDECREF(o); Py_XDECREF(bytes); #ifdef MS_WINDOWS +#if USE_UNICODE_WCHAR_CACHE Py_XDECREF(wo); +#else /* USE_UNICODE_WCHAR_CACHE */ + PyMem_Free(wide); +#endif /* USE_UNICODE_WCHAR_CACHE */ #endif return 0; } @@ -12824,7 +12855,15 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) #ifdef MS_WINDOWS if (!PyUnicode_FSDecoder(self->path, &ub)) return NULL; +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS const wchar_t *path = PyUnicode_AsUnicode(ub); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *path = PyUnicode_AsWideCharString(ub, NULL); + Py_DECREF(ub); +#endif /* USE_UNICODE_WCHAR_CACHE */ #else /* POSIX */ if (!PyUnicode_FSConverter(self->path, &ub)) return NULL; @@ -12834,6 +12873,7 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) result = fstatat(self->dir_fd, path, &st, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); #else + Py_DECREF(ub); PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat"); return NULL; #endif /* HAVE_FSTATAT */ @@ -12846,7 +12886,11 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) else result = LSTAT(path, &st); } +#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE + PyMem_Free(path); +#else /* USE_UNICODE_WCHAR_CACHE */ Py_DECREF(ub); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (result != 0) return path_object_error(self->path); @@ -13035,15 +13079,24 @@ os_DirEntry_inode_impl(DirEntry *self) #ifdef MS_WINDOWS if (!self->got_file_index) { PyObject *unicode; - const wchar_t *path; STRUCT_STAT stat; int result; if (!PyUnicode_FSDecoder(self->path, &unicode)) return NULL; - path = PyUnicode_AsUnicode(unicode); +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + const wchar_t *path = PyUnicode_AsUnicode(unicode); result = LSTAT(path, &stat); Py_DECREF(unicode); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL); + Py_DECREF(unicode); + result = LSTAT(path, &stat); + PyMem_Free(path); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (result != 0) return path_object_error(self->path); @@ -13597,10 +13650,9 @@ os_scandir_impl(PyObject *module, path_t *path) iterator->dirp = NULL; #endif - memcpy(&iterator->path, path, sizeof(path_t)); /* Move the ownership to iterator->path */ - path->object = NULL; - path->cleanup = NULL; + memcpy(&iterator->path, path, sizeof(path_t)); + memset(path, 0, sizeof(path_t)); #ifdef MS_WINDOWS iterator->first_time = 1; @@ -13622,9 +13674,9 @@ os_scandir_impl(PyObject *module, path_t *path) #else /* POSIX */ errno = 0; #ifdef HAVE_FDOPENDIR - if (path->fd != -1) { + if (iterator->path.fd != -1) { /* closedir() closes the FD, so we duplicate it */ - fd = _Py_dup(path->fd); + fd = _Py_dup(iterator->path.fd); if (fd == -1) goto error; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 648dd15ca09f588..2e1045ad3a7b6ed 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3150,9 +3150,11 @@ unicode_get_widechar_size(PyObject *unicode) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); +#if USE_UNICODE_WCHAR_CACHE if (_PyUnicode_WSTR(unicode) != NULL) { return PyUnicode_WSTR_LENGTH(unicode); } +#endif /* USE_UNICODE_WCHAR_CACHE */ assert(PyUnicode_IS_READY(unicode)); res = _PyUnicode_LENGTH(unicode); @@ -3173,16 +3175,21 @@ unicode_get_widechar_size(PyObject *unicode) static void unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) { - const wchar_t *wstr; - assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); - wstr = _PyUnicode_WSTR(unicode); +#if USE_UNICODE_WCHAR_CACHE + const wchar_t *wstr = _PyUnicode_WSTR(unicode); if (wstr != NULL) { memcpy(w, wstr, size * sizeof(wchar_t)); return; } +#else /* USE_UNICODE_WCHAR_CACHE */ + if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) { + memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t)); + return; + } +#endif /* USE_UNICODE_WCHAR_CACHE */ assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) { @@ -4378,7 +4385,6 @@ unicode_decode_call_errorhandler_wchar( Py_ssize_t requiredsize; Py_ssize_t newpos; PyObject *inputobj = NULL; - wchar_t *repwstr; Py_ssize_t repwlen; if (*errorHandler == NULL) { @@ -4424,9 +4430,19 @@ unicode_decode_call_errorhandler_wchar( goto onError; } - repwstr = PyUnicode_AsUnicodeAndSize(repunicode, &repwlen); - if (repwstr == NULL) +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + repwlen = PyUnicode_GetSize(repunicode); + if (repwlen < 0) + goto onError; +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + repwlen = PyUnicode_AsWideChar(repunicode, NULL, 0); + if (repwlen < 0) goto onError; + repwlen--; +#endif /* USE_UNICODE_WCHAR_CACHE */ /* need more space? (at least enough for what we have+the replacement+the rest of the string (starting at the new input position), so we won't have to check space @@ -4446,7 +4462,7 @@ unicode_decode_call_errorhandler_wchar( goto onError; } } - wcsncpy(*buf + *outpos, repwstr, repwlen); + PyUnicode_AsWideChar(repunicode, *buf + *outpos, repwlen); *outpos += repwlen; *endinpos = newpos; *inptr = *input + newpos; @@ -7748,6 +7764,7 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, /* Create a substring so that we can get the UTF-16 representation of just the slice under consideration. */ PyObject *substring; + int ret = -1; assert(len > 0); @@ -7759,11 +7776,22 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, substring = PyUnicode_Substring(unicode, offset, offset+len); if (substring == NULL) return -1; +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS p = PyUnicode_AsUnicodeAndSize(substring, &size); if (p == NULL) { Py_DECREF(substring); return -1; } +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + p = PyUnicode_AsWideCharString(substring, &size); + Py_CLEAR(substring); + if (p == NULL) { + return -1; + } +#endif /* USE_UNICODE_WCHAR_CACHE */ assert(size <= INT_MAX); /* First get the size of the result */ @@ -7775,16 +7803,15 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, goto error; /* If we used a default char, then we failed! */ if (pusedDefaultChar && *pusedDefaultChar) { - Py_DECREF(substring); - return -2; + ret = -2; + goto done; } if (*outbytes == NULL) { /* Create string object */ *outbytes = PyBytes_FromStringAndSize(NULL, outsize); if (*outbytes == NULL) { - Py_DECREF(substring); - return -1; + goto done; } out = PyBytes_AS_STRING(*outbytes); } @@ -7793,12 +7820,10 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, const Py_ssize_t n = PyBytes_Size(*outbytes); if (outsize > PY_SSIZE_T_MAX - n) { PyErr_NoMemory(); - Py_DECREF(substring); - return -1; + goto done; } if (_PyBytes_Resize(outbytes, n + outsize) < 0) { - Py_DECREF(substring); - return -1; + goto done; } out = PyBytes_AS_STRING(*outbytes) + n; } @@ -7808,19 +7833,29 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, p, (int)size, out, outsize, NULL, pusedDefaultChar); - Py_CLEAR(substring); if (outsize <= 0) goto error; - if (pusedDefaultChar && *pusedDefaultChar) - return -2; - return 0; + if (pusedDefaultChar && *pusedDefaultChar) { + ret = -2; + goto done; + } + ret = 0; + +done: +#if USE_UNICODE_WCHAR_CACHE + Py_DECREF(substring); +#else /* USE_UNICODE_WCHAR_CACHE */ + PyMem_Free(p); +#endif /* USE_UNICODE_WCHAR_CACHE */ + return ret; error: - Py_XDECREF(substring); - if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) - return -2; + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + ret = -2; + goto done; + } PyErr_SetFromWindowsErr(0); - return -1; + goto done; } /* diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 3301bed9713aa9a..183301f061866bc 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -1143,8 +1143,7 @@ PyDoc_STRVAR(winreg_SetValue__doc__, static PyObject * winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, - DWORD type, const Py_UNICODE *value, - Py_ssize_clean_t value_length); + DWORD type, PyObject *value_obj); static PyObject * winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) @@ -1153,14 +1152,13 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; DWORD type; - const Py_UNICODE *value; - Py_ssize_clean_t value_length; + PyObject *value_obj; - if (!_PyArg_ParseStack(args, nargs, "O&O&ku#:SetValue", - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value, &value_length)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&kU:SetValue", + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value_obj)) { goto exit; } - return_value = winreg_SetValue_impl(module, key, sub_key, type, value, value_length); + return_value = winreg_SetValue_impl(module, key, sub_key, type, value_obj); exit: /* Cleanup for sub_key */ @@ -1348,4 +1346,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=30b1311886c13907 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index b2725b857d0c227..a24d784c773c027 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -640,16 +640,25 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) for (j = 0; j < i; j++) { PyObject *t; - wchar_t *wstr; Py_ssize_t len; t = PyList_GET_ITEM(value, j); if (!PyUnicode_Check(t)) return FALSE; - wstr = PyUnicode_AsUnicodeAndSize(t, &len); - if (wstr == NULL) +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + len = PyUnicode_GetSize(t); + if (len < 0) return FALSE; - size += Py_SAFE_DOWNCAST((len + 1) * sizeof(wchar_t), + len++; +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + len = PyUnicode_AsWideChar(t, NULL, 0); + if (len < 0) + return FALSE; +#endif /* USE_UNICODE_WCHAR_CACHE */ + size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t), size_t, DWORD); } @@ -665,17 +674,18 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) for (j = 0; j < i; j++) { PyObject *t; - wchar_t *wstr; Py_ssize_t len; t = PyList_GET_ITEM(value, j); - wstr = PyUnicode_AsUnicodeAndSize(t, &len); - assert(wstr); - wcscpy(P, wstr); - P += (len + 1); + assert(size > 0); + len = PyUnicode_AsWideChar(t, P, size); + assert(len >= 0); + assert(len < size); + size -= (DWORD)len + 1; + P += len + 1; } /* And doubly-terminate the list... */ - *P = '\0'; + *P = L'\0'; break; } case REG_BINARY: @@ -1669,7 +1679,7 @@ winreg.SetValue type: DWORD An integer that specifies the type of the data. Currently this must be REG_SZ, meaning only strings are supported. - value: Py_UNICODE(zeroes=True) + value as value_obj: unicode A string that specifies the new value. / @@ -1688,30 +1698,51 @@ KEY_SET_VALUE access. static PyObject * winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, - DWORD type, const Py_UNICODE *value, - Py_ssize_clean_t value_length) -/*[clinic end generated code: output=686bedb1cbb4367b input=2cd2adab79339c53]*/ + DWORD type, PyObject *value_obj) +/*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/ { + Py_ssize_t value_length; long rc; if (type != REG_SZ) { PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ"); return NULL; } - if ((size_t)value_length >= PY_DWORD_MAX) { + +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + const wchar_t *value = PyUnicode_AsUnicodeAndSize(value_obj, &value_length); +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *value = PyUnicode_AsWideCharString(value_obj, &value_length); +#endif /* USE_UNICODE_WCHAR_CACHE */ + if (value == NULL) { + return NULL; + } + if ((Py_ssize_t)(DWORD)value_length != value_length) { PyErr_SetString(PyExc_OverflowError, "value is too long"); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(value); +#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } if (PySys_Audit("winreg.SetValue", "nunu#", (Py_ssize_t)key, sub_key, (Py_ssize_t)type, value, value_length) < 0) { +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(value); +#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } Py_BEGIN_ALLOW_THREADS rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1)); Py_END_ALLOW_THREADS +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(value); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); Py_RETURN_NONE; diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 8431c5b3b2f308e..5702ab2cd71ba12 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -166,11 +166,14 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { dl_funcptr p; char funcname[258], *import_python; - const wchar_t *wpathname; _Py_CheckPython3(); - wpathname = _PyUnicode_AsUnicode(pathname); +#if USE_UNICODE_WCHAR_CACHE + const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *wpathname = PyUnicode_AsWideCharString(pathname, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpathname == NULL) return NULL; @@ -192,6 +195,9 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); Py_END_ALLOW_THREADS +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpathname); +#endif /* USE_UNICODE_WCHAR_CACHE */ /* restore old error mode settings */ SetErrorMode(old_mode); diff --git a/Python/fileutils.c b/Python/fileutils.c index 2c86828ba989acd..50ef3c174acc844 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1008,15 +1008,21 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; struct _stat wstatbuf; - const wchar_t *wpath; - wpath = _PyUnicode_AsUnicode(path); +#if USE_UNICODE_WCHAR_CACHE + const wchar_t *wpath = _PyUnicode_AsUnicode(path); +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return -2; err = _wstat(wpath, &wstatbuf); if (!err) statbuf->st_mode = wstatbuf.st_mode; +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpath); +#endif /* USE_UNICODE_WCHAR_CACHE */ return err; #else int ret; @@ -1433,7 +1439,6 @@ _Py_fopen_obj(PyObject *path, const char *mode) FILE *f; int async_err = 0; #ifdef MS_WINDOWS - const wchar_t *wpath; wchar_t wmode[10]; int usize; @@ -1448,7 +1453,11 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } - wpath = _PyUnicode_AsUnicode(path); +#if USE_UNICODE_WCHAR_CACHE + const wchar_t *wpath = _PyUnicode_AsUnicode(path); +#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); +#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return NULL; @@ -1456,6 +1465,9 @@ _Py_fopen_obj(PyObject *path, const char *mode) wmode, Py_ARRAY_LENGTH(wmode)); if (usize == 0) { PyErr_SetFromWindowsErr(0); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpath); +#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } @@ -1465,6 +1477,9 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(wpath); +#endif /* USE_UNICODE_WCHAR_CACHE */ #else PyObject *bytes; const char *path_bytes; From 27091d87e6afc08229071dcab27f54339aeb2a87 Mon Sep 17 00:00:00 2001 From: Nima Dini Date: Fri, 10 Jul 2020 18:54:53 -0700 Subject: [PATCH 014/486] bpo-41228: Fix /a/are/ in monthcalendar() descripton (GH-21372) --- Doc/library/calendar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 56b75ef0f850a67..c3c04db853ed2d4 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -349,7 +349,7 @@ For simple text calendars this module provides the following functions. .. function:: monthcalendar(year, month) Returns a matrix representing a month's calendar. Each row represents a week; - days outside of the month a represented by zeros. Each week begins with Monday + days outside of the month are represented by zeros. Each week begins with Monday unless set by :func:`setfirstweekday`. From 3f6347714accf6708b3d4e3522da4bab2784645e Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Sat, 11 Jul 2020 19:18:31 -0400 Subject: [PATCH 015/486] Fix error in docstrings in bisect module (GH-21422) The docstrings for `bisect_right()` and `bisect_left()` contain sample code that has a bug: `a.insert(x)` should be `a.insert(i, x)`. --- Lib/bisect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/bisect.py b/Lib/bisect.py index 8f3f6a3fe35ffea..8336a4ed9ca0f8d 100644 --- a/Lib/bisect.py +++ b/Lib/bisect.py @@ -16,7 +16,7 @@ def bisect_right(a, x, lo=0, hi=None): """Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e <= x, and all e in - a[i:] have e > x. So if x already appears in the list, a.insert(x) will + a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will insert just after the rightmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the @@ -51,7 +51,7 @@ def bisect_left(a, x, lo=0, hi=None): """Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e < x, and all e in - a[i:] have e >= x. So if x already appears in the list, a.insert(x) will + a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will insert just before the leftmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the From 8be2233b226423114662160ca409bdea78343065 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 12 Jul 2020 10:01:03 -0600 Subject: [PATCH 016/486] bpo-20181: Convert the readline module to the Argument Clinic (#14326) --- Modules/clinic/readline.c.h | 686 ++++++++++++++++++++++++++++++++++++ Modules/readline.c | 583 +++++++++++++++++------------- 2 files changed, 1022 insertions(+), 247 deletions(-) create mode 100644 Modules/clinic/readline.c.h diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h new file mode 100644 index 000000000000000..80207caf0711002 --- /dev/null +++ b/Modules/clinic/readline.c.h @@ -0,0 +1,686 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(readline_parse_and_bind__doc__, +"parse_and_bind($module, string, /)\n" +"--\n" +"\n" +"Execute the init line provided in the string argument."); + +#define READLINE_PARSE_AND_BIND_METHODDEF \ + {"parse_and_bind", (PyCFunction)readline_parse_and_bind, METH_O, readline_parse_and_bind__doc__}, + +PyDoc_STRVAR(readline_read_init_file__doc__, +"read_init_file($module, filename=None, /)\n" +"--\n" +"\n" +"Execute a readline initialization file.\n" +"\n" +"The default filename is the last filename used."); + +#define READLINE_READ_INIT_FILE_METHODDEF \ + {"read_init_file", (PyCFunction)(void(*)(void))readline_read_init_file, METH_FASTCALL, readline_read_init_file__doc__}, + +static PyObject * +readline_read_init_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_read_init_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("read_init_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_read_init_file_impl(module, filename_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_read_history_file__doc__, +"read_history_file($module, filename=None, /)\n" +"--\n" +"\n" +"Load a readline history file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_READ_HISTORY_FILE_METHODDEF \ + {"read_history_file", (PyCFunction)(void(*)(void))readline_read_history_file, METH_FASTCALL, readline_read_history_file__doc__}, + +static PyObject * +readline_read_history_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_read_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("read_history_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_read_history_file_impl(module, filename_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_write_history_file__doc__, +"write_history_file($module, filename=None, /)\n" +"--\n" +"\n" +"Save a readline history file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_WRITE_HISTORY_FILE_METHODDEF \ + {"write_history_file", (PyCFunction)(void(*)(void))readline_write_history_file, METH_FASTCALL, readline_write_history_file__doc__}, + +static PyObject * +readline_write_history_file_impl(PyObject *module, PyObject *filename_obj); + +static PyObject * +readline_write_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("write_history_file", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + filename_obj = args[0]; +skip_optional: + return_value = readline_write_history_file_impl(module, filename_obj); + +exit: + return return_value; +} + +#if defined(HAVE_RL_APPEND_HISTORY) + +PyDoc_STRVAR(readline_append_history_file__doc__, +"append_history_file($module, nelements, filename=None, /)\n" +"--\n" +"\n" +"Append the last nelements items of the history list to file.\n" +"\n" +"The default filename is ~/.history."); + +#define READLINE_APPEND_HISTORY_FILE_METHODDEF \ + {"append_history_file", (PyCFunction)(void(*)(void))readline_append_history_file, METH_FASTCALL, readline_append_history_file__doc__}, + +static PyObject * +readline_append_history_file_impl(PyObject *module, int nelements, + PyObject *filename_obj); + +static PyObject * +readline_append_history_file(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nelements; + PyObject *filename_obj = Py_None; + + if (!_PyArg_CheckPositional("append_history_file", nargs, 1, 2)) { + goto exit; + } + nelements = _PyLong_AsInt(args[0]); + if (nelements == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + filename_obj = args[1]; +skip_optional: + return_value = readline_append_history_file_impl(module, nelements, filename_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RL_APPEND_HISTORY) */ + +PyDoc_STRVAR(readline_set_history_length__doc__, +"set_history_length($module, length, /)\n" +"--\n" +"\n" +"Set the maximal number of lines which will be written to the history file.\n" +"\n" +"A negative length is used to inhibit history truncation."); + +#define READLINE_SET_HISTORY_LENGTH_METHODDEF \ + {"set_history_length", (PyCFunction)readline_set_history_length, METH_O, readline_set_history_length__doc__}, + +static PyObject * +readline_set_history_length_impl(PyObject *module, int length); + +static PyObject * +readline_set_history_length(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int length; + + length = _PyLong_AsInt(arg); + if (length == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_set_history_length_impl(module, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_history_length__doc__, +"get_history_length($module, /)\n" +"--\n" +"\n" +"Return the maximum number of lines that will be written to the history file."); + +#define READLINE_GET_HISTORY_LENGTH_METHODDEF \ + {"get_history_length", (PyCFunction)readline_get_history_length, METH_NOARGS, readline_get_history_length__doc__}, + +static PyObject * +readline_get_history_length_impl(PyObject *module); + +static PyObject * +readline_get_history_length(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_history_length_impl(module); +} + +PyDoc_STRVAR(readline_set_completion_display_matches_hook__doc__, +"set_completion_display_matches_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the completion display function.\n" +"\n" +"The function is called as\n" +" function(substitution, [matches], longest_match_length)\n" +"once each time matches need to be displayed."); + +#define READLINE_SET_COMPLETION_DISPLAY_MATCHES_HOOK_METHODDEF \ + {"set_completion_display_matches_hook", (PyCFunction)(void(*)(void))readline_set_completion_display_matches_hook, METH_FASTCALL, readline_set_completion_display_matches_hook__doc__}, + +static PyObject * +readline_set_completion_display_matches_hook_impl(PyObject *module, + PyObject *function); + +static PyObject * +readline_set_completion_display_matches_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_completion_display_matches_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_completion_display_matches_hook_impl(module, function); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_set_startup_hook__doc__, +"set_startup_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the function invoked by the rl_startup_hook callback.\n" +"\n" +"The function is called with no arguments just\n" +"before readline prints the first prompt."); + +#define READLINE_SET_STARTUP_HOOK_METHODDEF \ + {"set_startup_hook", (PyCFunction)(void(*)(void))readline_set_startup_hook, METH_FASTCALL, readline_set_startup_hook__doc__}, + +static PyObject * +readline_set_startup_hook_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_startup_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_startup_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_startup_hook_impl(module, function); + +exit: + return return_value; +} + +#if defined(HAVE_RL_PRE_INPUT_HOOK) + +PyDoc_STRVAR(readline_set_pre_input_hook__doc__, +"set_pre_input_hook($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the function invoked by the rl_pre_input_hook callback.\n" +"\n" +"The function is called with no arguments after the first prompt\n" +"has been printed and just before readline starts reading input\n" +"characters."); + +#define READLINE_SET_PRE_INPUT_HOOK_METHODDEF \ + {"set_pre_input_hook", (PyCFunction)(void(*)(void))readline_set_pre_input_hook, METH_FASTCALL, readline_set_pre_input_hook__doc__}, + +static PyObject * +readline_set_pre_input_hook_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_pre_input_hook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_pre_input_hook", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_pre_input_hook_impl(module, function); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RL_PRE_INPUT_HOOK) */ + +PyDoc_STRVAR(readline_get_completion_type__doc__, +"get_completion_type($module, /)\n" +"--\n" +"\n" +"Get the type of completion being attempted."); + +#define READLINE_GET_COMPLETION_TYPE_METHODDEF \ + {"get_completion_type", (PyCFunction)readline_get_completion_type, METH_NOARGS, readline_get_completion_type__doc__}, + +static PyObject * +readline_get_completion_type_impl(PyObject *module); + +static PyObject * +readline_get_completion_type(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completion_type_impl(module); +} + +PyDoc_STRVAR(readline_get_begidx__doc__, +"get_begidx($module, /)\n" +"--\n" +"\n" +"Get the beginning index of the completion scope."); + +#define READLINE_GET_BEGIDX_METHODDEF \ + {"get_begidx", (PyCFunction)readline_get_begidx, METH_NOARGS, readline_get_begidx__doc__}, + +static PyObject * +readline_get_begidx_impl(PyObject *module); + +static PyObject * +readline_get_begidx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_begidx_impl(module); +} + +PyDoc_STRVAR(readline_get_endidx__doc__, +"get_endidx($module, /)\n" +"--\n" +"\n" +"Get the ending index of the completion scope."); + +#define READLINE_GET_ENDIDX_METHODDEF \ + {"get_endidx", (PyCFunction)readline_get_endidx, METH_NOARGS, readline_get_endidx__doc__}, + +static PyObject * +readline_get_endidx_impl(PyObject *module); + +static PyObject * +readline_get_endidx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_endidx_impl(module); +} + +PyDoc_STRVAR(readline_set_completer_delims__doc__, +"set_completer_delims($module, string, /)\n" +"--\n" +"\n" +"Set the word delimiters for completion."); + +#define READLINE_SET_COMPLETER_DELIMS_METHODDEF \ + {"set_completer_delims", (PyCFunction)readline_set_completer_delims, METH_O, readline_set_completer_delims__doc__}, + +PyDoc_STRVAR(readline_remove_history_item__doc__, +"remove_history_item($module, pos, /)\n" +"--\n" +"\n" +"Remove history item given by its position."); + +#define READLINE_REMOVE_HISTORY_ITEM_METHODDEF \ + {"remove_history_item", (PyCFunction)readline_remove_history_item, METH_O, readline_remove_history_item__doc__}, + +static PyObject * +readline_remove_history_item_impl(PyObject *module, int entry_number); + +static PyObject * +readline_remove_history_item(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int entry_number; + + entry_number = _PyLong_AsInt(arg); + if (entry_number == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_remove_history_item_impl(module, entry_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_replace_history_item__doc__, +"replace_history_item($module, pos, line, /)\n" +"--\n" +"\n" +"Replaces history item given by its position with contents of line."); + +#define READLINE_REPLACE_HISTORY_ITEM_METHODDEF \ + {"replace_history_item", (PyCFunction)(void(*)(void))readline_replace_history_item, METH_FASTCALL, readline_replace_history_item__doc__}, + +static PyObject * +readline_replace_history_item_impl(PyObject *module, int entry_number, + PyObject *line); + +static PyObject * +readline_replace_history_item(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int entry_number; + PyObject *line; + + if (!_PyArg_CheckPositional("replace_history_item", nargs, 2, 2)) { + goto exit; + } + entry_number = _PyLong_AsInt(args[0]); + if (entry_number == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("replace_history_item", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + line = args[1]; + return_value = readline_replace_history_item_impl(module, entry_number, line); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_add_history__doc__, +"add_history($module, string, /)\n" +"--\n" +"\n" +"Add an item to the history buffer."); + +#define READLINE_ADD_HISTORY_METHODDEF \ + {"add_history", (PyCFunction)readline_add_history, METH_O, readline_add_history__doc__}, + +PyDoc_STRVAR(readline_set_auto_history__doc__, +"set_auto_history($module, enabled, /)\n" +"--\n" +"\n" +"Enables or disables automatic history."); + +#define READLINE_SET_AUTO_HISTORY_METHODDEF \ + {"set_auto_history", (PyCFunction)readline_set_auto_history, METH_O, readline_set_auto_history__doc__}, + +static PyObject * +readline_set_auto_history_impl(PyObject *module, + int _should_auto_add_history); + +static PyObject * +readline_set_auto_history(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int _should_auto_add_history; + + _should_auto_add_history = PyObject_IsTrue(arg); + if (_should_auto_add_history < 0) { + goto exit; + } + return_value = readline_set_auto_history_impl(module, _should_auto_add_history); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_completer_delims__doc__, +"get_completer_delims($module, /)\n" +"--\n" +"\n" +"Get the word delimiters for completion."); + +#define READLINE_GET_COMPLETER_DELIMS_METHODDEF \ + {"get_completer_delims", (PyCFunction)readline_get_completer_delims, METH_NOARGS, readline_get_completer_delims__doc__}, + +static PyObject * +readline_get_completer_delims_impl(PyObject *module); + +static PyObject * +readline_get_completer_delims(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completer_delims_impl(module); +} + +PyDoc_STRVAR(readline_set_completer__doc__, +"set_completer($module, function=None, /)\n" +"--\n" +"\n" +"Set or remove the completer function.\n" +"\n" +"The function is called as function(text, state),\n" +"for state in 0, 1, 2, ..., until it returns a non-string.\n" +"It should return the next possible completion starting with \'text\'."); + +#define READLINE_SET_COMPLETER_METHODDEF \ + {"set_completer", (PyCFunction)(void(*)(void))readline_set_completer, METH_FASTCALL, readline_set_completer__doc__}, + +static PyObject * +readline_set_completer_impl(PyObject *module, PyObject *function); + +static PyObject * +readline_set_completer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *function = Py_None; + + if (!_PyArg_CheckPositional("set_completer", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + function = args[0]; +skip_optional: + return_value = readline_set_completer_impl(module, function); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_completer__doc__, +"get_completer($module, /)\n" +"--\n" +"\n" +"Get the current completer function."); + +#define READLINE_GET_COMPLETER_METHODDEF \ + {"get_completer", (PyCFunction)readline_get_completer, METH_NOARGS, readline_get_completer__doc__}, + +static PyObject * +readline_get_completer_impl(PyObject *module); + +static PyObject * +readline_get_completer(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_completer_impl(module); +} + +PyDoc_STRVAR(readline_get_history_item__doc__, +"get_history_item($module, index, /)\n" +"--\n" +"\n" +"Return the current contents of history item at index."); + +#define READLINE_GET_HISTORY_ITEM_METHODDEF \ + {"get_history_item", (PyCFunction)readline_get_history_item, METH_O, readline_get_history_item__doc__}, + +static PyObject * +readline_get_history_item_impl(PyObject *module, int idx); + +static PyObject * +readline_get_history_item(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int idx; + + idx = _PyLong_AsInt(arg); + if (idx == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = readline_get_history_item_impl(module, idx); + +exit: + return return_value; +} + +PyDoc_STRVAR(readline_get_current_history_length__doc__, +"get_current_history_length($module, /)\n" +"--\n" +"\n" +"Return the current (not the maximum) length of history."); + +#define READLINE_GET_CURRENT_HISTORY_LENGTH_METHODDEF \ + {"get_current_history_length", (PyCFunction)readline_get_current_history_length, METH_NOARGS, readline_get_current_history_length__doc__}, + +static PyObject * +readline_get_current_history_length_impl(PyObject *module); + +static PyObject * +readline_get_current_history_length(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_current_history_length_impl(module); +} + +PyDoc_STRVAR(readline_get_line_buffer__doc__, +"get_line_buffer($module, /)\n" +"--\n" +"\n" +"Return the current contents of the line buffer."); + +#define READLINE_GET_LINE_BUFFER_METHODDEF \ + {"get_line_buffer", (PyCFunction)readline_get_line_buffer, METH_NOARGS, readline_get_line_buffer__doc__}, + +static PyObject * +readline_get_line_buffer_impl(PyObject *module); + +static PyObject * +readline_get_line_buffer(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_get_line_buffer_impl(module); +} + +#if defined(HAVE_RL_COMPLETION_APPEND_CHARACTER) + +PyDoc_STRVAR(readline_clear_history__doc__, +"clear_history($module, /)\n" +"--\n" +"\n" +"Clear the current readline history."); + +#define READLINE_CLEAR_HISTORY_METHODDEF \ + {"clear_history", (PyCFunction)readline_clear_history, METH_NOARGS, readline_clear_history__doc__}, + +static PyObject * +readline_clear_history_impl(PyObject *module); + +static PyObject * +readline_clear_history(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_clear_history_impl(module); +} + +#endif /* defined(HAVE_RL_COMPLETION_APPEND_CHARACTER) */ + +PyDoc_STRVAR(readline_insert_text__doc__, +"insert_text($module, string, /)\n" +"--\n" +"\n" +"Insert text into the line buffer at the cursor position."); + +#define READLINE_INSERT_TEXT_METHODDEF \ + {"insert_text", (PyCFunction)readline_insert_text, METH_O, readline_insert_text__doc__}, + +PyDoc_STRVAR(readline_redisplay__doc__, +"redisplay($module, /)\n" +"--\n" +"\n" +"Change what\'s displayed on the screen to reflect contents of the line buffer."); + +#define READLINE_REDISPLAY_METHODDEF \ + {"redisplay", (PyCFunction)readline_redisplay, METH_NOARGS, readline_redisplay__doc__}, + +static PyObject * +readline_redisplay_impl(PyObject *module); + +static PyObject * +readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return readline_redisplay_impl(module); +} + +#ifndef READLINE_APPEND_HISTORY_FILE_METHODDEF + #define READLINE_APPEND_HISTORY_FILE_METHODDEF +#endif /* !defined(READLINE_APPEND_HISTORY_FILE_METHODDEF) */ + +#ifndef READLINE_SET_PRE_INPUT_HOOK_METHODDEF + #define READLINE_SET_PRE_INPUT_HOOK_METHODDEF +#endif /* !defined(READLINE_SET_PRE_INPUT_HOOK_METHODDEF) */ + +#ifndef READLINE_CLEAR_HISTORY_METHODDEF + #define READLINE_CLEAR_HISTORY_METHODDEF +#endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ +/*[clinic end generated code: output=cb44f391ccbfb565 input=a9049054013a1b77]*/ diff --git a/Modules/readline.c b/Modules/readline.c index 12d6cc78e38a774..bbab0f882e3f163 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -94,6 +94,11 @@ get_readline_state(PyObject *module) return (readlinestate *)state; } +/*[clinic input] +module readline +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad49da781b9c8721]*/ + static int readline_clear(PyObject *m) { @@ -148,8 +153,18 @@ decode(const char *s) /* Exported function to send one line to readline's init file parser */ +/*[clinic input] +readline.parse_and_bind + + string: object + / + +Execute the init line provided in the string argument. +[clinic start generated code]*/ + static PyObject * -parse_and_bind(PyObject *self, PyObject *string) +readline_parse_and_bind(PyObject *module, PyObject *string) +/*[clinic end generated code: output=1a1ede8afb9546c1 input=8a28a00bb4d61eec]*/ { char *copy; PyObject *encoded = encode(string); @@ -170,23 +185,28 @@ parse_and_bind(PyObject *self, PyObject *string) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_parse_and_bind, -"parse_and_bind(string) -> None\n\ -Execute the init line provided in the string argument."); +/* Exported function to parse a readline init file */ +/*[clinic input] +readline.read_init_file -/* Exported function to parse a readline init file */ + filename as filename_obj: object = None + / + +Execute a readline initialization file. + +The default filename is the last filename used. +[clinic start generated code]*/ static PyObject * -read_init_file(PyObject *self, PyObject *args) +readline_read_init_file_impl(PyObject *module, PyObject *filename_obj) +/*[clinic end generated code: output=8e059b676142831e input=4c80c473e448139d]*/ { - PyObject *filename_obj = Py_None, *filename_bytes; - if (!PyArg_ParseTuple(args, "|O:read_init_file", &filename_obj)) - return NULL; + PyObject *filename_bytes; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; - errno = rl_read_init_file(PyBytes_AsString(filename_bytes)); + errno = rl_read_init_file(PyBytes_AS_STRING(filename_bytes)); Py_DECREF(filename_bytes); } else errno = rl_read_init_file(NULL); @@ -195,24 +215,28 @@ read_init_file(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_read_init_file, -"read_init_file([filename]) -> None\n\ -Execute a readline initialization file.\n\ -The default filename is the last filename used."); +/* Exported function to load a readline history file */ +/*[clinic input] +readline.read_history_file -/* Exported function to load a readline history file */ + filename as filename_obj: object = None + / + +Load a readline history file. + +The default filename is ~/.history. +[clinic start generated code]*/ static PyObject * -read_history_file(PyObject *self, PyObject *args) +readline_read_history_file_impl(PyObject *module, PyObject *filename_obj) +/*[clinic end generated code: output=66a951836fb54fbb input=3d29d755b7e6932e]*/ { - PyObject *filename_obj = Py_None, *filename_bytes; - if (!PyArg_ParseTuple(args, "|O:read_history_file", &filename_obj)) - return NULL; + PyObject *filename_bytes; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; - errno = read_history(PyBytes_AsString(filename_bytes)); + errno = read_history(PyBytes_AS_STRING(filename_bytes)); Py_DECREF(filename_bytes); } else errno = read_history(NULL); @@ -222,26 +246,31 @@ read_history_file(PyObject *self, PyObject *args) } static int _history_length = -1; /* do not truncate history by default */ -PyDoc_STRVAR(doc_read_history_file, -"read_history_file([filename]) -> None\n\ -Load a readline history file.\n\ -The default filename is ~/.history."); - /* Exported function to save a readline history file */ +/*[clinic input] +readline.write_history_file + + filename as filename_obj: object = None + / + +Save a readline history file. + +The default filename is ~/.history. +[clinic start generated code]*/ + static PyObject * -write_history_file(PyObject *self, PyObject *args) +readline_write_history_file_impl(PyObject *module, PyObject *filename_obj) +/*[clinic end generated code: output=fbcad13d8ef59ae6 input=28a8e062fe363703]*/ { - PyObject *filename_obj = Py_None, *filename_bytes; + PyObject *filename_bytes; const char *filename; int err; - if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj)) - return NULL; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; - filename = PyBytes_AsString(filename_bytes); + filename = PyBytes_AS_STRING(filename_bytes); } else { filename_bytes = NULL; filename = NULL; @@ -256,28 +285,33 @@ write_history_file(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_write_history_file, -"write_history_file([filename]) -> None\n\ -Save a readline history file.\n\ -The default filename is ~/.history."); - - #ifdef HAVE_RL_APPEND_HISTORY /* Exported function to save part of a readline history file */ +/*[clinic input] +readline.append_history_file + + nelements: int + filename as filename_obj: object = None + / + +Append the last nelements items of the history list to file. + +The default filename is ~/.history. +[clinic start generated code]*/ + static PyObject * -append_history_file(PyObject *self, PyObject *args) +readline_append_history_file_impl(PyObject *module, int nelements, + PyObject *filename_obj) +/*[clinic end generated code: output=5df06fc9da56e4e4 input=784b774db3a4b7c5]*/ { - int nelements; - PyObject *filename_obj = Py_None, *filename_bytes; + PyObject *filename_bytes; const char *filename; int err; - if (!PyArg_ParseTuple(args, "i|O:append_history_file", &nelements, &filename_obj)) - return NULL; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; - filename = PyBytes_AsString(filename_bytes); + filename = PyBytes_AS_STRING(filename_bytes); } else { filename_bytes = NULL; filename = NULL; @@ -291,57 +325,50 @@ append_history_file(PyObject *self, PyObject *args) return PyErr_SetFromErrno(PyExc_OSError); Py_RETURN_NONE; } - -PyDoc_STRVAR(doc_append_history_file, -"append_history_file(nelements[, filename]) -> None\n\ -Append the last nelements items of the history list to file.\n\ -The default filename is ~/.history."); #endif /* Set history length */ -static PyObject* -set_history_length(PyObject *self, PyObject *args) +/*[clinic input] +readline.set_history_length + + length: int + / + +Set the maximal number of lines which will be written to the history file. + +A negative length is used to inhibit history truncation. +[clinic start generated code]*/ + +static PyObject * +readline_set_history_length_impl(PyObject *module, int length) +/*[clinic end generated code: output=e161a53e45987dc7 input=b8901bf16488b760]*/ { - int length = _history_length; - if (!PyArg_ParseTuple(args, "i:set_history_length", &length)) - return NULL; _history_length = length; Py_RETURN_NONE; } -PyDoc_STRVAR(set_history_length_doc, -"set_history_length(length) -> None\n\ -set the maximal number of lines which will be written to\n\ -the history file. A negative length is used to inhibit\n\ -history truncation."); +/* Get history length */ +/*[clinic input] +readline.get_history_length -/* Get history length */ +Return the maximum number of lines that will be written to the history file. +[clinic start generated code]*/ -static PyObject* -get_history_length(PyObject *self, PyObject *noarg) +static PyObject * +readline_get_history_length_impl(PyObject *module) +/*[clinic end generated code: output=83a2eeae35b6d2b9 input=5dce2eeba4327817]*/ { return PyLong_FromLong(_history_length); } -PyDoc_STRVAR(get_history_length_doc, -"get_history_length() -> int\n\ -return the maximum number of lines that will be written to\n\ -the history file."); - - /* Generic hook function setter */ static PyObject * -set_hook(const char *funcname, PyObject **hook_var, PyObject *args) +set_hook(const char *funcname, PyObject **hook_var, PyObject *function) { - PyObject *function = Py_None; - char buf[80]; - PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname); - if (!PyArg_ParseTuple(args, buf, &function)) - return NULL; if (function == Py_None) { Py_CLEAR(*hook_var); } @@ -358,12 +385,27 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +readline.set_completion_display_matches_hook + + function: object = None + / + +Set or remove the completion display function. + +The function is called as + function(substitution, [matches], longest_match_length) +once each time matches need to be displayed. +[clinic start generated code]*/ static PyObject * -set_completion_display_matches_hook(PyObject *self, PyObject *args) +readline_set_completion_display_matches_hook_impl(PyObject *module, + PyObject *function) +/*[clinic end generated code: output=516e5cb8db75a328 input=4f0bfd5ab0179a26]*/ { PyObject *result = set_hook("completion_display_matches_hook", - &readlinestate_global->completion_display_matches_hook, args); + &readlinestate_global->completion_display_matches_hook, + function); #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK /* We cannot set this hook globally, since it replaces the default completion display. */ @@ -379,90 +421,114 @@ set_completion_display_matches_hook(PyObject *self, PyObject *args) } -PyDoc_STRVAR(doc_set_completion_display_matches_hook, -"set_completion_display_matches_hook([function]) -> None\n\ -Set or remove the completion display function.\n\ -The function is called as\n\ - function(substitution, [matches], longest_match_length)\n\ -once each time matches need to be displayed."); +/*[clinic input] +readline.set_startup_hook + + function: object = None + / + +Set or remove the function invoked by the rl_startup_hook callback. + +The function is called with no arguments just +before readline prints the first prompt. +[clinic start generated code]*/ static PyObject * -set_startup_hook(PyObject *self, PyObject *args) +readline_set_startup_hook_impl(PyObject *module, PyObject *function) +/*[clinic end generated code: output=02cd0e0c4fa082ad input=7783b4334b26d16d]*/ { - return set_hook("startup_hook", &readlinestate_global->startup_hook, args); + return set_hook("startup_hook", &readlinestate_global->startup_hook, + function); } -PyDoc_STRVAR(doc_set_startup_hook, -"set_startup_hook([function]) -> None\n\ -Set or remove the function invoked by the rl_startup_hook callback.\n\ -The function is called with no arguments just\n\ -before readline prints the first prompt."); - - #ifdef HAVE_RL_PRE_INPUT_HOOK /* Set pre-input hook */ +/*[clinic input] +readline.set_pre_input_hook + + function: object = None + / + +Set or remove the function invoked by the rl_pre_input_hook callback. + +The function is called with no arguments after the first prompt +has been printed and just before readline starts reading input +characters. +[clinic start generated code]*/ + static PyObject * -set_pre_input_hook(PyObject *self, PyObject *args) +readline_set_pre_input_hook_impl(PyObject *module, PyObject *function) +/*[clinic end generated code: output=fe1a96505096f464 input=4f3eaeaf7ce1fdbe]*/ { - return set_hook("pre_input_hook", &readlinestate_global->pre_input_hook, args); + return set_hook("pre_input_hook", &readlinestate_global->pre_input_hook, + function); } - -PyDoc_STRVAR(doc_set_pre_input_hook, -"set_pre_input_hook([function]) -> None\n\ -Set or remove the function invoked by the rl_pre_input_hook callback.\n\ -The function is called with no arguments after the first prompt\n\ -has been printed and just before readline starts reading input\n\ -characters."); - #endif /* Get the completion type for the scope of the tab-completion */ + +/*[clinic input] +readline.get_completion_type + +Get the type of completion being attempted. +[clinic start generated code]*/ + static PyObject * -get_completion_type(PyObject *self, PyObject *noarg) +readline_get_completion_type_impl(PyObject *module) +/*[clinic end generated code: output=5c54d58a04997c07 input=04b92bc7a82dac91]*/ { return PyLong_FromLong(rl_completion_type); } -PyDoc_STRVAR(doc_get_completion_type, -"get_completion_type() -> int\n\ -Get the type of completion being attempted."); +/* Get the beginning index for the scope of the tab-completion */ +/*[clinic input] +readline.get_begidx -/* Get the beginning index for the scope of the tab-completion */ +Get the beginning index of the completion scope. +[clinic start generated code]*/ static PyObject * -get_begidx(PyObject *self, PyObject *noarg) +readline_get_begidx_impl(PyObject *module) +/*[clinic end generated code: output=362616ee8ed1b2b1 input=e083b81c8eb4bac3]*/ { Py_INCREF(readlinestate_global->begidx); return readlinestate_global->begidx; } -PyDoc_STRVAR(doc_get_begidx, -"get_begidx() -> int\n\ -get the beginning index of the completion scope"); +/* Get the ending index for the scope of the tab-completion */ +/*[clinic input] +readline.get_endidx -/* Get the ending index for the scope of the tab-completion */ +Get the ending index of the completion scope. +[clinic start generated code]*/ static PyObject * -get_endidx(PyObject *self, PyObject *noarg) +readline_get_endidx_impl(PyObject *module) +/*[clinic end generated code: output=7f763350b12d7517 input=d4c7e34a625fd770]*/ { Py_INCREF(readlinestate_global->endidx); return readlinestate_global->endidx; } -PyDoc_STRVAR(doc_get_endidx, -"get_endidx() -> int\n\ -get the ending index of the completion scope"); +/* Set the tab-completion word-delimiters that readline uses */ + +/*[clinic input] +readline.set_completer_delims + string: object + / -/* Set the tab-completion word-delimiters that readline uses */ +Set the word delimiters for completion. +[clinic start generated code]*/ static PyObject * -set_completer_delims(PyObject *self, PyObject *string) +readline_set_completer_delims(PyObject *module, PyObject *string) +/*[clinic end generated code: output=4305b266106c4f1f input=ae945337ebd01e20]*/ { char *break_chars; PyObject *encoded = encode(string); @@ -484,10 +550,6 @@ set_completer_delims(PyObject *self, PyObject *string) return PyErr_NoMemory(); } -PyDoc_STRVAR(doc_set_completer_delims, -"set_completer_delims(string) -> None\n\ -set the word delimiters for completion"); - /* _py_free_history_entry: Utility function to free a history entry. */ #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500 @@ -520,14 +582,21 @@ _py_free_history_entry(HIST_ENTRY *entry) #endif +/*[clinic input] +readline.remove_history_item + + pos as entry_number: int + / + +Remove history item given by its position. +[clinic start generated code]*/ + static PyObject * -py_remove_history(PyObject *self, PyObject *args) +readline_remove_history_item_impl(PyObject *module, int entry_number) +/*[clinic end generated code: output=ab114f029208c7e8 input=c8520ac3da50224e]*/ { - int entry_number; HIST_ENTRY *entry; - if (!PyArg_ParseTuple(args, "i:remove_history_item", &entry_number)) - return NULL; if (entry_number < 0) { PyErr_SetString(PyExc_ValueError, "History index cannot be negative"); @@ -545,22 +614,24 @@ py_remove_history(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_remove_history, -"remove_history_item(pos) -> None\n\ -remove history item given by its position"); +/*[clinic input] +readline.replace_history_item + + pos as entry_number: int + line: unicode + / + +Replaces history item given by its position with contents of line. +[clinic start generated code]*/ static PyObject * -py_replace_history(PyObject *self, PyObject *args) +readline_replace_history_item_impl(PyObject *module, int entry_number, + PyObject *line) +/*[clinic end generated code: output=f8cec2770ca125eb input=b7ccef0780ae041b]*/ { - int entry_number; - PyObject *line; PyObject *encoded; HIST_ENTRY *old_entry; - if (!PyArg_ParseTuple(args, "iU:replace_history_item", &entry_number, - &line)) { - return NULL; - } if (entry_number < 0) { PyErr_SetString(PyExc_ValueError, "History index cannot be negative"); @@ -583,14 +654,20 @@ py_replace_history(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_replace_history, -"replace_history_item(pos, line) -> None\n\ -replaces history item given by its position with contents of line"); - /* Add a line to the history buffer */ +/*[clinic input] +readline.add_history + + string: object + / + +Add an item to the history buffer. +[clinic start generated code]*/ + static PyObject * -py_add_history(PyObject *self, PyObject *string) +readline_add_history(PyObject *module, PyObject *string) +/*[clinic end generated code: output=b107b7e8106e803d input=e57c1cf6bc68d7e3]*/ { PyObject *encoded = encode(string); if (encoded == NULL) { @@ -601,60 +678,75 @@ py_add_history(PyObject *self, PyObject *string) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_add_history, -"add_history(string) -> None\n\ -add an item to the history buffer"); - static int should_auto_add_history = 1; /* Enable or disable automatic history */ +/*[clinic input] +readline.set_auto_history + + enabled as _should_auto_add_history: bool + / + +Enables or disables automatic history. +[clinic start generated code]*/ + static PyObject * -py_set_auto_history(PyObject *self, PyObject *args) +readline_set_auto_history_impl(PyObject *module, + int _should_auto_add_history) +/*[clinic end generated code: output=619c6968246fd82b input=3d413073a1a03355]*/ { - if (!PyArg_ParseTuple(args, "p:set_auto_history", - &should_auto_add_history)) { - return NULL; - } + should_auto_add_history = _should_auto_add_history; Py_RETURN_NONE; } -PyDoc_STRVAR(doc_set_auto_history, -"set_auto_history(enabled) -> None\n\ -Enables or disables automatic history."); - /* Get the tab-completion word-delimiters that readline uses */ +/*[clinic input] +readline.get_completer_delims + +Get the word delimiters for completion. +[clinic start generated code]*/ + static PyObject * -get_completer_delims(PyObject *self, PyObject *noarg) +readline_get_completer_delims_impl(PyObject *module) +/*[clinic end generated code: output=6b060280fa68ef43 input=e36eb14fb8a1f08a]*/ { return decode(rl_completer_word_break_characters); } -PyDoc_STRVAR(doc_get_completer_delims, -"get_completer_delims() -> string\n\ -get the word delimiters for completion"); +/* Set the completer function */ +/*[clinic input] +readline.set_completer -/* Set the completer function */ + function: object = None + / + +Set or remove the completer function. + +The function is called as function(text, state), +for state in 0, 1, 2, ..., until it returns a non-string. +It should return the next possible completion starting with 'text'. +[clinic start generated code]*/ static PyObject * -set_completer(PyObject *self, PyObject *args) +readline_set_completer_impl(PyObject *module, PyObject *function) +/*[clinic end generated code: output=171a2a60f81d3204 input=51e81e13118eb877]*/ { - return set_hook("completer", &readlinestate_global->completer, args); + return set_hook("completer", &readlinestate_global->completer, function); } -PyDoc_STRVAR(doc_set_completer, -"set_completer([function]) -> None\n\ -Set or remove the completer function.\n\ -The function is called as function(text, state),\n\ -for state in 0, 1, 2, ..., until it returns a non-string.\n\ -It should return the next possible completion starting with 'text'."); +/*[clinic input] +readline.get_completer +Get the current completer function. +[clinic start generated code]*/ static PyObject * -get_completer(PyObject *self, PyObject *noargs) +readline_get_completer_impl(PyObject *module) +/*[clinic end generated code: output=6e6bbd8226d14475 input=6457522e56d70d13]*/ { if (readlinestate_global->completer == NULL) { Py_RETURN_NONE; @@ -663,11 +755,6 @@ get_completer(PyObject *self, PyObject *noargs) return readlinestate_global->completer; } -PyDoc_STRVAR(doc_get_completer, -"get_completer() -> function\n\ -\n\ -Returns current completer function."); - /* Private function to get current length of history. XXX It may be * possible to replace this with a direct use of history_length instead, * but it's not clear whether BSD's libedit keeps history_length up to date. @@ -689,14 +776,21 @@ _py_get_history_length(void) /* Exported function to get any element of history */ +/*[clinic input] +readline.get_history_item + + index as idx: int + / + +Return the current contents of history item at index. +[clinic start generated code]*/ + static PyObject * -get_history_item(PyObject *self, PyObject *args) +readline_get_history_item_impl(PyObject *module, int idx) +/*[clinic end generated code: output=83d3e53ea5f34b3d input=63fff0c3c4323269]*/ { - int idx = 0; HIST_ENTRY *hist_ent; - if (!PyArg_ParseTuple(args, "i:get_history_item", &idx)) - return NULL; if (using_libedit_emulation) { /* Older versions of libedit's readline emulation * use 0-based indexes, while readline and newer @@ -723,58 +817,70 @@ get_history_item(PyObject *self, PyObject *args) } } -PyDoc_STRVAR(doc_get_history_item, -"get_history_item() -> string\n\ -return the current contents of history item at index."); +/* Exported function to get current length of history */ +/*[clinic input] +readline.get_current_history_length -/* Exported function to get current length of history */ +Return the current (not the maximum) length of history. +[clinic start generated code]*/ static PyObject * -get_current_history_length(PyObject *self, PyObject *noarg) +readline_get_current_history_length_impl(PyObject *module) +/*[clinic end generated code: output=436b294f12ba1e3f input=9cb3f431a68d071f]*/ { return PyLong_FromLong((long)_py_get_history_length()); } -PyDoc_STRVAR(doc_get_current_history_length, -"get_current_history_length() -> integer\n\ -return the current (not the maximum) length of history."); +/* Exported function to read the current line buffer */ +/*[clinic input] +readline.get_line_buffer -/* Exported function to read the current line buffer */ +Return the current contents of the line buffer. +[clinic start generated code]*/ static PyObject * -get_line_buffer(PyObject *self, PyObject *noarg) +readline_get_line_buffer_impl(PyObject *module) +/*[clinic end generated code: output=d22f9025ecad80e4 input=5f5fbc0d12c69412]*/ { return decode(rl_line_buffer); } -PyDoc_STRVAR(doc_get_line_buffer, -"get_line_buffer() -> string\n\ -return the current contents of the line buffer."); - - #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER /* Exported function to clear the current history */ +/*[clinic input] +readline.clear_history + +Clear the current readline history. +[clinic start generated code]*/ + static PyObject * -py_clear_history(PyObject *self, PyObject *noarg) +readline_clear_history_impl(PyObject *module) +/*[clinic end generated code: output=1f2dbb0dfa5d5ebb input=208962c4393f5d16]*/ { clear_history(); Py_RETURN_NONE; } - -PyDoc_STRVAR(doc_clear_history, -"clear_history() -> None\n\ -Clear the current readline history."); #endif /* Exported function to insert text into the line buffer */ +/*[clinic input] +readline.insert_text + + string: object + / + +Insert text into the line buffer at the cursor position. +[clinic start generated code]*/ + static PyObject * -insert_text(PyObject *self, PyObject *string) +readline_insert_text(PyObject *module, PyObject *string) +/*[clinic end generated code: output=23d792821d320c19 input=bc96c3c848d5ccb5]*/ { PyObject *encoded = encode(string); if (encoded == NULL) { @@ -785,77 +891,60 @@ insert_text(PyObject *self, PyObject *string) Py_RETURN_NONE; } -PyDoc_STRVAR(doc_insert_text, -"insert_text(string) -> None\n\ -Insert text into the line buffer at the cursor position."); +/* Redisplay the line buffer */ +/*[clinic input] +readline.redisplay -/* Redisplay the line buffer */ +Change what's displayed on the screen to reflect contents of the line buffer. +[clinic start generated code]*/ static PyObject * -redisplay(PyObject *self, PyObject *noarg) +readline_redisplay_impl(PyObject *module) +/*[clinic end generated code: output=a8b9725827c3c34b input=b485151058d75edc]*/ { rl_redisplay(); Py_RETURN_NONE; } -PyDoc_STRVAR(doc_redisplay, -"redisplay() -> None\n\ -Change what's displayed on the screen to reflect the current\n\ -contents of the line buffer."); - +#include "clinic/readline.c.h" /* Table of functions exported by the module */ static struct PyMethodDef readline_methods[] = { - {"parse_and_bind", parse_and_bind, METH_O, doc_parse_and_bind}, - {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer}, - {"insert_text", insert_text, METH_O, doc_insert_text}, - {"redisplay", redisplay, METH_NOARGS, doc_redisplay}, - {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, - {"read_history_file", read_history_file, - METH_VARARGS, doc_read_history_file}, - {"write_history_file", write_history_file, - METH_VARARGS, doc_write_history_file}, + READLINE_PARSE_AND_BIND_METHODDEF + READLINE_GET_LINE_BUFFER_METHODDEF + READLINE_INSERT_TEXT_METHODDEF + READLINE_REDISPLAY_METHODDEF + READLINE_READ_INIT_FILE_METHODDEF + READLINE_READ_HISTORY_FILE_METHODDEF + READLINE_WRITE_HISTORY_FILE_METHODDEF #ifdef HAVE_RL_APPEND_HISTORY - {"append_history_file", append_history_file, - METH_VARARGS, doc_append_history_file}, + READLINE_APPEND_HISTORY_FILE_METHODDEF #endif - {"get_history_item", get_history_item, - METH_VARARGS, doc_get_history_item}, - {"get_current_history_length", (PyCFunction)get_current_history_length, - METH_NOARGS, doc_get_current_history_length}, - {"set_history_length", set_history_length, - METH_VARARGS, set_history_length_doc}, - {"get_history_length", get_history_length, - METH_NOARGS, get_history_length_doc}, - {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, - {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, - {"get_completion_type", get_completion_type, - METH_NOARGS, doc_get_completion_type}, - {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx}, - {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx}, - - {"set_completer_delims", set_completer_delims, - METH_O, doc_set_completer_delims}, - {"set_auto_history", py_set_auto_history, METH_VARARGS, doc_set_auto_history}, - {"add_history", py_add_history, METH_O, doc_add_history}, - {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history}, - {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history}, - {"get_completer_delims", get_completer_delims, - METH_NOARGS, doc_get_completer_delims}, - - {"set_completion_display_matches_hook", set_completion_display_matches_hook, - METH_VARARGS, doc_set_completion_display_matches_hook}, - {"set_startup_hook", set_startup_hook, - METH_VARARGS, doc_set_startup_hook}, + READLINE_GET_HISTORY_ITEM_METHODDEF + READLINE_GET_CURRENT_HISTORY_LENGTH_METHODDEF + READLINE_SET_HISTORY_LENGTH_METHODDEF + READLINE_GET_HISTORY_LENGTH_METHODDEF + READLINE_SET_COMPLETER_METHODDEF + READLINE_GET_COMPLETER_METHODDEF + READLINE_GET_COMPLETION_TYPE_METHODDEF + READLINE_GET_BEGIDX_METHODDEF + READLINE_GET_ENDIDX_METHODDEF + READLINE_SET_COMPLETER_DELIMS_METHODDEF + READLINE_SET_AUTO_HISTORY_METHODDEF + READLINE_ADD_HISTORY_METHODDEF + READLINE_REMOVE_HISTORY_ITEM_METHODDEF + READLINE_REPLACE_HISTORY_ITEM_METHODDEF + READLINE_GET_COMPLETER_DELIMS_METHODDEF + READLINE_SET_COMPLETION_DISPLAY_MATCHES_HOOK_METHODDEF + READLINE_SET_STARTUP_HOOK_METHODDEF #ifdef HAVE_RL_PRE_INPUT_HOOK - {"set_pre_input_hook", set_pre_input_hook, - METH_VARARGS, doc_set_pre_input_hook}, + READLINE_SET_PRE_INPUT_HOOK_METHODDEF #endif #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history}, + READLINE_CLEAR_HISTORY_METHODDEF #endif {0, 0} }; From 0b286605762a69185a20536279a86449dfc6b1ec Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 12 Jul 2020 10:11:11 -0600 Subject: [PATCH 017/486] bpo-20175: Convert Modules/_multiprocessing to the Argument Clinic (GH-14245) --- .../clinic/multiprocessing.c.h | 151 +++++++ Modules/_multiprocessing/clinic/semaphore.c.h | 402 ++++++++++++++++++ Modules/_multiprocessing/multiprocessing.c | 92 ++-- Modules/_multiprocessing/multiprocessing.h | 2 +- Modules/_multiprocessing/semaphore.c | 244 ++++++++--- 5 files changed, 797 insertions(+), 94 deletions(-) create mode 100644 Modules/_multiprocessing/clinic/multiprocessing.c.h create mode 100644 Modules/_multiprocessing/clinic/semaphore.c.h diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h new file mode 100644 index 000000000000000..7096442bd0b52a3 --- /dev/null +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -0,0 +1,151 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_closesocket__doc__, +"closesocket($module, handle, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_CLOSESOCKET_METHODDEF \ + {"closesocket", (PyCFunction)_multiprocessing_closesocket, METH_O, _multiprocessing_closesocket__doc__}, + +static PyObject * +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle); + +static PyObject * +_multiprocessing_closesocket(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE handle; + + if (!PyArg_Parse(arg, ""F_HANDLE":closesocket", &handle)) { + goto exit; + } + return_value = _multiprocessing_closesocket_impl(module, handle); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_recv__doc__, +"recv($module, handle, size, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_RECV_METHODDEF \ + {"recv", (PyCFunction)(void(*)(void))_multiprocessing_recv, METH_FASTCALL, _multiprocessing_recv__doc__}, + +static PyObject * +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size); + +static PyObject * +_multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + int size; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:recv", + &handle, &size)) { + goto exit; + } + return_value = _multiprocessing_recv_impl(module, handle, size); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_send__doc__, +"send($module, handle, buf, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEND_METHODDEF \ + {"send", (PyCFunction)(void(*)(void))_multiprocessing_send, METH_FASTCALL, _multiprocessing_send__doc__}, + +static PyObject * +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf); + +static PyObject * +_multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + Py_buffer buf = {NULL, NULL}; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:send", + &handle, &buf)) { + goto exit; + } + return_value = _multiprocessing_send_impl(module, handle, &buf); + +exit: + /* Cleanup for buf */ + if (buf.obj) { + PyBuffer_Release(&buf); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +PyDoc_STRVAR(_multiprocessing_sem_unlink__doc__, +"sem_unlink($module, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEM_UNLINK_METHODDEF \ + {"sem_unlink", (PyCFunction)_multiprocessing_sem_unlink, METH_O, _multiprocessing_sem_unlink__doc__}, + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name); + +static PyObject * +_multiprocessing_sem_unlink(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("sem_unlink", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _multiprocessing_sem_unlink_impl(module, name); + +exit: + return return_value; +} + +#ifndef _MULTIPROCESSING_CLOSESOCKET_METHODDEF + #define _MULTIPROCESSING_CLOSESOCKET_METHODDEF +#endif /* !defined(_MULTIPROCESSING_CLOSESOCKET_METHODDEF) */ + +#ifndef _MULTIPROCESSING_RECV_METHODDEF + #define _MULTIPROCESSING_RECV_METHODDEF +#endif /* !defined(_MULTIPROCESSING_RECV_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEND_METHODDEF + #define _MULTIPROCESSING_SEND_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ +/*[clinic end generated code: output=418191c446cd5751 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h new file mode 100644 index 000000000000000..e1b9309e9f280b2 --- /dev/null +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -0,0 +1,402 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = _PyLong_AsInt(args[0]); + if (blocking == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, +"acquire($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Acquire the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ + {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + +static PyObject * +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj); + +static PyObject * +_multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"block", "timeout", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int blocking = 1; + PyObject *timeout_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + blocking = _PyLong_AsInt(args[0]); + if (blocking == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: + return_value = _multiprocessing_SemLock_acquire_impl(self, blocking, timeout_obj); + +exit: + return return_value; +} + +#endif /* !defined(MS_WINDOWS) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, +"release($self, /)\n" +"--\n" +"\n" +"Release the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF \ + {"release", (PyCFunction)_multiprocessing_SemLock_release, METH_NOARGS, _multiprocessing_SemLock_release__doc__}, + +static PyObject * +_multiprocessing_SemLock_release_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock_release_impl(self); +} + +#endif /* !defined(MS_WINDOWS) */ + +static PyObject * +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink); + +static PyObject * +_multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "SemLock", 0}; + PyObject *argsbuf[5]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + int kind; + int value; + int maxvalue; + const char *name; + int unlink; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 5, 5, 0, argsbuf); + if (!fastargs) { + goto exit; + } + kind = _PyLong_AsInt(fastargs[0]); + if (kind == -1 && PyErr_Occurred()) { + goto exit; + } + value = _PyLong_AsInt(fastargs[1]); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } + maxvalue = _PyLong_AsInt(fastargs[2]); + if (maxvalue == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(fastargs[3])) { + _PyArg_BadArgument("SemLock", "argument 'name'", "str", fastargs[3]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(fastargs[3], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + unlink = _PyLong_AsInt(fastargs[4]); + if (unlink == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _multiprocessing_SemLock_impl(type, kind, value, maxvalue, name, unlink); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multiprocessing_SemLock__rebuild__doc__, +"_rebuild($type, handle, kind, maxvalue, name, /)\n" +"--\n" +"\n"); + +#define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF \ + {"_rebuild", (PyCFunction)(void(*)(void))_multiprocessing_SemLock__rebuild, METH_FASTCALL|METH_CLASS, _multiprocessing_SemLock__rebuild__doc__}, + +static PyObject * +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name); + +static PyObject * +_multiprocessing_SemLock__rebuild(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + SEM_HANDLE handle; + int kind; + int maxvalue; + const char *name; + + if (!_PyArg_ParseStack(args, nargs, ""F_SEM_HANDLE"iiz:_rebuild", + &handle, &kind, &maxvalue, &name)) { + goto exit; + } + return_value = _multiprocessing_SemLock__rebuild_impl(type, handle, kind, maxvalue, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multiprocessing_SemLock__count__doc__, +"_count($self, /)\n" +"--\n" +"\n" +"Num of `acquire()`s minus num of `release()`s for this process."); + +#define _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF \ + {"_count", (PyCFunction)_multiprocessing_SemLock__count, METH_NOARGS, _multiprocessing_SemLock__count__doc__}, + +static PyObject * +_multiprocessing_SemLock__count_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__count_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__is_mine__doc__, +"_is_mine($self, /)\n" +"--\n" +"\n" +"Whether the lock is owned by this thread."); + +#define _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF \ + {"_is_mine", (PyCFunction)_multiprocessing_SemLock__is_mine, METH_NOARGS, _multiprocessing_SemLock__is_mine__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_mine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_mine_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__get_value__doc__, +"_get_value($self, /)\n" +"--\n" +"\n" +"Get the value of the semaphore."); + +#define _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF \ + {"_get_value", (PyCFunction)_multiprocessing_SemLock__get_value, METH_NOARGS, _multiprocessing_SemLock__get_value__doc__}, + +static PyObject * +_multiprocessing_SemLock__get_value_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__get_value(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__get_value_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__is_zero__doc__, +"_is_zero($self, /)\n" +"--\n" +"\n" +"Return whether semaphore has value zero."); + +#define _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF \ + {"_is_zero", (PyCFunction)_multiprocessing_SemLock__is_zero, METH_NOARGS, _multiprocessing_SemLock__is_zero__doc__}, + +static PyObject * +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__is_zero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__is_zero_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock__after_fork__doc__, +"_after_fork($self, /)\n" +"--\n" +"\n" +"Rezero the net acquisition count after fork()."); + +#define _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF \ + {"_after_fork", (PyCFunction)_multiprocessing_SemLock__after_fork, METH_NOARGS, _multiprocessing_SemLock__after_fork__doc__}, + +static PyObject * +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock__after_fork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock__after_fork_impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Enter the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)_multiprocessing_SemLock___enter__, METH_NOARGS, _multiprocessing_SemLock___enter____doc__}, + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self); + +static PyObject * +_multiprocessing_SemLock___enter__(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multiprocessing_SemLock___enter___impl(self); +} + +PyDoc_STRVAR(_multiprocessing_SemLock___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n" +"Exit the semaphore/lock."); + +#define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)(void(*)(void))_multiprocessing_SemLock___exit__, METH_FASTCALL, _multiprocessing_SemLock___exit____doc__}, + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +_multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + exc_type = args[0]; + if (nargs < 2) { + goto skip_optional; + } + exc_value = args[1]; + if (nargs < 3) { + goto skip_optional; + } + exc_tb = args[2]; +skip_optional: + return_value = _multiprocessing_SemLock___exit___impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#ifndef _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF) */ +/*[clinic end generated code: output=e7fd938150601fe5 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 806e638340f7af0..77e6c854068c0f2 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -9,6 +9,20 @@ #include "multiprocessing.h" +/*[python input] +class HANDLE_converter(CConverter): + type = "HANDLE" + format_unit = '"F_HANDLE"' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/ + +/*[clinic input] +module _multiprocessing +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/ + +#include "clinic/multiprocessing.c.h" /* * Function which raises exceptions based on error codes @@ -50,15 +64,20 @@ _PyMp_SetError(PyObject *Type, int num) } #ifdef MS_WINDOWS +/*[clinic input] +_multiprocessing.closesocket + + handle: HANDLE + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_closesocket(PyObject *self, PyObject *args) +_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle) +/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/ { - HANDLE handle; int ret; - if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle)) - return NULL; - Py_BEGIN_ALLOW_THREADS ret = closesocket((SOCKET) handle); Py_END_ALLOW_THREADS @@ -68,16 +87,22 @@ multiprocessing_closesocket(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_multiprocessing.recv + + handle: HANDLE + size: int + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_recv(PyObject *self, PyObject *args) +_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size) +/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/ { - HANDLE handle; - int size, nread; + int nread; PyObject *buf; - if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size)) - return NULL; - buf = PyBytes_FromStringAndSize(NULL, size); if (!buf) return NULL; @@ -94,23 +119,27 @@ multiprocessing_recv(PyObject *self, PyObject *args) return buf; } +/*[clinic input] +_multiprocessing.send + + handle: HANDLE + buf: Py_buffer + / + +[clinic start generated code]*/ + static PyObject * -multiprocessing_send(PyObject *self, PyObject *args) +_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf) +/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/ { - HANDLE handle; - Py_buffer buf; int ret, length; - if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf)) - return NULL; - - length = (int)Py_MIN(buf.len, INT_MAX); + length = (int)Py_MIN(buf->len, INT_MAX); Py_BEGIN_ALLOW_THREADS - ret = send((SOCKET) handle, buf.buf, length, 0); + ret = send((SOCKET) handle, buf->buf, length, 0); Py_END_ALLOW_THREADS - PyBuffer_Release(&buf); if (ret < 0) return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); return PyLong_FromLong(ret); @@ -118,18 +147,33 @@ multiprocessing_send(PyObject *self, PyObject *args) #endif +/*[clinic input] +_multiprocessing.sem_unlink + + name: str + / + +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_sem_unlink_impl(PyObject *module, const char *name) +/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/ +{ + return _PyMp_sem_unlink(name); +} + /* * Function table */ static PyMethodDef module_methods[] = { #ifdef MS_WINDOWS - {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""}, - {"recv", multiprocessing_recv, METH_VARARGS, ""}, - {"send", multiprocessing_send, METH_VARARGS, ""}, + _MULTIPROCESSING_CLOSESOCKET_METHODDEF + _MULTIPROCESSING_RECV_METHODDEF + _MULTIPROCESSING_SEND_METHODDEF #endif #if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) - {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, + _MULTIPROCESSING_SEM_UNLINK_METHODDEF #endif {NULL} }; diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h index fe78135d4669ece..277963bc1575bb4 100644 --- a/Modules/_multiprocessing/multiprocessing.h +++ b/Modules/_multiprocessing/multiprocessing.h @@ -88,6 +88,6 @@ PyObject *_PyMp_SetError(PyObject *Type, int num); */ extern PyTypeObject _PyMp_SemLockType; -extern PyObject *_PyMp_sem_unlink(PyObject *ignore, PyObject *args); +extern PyObject *_PyMp_sem_unlink(const char *name); #endif /* MULTIPROCESSING_H */ diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index ee490256d2a27e1..8732750e11be8c3 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -21,6 +21,22 @@ typedef struct { char *name; } SemLockObject; +/*[python input] +class SEM_HANDLE_converter(CConverter): + type = "SEM_HANDLE" + format_unit = '"F_SEM_HANDLE"' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e0ad43e482d8716]*/ + +/*[clinic input] +module _multiprocessing +class _multiprocessing.SemLock "SemLockObject *" "&_PyMp_SemLockType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=935fb41b7d032599]*/ + +#include "clinic/semaphore.c.h" + #define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) @@ -58,21 +74,24 @@ _GetSemaphoreValue(HANDLE handle, long *value) } } +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool(accept={int}) = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ { - int blocking = 1; double timeout; - PyObject *timeout_obj = Py_None; DWORD res, full_msecs, nhandles; HANDLE handles[2], sigint_event; - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - /* calculate timeout */ if (!blocking) { full_msecs = 0; @@ -146,8 +165,15 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) } } +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_release(SemLockObject *self, PyObject *args) +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ { if (self->kind == RECURSIVE_MUTEX) { if (!ISMINE(self)) { @@ -264,19 +290,23 @@ sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) #endif /* !HAVE_SEM_TIMEDWAIT */ +/*[clinic input] +_multiprocessing.SemLock.acquire + + block as blocking: bool(accept={int}) = True + timeout as timeout_obj: object = None + +Acquire the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, + PyObject *timeout_obj) +/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ { - int blocking = 1, res, err = 0; - PyObject *timeout_obj = Py_None; + int res, err = 0; struct timespec deadline = {0}; - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { ++self->count; Py_RETURN_TRUE; @@ -345,8 +375,15 @@ semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) Py_RETURN_TRUE; } +/*[clinic input] +_multiprocessing.SemLock.release + +Release the semaphore/lock. +[clinic start generated code]*/ + static PyObject * -semlock_release(SemLockObject *self, PyObject *args) +_multiprocessing_SemLock_release_impl(SemLockObject *self) +/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ { if (self->kind == RECURSIVE_MUTEX) { if (!ISMINE(self)) { @@ -429,19 +466,26 @@ newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, return (PyObject*)self; } +/*[clinic input] +@classmethod +_multiprocessing.SemLock.__new__ + + kind: int + value: int + maxvalue: int + name: str + unlink: bool(accept={int}) + +[clinic start generated code]*/ + static PyObject * -semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, + int maxvalue, const char *name, int unlink) +/*[clinic end generated code: output=30727e38f5f7577a input=b378c3ee27d3a0fa]*/ { SEM_HANDLE handle = SEM_FAILED; - int kind, maxvalue, value, unlink; PyObject *result; - char *name, *name_copy = NULL; - static char *kwlist[] = {"kind", "value", "maxvalue", "name", "unlink", - NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiisi", kwlist, - &kind, &value, &maxvalue, &name, &unlink)) - return NULL; + char *name_copy = NULL; if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { PyErr_SetString(PyExc_ValueError, "unrecognized kind"); @@ -481,16 +525,25 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } +/*[clinic input] +@classmethod +_multiprocessing.SemLock._rebuild + + handle: SEM_HANDLE + kind: int + maxvalue: int + name: str(accept={str, NoneType}) + / + +[clinic start generated code]*/ + static PyObject * -semlock_rebuild(PyTypeObject *type, PyObject *args) +_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, + int kind, int maxvalue, + const char *name) +/*[clinic end generated code: output=2aaee14f063f3bd9 input=f7040492ac6d9962]*/ { - SEM_HANDLE handle; - int kind, maxvalue; - char *name, *name_copy = NULL; - - if (!PyArg_ParseTuple(args, F_SEM_HANDLE "iiz", - &handle, &kind, &maxvalue, &name)) - return NULL; + char *name_copy = NULL; if (name != NULL) { name_copy = PyMem_Malloc(strlen(name) + 1); @@ -521,21 +574,42 @@ semlock_dealloc(SemLockObject* self) PyObject_Del(self); } +/*[clinic input] +_multiprocessing.SemLock._count + +Num of `acquire()`s minus num of `release()`s for this process. +[clinic start generated code]*/ + static PyObject * -semlock_count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__count_impl(SemLockObject *self) +/*[clinic end generated code: output=5ba8213900e517bb input=36fc59b1cd1025ab]*/ { return PyLong_FromLong((long)self->count); } +/*[clinic input] +_multiprocessing.SemLock._is_mine + +Whether the lock is owned by this thread. +[clinic start generated code]*/ + static PyObject * -semlock_ismine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__is_mine_impl(SemLockObject *self) +/*[clinic end generated code: output=92dc98863f4303be input=a96664cb2f0093ba]*/ { /* only makes sense for a lock */ return PyBool_FromLong(ISMINE(self)); } +/*[clinic input] +_multiprocessing.SemLock._get_value + +Get the value of the semaphore. +[clinic start generated code]*/ + static PyObject * -semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__get_value_impl(SemLockObject *self) +/*[clinic end generated code: output=64bc1b89bda05e36 input=cb10f9a769836203]*/ { #ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); @@ -552,8 +626,15 @@ semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) #endif } +/*[clinic input] +_multiprocessing.SemLock._is_zero + +Return whether semaphore has value zero. +[clinic start generated code]*/ + static PyObject * -semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__is_zero_impl(SemLockObject *self) +/*[clinic end generated code: output=815d4c878c806ed7 input=294a446418d31347]*/ { #ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { @@ -573,38 +654,68 @@ semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) #endif } +/*[clinic input] +_multiprocessing.SemLock._after_fork + +Rezero the net acquisition count after fork(). +[clinic start generated code]*/ + static PyObject * -semlock_afterfork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +_multiprocessing_SemLock__after_fork_impl(SemLockObject *self) +/*[clinic end generated code: output=718bb27914c6a6c1 input=190991008a76621e]*/ { self->count = 0; Py_RETURN_NONE; } +/*[clinic input] +_multiprocessing.SemLock.__enter__ + +Enter the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___enter___impl(SemLockObject *self) +/*[clinic end generated code: output=beeb2f07c858511f input=c5e27d594284690b]*/ +{ + return _multiprocessing_SemLock_acquire_impl(self, 1, Py_None); +} + +/*[clinic input] +_multiprocessing.SemLock.__exit__ + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +Exit the semaphore/lock. +[clinic start generated code]*/ + +static PyObject * +_multiprocessing_SemLock___exit___impl(SemLockObject *self, + PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=3b37c1a9f8b91a03 input=7d644b64a89903f8]*/ +{ + return _multiprocessing_SemLock_release_impl(self); +} + /* * Semaphore methods */ static PyMethodDef semlock_methods[] = { - {"acquire", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "acquire the semaphore/lock"}, - {"release", (PyCFunction)semlock_release, METH_NOARGS, - "release the semaphore/lock"}, - {"__enter__", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "enter the semaphore/lock"}, - {"__exit__", (PyCFunction)semlock_release, METH_VARARGS, - "exit the semaphore/lock"}, - {"_count", (PyCFunction)semlock_count, METH_NOARGS, - "num of `acquire()`s minus num of `release()`s for this process"}, - {"_is_mine", (PyCFunction)semlock_ismine, METH_NOARGS, - "whether the lock is owned by this thread"}, - {"_get_value", (PyCFunction)semlock_getvalue, METH_NOARGS, - "get the value of the semaphore"}, - {"_is_zero", (PyCFunction)semlock_iszero, METH_NOARGS, - "returns whether semaphore has value zero"}, - {"_rebuild", (PyCFunction)semlock_rebuild, METH_VARARGS | METH_CLASS, - ""}, - {"_after_fork", (PyCFunction)semlock_afterfork, METH_NOARGS, - "rezero the net acquisition count after fork()"}, + _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF + _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF + _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF + _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF + _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF + _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF + _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF + _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF + _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF {NULL} }; @@ -666,7 +777,7 @@ PyTypeObject _PyMp_SemLockType = { /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, - /* tp_new */ semlock_new, + /* tp_new */ _multiprocessing_SemLock, }; /* @@ -674,13 +785,8 @@ PyTypeObject _PyMp_SemLockType = { */ PyObject * -_PyMp_sem_unlink(PyObject *ignore, PyObject *args) +_PyMp_sem_unlink(const char *name) { - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - if (SEM_UNLINK(name) < 0) { _PyMp_SetError(NULL, MP_STANDARD_ERROR); return NULL; From 8fd255e91bde64d222c5d96e8ac32fecf54b8012 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 12 Jul 2020 19:15:20 +0300 Subject: [PATCH 018/486] bpo-41146: Convert signal.default_int_handler() to Argument Clinic (GH-21197) --- Modules/clinic/signalmodule.c.h | 38 ++++++++++++++++++++++++++++++++- Modules/signalmodule.c | 23 +++++++++++++------- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 33a278e488f9439..4713bab7486acb9 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,6 +2,42 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(signal_default_int_handler__doc__, +"default_int_handler($module, signalnum, frame, /)\n" +"--\n" +"\n" +"The default handler for SIGINT installed by Python.\n" +"\n" +"It raises KeyboardInterrupt."); + +#define SIGNAL_DEFAULT_INT_HANDLER_METHODDEF \ + {"default_int_handler", (PyCFunction)(void(*)(void))signal_default_int_handler, METH_FASTCALL, signal_default_int_handler__doc__}, + +static PyObject * +signal_default_int_handler_impl(PyObject *module, int signalnum, + PyObject *frame); + +static PyObject * +signal_default_int_handler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int signalnum; + PyObject *frame; + + if (!_PyArg_CheckPositional("default_int_handler", nargs, 2, 2)) { + goto exit; + } + signalnum = _PyLong_AsInt(args[0]); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + frame = args[1]; + return_value = signal_default_int_handler_impl(module, signalnum, frame); + +exit: + return return_value; +} + #if defined(HAVE_ALARM) PyDoc_STRVAR(signal_alarm__doc__, @@ -662,4 +698,4 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */ -/*[clinic end generated code: output=dff93c869101f043 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=59c33f0af42aebb5 input=a9049054013a1b77]*/ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index ef3536a210b04ce..7bc1b535e6e2caa 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -189,19 +189,26 @@ itimer_retval(struct itimerval *iv) } #endif +/*[clinic input] +signal.default_int_handler + signalnum: int + frame: object + / + +The default handler for SIGINT installed by Python. + +It raises KeyboardInterrupt. +[clinic start generated code]*/ + static PyObject * -signal_default_int_handler(PyObject *self, PyObject *args) +signal_default_int_handler_impl(PyObject *module, int signalnum, + PyObject *frame) +/*[clinic end generated code: output=bb11c2eb115ace4e input=efcd4a56a207acfd]*/ { PyErr_SetNone(PyExc_KeyboardInterrupt); return NULL; } -PyDoc_STRVAR(default_int_handler_doc, -"default_int_handler(...)\n\ -\n\ -The default handler for SIGINT installed by Python.\n\ -It raises KeyboardInterrupt."); - static int report_wakeup_write_error(void *data) @@ -1297,7 +1304,7 @@ signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, /* List of functions defined in the module -- some of the methoddefs are defined to nothing if the corresponding C function is not available. */ static PyMethodDef signal_methods[] = { - {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, + SIGNAL_DEFAULT_INT_HANDLER_METHODDEF SIGNAL_ALARM_METHODDEF SIGNAL_SETITIMER_METHODDEF SIGNAL_GETITIMER_METHODDEF From 9895fc6d2acdcd8d39ea9de71091e6ff8efb95f7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 13 Jul 2020 15:49:26 +0300 Subject: [PATCH 019/486] bpo-41288: Fix a crash in unpickling invalid NEWOBJ_EX. (GH-21458) Automerge-Triggered-By: @tiran --- Lib/test/pickletester.py | 18 ++++++++++++ .../2020-07-13-15-06-35.bpo-41288.8mn5P-.rst | 2 ++ Modules/_pickle.c | 29 ++++++++++++++----- 3 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index afbc2b3bf0a79c1..fb972a3ba5e9b05 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -1176,6 +1176,24 @@ def test_compat_unpickle(self): self.assertIs(type(unpickled), collections.UserDict) self.assertEqual(unpickled, collections.UserDict({1: 2})) + def test_bad_reduce(self): + self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0) + self.check_unpickling_error(TypeError, b'N)R.') + self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.') + + def test_bad_newobj(self): + error = (pickle.UnpicklingError, TypeError) + self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0) + self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.') + self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.') + + def test_bad_newobj_ex(self): + error = (pickle.UnpicklingError, TypeError) + self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0) + self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.') + self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.') + self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.') + def test_bad_stack(self): badpickles = [ b'.', # STOP diff --git a/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst new file mode 100644 index 000000000000000..3c3adbabf16ff18 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst @@ -0,0 +1,2 @@ +Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now +UnpicklingError instead of crashing. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 25e888db19c2358..611da7afdf80ec4 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5988,23 +5988,30 @@ load_newobj_ex(UnpicklerObject *self) } if (!PyType_Check(cls)) { - Py_DECREF(kwargs); - Py_DECREF(args); PyErr_Format(st->UnpicklingError, "NEWOBJ_EX class argument must be a type, not %.200s", Py_TYPE(cls)->tp_name); - Py_DECREF(cls); - return -1; + goto error; } if (((PyTypeObject *)cls)->tp_new == NULL) { - Py_DECREF(kwargs); - Py_DECREF(args); - Py_DECREF(cls); PyErr_SetString(st->UnpicklingError, "NEWOBJ_EX class argument doesn't have __new__"); - return -1; + goto error; + } + if (!PyTuple_Check(args)) { + PyErr_Format(st->UnpicklingError, + "NEWOBJ_EX args argument must be a tuple, not %.200s", + Py_TYPE(args)->tp_name); + goto error; + } + if (!PyDict_Check(kwargs)) { + PyErr_Format(st->UnpicklingError, + "NEWOBJ_EX kwargs argument must be a dict, not %.200s", + Py_TYPE(kwargs)->tp_name); + goto error; } + obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs); Py_DECREF(kwargs); Py_DECREF(args); @@ -6014,6 +6021,12 @@ load_newobj_ex(UnpicklerObject *self) } PDATA_PUSH(self->stack, obj, -1); return 0; + +error: + Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(cls); + return -1; } static int From c43253d491231fd6cca0effda918de85bccf7b2c Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Mon, 13 Jul 2020 18:31:02 -0300 Subject: [PATCH 020/486] bpo-32192: A basic lazy importer example (GH-21330) * Add example on lazy imports * Use four spaces for indentation * change to console --- Doc/library/importlib.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 99bfeacbbc74071..f7286d2ade8bd1d 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1719,6 +1719,29 @@ To import a Python source file directly, use the following recipe spec.loader.exec_module(module) +Implementing lazy imports +''''''''''''''''''''''''' + +The example below shows how to implement lazy imports:: + + >>> import importlib.util + >>> import sys + >>> def lazy_import(name): + ... spec = importlib.util.find_spec(name) + ... loader = importlib.util.LazyLoader(spec.loader) + ... spec.loader = loader + ... module = importlib.util.module_from_spec(spec) + ... sys.modules[name] = module + ... loader.exec_module(module) + ... return module + ... + >>> lazy_typing = lazy_import("typing") + >>> #lazy_typing is a real module object, + >>> #but it is not loaded in memory yet. + >>> lazy_typing.TYPE_CHECKING + False + + Setting up an importer '''''''''''''''''''''' From e0864202d2143123d611dfb753b9962b3eb7ede8 Mon Sep 17 00:00:00 2001 From: Paul McMillan Date: Mon, 13 Jul 2020 18:26:23 -0700 Subject: [PATCH 021/486] Fix repeated words in Classes tutorial (GH-21455) The phrase "At any time during execution," was repeated twice. Automerge-Triggered-By: @Mariatta --- Doc/tutorial/classes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 250d2a9ddb416b4..685552f99f440e9 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -114,8 +114,8 @@ accessible. "Directly accessible" here means that an unqualified reference to a name attempts to find the name in the namespace. Although scopes are determined statically, they are used dynamically. At any -time during execution, At any time during execution, there are 3 or 4 nested -scopes whose namespaces are directly accessible: +time during execution, there are 3 or 4 nested scopes whose namespaces are +directly accessible: * the innermost scope, which is searched first, contains the local names * the scopes of any enclosing functions, which are searched starting with the From 86be7a47d7b6394ce1025a5a434a5af2053356d7 Mon Sep 17 00:00:00 2001 From: JustAnotherArchivist Date: Tue, 14 Jul 2020 17:22:43 +0000 Subject: [PATCH 022/486] bpo-32528: Document the change in inheritance of asyncio.CancelledError (GH-21474) #msg373510 [bpo-32528]()/#13528 changed `asyncio.CancelledError` such that it no longer inherits from `concurrent.futures.CancelledError`. As this affects existing code, specifically when catching the latter instead of the former in exception handling, it should be documented in the "What's new in 3.8?" document. Automerge-Triggered-By: @1st1 --- Doc/whatsnew/3.8.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b6ed2da36889a32..a2fa17811b3fc89 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -646,7 +646,8 @@ loop on every invocation: (Contributed by Yury Selivanov in :issue:`37028`.) The exception :class:`asyncio.CancelledError` now inherits from -:class:`BaseException` rather than :class:`Exception`. +:class:`BaseException` rather than :class:`Exception` and no longer inherits +from :class:`concurrent.futures.CancelledError`. (Contributed by Yury Selivanov in :issue:`32528`.) On Windows, the default event loop is now :class:`~asyncio.ProactorEventLoop`. @@ -1951,7 +1952,8 @@ Changes in the Python API (Contributed by Anthony Sottile in :issue:`36264`.) * The exception :class:`asyncio.CancelledError` now inherits from - :class:`BaseException` rather than :class:`Exception`. + :class:`BaseException` rather than :class:`Exception` and no longer inherits + from :class:`concurrent.futures.CancelledError`. (Contributed by Yury Selivanov in :issue:`32528`.) * The function :func:`asyncio.wait_for` now correctly waits for cancellation From 00a4bb5d4acc7617eaefcb5fdf9b98f554bc7a3c Mon Sep 17 00:00:00 2001 From: Tony Solomonik Date: Tue, 14 Jul 2020 22:41:24 +0300 Subject: [PATCH 023/486] bpo-41273: asyncio's proactor read transport's better performance by using recv_into instead of recv (#21442) * bpo-41273: Proactor transport read loop to use recv_into By using recv_into instead of recv we do not allocate a new buffer each time _loop_reading calls recv. This betters performance for any stream using proactor (basically any asyncio stream on windows). * bpo-41273: Double proactor read transport buffer size By doubling the read buffer size we get better performance. --- Lib/asyncio/proactor_events.py | 40 ++++++----- Lib/test/test_asyncio/test_proactor_events.py | 70 ++++++++++++------- .../2020-07-11-00-15-01.bpo-41273.SVrsJh.rst | 3 + 3 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 8338449aaa0a3ef..d0b7100f5e05631 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -179,11 +179,12 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, """Transport for read pipes.""" def __init__(self, loop, sock, protocol, waiter=None, - extra=None, server=None): - self._pending_data = None + extra=None, server=None, buffer_size=65536): + self._pending_data_length = -1 self._paused = True super().__init__(loop, sock, protocol, waiter, extra, server) + self._data = bytearray(buffer_size) self._loop.call_soon(self._loop_reading) self._paused = False @@ -217,12 +218,12 @@ def resume_reading(self): if self._read_fut is None: self._loop.call_soon(self._loop_reading, None) - data = self._pending_data - self._pending_data = None - if data is not None: + length = self._pending_data_length + self._pending_data_length = -1 + if length > -1: # Call the protocol methode after calling _loop_reading(), # since the protocol can decide to pause reading again. - self._loop.call_soon(self._data_received, data) + self._loop.call_soon(self._data_received, self._data[:length], length) if self._loop.get_debug(): logger.debug("%r resumes reading", self) @@ -243,15 +244,15 @@ def _eof_received(self): if not keep_open: self.close() - def _data_received(self, data): + def _data_received(self, data, length): if self._paused: # Don't call any protocol method while reading is paused. # The protocol will be called on resume_reading(). - assert self._pending_data is None - self._pending_data = data + assert self._pending_data_length == -1 + self._pending_data_length = length return - if not data: + if length == 0: self._eof_received() return @@ -269,6 +270,7 @@ def _data_received(self, data): self._protocol.data_received(data) def _loop_reading(self, fut=None): + length = -1 data = None try: if fut is not None: @@ -277,18 +279,18 @@ def _loop_reading(self, fut=None): self._read_fut = None if fut.done(): # deliver data later in "finally" clause - data = fut.result() + length = fut.result() + if length == 0: + # we got end-of-file so no need to reschedule a new read + return + + data = self._data[:length] else: # the future will be replaced by next proactor.recv call fut.cancel() if self._closing: # since close() has been called we ignore any read data - data = None - return - - if data == b'': - # we got end-of-file so no need to reschedule a new read return # bpo-33694: buffer_updated() has currently no fast path because of @@ -296,7 +298,7 @@ def _loop_reading(self, fut=None): if not self._paused: # reschedule a new read - self._read_fut = self._loop._proactor.recv(self._sock, 32768) + self._read_fut = self._loop._proactor.recv_into(self._sock, self._data) except ConnectionAbortedError as exc: if not self._closing: self._fatal_error(exc, 'Fatal read error on pipe transport') @@ -314,8 +316,8 @@ def _loop_reading(self, fut=None): if not self._paused: self._read_fut.add_done_callback(self._loop_reading) finally: - if data is not None: - self._data_received(data) + if length > -1: + self._data_received(data, length) class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport, diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index b5d1df93efd6503..50ba4c19d425cac 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -40,6 +40,7 @@ def setUp(self): self.loop._proactor = self.proactor self.protocol = test_utils.make_test_protocol(asyncio.Protocol) self.sock = mock.Mock(socket.socket) + self.buffer_size = 65536 def socket_transport(self, waiter=None): transport = _ProactorSocketTransport(self.loop, self.sock, @@ -53,28 +54,32 @@ def test_ctor(self): test_utils.run_briefly(self.loop) self.assertIsNone(fut.result()) self.protocol.connection_made(tr) - self.proactor.recv.assert_called_with(self.sock, 32768) + self.proactor.recv_into.assert_called_with(self.sock, bytearray(self.buffer_size)) def test_loop_reading(self): tr = self.socket_transport() tr._loop_reading() - self.loop._proactor.recv.assert_called_with(self.sock, 32768) + self.loop._proactor.recv_into.assert_called_with(self.sock, bytearray(self.buffer_size)) self.assertFalse(self.protocol.data_received.called) self.assertFalse(self.protocol.eof_received.called) def test_loop_reading_data(self): + buf = b'data' res = self.loop.create_future() - res.set_result(b'data') + res.set_result(len(buf)) tr = self.socket_transport() tr._read_fut = res + tr._data[:len(buf)] = buf tr._loop_reading(res) - self.loop._proactor.recv.assert_called_with(self.sock, 32768) - self.protocol.data_received.assert_called_with(b'data') + called_buf = bytearray(self.buffer_size) + called_buf[:len(buf)] = buf + self.loop._proactor.recv_into.assert_called_with(self.sock, called_buf) + self.protocol.data_received.assert_called_with(bytearray(buf)) def test_loop_reading_no_data(self): res = self.loop.create_future() - res.set_result(b'') + res.set_result(0) tr = self.socket_transport() self.assertRaises(AssertionError, tr._loop_reading, res) @@ -82,12 +87,12 @@ def test_loop_reading_no_data(self): tr.close = mock.Mock() tr._read_fut = res tr._loop_reading(res) - self.assertFalse(self.loop._proactor.recv.called) + self.assertFalse(self.loop._proactor.recv_into.called) self.assertTrue(self.protocol.eof_received.called) self.assertTrue(tr.close.called) def test_loop_reading_aborted(self): - err = self.loop._proactor.recv.side_effect = ConnectionAbortedError() + err = self.loop._proactor.recv_into.side_effect = ConnectionAbortedError() tr = self.socket_transport() tr._fatal_error = mock.Mock() @@ -97,7 +102,7 @@ def test_loop_reading_aborted(self): 'Fatal read error on pipe transport') def test_loop_reading_aborted_closing(self): - self.loop._proactor.recv.side_effect = ConnectionAbortedError() + self.loop._proactor.recv_into.side_effect = ConnectionAbortedError() tr = self.socket_transport() tr._closing = True @@ -106,7 +111,7 @@ def test_loop_reading_aborted_closing(self): self.assertFalse(tr._fatal_error.called) def test_loop_reading_aborted_is_fatal(self): - self.loop._proactor.recv.side_effect = ConnectionAbortedError() + self.loop._proactor.recv_into.side_effect = ConnectionAbortedError() tr = self.socket_transport() tr._closing = False tr._fatal_error = mock.Mock() @@ -114,7 +119,7 @@ def test_loop_reading_aborted_is_fatal(self): self.assertTrue(tr._fatal_error.called) def test_loop_reading_conn_reset_lost(self): - err = self.loop._proactor.recv.side_effect = ConnectionResetError() + err = self.loop._proactor.recv_into.side_effect = ConnectionResetError() tr = self.socket_transport() tr._closing = False @@ -125,7 +130,7 @@ def test_loop_reading_conn_reset_lost(self): tr._force_close.assert_called_with(err) def test_loop_reading_exception(self): - err = self.loop._proactor.recv.side_effect = (OSError()) + err = self.loop._proactor.recv_into.side_effect = (OSError()) tr = self.socket_transport() tr._fatal_error = mock.Mock() @@ -351,20 +356,31 @@ def test_write_eof_duplex_pipe(self): def test_pause_resume_reading(self): tr = self.socket_transport() - futures = [] - for msg in [b'data1', b'data2', b'data3', b'data4', b'data5', b'']: + index = 0 + msgs = [b'data1', b'data2', b'data3', b'data4', b'data5', b''] + reversed_msgs = list(reversed(msgs)) + + def recv_into(sock, data): f = self.loop.create_future() - f.set_result(msg) - futures.append(f) + msg = reversed_msgs.pop() + + result = f.result + def monkey(): + data[:len(msg)] = msg + return result() + f.result = monkey + + f.set_result(len(msg)) + return f - self.loop._proactor.recv.side_effect = futures + self.loop._proactor.recv_into.side_effect = recv_into self.loop._run_once() self.assertFalse(tr._paused) self.assertTrue(tr.is_reading()) - self.loop._run_once() - self.protocol.data_received.assert_called_with(b'data1') - self.loop._run_once() - self.protocol.data_received.assert_called_with(b'data2') + + for msg in msgs[:2]: + self.loop._run_once() + self.protocol.data_received.assert_called_with(bytearray(msg)) tr.pause_reading() tr.pause_reading() @@ -372,23 +388,23 @@ def test_pause_resume_reading(self): self.assertFalse(tr.is_reading()) for i in range(10): self.loop._run_once() - self.protocol.data_received.assert_called_with(b'data2') + self.protocol.data_received.assert_called_with(bytearray(msgs[1])) tr.resume_reading() tr.resume_reading() self.assertFalse(tr._paused) self.assertTrue(tr.is_reading()) - self.loop._run_once() - self.protocol.data_received.assert_called_with(b'data3') - self.loop._run_once() - self.protocol.data_received.assert_called_with(b'data4') + + for msg in msgs[2:4]: + self.loop._run_once() + self.protocol.data_received.assert_called_with(bytearray(msg)) tr.pause_reading() tr.resume_reading() self.loop.call_exception_handler = mock.Mock() self.loop._run_once() self.loop.call_exception_handler.assert_not_called() - self.protocol.data_received.assert_called_with(b'data5') + self.protocol.data_received.assert_called_with(bytearray(msgs[4])) tr.close() self.assertFalse(tr.is_reading()) diff --git a/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst b/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst new file mode 100644 index 000000000000000..c08204b9908c635 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst @@ -0,0 +1,3 @@ +Speed up any transport using ``_ProactorReadPipeTransport`` by calling +``recv_into`` instead of ``recv``, thus not creating a new buffer for each +``recv`` call in the transport's read loop. From 36a56187b9f462bf41636b937b9fe94a4fed98b4 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 15 Jul 2020 03:07:34 -0600 Subject: [PATCH 024/486] bpo-20183: Convert _locale to the Argument Clinic (GH-14201) --- Modules/_localemodule.c | 290 +++++++++------ Modules/clinic/_localemodule.c.h | 587 +++++++++++++++++++++++++++++++ 2 files changed, 760 insertions(+), 117 deletions(-) create mode 100644 Modules/clinic/_localemodule.c.h diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 0819d0e1924087f..0fe2e08b41f9f6d 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -53,10 +53,14 @@ get_locale_state(PyObject *m) return (_locale_state *)state; } -/* support functions for formatting floating point numbers */ +#include "clinic/_localemodule.c.h" + +/*[clinic input] +module _locale +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed98569b726feada]*/ -PyDoc_STRVAR(setlocale__doc__, -"(integer,string=None) -> string. Activates/queries locale processing."); +/* support functions for formatting floating point numbers */ /* the grouping is terminated by either 0 or CHAR_MAX */ static PyObject* @@ -91,20 +95,27 @@ copy_grouping(const char* s) return result; } -static PyObject* -PyLocale_setlocale(PyObject* self, PyObject* args) +/*[clinic input] +_locale.setlocale + + category: int + locale: str(accept={str, NoneType}) = NULL + / + +Activates/queries locale processing. +[clinic start generated code]*/ + +static PyObject * +_locale_setlocale_impl(PyObject *module, int category, const char *locale) +/*[clinic end generated code: output=a0e777ae5d2ff117 input=dbe18f1d66c57a6a]*/ { - int category; - char *locale = NULL, *result; + char *result; PyObject *result_object; - if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) - return NULL; - #if defined(MS_WINDOWS) if (category < LC_MIN || category > LC_MAX) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "invalid locale category"); return NULL; } @@ -115,7 +126,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args) result = setlocale(category, locale); if (!result) { /* operation failed, no setting was changed */ - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "unsupported locale setting"); return NULL; } @@ -126,7 +137,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args) /* get locale */ result = setlocale(category, NULL); if (!result) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "locale query failed"); return NULL; } @@ -211,11 +222,15 @@ locale_decode_monetary(PyObject *dict, struct lconv *lc) return res; } -PyDoc_STRVAR(localeconv__doc__, -"() -> dict. Returns numeric and monetary locale-specific parameters."); +/*[clinic input] +_locale.localeconv -static PyObject* -PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) +Returns numeric and monetary locale-specific parameters. +[clinic start generated code]*/ + +static PyObject * +_locale_localeconv_impl(PyObject *module) +/*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/ { PyObject* result; struct lconv *lc; @@ -307,17 +322,24 @@ PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) } #if defined(HAVE_WCSCOLL) -PyDoc_STRVAR(strcoll__doc__, -"string,string -> int. Compares two strings according to the locale."); -static PyObject* -PyLocale_strcoll(PyObject* self, PyObject* args) +/*[clinic input] +_locale.strcoll + + os1: unicode + os2: unicode + / + +Compares two strings according to the locale. +[clinic start generated code]*/ + +static PyObject * +_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2) +/*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/ { - PyObject *os1, *os2, *result = NULL; + PyObject *result = NULL; wchar_t *ws1 = NULL, *ws2 = NULL; - if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) - return NULL; /* Convert the unicode strings to wchar[]. */ ws1 = PyUnicode_AsWideCharString(os1, NULL); if (ws1 == NULL) @@ -336,23 +358,25 @@ PyLocale_strcoll(PyObject* self, PyObject* args) #endif #ifdef HAVE_WCSXFRM -PyDoc_STRVAR(strxfrm__doc__, -"strxfrm(string) -> string.\n\ -\n\ -Return a string that can be used as a key for locale-aware comparisons."); -static PyObject* -PyLocale_strxfrm(PyObject* self, PyObject* args) +/*[clinic input] +_locale.strxfrm + + string as str: unicode + / + +Return a string that can be used as a key for locale-aware comparisons. +[clinic start generated code]*/ + +static PyObject * +_locale_strxfrm_impl(PyObject *module, PyObject *str) +/*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/ { - PyObject *str; Py_ssize_t n1; wchar_t *s = NULL, *buf = NULL; size_t n2; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "U:strxfrm", &str)) - return NULL; - s = PyUnicode_AsWideCharString(str, &n1); if (s == NULL) goto exit; @@ -399,8 +423,15 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) #endif #if defined(MS_WINDOWS) -static PyObject* -PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored)) + +/*[clinic input] +_locale._getdefaultlocale + +[clinic start generated code]*/ + +static PyObject * +_locale__getdefaultlocale_impl(PyObject *module) +/*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/ { char encoding[20]; char locale[100]; @@ -544,16 +575,20 @@ static struct langinfo_constant{ {0, 0} }; -PyDoc_STRVAR(nl_langinfo__doc__, -"nl_langinfo(key) -> string\n" -"Return the value for the locale information associated with key."); +/*[clinic input] +_locale.nl_langinfo -static PyObject* -PyLocale_nl_langinfo(PyObject* self, PyObject* args) + key as item: int + / + +Return the value for the locale information associated with key. +[clinic start generated code]*/ + +static PyObject * +_locale_nl_langinfo_impl(PyObject *module, int item) +/*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/ { - int item, i; - if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item)) - return NULL; + int i; /* Check whether this is a supported constant. GNU libc sometimes returns numeric values in the char* return value, which would crash PyUnicode_FromString. */ @@ -572,56 +607,75 @@ PyLocale_nl_langinfo(PyObject* self, PyObject* args) #ifdef HAVE_LIBINTL_H -PyDoc_STRVAR(gettext__doc__, -"gettext(msg) -> string\n" -"Return translation of msg."); +/*[clinic input] +_locale.gettext -static PyObject* -PyIntl_gettext(PyObject* self, PyObject *args) + msg as in: str + / + +gettext(msg) -> string + +Return translation of msg. +[clinic start generated code]*/ + +static PyObject * +_locale_gettext_impl(PyObject *module, const char *in) +/*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/ { - char *in; - if (!PyArg_ParseTuple(args, "s", &in)) - return 0; return PyUnicode_DecodeLocale(gettext(in), NULL); } -PyDoc_STRVAR(dgettext__doc__, -"dgettext(domain, msg) -> string\n" -"Return translation of msg in domain."); +/*[clinic input] +_locale.dgettext -static PyObject* -PyIntl_dgettext(PyObject* self, PyObject *args) + domain: str(accept={str, NoneType}) + msg as in: str + / + +dgettext(domain, msg) -> string + +Return translation of msg in domain. +[clinic start generated code]*/ + +static PyObject * +_locale_dgettext_impl(PyObject *module, const char *domain, const char *in) +/*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/ { - char *domain, *in; - if (!PyArg_ParseTuple(args, "zs", &domain, &in)) - return 0; return PyUnicode_DecodeLocale(dgettext(domain, in), NULL); } -PyDoc_STRVAR(dcgettext__doc__, -"dcgettext(domain, msg, category) -> string\n" -"Return translation of msg in domain and category."); +/*[clinic input] +_locale.dcgettext -static PyObject* -PyIntl_dcgettext(PyObject *self, PyObject *args) + domain: str(accept={str, NoneType}) + msg as msgid: str + category: int + / + +Return translation of msg in domain and category. +[clinic start generated code]*/ + +static PyObject * +_locale_dcgettext_impl(PyObject *module, const char *domain, + const char *msgid, int category) +/*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/ { - char *domain, *msgid; - int category; - if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category)) - return 0; return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL); } -PyDoc_STRVAR(textdomain__doc__, -"textdomain(domain) -> string\n" -"Set the C library's textdmain to domain, returning the new domain."); +/*[clinic input] +_locale.textdomain -static PyObject* -PyIntl_textdomain(PyObject* self, PyObject* args) + domain: str(accept={str, NoneType}) + / + +Set the C library's textdmain to domain, returning the new domain. +[clinic start generated code]*/ + +static PyObject * +_locale_textdomain_impl(PyObject *module, const char *domain) +/*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/ { - char *domain; - if (!PyArg_ParseTuple(args, "z", &domain)) - return 0; domain = textdomain(domain); if (!domain) { PyErr_SetFromErrno(PyExc_OSError); @@ -630,20 +684,26 @@ PyIntl_textdomain(PyObject* self, PyObject* args) return PyUnicode_DecodeLocale(domain, NULL); } -PyDoc_STRVAR(bindtextdomain__doc__, -"bindtextdomain(domain, dir) -> string\n" -"Bind the C library's domain to dir."); +/*[clinic input] +_locale.bindtextdomain -static PyObject* -PyIntl_bindtextdomain(PyObject* self, PyObject*args) + domain: str + dir as dirname_obj: object + / + +Bind the C library's domain to dir. +[clinic start generated code]*/ + +static PyObject * +_locale_bindtextdomain_impl(PyObject *module, const char *domain, + PyObject *dirname_obj) +/*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/ { - const char *domain, *dirname, *current_dirname; - PyObject *dirname_obj, *dirname_bytes = NULL, *result; + const char *dirname, *current_dirname; + PyObject *dirname_bytes = NULL, *result; - if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) - return 0; if (!strlen(domain)) { - PyErr_SetString(get_locale_state(self)->Error, + PyErr_SetString(get_locale_state(module)->Error, "domain must be a non-empty string"); return 0; } @@ -667,16 +727,22 @@ PyIntl_bindtextdomain(PyObject* self, PyObject*args) } #ifdef HAVE_BIND_TEXTDOMAIN_CODESET -PyDoc_STRVAR(bind_textdomain_codeset__doc__, -"bind_textdomain_codeset(domain, codeset) -> string\n" -"Bind the C library's domain to codeset."); -static PyObject* -PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) +/*[clinic input] +_locale.bind_textdomain_codeset + + domain: str + codeset: str(accept={str, NoneType}) + / + +Bind the C library's domain to codeset. +[clinic start generated code]*/ + +static PyObject * +_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, + const char *codeset) +/*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/ { - char *domain,*codeset; - if (!PyArg_ParseTuple(args, "sz", &domain, &codeset)) - return NULL; codeset = bind_textdomain_codeset(domain, codeset); if (codeset) { return PyUnicode_DecodeLocale(codeset, NULL); @@ -688,38 +754,28 @@ PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) #endif static struct PyMethodDef PyLocale_Methods[] = { - {"setlocale", (PyCFunction) PyLocale_setlocale, - METH_VARARGS, setlocale__doc__}, - {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__}, + _LOCALE_SETLOCALE_METHODDEF + _LOCALE_LOCALECONV_METHODDEF #ifdef HAVE_WCSCOLL - {"strcoll", (PyCFunction) PyLocale_strcoll, - METH_VARARGS, strcoll__doc__}, + _LOCALE_STRCOLL_METHODDEF #endif #ifdef HAVE_WCSXFRM - {"strxfrm", (PyCFunction) PyLocale_strxfrm, - METH_VARARGS, strxfrm__doc__}, + _LOCALE_STRXFRM_METHODDEF #endif #if defined(MS_WINDOWS) - {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS}, + _LOCALE__GETDEFAULTLOCALE_METHODDEF #endif #ifdef HAVE_LANGINFO_H - {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, - METH_VARARGS, nl_langinfo__doc__}, + _LOCALE_NL_LANGINFO_METHODDEF #endif #ifdef HAVE_LIBINTL_H - {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, - gettext__doc__}, - {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS, - dgettext__doc__}, - {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS, - dcgettext__doc__}, - {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS, - textdomain__doc__}, - {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS, - bindtextdomain__doc__}, + _LOCALE_GETTEXT_METHODDEF + _LOCALE_DGETTEXT_METHODDEF + _LOCALE_DCGETTEXT_METHODDEF + _LOCALE_TEXTDOMAIN_METHODDEF + _LOCALE_BINDTEXTDOMAIN_METHODDEF #ifdef HAVE_BIND_TEXTDOMAIN_CODESET - {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset, - METH_VARARGS, bind_textdomain_codeset__doc__}, + _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif #endif {NULL, NULL} diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h new file mode 100644 index 000000000000000..5d1db3ece796d86 --- /dev/null +++ b/Modules/clinic/_localemodule.c.h @@ -0,0 +1,587 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_locale_setlocale__doc__, +"setlocale($module, category, locale=, /)\n" +"--\n" +"\n" +"Activates/queries locale processing."); + +#define _LOCALE_SETLOCALE_METHODDEF \ + {"setlocale", (PyCFunction)(void(*)(void))_locale_setlocale, METH_FASTCALL, _locale_setlocale__doc__}, + +static PyObject * +_locale_setlocale_impl(PyObject *module, int category, const char *locale); + +static PyObject * +_locale_setlocale(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int category; + const char *locale = NULL; + + if (!_PyArg_CheckPositional("setlocale", nargs, 1, 2)) { + goto exit; + } + category = _PyLong_AsInt(args[0]); + if (category == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + locale = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t locale_length; + locale = PyUnicode_AsUTF8AndSize(args[1], &locale_length); + if (locale == NULL) { + goto exit; + } + if (strlen(locale) != (size_t)locale_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("setlocale", "argument 2", "str or None", args[1]); + goto exit; + } +skip_optional: + return_value = _locale_setlocale_impl(module, category, locale); + +exit: + return return_value; +} + +PyDoc_STRVAR(_locale_localeconv__doc__, +"localeconv($module, /)\n" +"--\n" +"\n" +"Returns numeric and monetary locale-specific parameters."); + +#define _LOCALE_LOCALECONV_METHODDEF \ + {"localeconv", (PyCFunction)_locale_localeconv, METH_NOARGS, _locale_localeconv__doc__}, + +static PyObject * +_locale_localeconv_impl(PyObject *module); + +static PyObject * +_locale_localeconv(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _locale_localeconv_impl(module); +} + +#if defined(HAVE_WCSCOLL) + +PyDoc_STRVAR(_locale_strcoll__doc__, +"strcoll($module, os1, os2, /)\n" +"--\n" +"\n" +"Compares two strings according to the locale."); + +#define _LOCALE_STRCOLL_METHODDEF \ + {"strcoll", (PyCFunction)(void(*)(void))_locale_strcoll, METH_FASTCALL, _locale_strcoll__doc__}, + +static PyObject * +_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2); + +static PyObject * +_locale_strcoll(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *os1; + PyObject *os2; + + if (!_PyArg_CheckPositional("strcoll", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("strcoll", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + os1 = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("strcoll", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + os2 = args[1]; + return_value = _locale_strcoll_impl(module, os1, os2); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WCSCOLL) */ + +#if defined(HAVE_WCSXFRM) + +PyDoc_STRVAR(_locale_strxfrm__doc__, +"strxfrm($module, string, /)\n" +"--\n" +"\n" +"Return a string that can be used as a key for locale-aware comparisons."); + +#define _LOCALE_STRXFRM_METHODDEF \ + {"strxfrm", (PyCFunction)_locale_strxfrm, METH_O, _locale_strxfrm__doc__}, + +static PyObject * +_locale_strxfrm_impl(PyObject *module, PyObject *str); + +static PyObject * +_locale_strxfrm(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *str; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("strxfrm", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + str = arg; + return_value = _locale_strxfrm_impl(module, str); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WCSXFRM) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_locale__getdefaultlocale__doc__, +"_getdefaultlocale($module, /)\n" +"--\n" +"\n"); + +#define _LOCALE__GETDEFAULTLOCALE_METHODDEF \ + {"_getdefaultlocale", (PyCFunction)_locale__getdefaultlocale, METH_NOARGS, _locale__getdefaultlocale__doc__}, + +static PyObject * +_locale__getdefaultlocale_impl(PyObject *module); + +static PyObject * +_locale__getdefaultlocale(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _locale__getdefaultlocale_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(HAVE_LANGINFO_H) + +PyDoc_STRVAR(_locale_nl_langinfo__doc__, +"nl_langinfo($module, key, /)\n" +"--\n" +"\n" +"Return the value for the locale information associated with key."); + +#define _LOCALE_NL_LANGINFO_METHODDEF \ + {"nl_langinfo", (PyCFunction)_locale_nl_langinfo, METH_O, _locale_nl_langinfo__doc__}, + +static PyObject * +_locale_nl_langinfo_impl(PyObject *module, int item); + +static PyObject * +_locale_nl_langinfo(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int item; + + item = _PyLong_AsInt(arg); + if (item == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _locale_nl_langinfo_impl(module, item); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LANGINFO_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_gettext__doc__, +"gettext($module, msg, /)\n" +"--\n" +"\n" +"gettext(msg) -> string\n" +"\n" +"Return translation of msg."); + +#define _LOCALE_GETTEXT_METHODDEF \ + {"gettext", (PyCFunction)_locale_gettext, METH_O, _locale_gettext__doc__}, + +static PyObject * +_locale_gettext_impl(PyObject *module, const char *in); + +static PyObject * +_locale_gettext(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *in; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("gettext", "argument", "str", arg); + goto exit; + } + Py_ssize_t in_length; + in = PyUnicode_AsUTF8AndSize(arg, &in_length); + if (in == NULL) { + goto exit; + } + if (strlen(in) != (size_t)in_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _locale_gettext_impl(module, in); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_dgettext__doc__, +"dgettext($module, domain, msg, /)\n" +"--\n" +"\n" +"dgettext(domain, msg) -> string\n" +"\n" +"Return translation of msg in domain."); + +#define _LOCALE_DGETTEXT_METHODDEF \ + {"dgettext", (PyCFunction)(void(*)(void))_locale_dgettext, METH_FASTCALL, _locale_dgettext__doc__}, + +static PyObject * +_locale_dgettext_impl(PyObject *module, const char *domain, const char *in); + +static PyObject * +_locale_dgettext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *in; + + if (!_PyArg_CheckPositional("dgettext", nargs, 2, 2)) { + goto exit; + } + if (args[0] == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("dgettext", "argument 1", "str or None", args[0]); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("dgettext", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t in_length; + in = PyUnicode_AsUTF8AndSize(args[1], &in_length); + if (in == NULL) { + goto exit; + } + if (strlen(in) != (size_t)in_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _locale_dgettext_impl(module, domain, in); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_dcgettext__doc__, +"dcgettext($module, domain, msg, category, /)\n" +"--\n" +"\n" +"Return translation of msg in domain and category."); + +#define _LOCALE_DCGETTEXT_METHODDEF \ + {"dcgettext", (PyCFunction)(void(*)(void))_locale_dcgettext, METH_FASTCALL, _locale_dcgettext__doc__}, + +static PyObject * +_locale_dcgettext_impl(PyObject *module, const char *domain, + const char *msgid, int category); + +static PyObject * +_locale_dcgettext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *msgid; + int category; + + if (!_PyArg_CheckPositional("dcgettext", nargs, 3, 3)) { + goto exit; + } + if (args[0] == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("dcgettext", "argument 1", "str or None", args[0]); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("dcgettext", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t msgid_length; + msgid = PyUnicode_AsUTF8AndSize(args[1], &msgid_length); + if (msgid == NULL) { + goto exit; + } + if (strlen(msgid) != (size_t)msgid_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + category = _PyLong_AsInt(args[2]); + if (category == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _locale_dcgettext_impl(module, domain, msgid, category); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_textdomain__doc__, +"textdomain($module, domain, /)\n" +"--\n" +"\n" +"Set the C library\'s textdmain to domain, returning the new domain."); + +#define _LOCALE_TEXTDOMAIN_METHODDEF \ + {"textdomain", (PyCFunction)_locale_textdomain, METH_O, _locale_textdomain__doc__}, + +static PyObject * +_locale_textdomain_impl(PyObject *module, const char *domain); + +static PyObject * +_locale_textdomain(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *domain; + + if (arg == Py_None) { + domain = NULL; + } + else if (PyUnicode_Check(arg)) { + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(arg, &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("textdomain", "argument", "str or None", arg); + goto exit; + } + return_value = _locale_textdomain_impl(module, domain); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) + +PyDoc_STRVAR(_locale_bindtextdomain__doc__, +"bindtextdomain($module, domain, dir, /)\n" +"--\n" +"\n" +"Bind the C library\'s domain to dir."); + +#define _LOCALE_BINDTEXTDOMAIN_METHODDEF \ + {"bindtextdomain", (PyCFunction)(void(*)(void))_locale_bindtextdomain, METH_FASTCALL, _locale_bindtextdomain__doc__}, + +static PyObject * +_locale_bindtextdomain_impl(PyObject *module, const char *domain, + PyObject *dirname_obj); + +static PyObject * +_locale_bindtextdomain(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + PyObject *dirname_obj; + + if (!_PyArg_CheckPositional("bindtextdomain", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("bindtextdomain", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + dirname_obj = args[1]; + return_value = _locale_bindtextdomain_impl(module, domain, dirname_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) */ + +#if defined(HAVE_LIBINTL_H) && defined(HAVE_BIND_TEXTDOMAIN_CODESET) + +PyDoc_STRVAR(_locale_bind_textdomain_codeset__doc__, +"bind_textdomain_codeset($module, domain, codeset, /)\n" +"--\n" +"\n" +"Bind the C library\'s domain to codeset."); + +#define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF \ + {"bind_textdomain_codeset", (PyCFunction)(void(*)(void))_locale_bind_textdomain_codeset, METH_FASTCALL, _locale_bind_textdomain_codeset__doc__}, + +static PyObject * +_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, + const char *codeset); + +static PyObject * +_locale_bind_textdomain_codeset(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *domain; + const char *codeset; + + if (!_PyArg_CheckPositional("bind_textdomain_codeset", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("bind_textdomain_codeset", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t domain_length; + domain = PyUnicode_AsUTF8AndSize(args[0], &domain_length); + if (domain == NULL) { + goto exit; + } + if (strlen(domain) != (size_t)domain_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (args[1] == Py_None) { + codeset = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t codeset_length; + codeset = PyUnicode_AsUTF8AndSize(args[1], &codeset_length); + if (codeset == NULL) { + goto exit; + } + if (strlen(codeset) != (size_t)codeset_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("bind_textdomain_codeset", "argument 2", "str or None", args[1]); + goto exit; + } + return_value = _locale_bind_textdomain_codeset_impl(module, domain, codeset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LIBINTL_H) && defined(HAVE_BIND_TEXTDOMAIN_CODESET) */ + +#ifndef _LOCALE_STRCOLL_METHODDEF + #define _LOCALE_STRCOLL_METHODDEF +#endif /* !defined(_LOCALE_STRCOLL_METHODDEF) */ + +#ifndef _LOCALE_STRXFRM_METHODDEF + #define _LOCALE_STRXFRM_METHODDEF +#endif /* !defined(_LOCALE_STRXFRM_METHODDEF) */ + +#ifndef _LOCALE__GETDEFAULTLOCALE_METHODDEF + #define _LOCALE__GETDEFAULTLOCALE_METHODDEF +#endif /* !defined(_LOCALE__GETDEFAULTLOCALE_METHODDEF) */ + +#ifndef _LOCALE_NL_LANGINFO_METHODDEF + #define _LOCALE_NL_LANGINFO_METHODDEF +#endif /* !defined(_LOCALE_NL_LANGINFO_METHODDEF) */ + +#ifndef _LOCALE_GETTEXT_METHODDEF + #define _LOCALE_GETTEXT_METHODDEF +#endif /* !defined(_LOCALE_GETTEXT_METHODDEF) */ + +#ifndef _LOCALE_DGETTEXT_METHODDEF + #define _LOCALE_DGETTEXT_METHODDEF +#endif /* !defined(_LOCALE_DGETTEXT_METHODDEF) */ + +#ifndef _LOCALE_DCGETTEXT_METHODDEF + #define _LOCALE_DCGETTEXT_METHODDEF +#endif /* !defined(_LOCALE_DCGETTEXT_METHODDEF) */ + +#ifndef _LOCALE_TEXTDOMAIN_METHODDEF + #define _LOCALE_TEXTDOMAIN_METHODDEF +#endif /* !defined(_LOCALE_TEXTDOMAIN_METHODDEF) */ + +#ifndef _LOCALE_BINDTEXTDOMAIN_METHODDEF + #define _LOCALE_BINDTEXTDOMAIN_METHODDEF +#endif /* !defined(_LOCALE_BINDTEXTDOMAIN_METHODDEF) */ + +#ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF + #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF +#endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ +/*[clinic end generated code: output=fe944779cd572d8e input=a9049054013a1b77]*/ From f5481db4bebf9d53b79f29f960f4188af8ccdfde Mon Sep 17 00:00:00 2001 From: Rishi Date: Wed, 15 Jul 2020 13:51:00 +0200 Subject: [PATCH 025/486] bpo-39017: Avoid infinite loop in the tarfile module (GH-21454) Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907). --- Lib/tarfile.py | 2 ++ Lib/test/recursion.tar | Bin 0 -> 516 bytes Lib/test/test_tarfile.py | 7 +++++++ .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst | 1 + 4 files changed, 10 insertions(+) create mode 100644 Lib/test/recursion.tar create mode 100644 Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index e2b60532f693d4b..6769066cabd6fcb 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -1249,6 +1249,8 @@ def _proc_pax(self, tarfile): length, keyword = match.groups() length = int(length) + if length == 0: + raise InvalidHeaderError("invalid header") value = buf[match.end(2) + 1:match.start(1) + length - 1] # Normally, we could just use "utf-8" as the encoding and "strict" diff --git a/Lib/test/recursion.tar b/Lib/test/recursion.tar new file mode 100644 index 0000000000000000000000000000000000000000..b8237251964983f54ed1966297e887636cd0c5f4 GIT binary patch literal 516 zcmYdFPRz+kEn=W0Fn}74P8%Xw3X=l~85kIuo0>8xq$A1Gm}!7)KUsFc41m#O8A5+e I1_}|j06>QaCIA2c literal 0 HcmV?d00001 diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index d60d35b5be04ae8..3ddeb97f5268fe8 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -429,6 +429,13 @@ def test_premature_end_of_archive(self): with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"): tar.extractfile(t).read() + def test_length_zero_header(self): + # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail + # with an exception + with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"): + with tarfile.open(support.findfile('recursion.tar')) as tar: + pass + class MiscReadTestBase(CommonReadTest): def requires_name_attribute(self): pass diff --git a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst new file mode 100644 index 000000000000000..ad26676f8b85633 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst @@ -0,0 +1 @@ +Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907). From c9babe5a627921ba389c48e9053fddc5c1084c21 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Wed, 15 Jul 2020 20:14:11 +0800 Subject: [PATCH 026/486] bpo-41302: Fix build with system libmpdec (GH-21481) Move definition of UNUSED from modified headers of libmpdec to _decimal.c itself. This makes the vendored source closer to the standalone library and fixes build with --with-system-libmpdec. Tested to build fine with either system libmpdec or the vendored one. --- Modules/_decimal/_decimal.c | 5 +++++ Modules/_decimal/libmpdec/mpdecimal.h | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index ff7c647c2220c18..fb4e020f1260e6e 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -56,6 +56,11 @@ #define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) + #define UNUSED __attribute__((unused)) +#else + #define UNUSED +#endif /* _Py_DEC_MINALLOC >= MPD_MINALLOC */ #define _Py_DEC_MINALLOC 4 diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h index 35ce429f60124a9..5a2439690c3509c 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.h +++ b/Modules/_decimal/libmpdec/mpdecimal.h @@ -61,12 +61,6 @@ extern "C" { #define MPD_HIDE_SYMBOLS_END #endif -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) - #define UNUSED __attribute__((unused)) -#else - #define UNUSED -#endif - #if defined(_MSC_VER) #include "vccompat.h" #define EXTINLINE extern inline From 00ef57815c554fd172e5faa694fd17df2e6bbaff Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 15 Jul 2020 06:12:05 -0700 Subject: [PATCH 027/486] Fix -Wstrict-prototypes warning in thread_pthread.h. (GH-21477) --- Python/thread_pthread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index cf4e854d829cb5f..e6910b3083a8920 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -134,7 +134,7 @@ do { \ static pthread_condattr_t *condattr_monotonic = NULL; static void -init_condattr() +init_condattr(void) { #ifdef CONDATTR_MONOTONIC static pthread_condattr_t ca; From 9dddf110a82e09c6eb152176225d16d17fbf609f Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 15 Jul 2020 10:02:14 -0700 Subject: [PATCH 028/486] Fix -Wstring-prototypes warnings in _zoneinfo.c. (GH-21478) --- Modules/_zoneinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index a2883495fe7fddd..319d6c7b7760e2e 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -2468,7 +2468,7 @@ clear_strong_cache(const PyTypeObject *const type) } static PyObject * -new_weak_cache() +new_weak_cache(void) { PyObject *weakref_module = PyImport_ImportModule("weakref"); if (weakref_module == NULL) { @@ -2482,7 +2482,7 @@ new_weak_cache() } static int -initialize_caches() +initialize_caches(void) { // TODO: Move to a PyModule_GetState / PEP 573 based caching system. if (TIMEDELTA_CACHE == NULL) { From b3764f6039de15d8381e88eb5c864cf1dbe12a0f Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 15 Jul 2020 12:43:00 -0600 Subject: [PATCH 029/486] bpo-40150: Fix mismatched argument in RegisterWaitForSingleObject() call (GH-19686) --- Modules/overlapped.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 4f0ba85d7983e00..5e7a1bbba76787c 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -293,7 +293,7 @@ struct PostCallbackData { }; static VOID CALLBACK -PostToQueueCallback(PVOID lpParameter, BOOL TimerOrWaitFired) +PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { struct PostCallbackData *p = (struct PostCallbackData*) lpParameter; @@ -335,8 +335,7 @@ _overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, *pdata = data; if (!RegisterWaitForSingleObject( - &NewWaitObject, Object, (WAITORTIMERCALLBACK)PostToQueueCallback, - pdata, Milliseconds, + &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { PyMem_RawFree(pdata); From c60a949b00dab2f549b3b11e5fb1acb2eae46525 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 15 Jul 2020 22:56:49 +0100 Subject: [PATCH 030/486] bpo-41304: Ensure python3x._pth is loaded on Windows (GH-21495) --- Lib/test/test_site.py | 36 +++++++++++++++++-- .../2020-07-15-20-15-08.bpo-41304.vNEeYA.rst | 1 + PC/getpathp.c | 2 +- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 9751c64c99e74a6..ec86c645981b36e 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -598,12 +598,19 @@ def test_startup_interactivehook_isolated_explicit(self): @unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") class _pthFileTests(unittest.TestCase): - def _create_underpth_exe(self, lines): + def _create_underpth_exe(self, lines, exe_pth=True): + import _winapi temp_dir = tempfile.mkdtemp() self.addCleanup(test.support.rmtree, temp_dir) exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) + dll_src_file = _winapi.GetModuleFileName(sys.dllhandle) + dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1]) shutil.copy(sys.executable, exe_file) - _pth_file = os.path.splitext(exe_file)[0] + '._pth' + shutil.copy(dll_src_file, dll_file) + if exe_pth: + _pth_file = os.path.splitext(exe_file)[0] + '._pth' + else: + _pth_file = os.path.splitext(dll_file)[0] + '._pth' with open(_pth_file, 'w') as f: for line in lines: print(line, file=f) @@ -671,5 +678,30 @@ def test_underpth_file(self): self.assertTrue(rc, "sys.path is incorrect") + def test_underpth_dll_file(self): + libpath = os.path.dirname(os.path.dirname(encodings.__file__)) + exe_prefix = os.path.dirname(sys.executable) + exe_file = self._create_underpth_exe([ + 'fake-path-name', + *[libpath for _ in range(200)], + '', + '# comment', + 'import site' + ], exe_pth=False) + sys_prefix = os.path.dirname(exe_file) + env = os.environ.copy() + env['PYTHONPATH'] = 'from-env' + env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) + rc = subprocess.call([exe_file, '-c', + 'import sys; sys.exit(not sys.flags.no_site and ' + '%r in sys.path and %r in sys.path and %r not in sys.path and ' + 'all("\\r" not in p and "\\n" not in p for p in sys.path))' % ( + os.path.join(sys_prefix, 'fake-path-name'), + libpath, + os.path.join(sys_prefix, 'from-env'), + )], env=env) + self.assertTrue(rc, "sys.path is incorrect") + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst b/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst new file mode 100644 index 000000000000000..90423e9a665fce3 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst @@ -0,0 +1 @@ +Fixes `python3x._pth` being ignored on Windows diff --git a/PC/getpathp.c b/PC/getpathp.c index 0939c5fa9842cd5..53da3a6d05faee9 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -669,7 +669,7 @@ static int get_pth_filename(PyCalculatePath *calculate, wchar_t *filename, const _PyPathConfig *pathconfig) { - if (get_dllpath(filename) && + if (!get_dllpath(filename) && !change_ext(filename, filename, L"._pth") && exists(filename)) { From 99b9160d8aac20d78bd5e18c2da485fe3d62ae96 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 16 Jul 2020 09:13:05 +0300 Subject: [PATCH 031/486] bpo-31844: Remove _markupbase.ParserBase.error() (GH-8562) --- Doc/whatsnew/3.9.rst | 5 +++ Lib/_markupbase.py | 35 ++++++++++--------- .../2018-07-30-12-48-17.bpo-31844.0_GKsD.rst | 4 +++ 3 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-07-30-12-48-17.bpo-31844.0_GKsD.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index c2db9bc74ccdd69..18cc5588bf23728 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -887,6 +887,11 @@ Removed :func:`asyncio.current_task` and :func:`asyncio.all_tasks` instead. (Contributed by Rémi Lapeyre in :issue:`40967`) +* The ``ParserBase.error()`` method from the private and undocumented ``_markupbase`` + module has been removed. :class:`html.parser.HTMLParser` is the only subclass of + ``ParserBase`` and its ``error()`` implementation has already been removed in + Python 3.5. + (Contributed by Berker Peksag in :issue:`31844`.) Porting to Python 3.9 ===================== diff --git a/Lib/_markupbase.py b/Lib/_markupbase.py index 2af5f1c23b60662..3ad7e279960f7e1 100644 --- a/Lib/_markupbase.py +++ b/Lib/_markupbase.py @@ -29,10 +29,6 @@ def __init__(self): raise RuntimeError( "_markupbase.ParserBase must be subclassed") - def error(self, message): - raise NotImplementedError( - "subclasses of ParserBase must override error()") - def reset(self): self.lineno = 1 self.offset = 0 @@ -131,12 +127,11 @@ def parse_declaration(self, i): # also in data attribute specifications of attlist declaration # also link type declaration subsets in linktype declarations # also link attribute specification lists in link declarations - self.error("unsupported '[' char in %s declaration" % decltype) + raise AssertionError("unsupported '[' char in %s declaration" % decltype) else: - self.error("unexpected '[' char in declaration") + raise AssertionError("unexpected '[' char in declaration") else: - self.error( - "unexpected %r char in declaration" % rawdata[j]) + raise AssertionError("unexpected %r char in declaration" % rawdata[j]) if j < 0: return j return -1 # incomplete @@ -156,7 +151,9 @@ def parse_marked_section(self, i, report=1): # look for MS Office ]> ending match= _msmarkedsectionclose.search(rawdata, i+3) else: - self.error('unknown status keyword %r in marked section' % rawdata[i+3:j]) + raise AssertionError( + 'unknown status keyword %r in marked section' % rawdata[i+3:j] + ) if not match: return -1 if report: @@ -168,7 +165,7 @@ def parse_marked_section(self, i, report=1): def parse_comment(self, i, report=1): rawdata = self.rawdata if rawdata[i:i+4] != ' x:JUMP_IF_FALSE_OR_POP z + x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z + --> x:POP_JUMP_IF_FALSE y+1 + where y+1 is the instruction following the second test. + */ + case JUMP_IF_FALSE_OR_POP: + switch(target->i_opcode) { + case POP_JUMP_IF_FALSE: + *inst = *target; + break; + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + case JUMP_IF_FALSE_OR_POP: + inst->i_target = target->i_target; + break; + case JUMP_IF_TRUE_OR_POP: + assert (inst->i_target->b_iused == 1); + inst->i_opcode = POP_JUMP_IF_FALSE; + inst->i_target = inst->i_target->b_next; + break; + } + break; + + case JUMP_IF_TRUE_OR_POP: + switch(target->i_opcode) { + case POP_JUMP_IF_TRUE: + *inst = *target; + break; + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + case JUMP_IF_TRUE_OR_POP: + inst->i_target = target->i_target; + break; + case JUMP_IF_FALSE_OR_POP: + assert (inst->i_target->b_iused == 1); + inst->i_opcode = POP_JUMP_IF_TRUE; + inst->i_target = inst->i_target->b_next; + break; + } + break; + + case POP_JUMP_IF_FALSE: + switch(target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + inst->i_target = target->i_target; + break; + } + break; + + case POP_JUMP_IF_TRUE: + switch(target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + inst->i_target = target->i_target; + break; + } + break; + + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + switch(target->i_opcode) { + case JUMP_FORWARD: + inst->i_target = target->i_target; + break; + case JUMP_ABSOLUTE: + case RETURN_VALUE: + case RERAISE: + case RAISE_VARARGS: + lineno = inst->i_lineno; + *inst = *target; + inst->i_lineno = lineno; + break; + } + break; + } + } + return 0; +error: + return -1; +} + + +static void +clean_basic_block(basicblock *bb) { + /* Remove NOPs and any code following a return or re-raise. */ + int dest = 0; + for (int src = 0; src < bb->b_iused; src++) { + switch(bb->b_instr[src].i_opcode) { + case NOP: + /* skip */ + break; + case RETURN_VALUE: + case RERAISE: + bb->b_next = NULL; + bb->b_instr[dest] = bb->b_instr[src]; + dest++; + goto end; + default: + if (dest != src) { + bb->b_instr[dest] = bb->b_instr[src]; + } + dest++; + break; + } + } +end: + assert(dest <= bb->b_iused); + bb->b_iused = dest; +} + +static int +mark_reachable(struct assembler *a) { + basicblock **stack, **sp; + sp = stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * a->a_nblocks); + if (stack == NULL) { + return -1; + } + basicblock *entry = a->a_reverse_postorder[0]; + entry->b_reachable = 1; + *sp++ = entry; + while (sp > stack) { + basicblock *b = *(--sp); + if (b->b_next && b->b_next->b_reachable == 0) { + b->b_next->b_reachable = 1; + *sp++ = b->b_next; + } + for (int i = 0; i < b->b_iused; i++) { + basicblock *target; + if (b->b_instr[i].i_jrel || b->b_instr[i].i_jabs) { + target = b->b_instr[i].i_target; + if (target->b_reachable == 0) { + target->b_reachable = 1; + *sp++ = target; + } + } + } + } + PyObject_Free(stack); + return 0; +} + + +/* Perform basic peephole optimizations on a control flow graph. + The consts object should still be in list form to allow new constants + to be appended. + + All transformations keep the code size the same or smaller. + For those that reduce size, the gaps are initially filled with + NOPs. Later those NOPs are removed. +*/ + +static int +optimize_cfg(struct assembler *a, PyObject *consts) +{ + for (int i = 0; i < a->a_nblocks; i++) { + if (optimize_basic_block(a->a_reverse_postorder[i], consts)) { + return -1; + } + clean_basic_block(a->a_reverse_postorder[i]); + assert(a->a_reverse_postorder[i]->b_reachable == 0); + } + if (mark_reachable(a)) { + return -1; + } + /* Delete unreachable instructions */ + for (int i = 0; i < a->a_nblocks; i++) { + if (a->a_reverse_postorder[i]->b_reachable == 0) { + a->a_reverse_postorder[i]->b_iused = 0; + } + } + return 0; +} + +/* Retained for API compatibility. + * Optimization is now done in optimize_cfg */ + +PyObject * +PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), + PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj)) +{ + Py_INCREF(code); + return code; +} + diff --git a/Python/importlib.h b/Python/importlib.h index 1fb877a75341975..00d1f3570b32297 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -475,215 +475,214 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,101,115,95,102,114,111,122,101,110,250,0,0,0,115,6, 0,0,0,0,2,12,5,10,1,114,91,0,0,0,99,2, 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3, - 0,0,0,67,0,0,0,115,62,0,0,0,116,0,124,1, + 0,0,0,67,0,0,0,115,58,0,0,0,116,0,124,1, 124,0,131,2,125,2,124,1,116,1,106,2,118,0,114,50, 116,1,106,2,124,1,25,0,125,3,116,3,124,2,124,3, 131,2,1,0,116,1,106,2,124,1,25,0,83,0,116,4, - 124,2,131,1,83,0,100,1,83,0,41,2,122,128,76,111, - 97,100,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,32,105,110,116,111,32,115,121,115, - 46,109,111,100,117,108,101,115,32,97,110,100,32,114,101,116, - 117,114,110,32,105,116,46,10,10,32,32,32,32,84,104,105, - 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,46,32,32,85,115,101,32,108,111,97, - 100,101,114,46,101,120,101,99,95,109,111,100,117,108,101,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,78,41, - 5,218,16,115,112,101,99,95,102,114,111,109,95,108,111,97, - 100,101,114,114,15,0,0,0,218,7,109,111,100,117,108,101, - 115,218,5,95,101,120,101,99,218,5,95,108,111,97,100,41, - 4,114,30,0,0,0,114,82,0,0,0,218,4,115,112,101, - 99,218,6,109,111,100,117,108,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,17,95,108,111,97,100,95, - 109,111,100,117,108,101,95,115,104,105,109,6,1,0,0,115, - 12,0,0,0,0,6,10,1,10,1,10,1,10,1,10,2, - 114,98,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,8,0,0,0,67,0,0,0,115,218, - 0,0,0,116,0,124,0,100,1,100,0,131,3,125,1,116, - 1,124,1,100,2,131,2,114,54,122,12,124,1,160,2,124, - 0,161,1,87,0,83,0,4,0,116,3,121,52,1,0,1, - 0,1,0,89,0,110,2,48,0,122,10,124,0,106,4,125, - 2,87,0,110,18,4,0,116,5,121,82,1,0,1,0,1, - 0,89,0,110,18,48,0,124,2,100,0,117,1,114,100,116, - 6,124,2,131,1,83,0,122,10,124,0,106,7,125,3,87, - 0,110,22,4,0,116,5,121,132,1,0,1,0,1,0,100, - 3,125,3,89,0,110,2,48,0,122,10,124,0,106,8,125, - 4,87,0,110,56,4,0,116,5,121,200,1,0,1,0,1, - 0,124,1,100,0,117,0,114,180,100,4,160,9,124,3,161, - 1,6,0,89,0,83,0,100,5,160,9,124,3,124,1,161, - 2,6,0,89,0,83,0,89,0,110,14,48,0,100,6,160, - 9,124,3,124,4,161,2,83,0,100,0,83,0,41,7,78, - 218,10,95,95,108,111,97,100,101,114,95,95,218,11,109,111, - 100,117,108,101,95,114,101,112,114,250,1,63,250,13,60,109, - 111,100,117,108,101,32,123,33,114,125,62,250,20,60,109,111, - 100,117,108,101,32,123,33,114,125,32,40,123,33,114,125,41, - 62,250,23,60,109,111,100,117,108,101,32,123,33,114,125,32, - 102,114,111,109,32,123,33,114,125,62,41,10,114,6,0,0, - 0,114,4,0,0,0,114,100,0,0,0,218,9,69,120,99, - 101,112,116,105,111,110,218,8,95,95,115,112,101,99,95,95, - 218,14,65,116,116,114,105,98,117,116,101,69,114,114,111,114, - 218,22,95,109,111,100,117,108,101,95,114,101,112,114,95,102, - 114,111,109,95,115,112,101,99,114,1,0,0,0,218,8,95, - 95,102,105,108,101,95,95,114,46,0,0,0,41,5,114,97, - 0,0,0,218,6,108,111,97,100,101,114,114,96,0,0,0, - 114,17,0,0,0,218,8,102,105,108,101,110,97,109,101,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,12, - 95,109,111,100,117,108,101,95,114,101,112,114,22,1,0,0, - 115,46,0,0,0,0,2,12,1,10,4,2,1,12,1,12, - 1,6,1,2,1,10,1,12,1,6,2,8,1,8,4,2, - 1,10,1,12,1,10,1,2,1,10,1,12,1,8,1,14, - 2,22,2,114,112,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, - 0,115,114,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,2,100,2,100,3,156,3,100,4,100,5, - 132,2,90,4,100,6,100,7,132,0,90,5,100,8,100,9, - 132,0,90,6,101,7,100,10,100,11,132,0,131,1,90,8, - 101,8,106,9,100,12,100,11,132,0,131,1,90,8,101,7, - 100,13,100,14,132,0,131,1,90,10,101,7,100,15,100,16, - 132,0,131,1,90,11,101,11,106,9,100,17,100,16,132,0, - 131,1,90,11,100,2,83,0,41,18,218,10,77,111,100,117, - 108,101,83,112,101,99,97,208,5,0,0,84,104,101,32,115, - 112,101,99,105,102,105,99,97,116,105,111,110,32,102,111,114, - 32,97,32,109,111,100,117,108,101,44,32,117,115,101,100,32, - 102,111,114,32,108,111,97,100,105,110,103,46,10,10,32,32, - 32,32,65,32,109,111,100,117,108,101,39,115,32,115,112,101, - 99,32,105,115,32,116,104,101,32,115,111,117,114,99,101,32, - 102,111,114,32,105,110,102,111,114,109,97,116,105,111,110,32, - 97,98,111,117,116,32,116,104,101,32,109,111,100,117,108,101, - 46,32,32,70,111,114,10,32,32,32,32,100,97,116,97,32, - 97,115,115,111,99,105,97,116,101,100,32,119,105,116,104,32, - 116,104,101,32,109,111,100,117,108,101,44,32,105,110,99,108, - 117,100,105,110,103,32,115,111,117,114,99,101,44,32,117,115, - 101,32,116,104,101,32,115,112,101,99,39,115,10,32,32,32, - 32,108,111,97,100,101,114,46,10,10,32,32,32,32,96,110, - 97,109,101,96,32,105,115,32,116,104,101,32,97,98,115,111, - 108,117,116,101,32,110,97,109,101,32,111,102,32,116,104,101, - 32,109,111,100,117,108,101,46,32,32,96,108,111,97,100,101, - 114,96,32,105,115,32,116,104,101,32,108,111,97,100,101,114, - 10,32,32,32,32,116,111,32,117,115,101,32,119,104,101,110, - 32,108,111,97,100,105,110,103,32,116,104,101,32,109,111,100, - 117,108,101,46,32,32,96,112,97,114,101,110,116,96,32,105, - 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,10,32,32,32,32,112,97,99,107,97,103,101,32,116,104, - 101,32,109,111,100,117,108,101,32,105,115,32,105,110,46,32, - 32,84,104,101,32,112,97,114,101,110,116,32,105,115,32,100, - 101,114,105,118,101,100,32,102,114,111,109,32,116,104,101,32, - 110,97,109,101,46,10,10,32,32,32,32,96,105,115,95,112, - 97,99,107,97,103,101,96,32,100,101,116,101,114,109,105,110, - 101,115,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,99,111,110,115,105,100,101,114,101,100,32,97, - 32,112,97,99,107,97,103,101,32,111,114,10,32,32,32,32, - 110,111,116,46,32,32,79,110,32,109,111,100,117,108,101,115, - 32,116,104,105,115,32,105,115,32,114,101,102,108,101,99,116, - 101,100,32,98,121,32,116,104,101,32,96,95,95,112,97,116, - 104,95,95,96,32,97,116,116,114,105,98,117,116,101,46,10, - 10,32,32,32,32,96,111,114,105,103,105,110,96,32,105,115, - 32,116,104,101,32,115,112,101,99,105,102,105,99,32,108,111, - 99,97,116,105,111,110,32,117,115,101,100,32,98,121,32,116, - 104,101,32,108,111,97,100,101,114,32,102,114,111,109,32,119, - 104,105,99,104,32,116,111,10,32,32,32,32,108,111,97,100, - 32,116,104,101,32,109,111,100,117,108,101,44,32,105,102,32, - 116,104,97,116,32,105,110,102,111,114,109,97,116,105,111,110, - 32,105,115,32,97,118,97,105,108,97,98,108,101,46,32,32, - 87,104,101,110,32,102,105,108,101,110,97,109,101,32,105,115, - 10,32,32,32,32,115,101,116,44,32,111,114,105,103,105,110, - 32,119,105,108,108,32,109,97,116,99,104,46,10,10,32,32, - 32,32,96,104,97,115,95,108,111,99,97,116,105,111,110,96, - 32,105,110,100,105,99,97,116,101,115,32,116,104,97,116,32, - 97,32,115,112,101,99,39,115,32,34,111,114,105,103,105,110, - 34,32,114,101,102,108,101,99,116,115,32,97,32,108,111,99, - 97,116,105,111,110,46,10,32,32,32,32,87,104,101,110,32, - 116,104,105,115,32,105,115,32,84,114,117,101,44,32,96,95, - 95,102,105,108,101,95,95,96,32,97,116,116,114,105,98,117, - 116,101,32,111,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,115,101,116,46,10,10,32,32,32,32,96,99, - 97,99,104,101,100,96,32,105,115,32,116,104,101,32,108,111, - 99,97,116,105,111,110,32,111,102,32,116,104,101,32,99,97, - 99,104,101,100,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,44,32,105,102,32,97,110,121,46,32,32,73,116,10, - 32,32,32,32,99,111,114,114,101,115,112,111,110,100,115,32, - 116,111,32,116,104,101,32,96,95,95,99,97,99,104,101,100, - 95,95,96,32,97,116,116,114,105,98,117,116,101,46,10,10, - 32,32,32,32,96,115,117,98,109,111,100,117,108,101,95,115, - 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,96, - 32,105,115,32,116,104,101,32,115,101,113,117,101,110,99,101, - 32,111,102,32,112,97,116,104,32,101,110,116,114,105,101,115, - 32,116,111,10,32,32,32,32,115,101,97,114,99,104,32,119, - 104,101,110,32,105,109,112,111,114,116,105,110,103,32,115,117, - 98,109,111,100,117,108,101,115,46,32,32,73,102,32,115,101, - 116,44,32,105,115,95,112,97,99,107,97,103,101,32,115,104, - 111,117,108,100,32,98,101,10,32,32,32,32,84,114,117,101, - 45,45,97,110,100,32,70,97,108,115,101,32,111,116,104,101, - 114,119,105,115,101,46,10,10,32,32,32,32,80,97,99,107, - 97,103,101,115,32,97,114,101,32,115,105,109,112,108,121,32, - 109,111,100,117,108,101,115,32,116,104,97,116,32,40,109,97, - 121,41,32,104,97,118,101,32,115,117,98,109,111,100,117,108, - 101,115,46,32,32,73,102,32,97,32,115,112,101,99,10,32, - 32,32,32,104,97,115,32,97,32,110,111,110,45,78,111,110, - 101,32,118,97,108,117,101,32,105,110,32,96,115,117,98,109, - 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, - 97,116,105,111,110,115,96,44,32,116,104,101,32,105,109,112, - 111,114,116,10,32,32,32,32,115,121,115,116,101,109,32,119, - 105,108,108,32,99,111,110,115,105,100,101,114,32,109,111,100, - 117,108,101,115,32,108,111,97,100,101,100,32,102,114,111,109, - 32,116,104,101,32,115,112,101,99,32,97,115,32,112,97,99, - 107,97,103,101,115,46,10,10,32,32,32,32,79,110,108,121, - 32,102,105,110,100,101,114,115,32,40,115,101,101,32,105,109, - 112,111,114,116,108,105,98,46,97,98,99,46,77,101,116,97, - 80,97,116,104,70,105,110,100,101,114,32,97,110,100,10,32, - 32,32,32,105,109,112,111,114,116,108,105,98,46,97,98,99, - 46,80,97,116,104,69,110,116,114,121,70,105,110,100,101,114, - 41,32,115,104,111,117,108,100,32,109,111,100,105,102,121,32, - 77,111,100,117,108,101,83,112,101,99,32,105,110,115,116,97, - 110,99,101,115,46,10,10,32,32,32,32,78,41,3,218,6, - 111,114,105,103,105,110,218,12,108,111,97,100,101,114,95,115, - 116,97,116,101,218,10,105,115,95,112,97,99,107,97,103,101, - 99,3,0,0,0,0,0,0,0,3,0,0,0,6,0,0, - 0,2,0,0,0,67,0,0,0,115,54,0,0,0,124,1, - 124,0,95,0,124,2,124,0,95,1,124,3,124,0,95,2, - 124,4,124,0,95,3,124,5,114,32,103,0,110,2,100,0, - 124,0,95,4,100,1,124,0,95,5,100,0,124,0,95,6, - 100,0,83,0,41,2,78,70,41,7,114,17,0,0,0,114, - 110,0,0,0,114,114,0,0,0,114,115,0,0,0,218,26, + 124,2,131,1,83,0,41,2,122,128,76,111,97,100,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,32,105,110,116,111,32,115,121,115,46,109,111,100, + 117,108,101,115,32,97,110,100,32,114,101,116,117,114,110,32, + 105,116,46,10,10,32,32,32,32,84,104,105,115,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,85,115,101,32,108,111,97,100,101,114,46, + 101,120,101,99,95,109,111,100,117,108,101,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,78,41,5,218,16,115, + 112,101,99,95,102,114,111,109,95,108,111,97,100,101,114,114, + 15,0,0,0,218,7,109,111,100,117,108,101,115,218,5,95, + 101,120,101,99,218,5,95,108,111,97,100,41,4,114,30,0, + 0,0,114,82,0,0,0,218,4,115,112,101,99,218,6,109, + 111,100,117,108,101,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,17,95,108,111,97,100,95,109,111,100,117, + 108,101,95,115,104,105,109,6,1,0,0,115,12,0,0,0, + 0,6,10,1,10,1,10,1,10,1,10,2,114,98,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,8,0,0,0,67,0,0,0,115,210,0,0,0,116, + 0,124,0,100,1,100,0,131,3,125,1,116,1,124,1,100, + 2,131,2,114,54,122,12,124,1,160,2,124,0,161,1,87, + 0,83,0,4,0,116,3,121,52,1,0,1,0,1,0,89, + 0,110,2,48,0,122,10,124,0,106,4,125,2,87,0,110, + 18,4,0,116,5,121,82,1,0,1,0,1,0,89,0,110, + 18,48,0,124,2,100,0,117,1,114,100,116,6,124,2,131, + 1,83,0,122,10,124,0,106,7,125,3,87,0,110,22,4, + 0,116,5,121,132,1,0,1,0,1,0,100,3,125,3,89, + 0,110,2,48,0,122,10,124,0,106,8,125,4,87,0,110, + 52,4,0,116,5,121,196,1,0,1,0,1,0,124,1,100, + 0,117,0,114,180,100,4,160,9,124,3,161,1,6,0,89, + 0,83,0,100,5,160,9,124,3,124,1,161,2,6,0,89, + 0,83,0,48,0,100,6,160,9,124,3,124,4,161,2,83, + 0,41,7,78,218,10,95,95,108,111,97,100,101,114,95,95, + 218,11,109,111,100,117,108,101,95,114,101,112,114,250,1,63, + 250,13,60,109,111,100,117,108,101,32,123,33,114,125,62,250, + 20,60,109,111,100,117,108,101,32,123,33,114,125,32,40,123, + 33,114,125,41,62,250,23,60,109,111,100,117,108,101,32,123, + 33,114,125,32,102,114,111,109,32,123,33,114,125,62,41,10, + 114,6,0,0,0,114,4,0,0,0,114,100,0,0,0,218, + 9,69,120,99,101,112,116,105,111,110,218,8,95,95,115,112, + 101,99,95,95,218,14,65,116,116,114,105,98,117,116,101,69, + 114,114,111,114,218,22,95,109,111,100,117,108,101,95,114,101, + 112,114,95,102,114,111,109,95,115,112,101,99,114,1,0,0, + 0,218,8,95,95,102,105,108,101,95,95,114,46,0,0,0, + 41,5,114,97,0,0,0,218,6,108,111,97,100,101,114,114, + 96,0,0,0,114,17,0,0,0,218,8,102,105,108,101,110, + 97,109,101,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,12,95,109,111,100,117,108,101,95,114,101,112,114, + 22,1,0,0,115,46,0,0,0,0,2,12,1,10,4,2, + 1,12,1,12,1,6,1,2,1,10,1,12,1,6,2,8, + 1,8,4,2,1,10,1,12,1,10,1,2,1,10,1,12, + 1,8,1,14,2,18,2,114,112,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,64,0,0,0,115,114,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,2,100,2,100,3,156,3, + 100,4,100,5,132,2,90,4,100,6,100,7,132,0,90,5, + 100,8,100,9,132,0,90,6,101,7,100,10,100,11,132,0, + 131,1,90,8,101,8,106,9,100,12,100,11,132,0,131,1, + 90,8,101,7,100,13,100,14,132,0,131,1,90,10,101,7, + 100,15,100,16,132,0,131,1,90,11,101,11,106,9,100,17, + 100,16,132,0,131,1,90,11,100,2,83,0,41,18,218,10, + 77,111,100,117,108,101,83,112,101,99,97,208,5,0,0,84, + 104,101,32,115,112,101,99,105,102,105,99,97,116,105,111,110, + 32,102,111,114,32,97,32,109,111,100,117,108,101,44,32,117, + 115,101,100,32,102,111,114,32,108,111,97,100,105,110,103,46, + 10,10,32,32,32,32,65,32,109,111,100,117,108,101,39,115, + 32,115,112,101,99,32,105,115,32,116,104,101,32,115,111,117, + 114,99,101,32,102,111,114,32,105,110,102,111,114,109,97,116, + 105,111,110,32,97,98,111,117,116,32,116,104,101,32,109,111, + 100,117,108,101,46,32,32,70,111,114,10,32,32,32,32,100, + 97,116,97,32,97,115,115,111,99,105,97,116,101,100,32,119, + 105,116,104,32,116,104,101,32,109,111,100,117,108,101,44,32, + 105,110,99,108,117,100,105,110,103,32,115,111,117,114,99,101, + 44,32,117,115,101,32,116,104,101,32,115,112,101,99,39,115, + 10,32,32,32,32,108,111,97,100,101,114,46,10,10,32,32, + 32,32,96,110,97,109,101,96,32,105,115,32,116,104,101,32, + 97,98,115,111,108,117,116,101,32,110,97,109,101,32,111,102, + 32,116,104,101,32,109,111,100,117,108,101,46,32,32,96,108, + 111,97,100,101,114,96,32,105,115,32,116,104,101,32,108,111, + 97,100,101,114,10,32,32,32,32,116,111,32,117,115,101,32, + 119,104,101,110,32,108,111,97,100,105,110,103,32,116,104,101, + 32,109,111,100,117,108,101,46,32,32,96,112,97,114,101,110, + 116,96,32,105,115,32,116,104,101,32,110,97,109,101,32,111, + 102,32,116,104,101,10,32,32,32,32,112,97,99,107,97,103, + 101,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 105,110,46,32,32,84,104,101,32,112,97,114,101,110,116,32, + 105,115,32,100,101,114,105,118,101,100,32,102,114,111,109,32, + 116,104,101,32,110,97,109,101,46,10,10,32,32,32,32,96, + 105,115,95,112,97,99,107,97,103,101,96,32,100,101,116,101, + 114,109,105,110,101,115,32,105,102,32,116,104,101,32,109,111, + 100,117,108,101,32,105,115,32,99,111,110,115,105,100,101,114, + 101,100,32,97,32,112,97,99,107,97,103,101,32,111,114,10, + 32,32,32,32,110,111,116,46,32,32,79,110,32,109,111,100, + 117,108,101,115,32,116,104,105,115,32,105,115,32,114,101,102, + 108,101,99,116,101,100,32,98,121,32,116,104,101,32,96,95, + 95,112,97,116,104,95,95,96,32,97,116,116,114,105,98,117, + 116,101,46,10,10,32,32,32,32,96,111,114,105,103,105,110, + 96,32,105,115,32,116,104,101,32,115,112,101,99,105,102,105, + 99,32,108,111,99,97,116,105,111,110,32,117,115,101,100,32, + 98,121,32,116,104,101,32,108,111,97,100,101,114,32,102,114, + 111,109,32,119,104,105,99,104,32,116,111,10,32,32,32,32, + 108,111,97,100,32,116,104,101,32,109,111,100,117,108,101,44, + 32,105,102,32,116,104,97,116,32,105,110,102,111,114,109,97, + 116,105,111,110,32,105,115,32,97,118,97,105,108,97,98,108, + 101,46,32,32,87,104,101,110,32,102,105,108,101,110,97,109, + 101,32,105,115,10,32,32,32,32,115,101,116,44,32,111,114, + 105,103,105,110,32,119,105,108,108,32,109,97,116,99,104,46, + 10,10,32,32,32,32,96,104,97,115,95,108,111,99,97,116, + 105,111,110,96,32,105,110,100,105,99,97,116,101,115,32,116, + 104,97,116,32,97,32,115,112,101,99,39,115,32,34,111,114, + 105,103,105,110,34,32,114,101,102,108,101,99,116,115,32,97, + 32,108,111,99,97,116,105,111,110,46,10,32,32,32,32,87, + 104,101,110,32,116,104,105,115,32,105,115,32,84,114,117,101, + 44,32,96,95,95,102,105,108,101,95,95,96,32,97,116,116, + 114,105,98,117,116,101,32,111,102,32,116,104,101,32,109,111, + 100,117,108,101,32,105,115,32,115,101,116,46,10,10,32,32, + 32,32,96,99,97,99,104,101,100,96,32,105,115,32,116,104, + 101,32,108,111,99,97,116,105,111,110,32,111,102,32,116,104, + 101,32,99,97,99,104,101,100,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,44,32,105,102,32,97,110,121,46,32, + 32,73,116,10,32,32,32,32,99,111,114,114,101,115,112,111, + 110,100,115,32,116,111,32,116,104,101,32,96,95,95,99,97, + 99,104,101,100,95,95,96,32,97,116,116,114,105,98,117,116, + 101,46,10,10,32,32,32,32,96,115,117,98,109,111,100,117, + 108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,105, + 111,110,115,96,32,105,115,32,116,104,101,32,115,101,113,117, + 101,110,99,101,32,111,102,32,112,97,116,104,32,101,110,116, + 114,105,101,115,32,116,111,10,32,32,32,32,115,101,97,114, + 99,104,32,119,104,101,110,32,105,109,112,111,114,116,105,110, + 103,32,115,117,98,109,111,100,117,108,101,115,46,32,32,73, + 102,32,115,101,116,44,32,105,115,95,112,97,99,107,97,103, + 101,32,115,104,111,117,108,100,32,98,101,10,32,32,32,32, + 84,114,117,101,45,45,97,110,100,32,70,97,108,115,101,32, + 111,116,104,101,114,119,105,115,101,46,10,10,32,32,32,32, + 80,97,99,107,97,103,101,115,32,97,114,101,32,115,105,109, + 112,108,121,32,109,111,100,117,108,101,115,32,116,104,97,116, + 32,40,109,97,121,41,32,104,97,118,101,32,115,117,98,109, + 111,100,117,108,101,115,46,32,32,73,102,32,97,32,115,112, + 101,99,10,32,32,32,32,104,97,115,32,97,32,110,111,110, + 45,78,111,110,101,32,118,97,108,117,101,32,105,110,32,96, 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,218,13,95,115,101,116, - 95,102,105,108,101,97,116,116,114,218,7,95,99,97,99,104, - 101,100,41,6,114,30,0,0,0,114,17,0,0,0,114,110, - 0,0,0,114,114,0,0,0,114,115,0,0,0,114,116,0, + 95,108,111,99,97,116,105,111,110,115,96,44,32,116,104,101, + 32,105,109,112,111,114,116,10,32,32,32,32,115,121,115,116, + 101,109,32,119,105,108,108,32,99,111,110,115,105,100,101,114, + 32,109,111,100,117,108,101,115,32,108,111,97,100,101,100,32, + 102,114,111,109,32,116,104,101,32,115,112,101,99,32,97,115, + 32,112,97,99,107,97,103,101,115,46,10,10,32,32,32,32, + 79,110,108,121,32,102,105,110,100,101,114,115,32,40,115,101, + 101,32,105,109,112,111,114,116,108,105,98,46,97,98,99,46, + 77,101,116,97,80,97,116,104,70,105,110,100,101,114,32,97, + 110,100,10,32,32,32,32,105,109,112,111,114,116,108,105,98, + 46,97,98,99,46,80,97,116,104,69,110,116,114,121,70,105, + 110,100,101,114,41,32,115,104,111,117,108,100,32,109,111,100, + 105,102,121,32,77,111,100,117,108,101,83,112,101,99,32,105, + 110,115,116,97,110,99,101,115,46,10,10,32,32,32,32,78, + 41,3,218,6,111,114,105,103,105,110,218,12,108,111,97,100, + 101,114,95,115,116,97,116,101,218,10,105,115,95,112,97,99, + 107,97,103,101,99,3,0,0,0,0,0,0,0,3,0,0, + 0,6,0,0,0,2,0,0,0,67,0,0,0,115,54,0, + 0,0,124,1,124,0,95,0,124,2,124,0,95,1,124,3, + 124,0,95,2,124,4,124,0,95,3,124,5,114,32,103,0, + 110,2,100,0,124,0,95,4,100,1,124,0,95,5,100,0, + 124,0,95,6,100,0,83,0,41,2,78,70,41,7,114,17, + 0,0,0,114,110,0,0,0,114,114,0,0,0,114,115,0, + 0,0,218,26,115,117,98,109,111,100,117,108,101,95,115,101, + 97,114,99,104,95,108,111,99,97,116,105,111,110,115,218,13, + 95,115,101,116,95,102,105,108,101,97,116,116,114,218,7,95, + 99,97,99,104,101,100,41,6,114,30,0,0,0,114,17,0, + 0,0,114,110,0,0,0,114,114,0,0,0,114,115,0,0, + 0,114,116,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,31,0,0,0,95,1,0,0,115,14, + 0,0,0,0,2,6,1,6,1,6,1,6,1,14,3,6, + 1,122,19,77,111,100,117,108,101,83,112,101,99,46,95,95, + 105,110,105,116,95,95,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115, + 102,0,0,0,100,1,160,0,124,0,106,1,161,1,100,2, + 160,0,124,0,106,2,161,1,103,2,125,1,124,0,106,3, + 100,0,117,1,114,52,124,1,160,4,100,3,160,0,124,0, + 106,3,161,1,161,1,1,0,124,0,106,5,100,0,117,1, + 114,80,124,1,160,4,100,4,160,0,124,0,106,5,161,1, + 161,1,1,0,100,5,160,0,124,0,106,6,106,7,100,6, + 160,8,124,1,161,1,161,2,83,0,41,7,78,122,9,110, + 97,109,101,61,123,33,114,125,122,11,108,111,97,100,101,114, + 61,123,33,114,125,122,11,111,114,105,103,105,110,61,123,33, + 114,125,122,29,115,117,98,109,111,100,117,108,101,95,115,101, + 97,114,99,104,95,108,111,99,97,116,105,111,110,115,61,123, + 125,122,6,123,125,40,123,125,41,122,2,44,32,41,9,114, + 46,0,0,0,114,17,0,0,0,114,110,0,0,0,114,114, + 0,0,0,218,6,97,112,112,101,110,100,114,117,0,0,0, + 218,9,95,95,99,108,97,115,115,95,95,114,1,0,0,0, + 218,4,106,111,105,110,41,2,114,30,0,0,0,114,56,0, 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,31,0,0,0,95,1,0,0,115,14,0,0,0,0, - 2,6,1,6,1,6,1,6,1,14,3,6,1,122,19,77, - 111,100,117,108,101,83,112,101,99,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,6,0,0,0,67,0,0,0,115,102,0,0,0, - 100,1,160,0,124,0,106,1,161,1,100,2,160,0,124,0, - 106,2,161,1,103,2,125,1,124,0,106,3,100,0,117,1, - 114,52,124,1,160,4,100,3,160,0,124,0,106,3,161,1, - 161,1,1,0,124,0,106,5,100,0,117,1,114,80,124,1, - 160,4,100,4,160,0,124,0,106,5,161,1,161,1,1,0, - 100,5,160,0,124,0,106,6,106,7,100,6,160,8,124,1, - 161,1,161,2,83,0,41,7,78,122,9,110,97,109,101,61, - 123,33,114,125,122,11,108,111,97,100,101,114,61,123,33,114, - 125,122,11,111,114,105,103,105,110,61,123,33,114,125,122,29, - 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,61,123,125,122,6,123, - 125,40,123,125,41,122,2,44,32,41,9,114,46,0,0,0, - 114,17,0,0,0,114,110,0,0,0,114,114,0,0,0,218, - 6,97,112,112,101,110,100,114,117,0,0,0,218,9,95,95, - 99,108,97,115,115,95,95,114,1,0,0,0,218,4,106,111, - 105,110,41,2,114,30,0,0,0,114,56,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,49,0, - 0,0,107,1,0,0,115,20,0,0,0,0,1,10,1,10, - 255,4,2,10,1,18,1,10,1,8,1,4,255,6,2,122, - 19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101, - 112,114,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,106,0, - 0,0,124,0,106,0,125,2,122,72,124,0,106,1,124,1, - 106,1,107,2,111,76,124,0,106,2,124,1,106,2,107,2, - 111,76,124,0,106,3,124,1,106,3,107,2,111,76,124,2, - 124,1,106,0,107,2,111,76,124,0,106,4,124,1,106,4, - 107,2,111,76,124,0,106,5,124,1,106,5,107,2,87,0, - 83,0,4,0,116,6,121,100,1,0,1,0,1,0,116,7, - 6,0,89,0,83,0,48,0,100,0,83,0,114,13,0,0, + 0,114,49,0,0,0,107,1,0,0,115,20,0,0,0,0, + 1,10,1,10,255,4,2,10,1,18,1,10,1,8,1,4, + 255,6,2,122,19,77,111,100,117,108,101,83,112,101,99,46, + 95,95,114,101,112,114,95,95,99,2,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, + 0,115,102,0,0,0,124,0,106,0,125,2,122,72,124,0, + 106,1,124,1,106,1,107,2,111,76,124,0,106,2,124,1, + 106,2,107,2,111,76,124,0,106,3,124,1,106,3,107,2, + 111,76,124,2,124,1,106,0,107,2,111,76,124,0,106,4, + 124,1,106,4,107,2,111,76,124,0,106,5,124,1,106,5, + 107,2,87,0,83,0,4,0,116,6,121,100,1,0,1,0, + 1,0,116,7,6,0,89,0,83,0,48,0,114,13,0,0, 0,41,8,114,117,0,0,0,114,17,0,0,0,114,110,0, 0,0,114,114,0,0,0,218,6,99,97,99,104,101,100,218, 12,104,97,115,95,108,111,99,97,116,105,111,110,114,107,0, @@ -716,335 +715,477 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0, 0,138,1,0,0,115,2,0,0,0,0,2,99,1,0,0, 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,36,0,0,0,124,0,106,0,100,1, + 0,67,0,0,0,115,32,0,0,0,124,0,106,0,100,1, 117,0,114,26,124,0,106,1,160,2,100,2,161,1,100,3, - 25,0,83,0,124,0,106,1,83,0,100,1,83,0,41,4, - 122,32,84,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,32,109,111,100,117,108,101,39,115,32,112,97,114,101,110, - 116,46,78,218,1,46,114,22,0,0,0,41,3,114,117,0, - 0,0,114,17,0,0,0,218,10,114,112,97,114,116,105,116, - 105,111,110,114,48,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,6,112,97,114,101,110,116,142, - 1,0,0,115,6,0,0,0,0,3,10,1,16,2,122,17, - 77,111,100,117,108,101,83,112,101,99,46,112,97,114,101,110, - 116,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124, - 0,106,0,83,0,114,13,0,0,0,41,1,114,118,0,0, - 0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,124,0,0,0,150,1,0,0,115,2, - 0,0,0,0,2,122,23,77,111,100,117,108,101,83,112,101, - 99,46,104,97,115,95,108,111,99,97,116,105,111,110,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,0,67,0,0,0,115,14,0,0,0,116,0,124,1, - 131,1,124,0,95,1,100,0,83,0,114,13,0,0,0,41, - 2,218,4,98,111,111,108,114,118,0,0,0,41,2,114,30, - 0,0,0,218,5,118,97,108,117,101,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,124,0,0,0,154,1, - 0,0,115,2,0,0,0,0,2,41,12,114,1,0,0,0, - 114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,114, - 31,0,0,0,114,49,0,0,0,114,126,0,0,0,218,8, - 112,114,111,112,101,114,116,121,114,123,0,0,0,218,6,115, - 101,116,116,101,114,114,131,0,0,0,114,124,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,113,0,0,0,58,1,0,0,115,32,0,0, - 0,8,1,4,36,4,1,2,255,12,12,8,10,8,12,2, - 1,10,8,4,1,10,3,2,1,10,7,2,1,10,3,4, - 1,114,113,0,0,0,169,2,114,114,0,0,0,114,116,0, - 0,0,99,2,0,0,0,0,0,0,0,2,0,0,0,6, - 0,0,0,8,0,0,0,67,0,0,0,115,152,0,0,0, - 116,0,124,1,100,1,131,2,114,74,116,1,100,2,117,0, - 114,22,116,2,130,1,116,1,106,3,125,4,124,3,100,2, - 117,0,114,48,124,4,124,0,124,1,100,3,141,2,83,0, - 124,3,114,56,103,0,110,2,100,2,125,5,124,4,124,0, - 124,1,124,5,100,4,141,3,83,0,124,3,100,2,117,0, - 114,136,116,0,124,1,100,5,131,2,114,132,122,14,124,1, - 160,4,124,0,161,1,125,3,87,0,113,136,4,0,116,5, - 121,128,1,0,1,0,1,0,100,2,125,3,89,0,113,136, - 48,0,110,4,100,6,125,3,116,6,124,0,124,1,124,2, - 124,3,100,7,141,4,83,0,41,8,122,53,82,101,116,117, - 114,110,32,97,32,109,111,100,117,108,101,32,115,112,101,99, - 32,98,97,115,101,100,32,111,110,32,118,97,114,105,111,117, - 115,32,108,111,97,100,101,114,32,109,101,116,104,111,100,115, - 46,90,12,103,101,116,95,102,105,108,101,110,97,109,101,78, - 41,1,114,110,0,0,0,41,2,114,110,0,0,0,114,117, - 0,0,0,114,116,0,0,0,70,114,136,0,0,0,41,7, - 114,4,0,0,0,114,127,0,0,0,114,128,0,0,0,218, - 23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95, - 108,111,99,97,116,105,111,110,114,116,0,0,0,114,80,0, - 0,0,114,113,0,0,0,41,6,114,17,0,0,0,114,110, - 0,0,0,114,114,0,0,0,114,116,0,0,0,114,137,0, - 0,0,90,6,115,101,97,114,99,104,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,92,0,0,0,159,1, - 0,0,115,36,0,0,0,0,2,10,1,8,1,4,1,6, - 2,8,1,12,1,12,1,6,1,2,255,6,3,8,1,10, - 1,2,1,14,1,12,1,12,3,4,2,114,92,0,0,0, - 99,3,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,8,0,0,0,67,0,0,0,115,42,1,0,0,122,10, - 124,0,106,0,125,3,87,0,110,18,4,0,116,1,121,28, - 1,0,1,0,1,0,89,0,110,14,48,0,124,3,100,0, - 117,1,114,42,124,3,83,0,124,0,106,2,125,4,124,1, - 100,0,117,0,114,86,122,10,124,0,106,3,125,1,87,0, - 110,18,4,0,116,1,121,84,1,0,1,0,1,0,89,0, - 110,2,48,0,122,10,124,0,106,4,125,5,87,0,110,22, - 4,0,116,1,121,118,1,0,1,0,1,0,100,0,125,5, - 89,0,110,2,48,0,124,2,100,0,117,0,114,176,124,5, - 100,0,117,0,114,172,122,10,124,1,106,5,125,2,87,0, - 113,176,4,0,116,1,121,168,1,0,1,0,1,0,100,0, - 125,2,89,0,113,176,48,0,110,4,124,5,125,2,122,10, - 124,0,106,6,125,6,87,0,110,22,4,0,116,1,121,208, - 1,0,1,0,1,0,100,0,125,6,89,0,110,2,48,0, - 122,14,116,7,124,0,106,8,131,1,125,7,87,0,110,22, - 4,0,116,1,121,246,1,0,1,0,1,0,100,0,125,7, - 89,0,110,2,48,0,116,9,124,4,124,1,124,2,100,1, - 141,3,125,3,124,5,100,0,117,0,144,1,114,20,100,2, - 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7, - 124,3,95,12,124,3,83,0,41,4,78,169,1,114,114,0, - 0,0,70,84,41,13,114,106,0,0,0,114,107,0,0,0, - 114,1,0,0,0,114,99,0,0,0,114,109,0,0,0,218, - 7,95,79,82,73,71,73,78,218,10,95,95,99,97,99,104, - 101,100,95,95,218,4,108,105,115,116,218,8,95,95,112,97, - 116,104,95,95,114,113,0,0,0,114,118,0,0,0,114,123, - 0,0,0,114,117,0,0,0,41,8,114,97,0,0,0,114, - 110,0,0,0,114,114,0,0,0,114,96,0,0,0,114,17, - 0,0,0,90,8,108,111,99,97,116,105,111,110,114,123,0, - 0,0,114,117,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,17,95,115,112,101,99,95,102,114, - 111,109,95,109,111,100,117,108,101,185,1,0,0,115,72,0, - 0,0,0,2,2,1,10,1,12,1,6,2,8,1,4,2, - 6,1,8,1,2,1,10,1,12,2,6,1,2,1,10,1, - 12,1,10,1,8,1,8,1,2,1,10,1,12,1,12,2, - 4,1,2,1,10,1,12,1,10,1,2,1,14,1,12,1, - 10,2,14,1,20,1,6,1,6,1,114,143,0,0,0,70, - 169,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0, - 0,0,0,0,0,1,0,0,0,5,0,0,0,8,0,0, - 0,67,0,0,0,115,210,1,0,0,124,2,115,20,116,0, - 124,1,100,1,100,0,131,3,100,0,117,0,114,52,122,12, - 124,0,106,1,124,1,95,2,87,0,110,18,4,0,116,3, - 121,50,1,0,1,0,1,0,89,0,110,2,48,0,124,2, - 115,72,116,0,124,1,100,2,100,0,131,3,100,0,117,0, - 114,174,124,0,106,4,125,3,124,3,100,0,117,0,114,144, - 124,0,106,5,100,0,117,1,114,144,116,6,100,0,117,0, - 114,108,116,7,130,1,116,6,106,8,125,4,124,4,160,9, - 124,4,161,1,125,3,124,0,106,5,124,3,95,10,124,3, - 124,0,95,4,100,0,124,1,95,11,122,10,124,3,124,1, - 95,12,87,0,110,18,4,0,116,3,121,172,1,0,1,0, - 1,0,89,0,110,2,48,0,124,2,115,194,116,0,124,1, - 100,3,100,0,131,3,100,0,117,0,114,226,122,12,124,0, - 106,13,124,1,95,14,87,0,110,18,4,0,116,3,121,224, - 1,0,1,0,1,0,89,0,110,2,48,0,122,10,124,0, - 124,1,95,15,87,0,110,18,4,0,116,3,121,254,1,0, - 1,0,1,0,89,0,110,2,48,0,124,2,144,1,115,24, - 116,0,124,1,100,4,100,0,131,3,100,0,117,0,144,1, - 114,70,124,0,106,5,100,0,117,1,144,1,114,70,122,12, - 124,0,106,5,124,1,95,16,87,0,110,20,4,0,116,3, - 144,1,121,68,1,0,1,0,1,0,89,0,110,2,48,0, - 124,0,106,17,144,1,114,206,124,2,144,1,115,102,116,0, - 124,1,100,5,100,0,131,3,100,0,117,0,144,1,114,136, - 122,12,124,0,106,18,124,1,95,11,87,0,110,20,4,0, - 116,3,144,1,121,134,1,0,1,0,1,0,89,0,110,2, - 48,0,124,2,144,1,115,160,116,0,124,1,100,6,100,0, - 131,3,100,0,117,0,144,1,114,206,124,0,106,19,100,0, - 117,1,144,1,114,206,122,12,124,0,106,19,124,1,95,20, - 87,0,110,20,4,0,116,3,144,1,121,204,1,0,1,0, - 1,0,89,0,110,2,48,0,124,1,83,0,41,7,78,114, - 1,0,0,0,114,99,0,0,0,218,11,95,95,112,97,99, - 107,97,103,101,95,95,114,142,0,0,0,114,109,0,0,0, - 114,140,0,0,0,41,21,114,6,0,0,0,114,17,0,0, - 0,114,1,0,0,0,114,107,0,0,0,114,110,0,0,0, - 114,117,0,0,0,114,127,0,0,0,114,128,0,0,0,218, - 16,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,218,7,95,95,110,101,119,95,95,90,5,95,112,97,116, - 104,114,109,0,0,0,114,99,0,0,0,114,131,0,0,0, - 114,146,0,0,0,114,106,0,0,0,114,142,0,0,0,114, - 124,0,0,0,114,114,0,0,0,114,123,0,0,0,114,140, - 0,0,0,41,5,114,96,0,0,0,114,97,0,0,0,114, - 145,0,0,0,114,110,0,0,0,114,147,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, - 105,110,105,116,95,109,111,100,117,108,101,95,97,116,116,114, - 115,230,1,0,0,115,96,0,0,0,0,4,20,1,2,1, - 12,1,12,1,6,2,20,1,6,1,8,2,10,1,8,1, - 4,1,6,2,10,1,8,1,6,11,6,1,2,1,10,1, - 12,1,6,2,20,1,2,1,12,1,12,1,6,2,2,1, - 10,1,12,1,6,2,24,1,12,1,2,1,12,1,14,1, - 6,2,8,1,24,1,2,1,12,1,14,1,6,2,24,1, - 12,1,2,1,12,1,14,1,6,1,114,149,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,82,0,0,0,100,1,125, - 1,116,0,124,0,106,1,100,2,131,2,114,30,124,0,106, - 1,160,2,124,0,161,1,125,1,110,20,116,0,124,0,106, - 1,100,3,131,2,114,50,116,3,100,4,131,1,130,1,124, - 1,100,1,117,0,114,68,116,4,124,0,106,5,131,1,125, - 1,116,6,124,0,124,1,131,2,1,0,124,1,83,0,41, - 5,122,43,67,114,101,97,116,101,32,97,32,109,111,100,117, - 108,101,32,98,97,115,101,100,32,111,110,32,116,104,101,32, - 112,114,111,118,105,100,101,100,32,115,112,101,99,46,78,218, - 13,99,114,101,97,116,101,95,109,111,100,117,108,101,218,11, - 101,120,101,99,95,109,111,100,117,108,101,122,66,108,111,97, - 100,101,114,115,32,116,104,97,116,32,100,101,102,105,110,101, - 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,109, - 117,115,116,32,97,108,115,111,32,100,101,102,105,110,101,32, - 99,114,101,97,116,101,95,109,111,100,117,108,101,40,41,41, - 7,114,4,0,0,0,114,110,0,0,0,114,150,0,0,0, - 114,80,0,0,0,114,18,0,0,0,114,17,0,0,0,114, - 149,0,0,0,169,2,114,96,0,0,0,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 16,109,111,100,117,108,101,95,102,114,111,109,95,115,112,101, - 99,46,2,0,0,115,18,0,0,0,0,3,4,1,12,3, - 14,1,12,1,8,2,8,1,10,1,10,1,114,153,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,4,0,0,0,67,0,0,0,115,106,0,0,0,124, - 0,106,0,100,1,117,0,114,14,100,2,110,4,124,0,106, - 0,125,1,124,0,106,1,100,1,117,0,114,66,124,0,106, - 2,100,1,117,0,114,50,100,3,160,3,124,1,161,1,83, - 0,100,4,160,3,124,1,124,0,106,2,161,2,83,0,110, - 36,124,0,106,4,114,86,100,5,160,3,124,1,124,0,106, - 1,161,2,83,0,100,6,160,3,124,0,106,0,124,0,106, - 1,161,2,83,0,100,1,83,0,41,7,122,38,82,101,116, - 117,114,110,32,116,104,101,32,114,101,112,114,32,116,111,32, - 117,115,101,32,102,111,114,32,116,104,101,32,109,111,100,117, - 108,101,46,78,114,101,0,0,0,114,102,0,0,0,114,103, - 0,0,0,114,104,0,0,0,250,18,60,109,111,100,117,108, - 101,32,123,33,114,125,32,40,123,125,41,62,41,5,114,17, - 0,0,0,114,114,0,0,0,114,110,0,0,0,114,46,0, - 0,0,114,124,0,0,0,41,2,114,96,0,0,0,114,17, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,108,0,0,0,63,2,0,0,115,16,0,0,0, - 0,3,20,1,10,1,10,1,10,2,16,2,6,1,14,2, - 114,108,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,10,0,0,0,67,0,0,0,115,250, - 0,0,0,124,0,106,0,125,2,116,1,124,2,131,1,143, - 216,1,0,116,2,106,3,160,4,124,2,161,1,124,1,117, - 1,114,54,100,1,160,5,124,2,161,1,125,3,116,6,124, - 3,124,2,100,2,141,2,130,1,122,132,124,0,106,7,100, - 3,117,0,114,106,124,0,106,8,100,3,117,0,114,90,116, - 6,100,4,124,0,106,0,100,2,141,2,130,1,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,110,52,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,116,10,124,0,106, - 7,100,7,131,2,115,146,124,0,106,7,160,11,124,2,161, - 1,1,0,110,12,124,0,106,7,160,12,124,1,161,1,1, - 0,87,0,116,2,106,3,160,13,124,0,106,0,161,1,125, - 1,124,1,116,2,106,3,124,0,106,0,60,0,110,28,116, - 2,106,3,160,13,124,0,106,0,161,1,125,1,124,1,116, - 2,106,3,124,0,106,0,60,0,48,0,87,0,100,3,4, - 0,4,0,131,3,1,0,110,16,49,0,115,236,48,0,1, - 0,1,0,1,0,89,0,1,0,124,1,83,0,41,8,122, - 70,69,120,101,99,117,116,101,32,116,104,101,32,115,112,101, - 99,39,115,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,32,105,110,32,97,110,32,101,120,105,115,116, - 105,110,103,32,109,111,100,117,108,101,39,115,32,110,97,109, - 101,115,112,97,99,101,46,122,30,109,111,100,117,108,101,32, - 123,33,114,125,32,110,111,116,32,105,110,32,115,121,115,46, - 109,111,100,117,108,101,115,114,16,0,0,0,78,250,14,109, - 105,115,115,105,110,103,32,108,111,97,100,101,114,84,114,144, - 0,0,0,114,151,0,0,0,41,14,114,17,0,0,0,114, - 51,0,0,0,114,15,0,0,0,114,93,0,0,0,114,35, - 0,0,0,114,46,0,0,0,114,80,0,0,0,114,110,0, - 0,0,114,117,0,0,0,114,149,0,0,0,114,4,0,0, - 0,218,11,108,111,97,100,95,109,111,100,117,108,101,114,151, - 0,0,0,218,3,112,111,112,41,4,114,96,0,0,0,114, - 97,0,0,0,114,17,0,0,0,218,3,109,115,103,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,94,0, - 0,0,80,2,0,0,115,38,0,0,0,0,2,6,1,10, - 1,16,1,10,1,12,1,2,1,10,1,10,1,14,2,16, - 2,14,1,12,4,14,2,14,4,14,1,14,255,14,1,44, - 1,114,94,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, - 20,1,0,0,122,18,124,0,106,0,160,1,124,0,106,2, - 161,1,1,0,87,0,110,52,1,0,1,0,1,0,124,0, - 106,2,116,3,106,4,118,0,114,64,116,3,106,4,160,5, - 124,0,106,2,161,1,125,1,124,1,116,3,106,4,124,0, - 106,2,60,0,130,0,89,0,110,2,48,0,116,3,106,4, + 25,0,83,0,124,0,106,1,83,0,41,4,122,32,84,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,32,109,111, + 100,117,108,101,39,115,32,112,97,114,101,110,116,46,78,218, + 1,46,114,22,0,0,0,41,3,114,117,0,0,0,114,17, + 0,0,0,218,10,114,112,97,114,116,105,116,105,111,110,114, + 48,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,6,112,97,114,101,110,116,142,1,0,0,115, + 6,0,0,0,0,3,10,1,16,2,122,17,77,111,100,117, + 108,101,83,112,101,99,46,112,97,114,101,110,116,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,114,13,0,0,0,41,1,114,118,0,0,0,114,48,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,124,0,0,0,150,1,0,0,115,2,0,0,0,0, + 2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,97, + 115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, + 0,0,0,115,14,0,0,0,116,0,124,1,131,1,124,0, + 95,1,100,0,83,0,114,13,0,0,0,41,2,218,4,98, + 111,111,108,114,118,0,0,0,41,2,114,30,0,0,0,218, + 5,118,97,108,117,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,124,0,0,0,154,1,0,0,115,2, + 0,0,0,0,2,41,12,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,3,0,0,0,114,31,0,0,0, + 114,49,0,0,0,114,126,0,0,0,218,8,112,114,111,112, + 101,114,116,121,114,123,0,0,0,218,6,115,101,116,116,101, + 114,114,131,0,0,0,114,124,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 113,0,0,0,58,1,0,0,115,32,0,0,0,8,1,4, + 36,4,1,2,255,12,12,8,10,8,12,2,1,10,8,4, + 1,10,3,2,1,10,7,2,1,10,3,4,1,114,113,0, + 0,0,169,2,114,114,0,0,0,114,116,0,0,0,99,2, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,8, + 0,0,0,67,0,0,0,115,150,0,0,0,116,0,124,1, + 100,1,131,2,114,74,116,1,100,2,117,0,114,22,116,2, + 130,1,116,1,106,3,125,4,124,3,100,2,117,0,114,48, + 124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,56, + 103,0,110,2,100,2,125,5,124,4,124,0,124,1,124,5, + 100,4,141,3,83,0,124,3,100,2,117,0,114,134,116,0, + 124,1,100,5,131,2,114,130,122,14,124,1,160,4,124,0, + 161,1,125,3,87,0,110,26,4,0,116,5,121,128,1,0, + 1,0,1,0,100,2,125,3,89,0,110,6,48,0,100,6, + 125,3,116,6,124,0,124,1,124,2,124,3,100,7,141,4, + 83,0,41,8,122,53,82,101,116,117,114,110,32,97,32,109, + 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, + 32,111,110,32,118,97,114,105,111,117,115,32,108,111,97,100, + 101,114,32,109,101,116,104,111,100,115,46,90,12,103,101,116, + 95,102,105,108,101,110,97,109,101,78,41,1,114,110,0,0, + 0,41,2,114,110,0,0,0,114,117,0,0,0,114,116,0, + 0,0,70,114,136,0,0,0,41,7,114,4,0,0,0,114, + 127,0,0,0,114,128,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,114,116,0,0,0,114,80,0,0,0,114,113,0,0, + 0,41,6,114,17,0,0,0,114,110,0,0,0,114,114,0, + 0,0,114,116,0,0,0,114,137,0,0,0,90,6,115,101, + 97,114,99,104,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,92,0,0,0,159,1,0,0,115,36,0,0, + 0,0,2,10,1,8,1,4,1,6,2,8,1,12,1,12, + 1,6,1,2,255,6,3,8,1,10,1,2,1,14,1,12, + 1,10,3,4,2,114,92,0,0,0,99,3,0,0,0,0, + 0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,67, + 0,0,0,115,40,1,0,0,122,10,124,0,106,0,125,3, + 87,0,110,18,4,0,116,1,121,28,1,0,1,0,1,0, + 89,0,110,14,48,0,124,3,100,0,117,1,114,42,124,3, + 83,0,124,0,106,2,125,4,124,1,100,0,117,0,114,86, + 122,10,124,0,106,3,125,1,87,0,110,18,4,0,116,1, + 121,84,1,0,1,0,1,0,89,0,110,2,48,0,122,10, + 124,0,106,4,125,5,87,0,110,22,4,0,116,1,121,118, + 1,0,1,0,1,0,100,0,125,5,89,0,110,2,48,0, + 124,2,100,0,117,0,114,174,124,5,100,0,117,0,114,170, + 122,10,124,1,106,5,125,2,87,0,110,26,4,0,116,1, + 121,168,1,0,1,0,1,0,100,0,125,2,89,0,110,6, + 48,0,124,5,125,2,122,10,124,0,106,6,125,6,87,0, + 110,22,4,0,116,1,121,206,1,0,1,0,1,0,100,0, + 125,6,89,0,110,2,48,0,122,14,116,7,124,0,106,8, + 131,1,125,7,87,0,110,22,4,0,116,1,121,244,1,0, + 1,0,1,0,100,0,125,7,89,0,110,2,48,0,116,9, + 124,4,124,1,124,2,100,1,141,3,125,3,124,5,100,0, + 117,0,144,1,114,18,100,2,110,2,100,3,124,3,95,10, + 124,6,124,3,95,11,124,7,124,3,95,12,124,3,83,0, + 41,4,78,169,1,114,114,0,0,0,70,84,41,13,114,106, + 0,0,0,114,107,0,0,0,114,1,0,0,0,114,99,0, + 0,0,114,109,0,0,0,218,7,95,79,82,73,71,73,78, + 218,10,95,95,99,97,99,104,101,100,95,95,218,4,108,105, + 115,116,218,8,95,95,112,97,116,104,95,95,114,113,0,0, + 0,114,118,0,0,0,114,123,0,0,0,114,117,0,0,0, + 41,8,114,97,0,0,0,114,110,0,0,0,114,114,0,0, + 0,114,96,0,0,0,114,17,0,0,0,90,8,108,111,99, + 97,116,105,111,110,114,123,0,0,0,114,117,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,17, + 95,115,112,101,99,95,102,114,111,109,95,109,111,100,117,108, + 101,185,1,0,0,115,72,0,0,0,0,2,2,1,10,1, + 12,1,6,2,8,1,4,2,6,1,8,1,2,1,10,1, + 12,2,6,1,2,1,10,1,12,1,10,1,8,1,8,1, + 2,1,10,1,12,1,10,2,4,1,2,1,10,1,12,1, + 10,1,2,1,14,1,12,1,10,2,14,1,20,1,6,1, + 6,1,114,143,0,0,0,70,169,1,218,8,111,118,101,114, + 114,105,100,101,99,2,0,0,0,0,0,0,0,1,0,0, + 0,5,0,0,0,8,0,0,0,67,0,0,0,115,210,1, + 0,0,124,2,115,20,116,0,124,1,100,1,100,0,131,3, + 100,0,117,0,114,52,122,12,124,0,106,1,124,1,95,2, + 87,0,110,18,4,0,116,3,121,50,1,0,1,0,1,0, + 89,0,110,2,48,0,124,2,115,72,116,0,124,1,100,2, + 100,0,131,3,100,0,117,0,114,174,124,0,106,4,125,3, + 124,3,100,0,117,0,114,144,124,0,106,5,100,0,117,1, + 114,144,116,6,100,0,117,0,114,108,116,7,130,1,116,6, + 106,8,125,4,124,4,160,9,124,4,161,1,125,3,124,0, + 106,5,124,3,95,10,124,3,124,0,95,4,100,0,124,1, + 95,11,122,10,124,3,124,1,95,12,87,0,110,18,4,0, + 116,3,121,172,1,0,1,0,1,0,89,0,110,2,48,0, + 124,2,115,194,116,0,124,1,100,3,100,0,131,3,100,0, + 117,0,114,226,122,12,124,0,106,13,124,1,95,14,87,0, + 110,18,4,0,116,3,121,224,1,0,1,0,1,0,89,0, + 110,2,48,0,122,10,124,0,124,1,95,15,87,0,110,18, + 4,0,116,3,121,254,1,0,1,0,1,0,89,0,110,2, + 48,0,124,2,144,1,115,24,116,0,124,1,100,4,100,0, + 131,3,100,0,117,0,144,1,114,70,124,0,106,5,100,0, + 117,1,144,1,114,70,122,12,124,0,106,5,124,1,95,16, + 87,0,110,20,4,0,116,3,144,1,121,68,1,0,1,0, + 1,0,89,0,110,2,48,0,124,0,106,17,144,1,114,206, + 124,2,144,1,115,102,116,0,124,1,100,5,100,0,131,3, + 100,0,117,0,144,1,114,136,122,12,124,0,106,18,124,1, + 95,11,87,0,110,20,4,0,116,3,144,1,121,134,1,0, + 1,0,1,0,89,0,110,2,48,0,124,2,144,1,115,160, + 116,0,124,1,100,6,100,0,131,3,100,0,117,0,144,1, + 114,206,124,0,106,19,100,0,117,1,144,1,114,206,122,12, + 124,0,106,19,124,1,95,20,87,0,110,20,4,0,116,3, + 144,1,121,204,1,0,1,0,1,0,89,0,110,2,48,0, + 124,1,83,0,41,7,78,114,1,0,0,0,114,99,0,0, + 0,218,11,95,95,112,97,99,107,97,103,101,95,95,114,142, + 0,0,0,114,109,0,0,0,114,140,0,0,0,41,21,114, + 6,0,0,0,114,17,0,0,0,114,1,0,0,0,114,107, + 0,0,0,114,110,0,0,0,114,117,0,0,0,114,127,0, + 0,0,114,128,0,0,0,218,16,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,218,7,95,95,110,101,119, + 95,95,90,5,95,112,97,116,104,114,109,0,0,0,114,99, + 0,0,0,114,131,0,0,0,114,146,0,0,0,114,106,0, + 0,0,114,142,0,0,0,114,124,0,0,0,114,114,0,0, + 0,114,123,0,0,0,114,140,0,0,0,41,5,114,96,0, + 0,0,114,97,0,0,0,114,145,0,0,0,114,110,0,0, + 0,114,147,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,18,95,105,110,105,116,95,109,111,100, + 117,108,101,95,97,116,116,114,115,230,1,0,0,115,96,0, + 0,0,0,4,20,1,2,1,12,1,12,1,6,2,20,1, + 6,1,8,2,10,1,8,1,4,1,6,2,10,1,8,1, + 6,11,6,1,2,1,10,1,12,1,6,2,20,1,2,1, + 12,1,12,1,6,2,2,1,10,1,12,1,6,2,24,1, + 12,1,2,1,12,1,14,1,6,2,8,1,24,1,2,1, + 12,1,14,1,6,2,24,1,12,1,2,1,12,1,14,1, + 6,1,114,149,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,82,0,0,0,100,1,125,1,116,0,124,0,106,1,100, + 2,131,2,114,30,124,0,106,1,160,2,124,0,161,1,125, + 1,110,20,116,0,124,0,106,1,100,3,131,2,114,50,116, + 3,100,4,131,1,130,1,124,1,100,1,117,0,114,68,116, + 4,124,0,106,5,131,1,125,1,116,6,124,0,124,1,131, + 2,1,0,124,1,83,0,41,5,122,43,67,114,101,97,116, + 101,32,97,32,109,111,100,117,108,101,32,98,97,115,101,100, + 32,111,110,32,116,104,101,32,112,114,111,118,105,100,101,100, + 32,115,112,101,99,46,78,218,13,99,114,101,97,116,101,95, + 109,111,100,117,108,101,218,11,101,120,101,99,95,109,111,100, + 117,108,101,122,66,108,111,97,100,101,114,115,32,116,104,97, + 116,32,100,101,102,105,110,101,32,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,109,117,115,116,32,97,108,115,111, + 32,100,101,102,105,110,101,32,99,114,101,97,116,101,95,109, + 111,100,117,108,101,40,41,41,7,114,4,0,0,0,114,110, + 0,0,0,114,150,0,0,0,114,80,0,0,0,114,18,0, + 0,0,114,17,0,0,0,114,149,0,0,0,169,2,114,96, + 0,0,0,114,97,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,16,109,111,100,117,108,101,95, + 102,114,111,109,95,115,112,101,99,46,2,0,0,115,18,0, + 0,0,0,3,4,1,12,3,14,1,12,1,8,2,8,1, + 10,1,10,1,114,153,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,67,0, + 0,0,115,100,0,0,0,124,0,106,0,100,1,117,0,114, + 14,100,2,110,4,124,0,106,0,125,1,124,0,106,1,100, + 1,117,0,114,64,124,0,106,2,100,1,117,0,114,50,100, + 3,160,3,124,1,161,1,83,0,100,4,160,3,124,1,124, + 0,106,2,161,2,83,0,124,0,106,4,114,84,100,5,160, + 3,124,1,124,0,106,1,161,2,83,0,100,6,160,3,124, + 0,106,0,124,0,106,1,161,2,83,0,41,7,122,38,82, + 101,116,117,114,110,32,116,104,101,32,114,101,112,114,32,116, + 111,32,117,115,101,32,102,111,114,32,116,104,101,32,109,111, + 100,117,108,101,46,78,114,101,0,0,0,114,102,0,0,0, + 114,103,0,0,0,114,104,0,0,0,250,18,60,109,111,100, + 117,108,101,32,123,33,114,125,32,40,123,125,41,62,41,5, + 114,17,0,0,0,114,114,0,0,0,114,110,0,0,0,114, + 46,0,0,0,114,124,0,0,0,41,2,114,96,0,0,0, + 114,17,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,108,0,0,0,63,2,0,0,115,16,0, + 0,0,0,3,20,1,10,1,10,1,10,2,14,2,6,1, + 14,2,114,108,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,10,0,0,0,67,0,0,0, + 115,250,0,0,0,124,0,106,0,125,2,116,1,124,2,131, + 1,143,216,1,0,116,2,106,3,160,4,124,2,161,1,124, + 1,117,1,114,54,100,1,160,5,124,2,161,1,125,3,116, + 6,124,3,124,2,100,2,141,2,130,1,122,132,124,0,106, + 7,100,3,117,0,114,106,124,0,106,8,100,3,117,0,114, + 90,116,6,100,4,124,0,106,0,100,2,141,2,130,1,116, + 9,124,0,124,1,100,5,100,6,141,3,1,0,110,52,116, + 9,124,0,124,1,100,5,100,6,141,3,1,0,116,10,124, + 0,106,7,100,7,131,2,115,146,124,0,106,7,160,11,124, + 2,161,1,1,0,110,12,124,0,106,7,160,12,124,1,161, + 1,1,0,87,0,116,2,106,3,160,13,124,0,106,0,161, + 1,125,1,124,1,116,2,106,3,124,0,106,0,60,0,110, + 28,116,2,106,3,160,13,124,0,106,0,161,1,125,1,124, + 1,116,2,106,3,124,0,106,0,60,0,48,0,87,0,100, + 3,4,0,4,0,131,3,1,0,110,16,49,0,115,236,48, + 0,1,0,1,0,1,0,89,0,1,0,124,1,83,0,41, + 8,122,70,69,120,101,99,117,116,101,32,116,104,101,32,115, + 112,101,99,39,115,32,115,112,101,99,105,102,105,101,100,32, + 109,111,100,117,108,101,32,105,110,32,97,110,32,101,120,105, + 115,116,105,110,103,32,109,111,100,117,108,101,39,115,32,110, + 97,109,101,115,112,97,99,101,46,122,30,109,111,100,117,108, + 101,32,123,33,114,125,32,110,111,116,32,105,110,32,115,121, + 115,46,109,111,100,117,108,101,115,114,16,0,0,0,78,250, + 14,109,105,115,115,105,110,103,32,108,111,97,100,101,114,84, + 114,144,0,0,0,114,151,0,0,0,41,14,114,17,0,0, + 0,114,51,0,0,0,114,15,0,0,0,114,93,0,0,0, + 114,35,0,0,0,114,46,0,0,0,114,80,0,0,0,114, + 110,0,0,0,114,117,0,0,0,114,149,0,0,0,114,4, + 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, + 114,151,0,0,0,218,3,112,111,112,41,4,114,96,0,0, + 0,114,97,0,0,0,114,17,0,0,0,218,3,109,115,103, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 94,0,0,0,80,2,0,0,115,38,0,0,0,0,2,6, + 1,10,1,16,1,10,1,12,1,2,1,10,1,10,1,14, + 2,16,2,14,1,12,4,14,2,14,4,14,1,14,255,14, + 1,44,1,114,94,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, + 0,115,20,1,0,0,122,18,124,0,106,0,160,1,124,0, + 106,2,161,1,1,0,87,0,110,52,1,0,1,0,1,0, + 124,0,106,2,116,3,106,4,118,0,114,64,116,3,106,4, 160,5,124,0,106,2,161,1,125,1,124,1,116,3,106,4, - 124,0,106,2,60,0,116,6,124,1,100,1,100,0,131,3, - 100,0,117,0,114,146,122,12,124,0,106,0,124,1,95,7, - 87,0,110,18,4,0,116,8,121,144,1,0,1,0,1,0, - 89,0,110,2,48,0,116,6,124,1,100,2,100,0,131,3, - 100,0,117,0,114,222,122,40,124,1,106,9,124,1,95,10, - 116,11,124,1,100,3,131,2,115,200,124,0,106,2,160,12, - 100,4,161,1,100,5,25,0,124,1,95,10,87,0,110,18, - 4,0,116,8,121,220,1,0,1,0,1,0,89,0,110,2, - 48,0,116,6,124,1,100,6,100,0,131,3,100,0,117,0, - 144,1,114,16,122,10,124,0,124,1,95,13,87,0,110,20, - 4,0,116,8,144,1,121,14,1,0,1,0,1,0,89,0, - 110,2,48,0,124,1,83,0,41,7,78,114,99,0,0,0, - 114,146,0,0,0,114,142,0,0,0,114,129,0,0,0,114, - 22,0,0,0,114,106,0,0,0,41,14,114,110,0,0,0, - 114,156,0,0,0,114,17,0,0,0,114,15,0,0,0,114, - 93,0,0,0,114,157,0,0,0,114,6,0,0,0,114,99, - 0,0,0,114,107,0,0,0,114,1,0,0,0,114,146,0, - 0,0,114,4,0,0,0,114,130,0,0,0,114,106,0,0, - 0,114,152,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, - 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, - 110,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, - 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, - 1,12,1,12,1,6,1,16,1,2,4,8,1,10,1,22, - 1,12,1,6,1,18,1,2,1,10,1,14,1,6,1,114, - 159,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,11,0,0,0,67,0,0,0,115,224,0, - 0,0,124,0,106,0,100,0,117,1,114,30,116,1,124,0, - 106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0, - 116,3,124,0,131,1,125,1,100,2,124,0,95,4,122,166, - 124,1,116,5,106,6,124,0,106,7,60,0,122,52,124,0, - 106,0,100,0,117,0,114,96,124,0,106,8,100,0,117,0, - 114,108,116,9,100,3,124,0,106,7,100,4,141,2,130,1, - 110,12,124,0,106,0,160,10,124,1,161,1,1,0,87,0, - 110,48,1,0,1,0,1,0,122,14,116,5,106,6,124,0, - 106,7,61,0,87,0,110,18,4,0,116,11,121,150,1,0, - 1,0,1,0,89,0,110,2,48,0,130,0,89,0,110,2, - 48,0,116,5,106,6,160,12,124,0,106,7,161,1,125,1, - 124,1,116,5,106,6,124,0,106,7,60,0,116,13,100,5, - 124,0,106,7,124,0,106,0,131,3,1,0,87,0,100,6, - 124,0,95,4,110,8,100,6,124,0,95,4,48,0,124,1, - 83,0,41,7,78,114,151,0,0,0,84,114,155,0,0,0, - 114,16,0,0,0,122,18,105,109,112,111,114,116,32,123,33, - 114,125,32,35,32,123,33,114,125,70,41,14,114,110,0,0, - 0,114,4,0,0,0,114,159,0,0,0,114,153,0,0,0, - 90,13,95,105,110,105,116,105,97,108,105,122,105,110,103,114, - 15,0,0,0,114,93,0,0,0,114,17,0,0,0,114,117, - 0,0,0,114,80,0,0,0,114,151,0,0,0,114,64,0, - 0,0,114,157,0,0,0,114,77,0,0,0,114,152,0,0, + 124,0,106,2,60,0,130,0,89,0,110,2,48,0,116,3, + 106,4,160,5,124,0,106,2,161,1,125,1,124,1,116,3, + 106,4,124,0,106,2,60,0,116,6,124,1,100,1,100,0, + 131,3,100,0,117,0,114,146,122,12,124,0,106,0,124,1, + 95,7,87,0,110,18,4,0,116,8,121,144,1,0,1,0, + 1,0,89,0,110,2,48,0,116,6,124,1,100,2,100,0, + 131,3,100,0,117,0,114,222,122,40,124,1,106,9,124,1, + 95,10,116,11,124,1,100,3,131,2,115,200,124,0,106,2, + 160,12,100,4,161,1,100,5,25,0,124,1,95,10,87,0, + 110,18,4,0,116,8,121,220,1,0,1,0,1,0,89,0, + 110,2,48,0,116,6,124,1,100,6,100,0,131,3,100,0, + 117,0,144,1,114,16,122,10,124,0,124,1,95,13,87,0, + 110,20,4,0,116,8,144,1,121,14,1,0,1,0,1,0, + 89,0,110,2,48,0,124,1,83,0,41,7,78,114,99,0, + 0,0,114,146,0,0,0,114,142,0,0,0,114,129,0,0, + 0,114,22,0,0,0,114,106,0,0,0,41,14,114,110,0, + 0,0,114,156,0,0,0,114,17,0,0,0,114,15,0,0, + 0,114,93,0,0,0,114,157,0,0,0,114,6,0,0,0, + 114,99,0,0,0,114,107,0,0,0,114,1,0,0,0,114, + 146,0,0,0,114,4,0,0,0,114,130,0,0,0,114,106, + 0,0,0,114,152,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,25,95,108,111,97,100,95,98, + 97,99,107,119,97,114,100,95,99,111,109,112,97,116,105,98, + 108,101,110,2,0,0,115,54,0,0,0,0,4,2,1,18, + 1,6,1,12,1,14,1,12,1,8,3,14,1,12,1,16, + 1,2,1,12,1,12,1,6,1,16,1,2,4,8,1,10, + 1,22,1,12,1,6,1,18,1,2,1,10,1,14,1,6, + 1,114,159,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,11,0,0,0,67,0,0,0,115, + 216,0,0,0,124,0,106,0,100,0,117,1,114,30,116,1, + 124,0,106,0,100,1,131,2,115,30,116,2,124,0,131,1, + 83,0,116,3,124,0,131,1,125,1,100,2,124,0,95,4, + 122,158,124,1,116,5,106,6,124,0,106,7,60,0,122,52, + 124,0,106,0,100,0,117,0,114,96,124,0,106,8,100,0, + 117,0,114,108,116,9,100,3,124,0,106,7,100,4,141,2, + 130,1,110,12,124,0,106,0,160,10,124,1,161,1,1,0, + 87,0,110,40,1,0,1,0,1,0,122,14,116,5,106,6, + 124,0,106,7,61,0,87,0,130,0,4,0,116,11,121,150, + 1,0,1,0,1,0,89,0,130,0,48,0,116,5,106,6, + 160,12,124,0,106,7,161,1,125,1,124,1,116,5,106,6, + 124,0,106,7,60,0,116,13,100,5,124,0,106,7,124,0, + 106,0,131,3,1,0,87,0,100,6,124,0,95,4,110,8, + 100,6,124,0,95,4,48,0,124,1,83,0,41,7,78,114, + 151,0,0,0,84,114,155,0,0,0,114,16,0,0,0,122, + 18,105,109,112,111,114,116,32,123,33,114,125,32,35,32,123, + 33,114,125,70,41,14,114,110,0,0,0,114,4,0,0,0, + 114,159,0,0,0,114,153,0,0,0,90,13,95,105,110,105, + 116,105,97,108,105,122,105,110,103,114,15,0,0,0,114,93, + 0,0,0,114,17,0,0,0,114,117,0,0,0,114,80,0, + 0,0,114,151,0,0,0,114,64,0,0,0,114,157,0,0, + 0,114,77,0,0,0,114,152,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,14,95,108,111,97, + 100,95,117,110,108,111,99,107,101,100,147,2,0,0,115,44, + 0,0,0,0,2,10,2,12,1,8,2,8,5,6,1,2, + 1,12,1,2,1,10,1,10,1,16,3,16,1,6,1,2, + 1,14,1,12,1,6,6,14,1,12,1,18,2,16,2,114, + 160,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,8,0,0,0,67,0,0,0,115,54,0, + 0,0,116,0,124,0,106,1,131,1,143,24,1,0,116,2, + 124,0,131,1,87,0,2,0,100,1,4,0,4,0,131,3, + 1,0,83,0,49,0,115,40,48,0,1,0,1,0,1,0, + 89,0,1,0,100,1,83,0,41,2,122,191,82,101,116,117, + 114,110,32,97,32,110,101,119,32,109,111,100,117,108,101,32, + 111,98,106,101,99,116,44,32,108,111,97,100,101,100,32,98, + 121,32,116,104,101,32,115,112,101,99,39,115,32,108,111,97, + 100,101,114,46,10,10,32,32,32,32,84,104,101,32,109,111, + 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, + 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, + 10,10,32,32,32,32,73,102,32,97,32,109,111,100,117,108, + 101,32,105,115,32,97,108,114,101,97,100,121,32,105,110,32, + 115,121,115,46,109,111,100,117,108,101,115,44,32,116,104,97, + 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, + 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, + 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,51, + 0,0,0,114,17,0,0,0,114,160,0,0,0,41,1,114, + 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,95,0,0,0,189,2,0,0,115,4,0,0, + 0,0,9,12,1,114,95,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64, + 0,0,0,115,140,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,90,4,101,5,100,3,100,4,132,0, + 131,1,90,6,101,7,100,20,100,6,100,7,132,1,131,1, + 90,8,101,7,100,21,100,8,100,9,132,1,131,1,90,9, + 101,7,100,10,100,11,132,0,131,1,90,10,101,7,100,12, + 100,13,132,0,131,1,90,11,101,7,101,12,100,14,100,15, + 132,0,131,1,131,1,90,13,101,7,101,12,100,16,100,17, + 132,0,131,1,131,1,90,14,101,7,101,12,100,18,100,19, + 132,0,131,1,131,1,90,15,101,7,101,16,131,1,90,17, + 100,5,83,0,41,22,218,15,66,117,105,108,116,105,110,73, + 109,112,111,114,116,101,114,122,144,77,101,116,97,32,112,97, + 116,104,32,105,109,112,111,114,116,32,102,111,114,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,115,46,10, + 10,32,32,32,32,65,108,108,32,109,101,116,104,111,100,115, + 32,97,114,101,32,101,105,116,104,101,114,32,99,108,97,115, + 115,32,111,114,32,115,116,97,116,105,99,32,109,101,116,104, + 111,100,115,32,116,111,32,97,118,111,105,100,32,116,104,101, + 32,110,101,101,100,32,116,111,10,32,32,32,32,105,110,115, + 116,97,110,116,105,97,116,101,32,116,104,101,32,99,108,97, + 115,115,46,10,10,32,32,32,32,122,8,98,117,105,108,116, + 45,105,110,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,5,0,0,0,67,0,0,0,115,22,0,0, + 0,100,1,124,0,106,0,155,2,100,2,116,1,106,2,155, + 0,100,3,157,5,83,0,41,4,250,115,82,101,116,117,114, + 110,32,114,101,112,114,32,102,111,114,32,116,104,101,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,101,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,84,104,101,32,105, + 109,112,111,114,116,32,109,97,99,104,105,110,101,114,121,32, + 100,111,101,115,32,116,104,101,32,106,111,98,32,105,116,115, + 101,108,102,46,10,10,32,32,32,32,32,32,32,32,122,8, + 60,109,111,100,117,108,101,32,122,2,32,40,122,2,41,62, + 41,3,114,1,0,0,0,114,161,0,0,0,114,139,0,0, + 0,41,1,114,97,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,100,0,0,0,215,2,0,0, + 115,2,0,0,0,0,7,122,27,66,117,105,108,116,105,110, + 73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95, + 114,101,112,114,78,99,4,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,42, + 0,0,0,124,2,100,0,117,1,114,12,100,0,83,0,116, + 0,160,1,124,1,161,1,114,38,116,2,124,1,124,0,124, + 0,106,3,100,1,141,3,83,0,100,0,83,0,169,2,78, + 114,138,0,0,0,41,4,114,58,0,0,0,90,10,105,115, + 95,98,117,105,108,116,105,110,114,92,0,0,0,114,139,0, + 0,0,169,4,218,3,99,108,115,114,82,0,0,0,218,4, + 112,97,116,104,218,6,116,97,114,103,101,116,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,9,102,105,110, + 100,95,115,112,101,99,224,2,0,0,115,10,0,0,0,0, + 2,8,1,4,1,10,1,16,2,122,25,66,117,105,108,116, + 105,110,73,109,112,111,114,116,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, + 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, + 100,1,117,1,114,26,124,3,106,1,83,0,100,1,83,0, + 41,2,122,175,70,105,110,100,32,116,104,101,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,73,102,32,39,112,97,116,104,39, + 32,105,115,32,101,118,101,114,32,115,112,101,99,105,102,105, + 101,100,32,116,104,101,110,32,116,104,101,32,115,101,97,114, + 99,104,32,105,115,32,99,111,110,115,105,100,101,114,101,100, + 32,97,32,102,97,105,108,117,114,101,46,10,10,32,32,32, + 32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,32, + 32,85,115,101,32,102,105,110,100,95,115,112,101,99,40,41, + 32,105,110,115,116,101,97,100,46,10,10,32,32,32,32,32, + 32,32,32,78,41,2,114,168,0,0,0,114,110,0,0,0, + 41,4,114,165,0,0,0,114,82,0,0,0,114,166,0,0, + 0,114,96,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,11,102,105,110,100,95,109,111,100,117, + 108,101,233,2,0,0,115,4,0,0,0,0,9,12,1,122, + 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, + 46,102,105,110,100,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, + 0,67,0,0,0,115,46,0,0,0,124,1,106,0,116,1, + 106,2,118,1,114,34,116,3,100,1,160,4,124,1,106,0, + 161,1,124,1,106,0,100,2,141,2,130,1,116,5,116,6, + 106,7,124,1,131,2,83,0,41,3,122,24,67,114,101,97, + 116,101,32,97,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,114,78,0,0,0,114,16,0,0,0,41,8, + 114,17,0,0,0,114,15,0,0,0,114,79,0,0,0,114, + 80,0,0,0,114,46,0,0,0,114,68,0,0,0,114,58, + 0,0,0,90,14,99,114,101,97,116,101,95,98,117,105,108, + 116,105,110,41,2,114,30,0,0,0,114,96,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,150, + 0,0,0,245,2,0,0,115,10,0,0,0,0,3,12,1, + 12,1,4,255,6,2,122,29,66,117,105,108,116,105,110,73, + 109,112,111,114,116,101,114,46,99,114,101,97,116,101,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,16, + 0,0,0,116,0,116,1,106,2,124,1,131,2,1,0,100, + 1,83,0,41,2,122,22,69,120,101,99,32,97,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,78,41,3, + 114,68,0,0,0,114,58,0,0,0,90,12,101,120,101,99, + 95,98,117,105,108,116,105,110,41,2,114,30,0,0,0,114, + 97,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,151,0,0,0,253,2,0,0,115,2,0,0, + 0,0,3,122,27,66,117,105,108,116,105,110,73,109,112,111, + 114,116,101,114,46,101,120,101,99,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,122,57,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,115,32,100,111,32,110,111,116,32,104,97,118, + 101,32,99,111,100,101,32,111,98,106,101,99,116,115,46,78, + 114,10,0,0,0,169,2,114,165,0,0,0,114,82,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,14,95,108,111,97,100,95,117,110,108,111,99,107,101,100, - 147,2,0,0,115,46,0,0,0,0,2,10,2,12,1,8, - 2,8,5,6,1,2,1,12,1,2,1,10,1,10,1,16, - 3,16,1,6,1,2,1,14,1,12,1,6,1,8,5,14, - 1,12,1,18,2,16,2,114,160,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, - 0,67,0,0,0,115,54,0,0,0,116,0,124,0,106,1, - 131,1,143,24,1,0,116,2,124,0,131,1,87,0,2,0, - 100,1,4,0,4,0,131,3,1,0,83,0,49,0,115,40, - 48,0,1,0,1,0,1,0,89,0,1,0,100,1,83,0, - 41,2,122,191,82,101,116,117,114,110,32,97,32,110,101,119, - 32,109,111,100,117,108,101,32,111,98,106,101,99,116,44,32, - 108,111,97,100,101,100,32,98,121,32,116,104,101,32,115,112, - 101,99,39,115,32,108,111,97,100,101,114,46,10,10,32,32, - 32,32,84,104,101,32,109,111,100,117,108,101,32,105,115,32, - 110,111,116,32,97,100,100,101,100,32,116,111,32,105,116,115, - 32,112,97,114,101,110,116,46,10,10,32,32,32,32,73,102, - 32,97,32,109,111,100,117,108,101,32,105,115,32,97,108,114, - 101,97,100,121,32,105,110,32,115,121,115,46,109,111,100,117, - 108,101,115,44,32,116,104,97,116,32,101,120,105,115,116,105, - 110,103,32,109,111,100,117,108,101,32,103,101,116,115,10,32, - 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, - 32,32,32,78,41,3,114,51,0,0,0,114,17,0,0,0, - 114,160,0,0,0,41,1,114,96,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,95,0,0,0, - 189,2,0,0,115,4,0,0,0,0,9,12,1,114,95,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,64,0,0,0,115,140,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,90,4, - 101,5,100,3,100,4,132,0,131,1,90,6,101,7,100,20, - 100,6,100,7,132,1,131,1,90,8,101,7,100,21,100,8, - 100,9,132,1,131,1,90,9,101,7,100,10,100,11,132,0, - 131,1,90,10,101,7,100,12,100,13,132,0,131,1,90,11, - 101,7,101,12,100,14,100,15,132,0,131,1,131,1,90,13, - 101,7,101,12,100,16,100,17,132,0,131,1,131,1,90,14, - 101,7,101,12,100,18,100,19,132,0,131,1,131,1,90,15, - 101,7,101,16,131,1,90,17,100,5,83,0,41,22,218,15, - 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,122, - 144,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114, - 116,32,102,111,114,32,98,117,105,108,116,45,105,110,32,109, + 218,8,103,101,116,95,99,111,100,101,2,3,0,0,115,2, + 0,0,0,0,4,122,24,66,117,105,108,116,105,110,73,109, + 112,111,114,116,101,114,46,103,101,116,95,99,111,100,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, + 0,41,2,122,56,82,101,116,117,114,110,32,78,111,110,101, + 32,97,115,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,10, + 0,0,0,114,170,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,10,103,101,116,95,115,111,117, + 114,99,101,8,3,0,0,115,2,0,0,0,0,4,122,26, + 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,52, + 82,101,116,117,114,110,32,70,97,108,115,101,32,97,115,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, + 32,97,114,101,32,110,101,118,101,114,32,112,97,99,107,97, + 103,101,115,46,70,114,10,0,0,0,114,170,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,116, + 0,0,0,14,3,0,0,115,2,0,0,0,0,4,122,26, + 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, + 105,115,95,112,97,99,107,97,103,101,41,2,78,78,41,1, + 78,41,18,114,1,0,0,0,114,0,0,0,0,114,2,0, + 0,0,114,3,0,0,0,114,139,0,0,0,218,12,115,116, + 97,116,105,99,109,101,116,104,111,100,114,100,0,0,0,218, + 11,99,108,97,115,115,109,101,116,104,111,100,114,168,0,0, + 0,114,169,0,0,0,114,150,0,0,0,114,151,0,0,0, + 114,87,0,0,0,114,171,0,0,0,114,172,0,0,0,114, + 116,0,0,0,114,98,0,0,0,114,156,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,161,0,0,0,204,2,0,0,115,44,0,0,0, + 8,2,4,7,4,2,2,1,10,8,2,1,12,8,2,1, + 12,11,2,1,10,7,2,1,10,4,2,1,2,1,12,4, + 2,1,2,1,12,4,2,1,2,1,12,4,114,161,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,64,0,0,0,115,144,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,101, + 5,100,3,100,4,132,0,131,1,90,6,101,7,100,22,100, + 6,100,7,132,1,131,1,90,8,101,7,100,23,100,8,100, + 9,132,1,131,1,90,9,101,7,100,10,100,11,132,0,131, + 1,90,10,101,5,100,12,100,13,132,0,131,1,90,11,101, + 7,100,14,100,15,132,0,131,1,90,12,101,7,101,13,100, + 16,100,17,132,0,131,1,131,1,90,14,101,7,101,13,100, + 18,100,19,132,0,131,1,131,1,90,15,101,7,101,13,100, + 20,100,21,132,0,131,1,131,1,90,16,100,5,83,0,41, + 24,218,14,70,114,111,122,101,110,73,109,112,111,114,116,101, + 114,122,142,77,101,116,97,32,112,97,116,104,32,105,109,112, + 111,114,116,32,102,111,114,32,102,114,111,122,101,110,32,109, 111,100,117,108,101,115,46,10,10,32,32,32,32,65,108,108, 32,109,101,116,104,111,100,115,32,97,114,101,32,101,105,116, 104,101,114,32,99,108,97,115,115,32,111,114,32,115,116,97, @@ -1052,163 +1193,19 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 118,111,105,100,32,116,104,101,32,110,101,101,100,32,116,111, 10,32,32,32,32,105,110,115,116,97,110,116,105,97,116,101, 32,116,104,101,32,99,108,97,115,115,46,10,10,32,32,32, - 32,122,8,98,117,105,108,116,45,105,110,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0, - 67,0,0,0,115,22,0,0,0,100,1,124,0,106,0,155, - 2,100,2,116,1,106,2,155,0,100,3,157,5,83,0,41, - 4,250,115,82,101,116,117,114,110,32,114,101,112,114,32,102, - 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97, - 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101, - 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32, - 32,32,32,32,32,32,122,8,60,109,111,100,117,108,101,32, - 122,2,32,40,122,2,41,62,41,3,114,1,0,0,0,114, - 161,0,0,0,114,139,0,0,0,41,1,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 100,0,0,0,215,2,0,0,115,2,0,0,0,0,7,122, - 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0, - 0,0,67,0,0,0,115,46,0,0,0,124,2,100,0,117, - 1,114,12,100,0,83,0,116,0,160,1,124,1,161,1,114, - 38,116,2,124,1,124,0,124,0,106,3,100,1,141,3,83, - 0,100,0,83,0,100,0,83,0,169,2,78,114,138,0,0, - 0,41,4,114,58,0,0,0,90,10,105,115,95,98,117,105, - 108,116,105,110,114,92,0,0,0,114,139,0,0,0,169,4, - 218,3,99,108,115,114,82,0,0,0,218,4,112,97,116,104, - 218,6,116,97,114,103,101,116,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,9,102,105,110,100,95,115,112, - 101,99,224,2,0,0,115,10,0,0,0,0,2,8,1,4, - 1,10,1,16,2,122,25,66,117,105,108,116,105,110,73,109, - 112,111,114,116,101,114,46,102,105,110,100,95,115,112,101,99, - 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,4,0,0,0,67,0,0,0,115,30,0,0,0,124,0, - 160,0,124,1,124,2,161,2,125,3,124,3,100,1,117,1, - 114,26,124,3,106,1,83,0,100,1,83,0,41,2,122,175, - 70,105,110,100,32,116,104,101,32,98,117,105,108,116,45,105, - 110,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,39,112,97,116,104,39,32,105,115,32, - 101,118,101,114,32,115,112,101,99,105,102,105,101,100,32,116, - 104,101,110,32,116,104,101,32,115,101,97,114,99,104,32,105, - 115,32,99,111,110,115,105,100,101,114,101,100,32,97,32,102, - 97,105,108,117,114,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, - 41,2,114,168,0,0,0,114,110,0,0,0,41,4,114,165, - 0,0,0,114,82,0,0,0,114,166,0,0,0,114,96,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,11,102,105,110,100,95,109,111,100,117,108,101,233,2, - 0,0,115,4,0,0,0,0,9,12,1,122,27,66,117,105, - 108,116,105,110,73,109,112,111,114,116,101,114,46,102,105,110, - 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,46,0,0,0,124,1,106,0,116,1,106,2,118,1, - 114,34,116,3,100,1,160,4,124,1,106,0,161,1,124,1, - 106,0,100,2,141,2,130,1,116,5,116,6,106,7,124,1, - 131,2,83,0,41,3,122,24,67,114,101,97,116,101,32,97, - 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, - 114,78,0,0,0,114,16,0,0,0,41,8,114,17,0,0, - 0,114,15,0,0,0,114,79,0,0,0,114,80,0,0,0, - 114,46,0,0,0,114,68,0,0,0,114,58,0,0,0,90, - 14,99,114,101,97,116,101,95,98,117,105,108,116,105,110,41, - 2,114,30,0,0,0,114,96,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,150,0,0,0,245, - 2,0,0,115,10,0,0,0,0,3,12,1,12,1,4,255, - 6,2,122,29,66,117,105,108,116,105,110,73,109,112,111,114, - 116,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,116,1,106,2,124,1,131,2,1,0,100,1,83,0,41, - 2,122,22,69,120,101,99,32,97,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,78,41,3,114,68,0,0, - 0,114,58,0,0,0,90,12,101,120,101,99,95,98,117,105, - 108,116,105,110,41,2,114,30,0,0,0,114,97,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 151,0,0,0,253,2,0,0,115,2,0,0,0,0,3,122, - 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, - 122,57,82,101,116,117,114,110,32,78,111,110,101,32,97,115, - 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, - 115,32,100,111,32,110,111,116,32,104,97,118,101,32,99,111, - 100,101,32,111,98,106,101,99,116,115,46,78,114,10,0,0, - 0,169,2,114,165,0,0,0,114,82,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,8,103,101, - 116,95,99,111,100,101,2,3,0,0,115,2,0,0,0,0, - 4,122,24,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, - 56,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, - 32,100,111,32,110,111,116,32,104,97,118,101,32,115,111,117, - 114,99,101,32,99,111,100,101,46,78,114,10,0,0,0,114, - 170,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,8, - 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108, - 116,105,110,73,109,112,111,114,116,101,114,46,103,101,116,95, - 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,41,2,122,52,82,101,116,117, - 114,110,32,70,97,108,115,101,32,97,115,32,98,117,105,108, - 116,45,105,110,32,109,111,100,117,108,101,115,32,97,114,101, - 32,110,101,118,101,114,32,112,97,99,107,97,103,101,115,46, - 70,114,10,0,0,0,114,170,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,116,0,0,0,14, - 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108, - 116,105,110,73,109,112,111,114,116,101,114,46,105,115,95,112, - 97,99,107,97,103,101,41,2,78,78,41,1,78,41,18,114, - 1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3, - 0,0,0,114,139,0,0,0,218,12,115,116,97,116,105,99, - 109,101,116,104,111,100,114,100,0,0,0,218,11,99,108,97, - 115,115,109,101,116,104,111,100,114,168,0,0,0,114,169,0, - 0,0,114,150,0,0,0,114,151,0,0,0,114,87,0,0, - 0,114,171,0,0,0,114,172,0,0,0,114,116,0,0,0, - 114,98,0,0,0,114,156,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,161, - 0,0,0,204,2,0,0,115,44,0,0,0,8,2,4,7, - 4,2,2,1,10,8,2,1,12,8,2,1,12,11,2,1, - 10,7,2,1,10,4,2,1,2,1,12,4,2,1,2,1, - 12,4,2,1,2,1,12,4,114,161,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,64,0,0,0,115,144,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,90,4,101,5,100,3,100, - 4,132,0,131,1,90,6,101,7,100,22,100,6,100,7,132, - 1,131,1,90,8,101,7,100,23,100,8,100,9,132,1,131, - 1,90,9,101,7,100,10,100,11,132,0,131,1,90,10,101, - 5,100,12,100,13,132,0,131,1,90,11,101,7,100,14,100, - 15,132,0,131,1,90,12,101,7,101,13,100,16,100,17,132, - 0,131,1,131,1,90,14,101,7,101,13,100,18,100,19,132, - 0,131,1,131,1,90,15,101,7,101,13,100,20,100,21,132, - 0,131,1,131,1,90,16,100,5,83,0,41,24,218,14,70, - 114,111,122,101,110,73,109,112,111,114,116,101,114,122,142,77, - 101,116,97,32,112,97,116,104,32,105,109,112,111,114,116,32, - 102,111,114,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116, - 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32, - 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32, - 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100, - 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32, - 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101, - 32,99,108,97,115,115,46,10,10,32,32,32,32,90,6,102, - 114,111,122,101,110,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,16, - 0,0,0,100,1,160,0,124,0,106,1,116,2,106,3,161, - 2,83,0,41,2,114,162,0,0,0,114,154,0,0,0,41, - 4,114,46,0,0,0,114,1,0,0,0,114,175,0,0,0, - 114,139,0,0,0,41,1,218,1,109,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,100,0,0,0,34,3, - 0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,101, - 110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,101, - 95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, - 34,0,0,0,116,0,160,1,124,1,161,1,114,26,116,2, - 124,1,124,0,124,0,106,3,100,1,141,3,83,0,100,0, + 32,90,6,102,114,111,122,101,110,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,67,0, + 0,0,115,16,0,0,0,100,1,160,0,124,0,106,1,116, + 2,106,3,161,2,83,0,41,2,114,162,0,0,0,114,154, + 0,0,0,41,4,114,46,0,0,0,114,1,0,0,0,114, + 175,0,0,0,114,139,0,0,0,41,1,218,1,109,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,100,0, + 0,0,34,3,0,0,115,2,0,0,0,0,7,122,26,70, + 114,111,122,101,110,73,109,112,111,114,116,101,114,46,109,111, + 100,117,108,101,95,114,101,112,114,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, + 0,0,0,115,30,0,0,0,116,0,160,1,124,1,161,1, + 114,26,116,2,124,1,124,0,124,0,106,3,100,1,141,3, 83,0,100,0,83,0,114,163,0,0,0,41,4,114,58,0, 0,0,114,89,0,0,0,114,92,0,0,0,114,139,0,0, 0,114,164,0,0,0,114,10,0,0,0,114,10,0,0,0, @@ -1379,11 +1376,11 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,95,115,112,101,99,95,108,101,103,97,99,121,124,3,0, 0,115,8,0,0,0,0,3,12,1,8,1,4,1,114,191, 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 10,0,0,0,10,0,0,0,67,0,0,0,115,32,1,0, + 10,0,0,0,10,0,0,0,67,0,0,0,115,28,1,0, 0,116,0,106,1,125,3,124,3,100,1,117,0,114,22,116, 2,100,2,131,1,130,1,124,3,115,38,116,3,160,4,100, 3,116,5,161,2,1,0,124,0,116,0,106,6,118,0,125, - 4,124,3,68,0,93,230,125,5,116,7,131,0,143,94,1, + 4,124,3,68,0,93,226,125,5,116,7,131,0,143,94,1, 0,122,10,124,5,106,8,125,6,87,0,110,54,4,0,116, 9,121,128,1,0,1,0,1,0,116,10,124,5,124,0,124, 1,131,3,125,7,124,7,100,1,117,0,114,124,89,0,87, @@ -1391,422 +1388,421 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 14,48,0,124,6,124,0,124,1,124,2,131,3,125,7,87, 0,100,1,4,0,4,0,131,3,1,0,110,16,49,0,115, 162,48,0,1,0,1,0,1,0,89,0,1,0,124,7,100, - 1,117,1,114,52,124,4,144,1,115,18,124,0,116,0,106, - 6,118,0,144,1,114,18,116,0,106,6,124,0,25,0,125, + 1,117,1,114,52,124,4,144,1,115,16,124,0,116,0,106, + 6,118,0,144,1,114,16,116,0,106,6,124,0,25,0,125, 8,122,10,124,8,106,11,125,9,87,0,110,26,4,0,116, 9,121,244,1,0,1,0,1,0,124,7,6,0,89,0,2, 0,1,0,83,0,48,0,124,9,100,1,117,0,144,1,114, 8,124,7,2,0,1,0,83,0,124,9,2,0,1,0,83, - 0,113,52,124,7,2,0,1,0,83,0,113,52,100,1,83, - 0,41,4,122,21,70,105,110,100,32,97,32,109,111,100,117, - 108,101,39,115,32,115,112,101,99,46,78,122,53,115,121,115, - 46,109,101,116,97,95,112,97,116,104,32,105,115,32,78,111, - 110,101,44,32,80,121,116,104,111,110,32,105,115,32,108,105, - 107,101,108,121,32,115,104,117,116,116,105,110,103,32,100,111, - 119,110,122,22,115,121,115,46,109,101,116,97,95,112,97,116, - 104,32,105,115,32,101,109,112,116,121,41,12,114,15,0,0, - 0,218,9,109,101,116,97,95,112,97,116,104,114,80,0,0, - 0,218,9,95,119,97,114,110,105,110,103,115,218,4,119,97, - 114,110,218,13,73,109,112,111,114,116,87,97,114,110,105,110, - 103,114,93,0,0,0,114,180,0,0,0,114,168,0,0,0, - 114,107,0,0,0,114,191,0,0,0,114,106,0,0,0,41, - 10,114,17,0,0,0,114,166,0,0,0,114,167,0,0,0, - 114,192,0,0,0,90,9,105,115,95,114,101,108,111,97,100, - 114,190,0,0,0,114,168,0,0,0,114,96,0,0,0,114, - 97,0,0,0,114,106,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,10,95,102,105,110,100,95, - 115,112,101,99,133,3,0,0,115,54,0,0,0,0,2,6, - 1,8,2,8,3,4,1,12,5,10,1,8,1,8,1,2, - 1,10,1,12,1,12,1,8,1,22,2,42,1,8,2,18, - 1,10,1,2,1,10,1,12,4,14,2,10,1,8,2,10, - 2,10,2,114,196,0,0,0,99,3,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,5,0,0,0,67,0,0, - 0,115,108,0,0,0,116,0,124,0,116,1,131,2,115,28, - 116,2,100,1,160,3,116,4,124,0,131,1,161,1,131,1, - 130,1,124,2,100,2,107,0,114,44,116,5,100,3,131,1, - 130,1,124,2,100,2,107,4,114,84,116,0,124,1,116,1, - 131,2,115,72,116,2,100,4,131,1,130,1,110,12,124,1, - 115,84,116,6,100,5,131,1,130,1,124,0,115,104,124,2, - 100,2,107,2,114,104,116,5,100,6,131,1,130,1,100,7, - 83,0,41,8,122,28,86,101,114,105,102,121,32,97,114,103, - 117,109,101,110,116,115,32,97,114,101,32,34,115,97,110,101, - 34,46,122,31,109,111,100,117,108,101,32,110,97,109,101,32, - 109,117,115,116,32,98,101,32,115,116,114,44,32,110,111,116, - 32,123,125,114,22,0,0,0,122,18,108,101,118,101,108,32, - 109,117,115,116,32,98,101,32,62,61,32,48,122,31,95,95, - 112,97,99,107,97,103,101,95,95,32,110,111,116,32,115,101, - 116,32,116,111,32,97,32,115,116,114,105,110,103,122,54,97, - 116,116,101,109,112,116,101,100,32,114,101,108,97,116,105,118, - 101,32,105,109,112,111,114,116,32,119,105,116,104,32,110,111, - 32,107,110,111,119,110,32,112,97,114,101,110,116,32,112,97, - 99,107,97,103,101,122,17,69,109,112,116,121,32,109,111,100, - 117,108,101,32,110,97,109,101,78,41,7,218,10,105,115,105, - 110,115,116,97,110,99,101,218,3,115,116,114,218,9,84,121, - 112,101,69,114,114,111,114,114,46,0,0,0,114,14,0,0, - 0,218,10,86,97,108,117,101,69,114,114,111,114,114,80,0, - 0,0,169,3,114,17,0,0,0,114,187,0,0,0,114,188, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,13,95,115,97,110,105,116,121,95,99,104,101,99, - 107,180,3,0,0,115,22,0,0,0,0,2,10,1,18,1, - 8,1,8,1,8,1,10,1,10,1,4,1,8,2,12,1, - 114,202,0,0,0,122,16,78,111,32,109,111,100,117,108,101, - 32,110,97,109,101,100,32,122,4,123,33,114,125,99,2,0, - 0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0, - 0,0,67,0,0,0,115,22,1,0,0,100,0,125,2,124, - 0,160,0,100,1,161,1,100,2,25,0,125,3,124,3,114, - 132,124,3,116,1,106,2,118,1,114,42,116,3,124,1,124, - 3,131,2,1,0,124,0,116,1,106,2,118,0,114,62,116, - 1,106,2,124,0,25,0,83,0,116,1,106,2,124,3,25, - 0,125,4,122,10,124,4,106,4,125,2,87,0,110,48,4, - 0,116,5,121,130,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,48,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,117,0,114, - 170,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,144, - 1,114,18,116,1,106,2,124,3,25,0,125,4,124,0,160, - 0,100,1,161,1,100,5,25,0,125,8,122,16,116,11,124, - 4,124,8,124,7,131,3,1,0,87,0,110,48,4,0,116, - 5,144,1,121,16,1,0,1,0,1,0,100,6,124,3,155, - 2,100,7,124,8,155,2,157,4,125,5,116,12,160,13,124, - 5,116,14,161,2,1,0,89,0,110,2,48,0,124,7,83, - 0,41,8,78,114,129,0,0,0,114,22,0,0,0,122,23, - 59,32,123,33,114,125,32,105,115,32,110,111,116,32,97,32, - 112,97,99,107,97,103,101,114,16,0,0,0,233,2,0,0, - 0,122,27,67,97,110,110,111,116,32,115,101,116,32,97,110, - 32,97,116,116,114,105,98,117,116,101,32,111,110,32,122,18, - 32,102,111,114,32,99,104,105,108,100,32,109,111,100,117,108, - 101,32,41,15,114,130,0,0,0,114,15,0,0,0,114,93, - 0,0,0,114,68,0,0,0,114,142,0,0,0,114,107,0, - 0,0,218,8,95,69,82,82,95,77,83,71,114,46,0,0, - 0,218,19,77,111,100,117,108,101,78,111,116,70,111,117,110, - 100,69,114,114,111,114,114,196,0,0,0,114,160,0,0,0, - 114,5,0,0,0,114,193,0,0,0,114,194,0,0,0,114, - 195,0,0,0,41,9,114,17,0,0,0,218,7,105,109,112, - 111,114,116,95,114,166,0,0,0,114,131,0,0,0,90,13, - 112,97,114,101,110,116,95,109,111,100,117,108,101,114,158,0, - 0,0,114,96,0,0,0,114,97,0,0,0,90,5,99,104, - 105,108,100,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,23,95,102,105,110,100,95,97,110,100,95,108,111, - 97,100,95,117,110,108,111,99,107,101,100,199,3,0,0,115, - 52,0,0,0,0,1,4,1,14,1,4,1,10,1,10,2, - 10,1,10,1,10,1,2,1,10,1,12,1,16,1,20,1, - 10,1,8,1,20,2,8,1,6,2,10,1,14,1,2,1, - 16,1,14,1,16,1,18,1,114,207,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0, - 0,0,67,0,0,0,115,128,0,0,0,116,0,124,0,131, - 1,143,62,1,0,116,1,106,2,160,3,124,0,116,4,161, - 2,125,2,124,2,116,4,117,0,114,56,116,5,124,0,124, - 1,131,2,87,0,2,0,100,1,4,0,4,0,131,3,1, - 0,83,0,87,0,100,1,4,0,4,0,131,3,1,0,110, - 16,49,0,115,76,48,0,1,0,1,0,1,0,89,0,1, - 0,124,2,100,1,117,0,114,116,100,2,160,6,124,0,161, - 1,125,3,116,7,124,3,124,0,100,3,141,2,130,1,116, - 8,124,0,131,1,1,0,124,2,83,0,41,4,122,25,70, - 105,110,100,32,97,110,100,32,108,111,97,100,32,116,104,101, - 32,109,111,100,117,108,101,46,78,122,40,105,109,112,111,114, - 116,32,111,102,32,123,125,32,104,97,108,116,101,100,59,32, - 78,111,110,101,32,105,110,32,115,121,115,46,109,111,100,117, - 108,101,115,114,16,0,0,0,41,9,114,51,0,0,0,114, - 15,0,0,0,114,93,0,0,0,114,35,0,0,0,218,14, - 95,78,69,69,68,83,95,76,79,65,68,73,78,71,114,207, - 0,0,0,114,46,0,0,0,114,205,0,0,0,114,66,0, - 0,0,41,4,114,17,0,0,0,114,206,0,0,0,114,97, - 0,0,0,114,76,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,14,95,102,105,110,100,95,97, - 110,100,95,108,111,97,100,234,3,0,0,115,22,0,0,0, - 0,2,10,1,14,1,8,1,54,2,8,1,4,1,2,255, - 4,2,12,2,8,1,114,209,0,0,0,114,22,0,0,0, - 99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,42,0,0,0,116,0, - 124,0,124,1,124,2,131,3,1,0,124,2,100,1,107,4, - 114,32,116,1,124,0,124,1,124,2,131,3,125,0,116,2, - 124,0,116,3,131,2,83,0,41,2,97,50,1,0,0,73, - 109,112,111,114,116,32,97,110,100,32,114,101,116,117,114,110, - 32,116,104,101,32,109,111,100,117,108,101,32,98,97,115,101, - 100,32,111,110,32,105,116,115,32,110,97,109,101,44,32,116, - 104,101,32,112,97,99,107,97,103,101,32,116,104,101,32,99, - 97,108,108,32,105,115,10,32,32,32,32,98,101,105,110,103, - 32,109,97,100,101,32,102,114,111,109,44,32,97,110,100,32, - 116,104,101,32,108,101,118,101,108,32,97,100,106,117,115,116, - 109,101,110,116,46,10,10,32,32,32,32,84,104,105,115,32, - 102,117,110,99,116,105,111,110,32,114,101,112,114,101,115,101, - 110,116,115,32,116,104,101,32,103,114,101,97,116,101,115,116, - 32,99,111,109,109,111,110,32,100,101,110,111,109,105,110,97, - 116,111,114,32,111,102,32,102,117,110,99,116,105,111,110,97, - 108,105,116,121,10,32,32,32,32,98,101,116,119,101,101,110, - 32,105,109,112,111,114,116,95,109,111,100,117,108,101,32,97, - 110,100,32,95,95,105,109,112,111,114,116,95,95,46,32,84, - 104,105,115,32,105,110,99,108,117,100,101,115,32,115,101,116, - 116,105,110,103,32,95,95,112,97,99,107,97,103,101,95,95, - 32,105,102,10,32,32,32,32,116,104,101,32,108,111,97,100, - 101,114,32,100,105,100,32,110,111,116,46,10,10,32,32,32, - 32,114,22,0,0,0,41,4,114,202,0,0,0,114,189,0, - 0,0,114,209,0,0,0,218,11,95,103,99,100,95,105,109, - 112,111,114,116,114,201,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,210,0,0,0,250,3,0, - 0,115,8,0,0,0,0,9,12,1,8,1,12,1,114,210, - 0,0,0,169,1,218,9,114,101,99,117,114,115,105,118,101, - 99,3,0,0,0,0,0,0,0,1,0,0,0,8,0,0, - 0,11,0,0,0,67,0,0,0,115,232,0,0,0,124,1, - 68,0,93,222,125,4,116,0,124,4,116,1,131,2,115,66, - 124,3,114,34,124,0,106,2,100,1,23,0,125,5,110,4, - 100,2,125,5,116,3,100,3,124,5,155,0,100,4,116,4, - 124,4,131,1,106,2,155,0,157,4,131,1,130,1,113,4, - 124,4,100,5,107,2,114,108,124,3,115,226,116,5,124,0, - 100,6,131,2,114,226,116,6,124,0,124,0,106,7,124,2, - 100,7,100,8,141,4,1,0,113,4,116,5,124,0,124,4, - 131,2,115,4,100,9,160,8,124,0,106,2,124,4,161,2, - 125,6,122,14,116,9,124,2,124,6,131,2,1,0,87,0, - 113,4,4,0,116,10,121,224,1,0,125,7,1,0,122,54, - 124,7,106,11,124,6,107,2,114,202,116,12,106,13,160,14, - 124,6,116,15,161,2,100,10,117,1,114,202,87,0,89,0, - 100,10,125,7,126,7,113,4,130,0,87,0,89,0,100,10, - 125,7,126,7,113,4,100,10,125,7,126,7,48,0,48,0, - 113,4,124,0,83,0,41,11,122,238,70,105,103,117,114,101, - 32,111,117,116,32,119,104,97,116,32,95,95,105,109,112,111, - 114,116,95,95,32,115,104,111,117,108,100,32,114,101,116,117, - 114,110,46,10,10,32,32,32,32,84,104,101,32,105,109,112, - 111,114,116,95,32,112,97,114,97,109,101,116,101,114,32,105, - 115,32,97,32,99,97,108,108,97,98,108,101,32,119,104,105, - 99,104,32,116,97,107,101,115,32,116,104,101,32,110,97,109, - 101,32,111,102,32,109,111,100,117,108,101,32,116,111,10,32, - 32,32,32,105,109,112,111,114,116,46,32,73,116,32,105,115, - 32,114,101,113,117,105,114,101,100,32,116,111,32,100,101,99, - 111,117,112,108,101,32,116,104,101,32,102,117,110,99,116,105, - 111,110,32,102,114,111,109,32,97,115,115,117,109,105,110,103, - 32,105,109,112,111,114,116,108,105,98,39,115,10,32,32,32, - 32,105,109,112,111,114,116,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,105,115,32,100,101,115,105,114,101, - 100,46,10,10,32,32,32,32,122,8,46,95,95,97,108,108, - 95,95,122,13,96,96,102,114,111,109,32,108,105,115,116,39, - 39,122,8,73,116,101,109,32,105,110,32,122,18,32,109,117, - 115,116,32,98,101,32,115,116,114,44,32,110,111,116,32,250, - 1,42,218,7,95,95,97,108,108,95,95,84,114,211,0,0, - 0,114,184,0,0,0,78,41,16,114,197,0,0,0,114,198, - 0,0,0,114,1,0,0,0,114,199,0,0,0,114,14,0, - 0,0,114,4,0,0,0,218,16,95,104,97,110,100,108,101, - 95,102,114,111,109,108,105,115,116,114,214,0,0,0,114,46, - 0,0,0,114,68,0,0,0,114,205,0,0,0,114,17,0, - 0,0,114,15,0,0,0,114,93,0,0,0,114,35,0,0, - 0,114,208,0,0,0,41,8,114,97,0,0,0,218,8,102, - 114,111,109,108,105,115,116,114,206,0,0,0,114,212,0,0, - 0,218,1,120,90,5,119,104,101,114,101,90,9,102,114,111, - 109,95,110,97,109,101,90,3,101,120,99,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,215,0,0,0,9, - 4,0,0,115,48,0,0,0,0,10,8,1,10,1,4,1, - 12,2,4,1,10,1,8,255,10,2,8,1,14,1,10,1, - 2,255,8,2,10,1,14,1,2,1,14,1,14,4,10,1, - 16,255,2,2,12,1,26,1,114,215,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,6,0, - 0,0,67,0,0,0,115,146,0,0,0,124,0,160,0,100, - 1,161,1,125,1,124,0,160,0,100,2,161,1,125,2,124, - 1,100,3,117,1,114,82,124,2,100,3,117,1,114,78,124, - 1,124,2,106,1,107,3,114,78,116,2,106,3,100,4,124, - 1,155,2,100,5,124,2,106,1,155,2,100,6,157,5,116, - 4,100,7,100,8,141,3,1,0,124,1,83,0,124,2,100, - 3,117,1,114,96,124,2,106,1,83,0,116,2,106,3,100, - 9,116,4,100,7,100,8,141,3,1,0,124,0,100,10,25, - 0,125,1,100,11,124,0,118,1,114,142,124,1,160,5,100, - 12,161,1,100,13,25,0,125,1,124,1,83,0,41,14,122, - 167,67,97,108,99,117,108,97,116,101,32,119,104,97,116,32, - 95,95,112,97,99,107,97,103,101,95,95,32,115,104,111,117, - 108,100,32,98,101,46,10,10,32,32,32,32,95,95,112,97, - 99,107,97,103,101,95,95,32,105,115,32,110,111,116,32,103, - 117,97,114,97,110,116,101,101,100,32,116,111,32,98,101,32, - 100,101,102,105,110,101,100,32,111,114,32,99,111,117,108,100, - 32,98,101,32,115,101,116,32,116,111,32,78,111,110,101,10, - 32,32,32,32,116,111,32,114,101,112,114,101,115,101,110,116, - 32,116,104,97,116,32,105,116,115,32,112,114,111,112,101,114, - 32,118,97,108,117,101,32,105,115,32,117,110,107,110,111,119, - 110,46,10,10,32,32,32,32,114,146,0,0,0,114,106,0, - 0,0,78,122,32,95,95,112,97,99,107,97,103,101,95,95, - 32,33,61,32,95,95,115,112,101,99,95,95,46,112,97,114, - 101,110,116,32,40,122,4,32,33,61,32,250,1,41,233,3, - 0,0,0,41,1,90,10,115,116,97,99,107,108,101,118,101, - 108,122,89,99,97,110,39,116,32,114,101,115,111,108,118,101, - 32,112,97,99,107,97,103,101,32,102,114,111,109,32,95,95, - 115,112,101,99,95,95,32,111,114,32,95,95,112,97,99,107, - 97,103,101,95,95,44,32,102,97,108,108,105,110,103,32,98, - 97,99,107,32,111,110,32,95,95,110,97,109,101,95,95,32, - 97,110,100,32,95,95,112,97,116,104,95,95,114,1,0,0, - 0,114,142,0,0,0,114,129,0,0,0,114,22,0,0,0, - 41,6,114,35,0,0,0,114,131,0,0,0,114,193,0,0, - 0,114,194,0,0,0,114,195,0,0,0,114,130,0,0,0, - 41,3,218,7,103,108,111,98,97,108,115,114,187,0,0,0, + 0,124,7,2,0,1,0,83,0,100,1,83,0,41,4,122, + 21,70,105,110,100,32,97,32,109,111,100,117,108,101,39,115, + 32,115,112,101,99,46,78,122,53,115,121,115,46,109,101,116, + 97,95,112,97,116,104,32,105,115,32,78,111,110,101,44,32, + 80,121,116,104,111,110,32,105,115,32,108,105,107,101,108,121, + 32,115,104,117,116,116,105,110,103,32,100,111,119,110,122,22, + 115,121,115,46,109,101,116,97,95,112,97,116,104,32,105,115, + 32,101,109,112,116,121,41,12,114,15,0,0,0,218,9,109, + 101,116,97,95,112,97,116,104,114,80,0,0,0,218,9,95, + 119,97,114,110,105,110,103,115,218,4,119,97,114,110,218,13, + 73,109,112,111,114,116,87,97,114,110,105,110,103,114,93,0, + 0,0,114,180,0,0,0,114,168,0,0,0,114,107,0,0, + 0,114,191,0,0,0,114,106,0,0,0,41,10,114,17,0, + 0,0,114,166,0,0,0,114,167,0,0,0,114,192,0,0, + 0,90,9,105,115,95,114,101,108,111,97,100,114,190,0,0, + 0,114,168,0,0,0,114,96,0,0,0,114,97,0,0,0, + 114,106,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,10,95,102,105,110,100,95,115,112,101,99, + 133,3,0,0,115,54,0,0,0,0,2,6,1,8,2,8, + 3,4,1,12,5,10,1,8,1,8,1,2,1,10,1,12, + 1,12,1,8,1,22,2,42,1,8,2,18,1,10,1,2, + 1,10,1,12,4,14,2,10,1,8,2,8,2,8,2,114, + 196,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,5,0,0,0,67,0,0,0,115,108,0, + 0,0,116,0,124,0,116,1,131,2,115,28,116,2,100,1, + 160,3,116,4,124,0,131,1,161,1,131,1,130,1,124,2, + 100,2,107,0,114,44,116,5,100,3,131,1,130,1,124,2, + 100,2,107,4,114,84,116,0,124,1,116,1,131,2,115,72, + 116,2,100,4,131,1,130,1,110,12,124,1,115,84,116,6, + 100,5,131,1,130,1,124,0,115,104,124,2,100,2,107,2, + 114,104,116,5,100,6,131,1,130,1,100,7,83,0,41,8, + 122,28,86,101,114,105,102,121,32,97,114,103,117,109,101,110, + 116,115,32,97,114,101,32,34,115,97,110,101,34,46,122,31, + 109,111,100,117,108,101,32,110,97,109,101,32,109,117,115,116, + 32,98,101,32,115,116,114,44,32,110,111,116,32,123,125,114, + 22,0,0,0,122,18,108,101,118,101,108,32,109,117,115,116, + 32,98,101,32,62,61,32,48,122,31,95,95,112,97,99,107, + 97,103,101,95,95,32,110,111,116,32,115,101,116,32,116,111, + 32,97,32,115,116,114,105,110,103,122,54,97,116,116,101,109, + 112,116,101,100,32,114,101,108,97,116,105,118,101,32,105,109, + 112,111,114,116,32,119,105,116,104,32,110,111,32,107,110,111, + 119,110,32,112,97,114,101,110,116,32,112,97,99,107,97,103, + 101,122,17,69,109,112,116,121,32,109,111,100,117,108,101,32, + 110,97,109,101,78,41,7,218,10,105,115,105,110,115,116,97, + 110,99,101,218,3,115,116,114,218,9,84,121,112,101,69,114, + 114,111,114,114,46,0,0,0,114,14,0,0,0,218,10,86, + 97,108,117,101,69,114,114,111,114,114,80,0,0,0,169,3, + 114,17,0,0,0,114,187,0,0,0,114,188,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,13, + 95,115,97,110,105,116,121,95,99,104,101,99,107,180,3,0, + 0,115,22,0,0,0,0,2,10,1,18,1,8,1,8,1, + 8,1,10,1,10,1,4,1,8,2,12,1,114,202,0,0, + 0,122,16,78,111,32,109,111,100,117,108,101,32,110,97,109, + 101,100,32,122,4,123,33,114,125,99,2,0,0,0,0,0, + 0,0,0,0,0,0,9,0,0,0,8,0,0,0,67,0, + 0,0,115,22,1,0,0,100,0,125,2,124,0,160,0,100, + 1,161,1,100,2,25,0,125,3,124,3,114,132,124,3,116, + 1,106,2,118,1,114,42,116,3,124,1,124,3,131,2,1, + 0,124,0,116,1,106,2,118,0,114,62,116,1,106,2,124, + 0,25,0,83,0,116,1,106,2,124,3,25,0,125,4,122, + 10,124,4,106,4,125,2,87,0,110,48,4,0,116,5,121, + 130,1,0,1,0,1,0,116,6,100,3,23,0,160,7,124, + 0,124,3,161,2,125,5,116,8,124,5,124,0,100,4,141, + 2,100,0,130,2,89,0,110,2,48,0,116,9,124,0,124, + 2,131,2,125,6,124,6,100,0,117,0,114,170,116,8,116, + 6,160,7,124,0,161,1,124,0,100,4,141,2,130,1,110, + 8,116,10,124,6,131,1,125,7,124,3,144,1,114,18,116, + 1,106,2,124,3,25,0,125,4,124,0,160,0,100,1,161, + 1,100,5,25,0,125,8,122,16,116,11,124,4,124,8,124, + 7,131,3,1,0,87,0,110,48,4,0,116,5,144,1,121, + 16,1,0,1,0,1,0,100,6,124,3,155,2,100,7,124, + 8,155,2,157,4,125,5,116,12,160,13,124,5,116,14,161, + 2,1,0,89,0,110,2,48,0,124,7,83,0,41,8,78, + 114,129,0,0,0,114,22,0,0,0,122,23,59,32,123,33, + 114,125,32,105,115,32,110,111,116,32,97,32,112,97,99,107, + 97,103,101,114,16,0,0,0,233,2,0,0,0,122,27,67, + 97,110,110,111,116,32,115,101,116,32,97,110,32,97,116,116, + 114,105,98,117,116,101,32,111,110,32,122,18,32,102,111,114, + 32,99,104,105,108,100,32,109,111,100,117,108,101,32,41,15, + 114,130,0,0,0,114,15,0,0,0,114,93,0,0,0,114, + 68,0,0,0,114,142,0,0,0,114,107,0,0,0,218,8, + 95,69,82,82,95,77,83,71,114,46,0,0,0,218,19,77, + 111,100,117,108,101,78,111,116,70,111,117,110,100,69,114,114, + 111,114,114,196,0,0,0,114,160,0,0,0,114,5,0,0, + 0,114,193,0,0,0,114,194,0,0,0,114,195,0,0,0, + 41,9,114,17,0,0,0,218,7,105,109,112,111,114,116,95, + 114,166,0,0,0,114,131,0,0,0,90,13,112,97,114,101, + 110,116,95,109,111,100,117,108,101,114,158,0,0,0,114,96, + 0,0,0,114,97,0,0,0,90,5,99,104,105,108,100,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,23, + 95,102,105,110,100,95,97,110,100,95,108,111,97,100,95,117, + 110,108,111,99,107,101,100,199,3,0,0,115,52,0,0,0, + 0,1,4,1,14,1,4,1,10,1,10,2,10,1,10,1, + 10,1,2,1,10,1,12,1,16,1,20,1,10,1,8,1, + 20,2,8,1,6,2,10,1,14,1,2,1,16,1,14,1, + 16,1,18,1,114,207,0,0,0,99,2,0,0,0,0,0, + 0,0,0,0,0,0,4,0,0,0,8,0,0,0,67,0, + 0,0,115,128,0,0,0,116,0,124,0,131,1,143,62,1, + 0,116,1,106,2,160,3,124,0,116,4,161,2,125,2,124, + 2,116,4,117,0,114,56,116,5,124,0,124,1,131,2,87, + 0,2,0,100,1,4,0,4,0,131,3,1,0,83,0,87, + 0,100,1,4,0,4,0,131,3,1,0,110,16,49,0,115, + 76,48,0,1,0,1,0,1,0,89,0,1,0,124,2,100, + 1,117,0,114,116,100,2,160,6,124,0,161,1,125,3,116, + 7,124,3,124,0,100,3,141,2,130,1,116,8,124,0,131, + 1,1,0,124,2,83,0,41,4,122,25,70,105,110,100,32, + 97,110,100,32,108,111,97,100,32,116,104,101,32,109,111,100, + 117,108,101,46,78,122,40,105,109,112,111,114,116,32,111,102, + 32,123,125,32,104,97,108,116,101,100,59,32,78,111,110,101, + 32,105,110,32,115,121,115,46,109,111,100,117,108,101,115,114, + 16,0,0,0,41,9,114,51,0,0,0,114,15,0,0,0, + 114,93,0,0,0,114,35,0,0,0,218,14,95,78,69,69, + 68,83,95,76,79,65,68,73,78,71,114,207,0,0,0,114, + 46,0,0,0,114,205,0,0,0,114,66,0,0,0,41,4, + 114,17,0,0,0,114,206,0,0,0,114,97,0,0,0,114, + 76,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,14,95,102,105,110,100,95,97,110,100,95,108, + 111,97,100,234,3,0,0,115,22,0,0,0,0,2,10,1, + 14,1,8,1,54,2,8,1,4,1,2,255,4,2,12,2, + 8,1,114,209,0,0,0,114,22,0,0,0,99,3,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,67,0,0,0,115,42,0,0,0,116,0,124,0,124,1, + 124,2,131,3,1,0,124,2,100,1,107,4,114,32,116,1, + 124,0,124,1,124,2,131,3,125,0,116,2,124,0,116,3, + 131,2,83,0,41,2,97,50,1,0,0,73,109,112,111,114, + 116,32,97,110,100,32,114,101,116,117,114,110,32,116,104,101, + 32,109,111,100,117,108,101,32,98,97,115,101,100,32,111,110, + 32,105,116,115,32,110,97,109,101,44,32,116,104,101,32,112, + 97,99,107,97,103,101,32,116,104,101,32,99,97,108,108,32, + 105,115,10,32,32,32,32,98,101,105,110,103,32,109,97,100, + 101,32,102,114,111,109,44,32,97,110,100,32,116,104,101,32, + 108,101,118,101,108,32,97,100,106,117,115,116,109,101,110,116, + 46,10,10,32,32,32,32,84,104,105,115,32,102,117,110,99, + 116,105,111,110,32,114,101,112,114,101,115,101,110,116,115,32, + 116,104,101,32,103,114,101,97,116,101,115,116,32,99,111,109, + 109,111,110,32,100,101,110,111,109,105,110,97,116,111,114,32, + 111,102,32,102,117,110,99,116,105,111,110,97,108,105,116,121, + 10,32,32,32,32,98,101,116,119,101,101,110,32,105,109,112, + 111,114,116,95,109,111,100,117,108,101,32,97,110,100,32,95, + 95,105,109,112,111,114,116,95,95,46,32,84,104,105,115,32, + 105,110,99,108,117,100,101,115,32,115,101,116,116,105,110,103, + 32,95,95,112,97,99,107,97,103,101,95,95,32,105,102,10, + 32,32,32,32,116,104,101,32,108,111,97,100,101,114,32,100, + 105,100,32,110,111,116,46,10,10,32,32,32,32,114,22,0, + 0,0,41,4,114,202,0,0,0,114,189,0,0,0,114,209, + 0,0,0,218,11,95,103,99,100,95,105,109,112,111,114,116, + 114,201,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,210,0,0,0,250,3,0,0,115,8,0, + 0,0,0,9,12,1,8,1,12,1,114,210,0,0,0,169, + 1,218,9,114,101,99,117,114,115,105,118,101,99,3,0,0, + 0,0,0,0,0,1,0,0,0,8,0,0,0,11,0,0, + 0,67,0,0,0,115,232,0,0,0,124,1,68,0,93,222, + 125,4,116,0,124,4,116,1,131,2,115,66,124,3,114,34, + 124,0,106,2,100,1,23,0,125,5,110,4,100,2,125,5, + 116,3,100,3,124,5,155,0,100,4,116,4,124,4,131,1, + 106,2,155,0,157,4,131,1,130,1,113,4,124,4,100,5, + 107,2,114,108,124,3,115,226,116,5,124,0,100,6,131,2, + 114,226,116,6,124,0,124,0,106,7,124,2,100,7,100,8, + 141,4,1,0,113,4,116,5,124,0,124,4,131,2,115,4, + 100,9,160,8,124,0,106,2,124,4,161,2,125,6,122,14, + 116,9,124,2,124,6,131,2,1,0,87,0,113,4,4,0, + 116,10,121,224,1,0,125,7,1,0,122,54,124,7,106,11, + 124,6,107,2,114,202,116,12,106,13,160,14,124,6,116,15, + 161,2,100,10,117,1,114,202,87,0,89,0,100,10,125,7, + 126,7,113,4,130,0,87,0,89,0,100,10,125,7,126,7, + 113,4,100,10,125,7,126,7,48,0,48,0,113,4,124,0, + 83,0,41,11,122,238,70,105,103,117,114,101,32,111,117,116, + 32,119,104,97,116,32,95,95,105,109,112,111,114,116,95,95, + 32,115,104,111,117,108,100,32,114,101,116,117,114,110,46,10, + 10,32,32,32,32,84,104,101,32,105,109,112,111,114,116,95, + 32,112,97,114,97,109,101,116,101,114,32,105,115,32,97,32, + 99,97,108,108,97,98,108,101,32,119,104,105,99,104,32,116, + 97,107,101,115,32,116,104,101,32,110,97,109,101,32,111,102, + 32,109,111,100,117,108,101,32,116,111,10,32,32,32,32,105, + 109,112,111,114,116,46,32,73,116,32,105,115,32,114,101,113, + 117,105,114,101,100,32,116,111,32,100,101,99,111,117,112,108, + 101,32,116,104,101,32,102,117,110,99,116,105,111,110,32,102, + 114,111,109,32,97,115,115,117,109,105,110,103,32,105,109,112, + 111,114,116,108,105,98,39,115,10,32,32,32,32,105,109,112, + 111,114,116,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,105,115,32,100,101,115,105,114,101,100,46,10,10, + 32,32,32,32,122,8,46,95,95,97,108,108,95,95,122,13, + 96,96,102,114,111,109,32,108,105,115,116,39,39,122,8,73, + 116,101,109,32,105,110,32,122,18,32,109,117,115,116,32,98, + 101,32,115,116,114,44,32,110,111,116,32,250,1,42,218,7, + 95,95,97,108,108,95,95,84,114,211,0,0,0,114,184,0, + 0,0,78,41,16,114,197,0,0,0,114,198,0,0,0,114, + 1,0,0,0,114,199,0,0,0,114,14,0,0,0,114,4, + 0,0,0,218,16,95,104,97,110,100,108,101,95,102,114,111, + 109,108,105,115,116,114,214,0,0,0,114,46,0,0,0,114, + 68,0,0,0,114,205,0,0,0,114,17,0,0,0,114,15, + 0,0,0,114,93,0,0,0,114,35,0,0,0,114,208,0, + 0,0,41,8,114,97,0,0,0,218,8,102,114,111,109,108, + 105,115,116,114,206,0,0,0,114,212,0,0,0,218,1,120, + 90,5,119,104,101,114,101,90,9,102,114,111,109,95,110,97, + 109,101,90,3,101,120,99,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,215,0,0,0,9,4,0,0,115, + 48,0,0,0,0,10,8,1,10,1,4,1,12,2,4,1, + 10,1,8,255,10,2,8,1,14,1,10,1,2,255,8,2, + 10,1,14,1,2,1,14,1,14,4,10,1,16,255,2,2, + 12,1,26,1,114,215,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,6,0,0,0,67,0, + 0,0,115,146,0,0,0,124,0,160,0,100,1,161,1,125, + 1,124,0,160,0,100,2,161,1,125,2,124,1,100,3,117, + 1,114,82,124,2,100,3,117,1,114,78,124,1,124,2,106, + 1,107,3,114,78,116,2,106,3,100,4,124,1,155,2,100, + 5,124,2,106,1,155,2,100,6,157,5,116,4,100,7,100, + 8,141,3,1,0,124,1,83,0,124,2,100,3,117,1,114, + 96,124,2,106,1,83,0,116,2,106,3,100,9,116,4,100, + 7,100,8,141,3,1,0,124,0,100,10,25,0,125,1,100, + 11,124,0,118,1,114,142,124,1,160,5,100,12,161,1,100, + 13,25,0,125,1,124,1,83,0,41,14,122,167,67,97,108, + 99,117,108,97,116,101,32,119,104,97,116,32,95,95,112,97, + 99,107,97,103,101,95,95,32,115,104,111,117,108,100,32,98, + 101,46,10,10,32,32,32,32,95,95,112,97,99,107,97,103, + 101,95,95,32,105,115,32,110,111,116,32,103,117,97,114,97, + 110,116,101,101,100,32,116,111,32,98,101,32,100,101,102,105, + 110,101,100,32,111,114,32,99,111,117,108,100,32,98,101,32, + 115,101,116,32,116,111,32,78,111,110,101,10,32,32,32,32, + 116,111,32,114,101,112,114,101,115,101,110,116,32,116,104,97, + 116,32,105,116,115,32,112,114,111,112,101,114,32,118,97,108, + 117,101,32,105,115,32,117,110,107,110,111,119,110,46,10,10, + 32,32,32,32,114,146,0,0,0,114,106,0,0,0,78,122, + 32,95,95,112,97,99,107,97,103,101,95,95,32,33,61,32, + 95,95,115,112,101,99,95,95,46,112,97,114,101,110,116,32, + 40,122,4,32,33,61,32,250,1,41,233,3,0,0,0,41, + 1,90,10,115,116,97,99,107,108,101,118,101,108,122,89,99, + 97,110,39,116,32,114,101,115,111,108,118,101,32,112,97,99, + 107,97,103,101,32,102,114,111,109,32,95,95,115,112,101,99, + 95,95,32,111,114,32,95,95,112,97,99,107,97,103,101,95, + 95,44,32,102,97,108,108,105,110,103,32,98,97,99,107,32, + 111,110,32,95,95,110,97,109,101,95,95,32,97,110,100,32, + 95,95,112,97,116,104,95,95,114,1,0,0,0,114,142,0, + 0,0,114,129,0,0,0,114,22,0,0,0,41,6,114,35, + 0,0,0,114,131,0,0,0,114,193,0,0,0,114,194,0, + 0,0,114,195,0,0,0,114,130,0,0,0,41,3,218,7, + 103,108,111,98,97,108,115,114,187,0,0,0,114,96,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,17,95,99,97,108,99,95,95,95,112,97,99,107,97,103, + 101,95,95,46,4,0,0,115,42,0,0,0,0,7,10,1, + 10,1,8,1,18,1,6,1,2,255,4,1,4,255,6,2, + 4,254,6,3,4,1,8,1,6,2,6,2,4,254,6,3, + 8,1,8,1,14,1,114,221,0,0,0,114,10,0,0,0, + 99,5,0,0,0,0,0,0,0,0,0,0,0,9,0,0, + 0,5,0,0,0,67,0,0,0,115,174,0,0,0,124,4, + 100,1,107,2,114,18,116,0,124,0,131,1,125,5,110,36, + 124,1,100,2,117,1,114,30,124,1,110,2,105,0,125,6, + 116,1,124,6,131,1,125,7,116,0,124,0,124,7,124,4, + 131,3,125,5,124,3,115,148,124,4,100,1,107,2,114,84, + 116,0,124,0,160,2,100,3,161,1,100,1,25,0,131,1, + 83,0,124,0,115,92,124,5,83,0,116,3,124,0,131,1, + 116,3,124,0,160,2,100,3,161,1,100,1,25,0,131,1, + 24,0,125,8,116,4,106,5,124,5,106,6,100,2,116,3, + 124,5,106,6,131,1,124,8,24,0,133,2,25,0,25,0, + 83,0,116,7,124,5,100,4,131,2,114,170,116,8,124,5, + 124,3,116,0,131,3,83,0,124,5,83,0,41,5,97,215, + 1,0,0,73,109,112,111,114,116,32,97,32,109,111,100,117, + 108,101,46,10,10,32,32,32,32,84,104,101,32,39,103,108, + 111,98,97,108,115,39,32,97,114,103,117,109,101,110,116,32, + 105,115,32,117,115,101,100,32,116,111,32,105,110,102,101,114, + 32,119,104,101,114,101,32,116,104,101,32,105,109,112,111,114, + 116,32,105,115,32,111,99,99,117,114,114,105,110,103,32,102, + 114,111,109,10,32,32,32,32,116,111,32,104,97,110,100,108, + 101,32,114,101,108,97,116,105,118,101,32,105,109,112,111,114, + 116,115,46,32,84,104,101,32,39,108,111,99,97,108,115,39, + 32,97,114,103,117,109,101,110,116,32,105,115,32,105,103,110, + 111,114,101,100,46,32,84,104,101,10,32,32,32,32,39,102, + 114,111,109,108,105,115,116,39,32,97,114,103,117,109,101,110, + 116,32,115,112,101,99,105,102,105,101,115,32,119,104,97,116, + 32,115,104,111,117,108,100,32,101,120,105,115,116,32,97,115, + 32,97,116,116,114,105,98,117,116,101,115,32,111,110,32,116, + 104,101,32,109,111,100,117,108,101,10,32,32,32,32,98,101, + 105,110,103,32,105,109,112,111,114,116,101,100,32,40,101,46, + 103,46,32,96,96,102,114,111,109,32,109,111,100,117,108,101, + 32,105,109,112,111,114,116,32,60,102,114,111,109,108,105,115, + 116,62,96,96,41,46,32,32,84,104,101,32,39,108,101,118, + 101,108,39,10,32,32,32,32,97,114,103,117,109,101,110,116, + 32,114,101,112,114,101,115,101,110,116,115,32,116,104,101,32, + 112,97,99,107,97,103,101,32,108,111,99,97,116,105,111,110, + 32,116,111,32,105,109,112,111,114,116,32,102,114,111,109,32, + 105,110,32,97,32,114,101,108,97,116,105,118,101,10,32,32, + 32,32,105,109,112,111,114,116,32,40,101,46,103,46,32,96, + 96,102,114,111,109,32,46,46,112,107,103,32,105,109,112,111, + 114,116,32,109,111,100,96,96,32,119,111,117,108,100,32,104, + 97,118,101,32,97,32,39,108,101,118,101,108,39,32,111,102, + 32,50,41,46,10,10,32,32,32,32,114,22,0,0,0,78, + 114,129,0,0,0,114,142,0,0,0,41,9,114,210,0,0, + 0,114,221,0,0,0,218,9,112,97,114,116,105,116,105,111, + 110,114,186,0,0,0,114,15,0,0,0,114,93,0,0,0, + 114,1,0,0,0,114,4,0,0,0,114,215,0,0,0,41, + 9,114,17,0,0,0,114,220,0,0,0,218,6,108,111,99, + 97,108,115,114,216,0,0,0,114,188,0,0,0,114,97,0, + 0,0,90,8,103,108,111,98,97,108,115,95,114,187,0,0, + 0,90,7,99,117,116,95,111,102,102,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,10,95,95,105,109,112, + 111,114,116,95,95,73,4,0,0,115,30,0,0,0,0,11, + 8,1,10,2,16,1,8,1,12,1,4,3,8,1,18,1, + 4,1,4,4,26,3,30,1,10,1,12,2,114,224,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,67,0,0,0,115,38,0,0,0,116, + 0,160,1,124,0,161,1,125,1,124,1,100,0,117,0,114, + 30,116,2,100,1,124,0,23,0,131,1,130,1,116,3,124, + 1,131,1,83,0,41,2,78,122,25,110,111,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,32,110,97,109, + 101,100,32,41,4,114,161,0,0,0,114,168,0,0,0,114, + 80,0,0,0,114,160,0,0,0,41,2,114,17,0,0,0, 114,96,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,17,95,99,97,108,99,95,95,95,112,97, - 99,107,97,103,101,95,95,46,4,0,0,115,42,0,0,0, - 0,7,10,1,10,1,8,1,18,1,6,1,2,255,4,1, - 4,255,6,2,4,254,6,3,4,1,8,1,6,2,6,2, - 4,254,6,3,8,1,8,1,14,1,114,221,0,0,0,114, - 10,0,0,0,99,5,0,0,0,0,0,0,0,0,0,0, - 0,9,0,0,0,5,0,0,0,67,0,0,0,115,180,0, - 0,0,124,4,100,1,107,2,114,18,116,0,124,0,131,1, - 125,5,110,36,124,1,100,2,117,1,114,30,124,1,110,2, - 105,0,125,6,116,1,124,6,131,1,125,7,116,0,124,0, - 124,7,124,4,131,3,125,5,124,3,115,150,124,4,100,1, - 107,2,114,84,116,0,124,0,160,2,100,3,161,1,100,1, - 25,0,131,1,83,0,124,0,115,92,124,5,83,0,116,3, - 124,0,131,1,116,3,124,0,160,2,100,3,161,1,100,1, - 25,0,131,1,24,0,125,8,116,4,106,5,124,5,106,6, - 100,2,116,3,124,5,106,6,131,1,124,8,24,0,133,2, - 25,0,25,0,83,0,110,26,116,7,124,5,100,4,131,2, - 114,172,116,8,124,5,124,3,116,0,131,3,83,0,124,5, - 83,0,100,2,83,0,41,5,97,215,1,0,0,73,109,112, - 111,114,116,32,97,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,84,104,101,32,39,103,108,111,98,97,108,115,39, - 32,97,114,103,117,109,101,110,116,32,105,115,32,117,115,101, - 100,32,116,111,32,105,110,102,101,114,32,119,104,101,114,101, - 32,116,104,101,32,105,109,112,111,114,116,32,105,115,32,111, - 99,99,117,114,114,105,110,103,32,102,114,111,109,10,32,32, - 32,32,116,111,32,104,97,110,100,108,101,32,114,101,108,97, - 116,105,118,101,32,105,109,112,111,114,116,115,46,32,84,104, - 101,32,39,108,111,99,97,108,115,39,32,97,114,103,117,109, - 101,110,116,32,105,115,32,105,103,110,111,114,101,100,46,32, - 84,104,101,10,32,32,32,32,39,102,114,111,109,108,105,115, - 116,39,32,97,114,103,117,109,101,110,116,32,115,112,101,99, - 105,102,105,101,115,32,119,104,97,116,32,115,104,111,117,108, - 100,32,101,120,105,115,116,32,97,115,32,97,116,116,114,105, - 98,117,116,101,115,32,111,110,32,116,104,101,32,109,111,100, - 117,108,101,10,32,32,32,32,98,101,105,110,103,32,105,109, - 112,111,114,116,101,100,32,40,101,46,103,46,32,96,96,102, - 114,111,109,32,109,111,100,117,108,101,32,105,109,112,111,114, - 116,32,60,102,114,111,109,108,105,115,116,62,96,96,41,46, - 32,32,84,104,101,32,39,108,101,118,101,108,39,10,32,32, - 32,32,97,114,103,117,109,101,110,116,32,114,101,112,114,101, - 115,101,110,116,115,32,116,104,101,32,112,97,99,107,97,103, - 101,32,108,111,99,97,116,105,111,110,32,116,111,32,105,109, - 112,111,114,116,32,102,114,111,109,32,105,110,32,97,32,114, - 101,108,97,116,105,118,101,10,32,32,32,32,105,109,112,111, - 114,116,32,40,101,46,103,46,32,96,96,102,114,111,109,32, - 46,46,112,107,103,32,105,109,112,111,114,116,32,109,111,100, - 96,96,32,119,111,117,108,100,32,104,97,118,101,32,97,32, - 39,108,101,118,101,108,39,32,111,102,32,50,41,46,10,10, - 32,32,32,32,114,22,0,0,0,78,114,129,0,0,0,114, - 142,0,0,0,41,9,114,210,0,0,0,114,221,0,0,0, - 218,9,112,97,114,116,105,116,105,111,110,114,186,0,0,0, - 114,15,0,0,0,114,93,0,0,0,114,1,0,0,0,114, - 4,0,0,0,114,215,0,0,0,41,9,114,17,0,0,0, - 114,220,0,0,0,218,6,108,111,99,97,108,115,114,216,0, - 0,0,114,188,0,0,0,114,97,0,0,0,90,8,103,108, - 111,98,97,108,115,95,114,187,0,0,0,90,7,99,117,116, - 95,111,102,102,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,10,95,95,105,109,112,111,114,116,95,95,73, - 4,0,0,115,30,0,0,0,0,11,8,1,10,2,16,1, - 8,1,12,1,4,3,8,1,18,1,4,1,4,4,26,3, - 32,1,10,1,12,2,114,224,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,116,0,160,1,124,0,161, - 1,125,1,124,1,100,0,117,0,114,30,116,2,100,1,124, - 0,23,0,131,1,130,1,116,3,124,1,131,1,83,0,41, - 2,78,122,25,110,111,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,32,110,97,109,101,100,32,41,4,114, - 161,0,0,0,114,168,0,0,0,114,80,0,0,0,114,160, - 0,0,0,41,2,114,17,0,0,0,114,96,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,18, - 95,98,117,105,108,116,105,110,95,102,114,111,109,95,110,97, - 109,101,110,4,0,0,115,8,0,0,0,0,1,10,1,8, - 1,12,1,114,225,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,10,0,0,0,5,0,0,0,67,0,0, - 0,115,166,0,0,0,124,1,97,0,124,0,97,1,116,2, - 116,1,131,1,125,2,116,1,106,3,160,4,161,0,68,0, - 93,72,92,2,125,3,125,4,116,5,124,4,124,2,131,2, - 114,26,124,3,116,1,106,6,118,0,114,60,116,7,125,5, - 110,18,116,0,160,8,124,3,161,1,114,26,116,9,125,5, - 110,2,113,26,116,10,124,4,124,5,131,2,125,6,116,11, - 124,6,124,4,131,2,1,0,113,26,116,1,106,3,116,12, - 25,0,125,7,100,1,68,0,93,46,125,8,124,8,116,1, - 106,3,118,1,114,138,116,13,124,8,131,1,125,9,110,10, - 116,1,106,3,124,8,25,0,125,9,116,14,124,7,124,8, - 124,9,131,3,1,0,113,114,100,2,83,0,41,3,122,250, - 83,101,116,117,112,32,105,109,112,111,114,116,108,105,98,32, - 98,121,32,105,109,112,111,114,116,105,110,103,32,110,101,101, - 100,101,100,32,98,117,105,108,116,45,105,110,32,109,111,100, - 117,108,101,115,32,97,110,100,32,105,110,106,101,99,116,105, - 110,103,32,116,104,101,109,10,32,32,32,32,105,110,116,111, - 32,116,104,101,32,103,108,111,98,97,108,32,110,97,109,101, - 115,112,97,99,101,46,10,10,32,32,32,32,65,115,32,115, - 121,115,32,105,115,32,110,101,101,100,101,100,32,102,111,114, - 32,115,121,115,46,109,111,100,117,108,101,115,32,97,99,99, - 101,115,115,32,97,110,100,32,95,105,109,112,32,105,115,32, - 110,101,101,100,101,100,32,116,111,32,108,111,97,100,32,98, - 117,105,108,116,45,105,110,10,32,32,32,32,109,111,100,117, - 108,101,115,44,32,116,104,111,115,101,32,116,119,111,32,109, - 111,100,117,108,101,115,32,109,117,115,116,32,98,101,32,101, - 120,112,108,105,99,105,116,108,121,32,112,97,115,115,101,100, - 32,105,110,46,10,10,32,32,32,32,41,3,114,23,0,0, - 0,114,193,0,0,0,114,65,0,0,0,78,41,15,114,58, - 0,0,0,114,15,0,0,0,114,14,0,0,0,114,93,0, - 0,0,218,5,105,116,101,109,115,114,197,0,0,0,114,79, - 0,0,0,114,161,0,0,0,114,89,0,0,0,114,175,0, - 0,0,114,143,0,0,0,114,149,0,0,0,114,1,0,0, - 0,114,225,0,0,0,114,5,0,0,0,41,10,218,10,115, - 121,115,95,109,111,100,117,108,101,218,11,95,105,109,112,95, - 109,111,100,117,108,101,90,11,109,111,100,117,108,101,95,116, - 121,112,101,114,17,0,0,0,114,97,0,0,0,114,110,0, - 0,0,114,96,0,0,0,90,11,115,101,108,102,95,109,111, - 100,117,108,101,90,12,98,117,105,108,116,105,110,95,110,97, - 109,101,90,14,98,117,105,108,116,105,110,95,109,111,100,117, - 108,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,6,95,115,101,116,117,112,117,4,0,0,115,36,0, - 0,0,0,9,4,1,4,3,8,1,18,1,10,1,10,1, - 6,1,10,1,6,2,2,1,10,1,12,3,10,1,8,1, - 10,1,10,2,10,1,114,229,0,0,0,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,116,0,124,0,124,1,131, - 2,1,0,116,1,106,2,160,3,116,4,161,1,1,0,116, - 1,106,2,160,3,116,5,161,1,1,0,100,1,83,0,41, - 2,122,48,73,110,115,116,97,108,108,32,105,109,112,111,114, - 116,101,114,115,32,102,111,114,32,98,117,105,108,116,105,110, - 32,97,110,100,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,115,78,41,6,114,229,0,0,0,114,15,0,0,0, - 114,192,0,0,0,114,120,0,0,0,114,161,0,0,0,114, - 175,0,0,0,41,2,114,227,0,0,0,114,228,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 8,95,105,110,115,116,97,108,108,152,4,0,0,115,6,0, - 0,0,0,2,10,2,12,1,114,230,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,67,0,0,0,115,32,0,0,0,100,1,100,2,108, - 0,125,0,124,0,97,1,124,0,160,2,116,3,106,4,116, - 5,25,0,161,1,1,0,100,2,83,0,41,3,122,57,73, - 110,115,116,97,108,108,32,105,109,112,111,114,116,101,114,115, - 32,116,104,97,116,32,114,101,113,117,105,114,101,32,101,120, - 116,101,114,110,97,108,32,102,105,108,101,115,121,115,116,101, - 109,32,97,99,99,101,115,115,114,22,0,0,0,78,41,6, - 218,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116, - 108,105,98,95,101,120,116,101,114,110,97,108,114,127,0,0, - 0,114,230,0,0,0,114,15,0,0,0,114,93,0,0,0, - 114,1,0,0,0,41,1,114,231,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,27,95,105,110, - 115,116,97,108,108,95,101,120,116,101,114,110,97,108,95,105, - 109,112,111,114,116,101,114,115,160,4,0,0,115,6,0,0, - 0,0,3,8,1,4,1,114,232,0,0,0,41,2,78,78, - 41,1,78,41,2,78,114,22,0,0,0,41,4,78,78,114, - 10,0,0,0,114,22,0,0,0,41,50,114,3,0,0,0, - 114,127,0,0,0,114,12,0,0,0,114,18,0,0,0,114, - 60,0,0,0,114,34,0,0,0,114,44,0,0,0,114,19, - 0,0,0,114,20,0,0,0,114,50,0,0,0,114,51,0, - 0,0,114,54,0,0,0,114,66,0,0,0,114,68,0,0, - 0,114,77,0,0,0,114,87,0,0,0,114,91,0,0,0, - 114,98,0,0,0,114,112,0,0,0,114,113,0,0,0,114, - 92,0,0,0,114,143,0,0,0,114,149,0,0,0,114,153, - 0,0,0,114,108,0,0,0,114,94,0,0,0,114,159,0, - 0,0,114,160,0,0,0,114,95,0,0,0,114,161,0,0, - 0,114,175,0,0,0,114,180,0,0,0,114,189,0,0,0, - 114,191,0,0,0,114,196,0,0,0,114,202,0,0,0,90, - 15,95,69,82,82,95,77,83,71,95,80,82,69,70,73,88, - 114,204,0,0,0,114,207,0,0,0,218,6,111,98,106,101, - 99,116,114,208,0,0,0,114,209,0,0,0,114,210,0,0, - 0,114,215,0,0,0,114,221,0,0,0,114,224,0,0,0, - 114,225,0,0,0,114,229,0,0,0,114,230,0,0,0,114, - 232,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,8,60,109,111,100,117,108, - 101,62,1,0,0,0,115,94,0,0,0,4,24,4,2,8, - 8,8,8,4,2,4,3,16,4,14,77,14,21,14,16,8, - 37,8,17,8,11,14,8,8,11,8,12,8,16,8,36,14, - 101,16,26,10,45,14,72,8,17,8,17,8,30,8,37,8, - 42,8,15,14,75,14,79,14,13,8,9,8,9,10,47,8, - 16,4,1,8,2,8,32,6,3,8,16,10,15,14,37,8, - 27,10,37,8,7,8,35,8,8, + 11,0,0,0,218,18,95,98,117,105,108,116,105,110,95,102, + 114,111,109,95,110,97,109,101,110,4,0,0,115,8,0,0, + 0,0,1,10,1,8,1,12,1,114,225,0,0,0,99,2, + 0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,5, + 0,0,0,67,0,0,0,115,166,0,0,0,124,1,97,0, + 124,0,97,1,116,2,116,1,131,1,125,2,116,1,106,3, + 160,4,161,0,68,0,93,72,92,2,125,3,125,4,116,5, + 124,4,124,2,131,2,114,26,124,3,116,1,106,6,118,0, + 114,60,116,7,125,5,110,18,116,0,160,8,124,3,161,1, + 114,26,116,9,125,5,110,2,113,26,116,10,124,4,124,5, + 131,2,125,6,116,11,124,6,124,4,131,2,1,0,113,26, + 116,1,106,3,116,12,25,0,125,7,100,1,68,0,93,46, + 125,8,124,8,116,1,106,3,118,1,114,138,116,13,124,8, + 131,1,125,9,110,10,116,1,106,3,124,8,25,0,125,9, + 116,14,124,7,124,8,124,9,131,3,1,0,113,114,100,2, + 83,0,41,3,122,250,83,101,116,117,112,32,105,109,112,111, + 114,116,108,105,98,32,98,121,32,105,109,112,111,114,116,105, + 110,103,32,110,101,101,100,101,100,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,32,97,110,100,32,105, + 110,106,101,99,116,105,110,103,32,116,104,101,109,10,32,32, + 32,32,105,110,116,111,32,116,104,101,32,103,108,111,98,97, + 108,32,110,97,109,101,115,112,97,99,101,46,10,10,32,32, + 32,32,65,115,32,115,121,115,32,105,115,32,110,101,101,100, + 101,100,32,102,111,114,32,115,121,115,46,109,111,100,117,108, + 101,115,32,97,99,99,101,115,115,32,97,110,100,32,95,105, + 109,112,32,105,115,32,110,101,101,100,101,100,32,116,111,32, + 108,111,97,100,32,98,117,105,108,116,45,105,110,10,32,32, + 32,32,109,111,100,117,108,101,115,44,32,116,104,111,115,101, + 32,116,119,111,32,109,111,100,117,108,101,115,32,109,117,115, + 116,32,98,101,32,101,120,112,108,105,99,105,116,108,121,32, + 112,97,115,115,101,100,32,105,110,46,10,10,32,32,32,32, + 41,3,114,23,0,0,0,114,193,0,0,0,114,65,0,0, + 0,78,41,15,114,58,0,0,0,114,15,0,0,0,114,14, + 0,0,0,114,93,0,0,0,218,5,105,116,101,109,115,114, + 197,0,0,0,114,79,0,0,0,114,161,0,0,0,114,89, + 0,0,0,114,175,0,0,0,114,143,0,0,0,114,149,0, + 0,0,114,1,0,0,0,114,225,0,0,0,114,5,0,0, + 0,41,10,218,10,115,121,115,95,109,111,100,117,108,101,218, + 11,95,105,109,112,95,109,111,100,117,108,101,90,11,109,111, + 100,117,108,101,95,116,121,112,101,114,17,0,0,0,114,97, + 0,0,0,114,110,0,0,0,114,96,0,0,0,90,11,115, + 101,108,102,95,109,111,100,117,108,101,90,12,98,117,105,108, + 116,105,110,95,110,97,109,101,90,14,98,117,105,108,116,105, + 110,95,109,111,100,117,108,101,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,6,95,115,101,116,117,112,117, + 4,0,0,115,36,0,0,0,0,9,4,1,4,3,8,1, + 18,1,10,1,10,1,6,1,10,1,6,2,2,1,10,1, + 12,3,10,1,8,1,10,1,10,2,10,1,114,229,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,67,0,0,0,115,38,0,0,0,116, + 0,124,0,124,1,131,2,1,0,116,1,106,2,160,3,116, + 4,161,1,1,0,116,1,106,2,160,3,116,5,161,1,1, + 0,100,1,83,0,41,2,122,48,73,110,115,116,97,108,108, + 32,105,109,112,111,114,116,101,114,115,32,102,111,114,32,98, + 117,105,108,116,105,110,32,97,110,100,32,102,114,111,122,101, + 110,32,109,111,100,117,108,101,115,78,41,6,114,229,0,0, + 0,114,15,0,0,0,114,192,0,0,0,114,120,0,0,0, + 114,161,0,0,0,114,175,0,0,0,41,2,114,227,0,0, + 0,114,228,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,8,95,105,110,115,116,97,108,108,152, + 4,0,0,115,6,0,0,0,0,2,10,2,12,1,114,230, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,4,0,0,0,67,0,0,0,115,32,0,0, + 0,100,1,100,2,108,0,125,0,124,0,97,1,124,0,160, + 2,116,3,106,4,116,5,25,0,161,1,1,0,100,2,83, + 0,41,3,122,57,73,110,115,116,97,108,108,32,105,109,112, + 111,114,116,101,114,115,32,116,104,97,116,32,114,101,113,117, + 105,114,101,32,101,120,116,101,114,110,97,108,32,102,105,108, + 101,115,121,115,116,101,109,32,97,99,99,101,115,115,114,22, + 0,0,0,78,41,6,218,26,95,102,114,111,122,101,110,95, + 105,109,112,111,114,116,108,105,98,95,101,120,116,101,114,110, + 97,108,114,127,0,0,0,114,230,0,0,0,114,15,0,0, + 0,114,93,0,0,0,114,1,0,0,0,41,1,114,231,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,27,95,105,110,115,116,97,108,108,95,101,120,116,101, + 114,110,97,108,95,105,109,112,111,114,116,101,114,115,160,4, + 0,0,115,6,0,0,0,0,3,8,1,4,1,114,232,0, + 0,0,41,2,78,78,41,1,78,41,2,78,114,22,0,0, + 0,41,4,78,78,114,10,0,0,0,114,22,0,0,0,41, + 50,114,3,0,0,0,114,127,0,0,0,114,12,0,0,0, + 114,18,0,0,0,114,60,0,0,0,114,34,0,0,0,114, + 44,0,0,0,114,19,0,0,0,114,20,0,0,0,114,50, + 0,0,0,114,51,0,0,0,114,54,0,0,0,114,66,0, + 0,0,114,68,0,0,0,114,77,0,0,0,114,87,0,0, + 0,114,91,0,0,0,114,98,0,0,0,114,112,0,0,0, + 114,113,0,0,0,114,92,0,0,0,114,143,0,0,0,114, + 149,0,0,0,114,153,0,0,0,114,108,0,0,0,114,94, + 0,0,0,114,159,0,0,0,114,160,0,0,0,114,95,0, + 0,0,114,161,0,0,0,114,175,0,0,0,114,180,0,0, + 0,114,189,0,0,0,114,191,0,0,0,114,196,0,0,0, + 114,202,0,0,0,90,15,95,69,82,82,95,77,83,71,95, + 80,82,69,70,73,88,114,204,0,0,0,114,207,0,0,0, + 218,6,111,98,106,101,99,116,114,208,0,0,0,114,209,0, + 0,0,114,210,0,0,0,114,215,0,0,0,114,221,0,0, + 0,114,224,0,0,0,114,225,0,0,0,114,229,0,0,0, + 114,230,0,0,0,114,232,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 60,109,111,100,117,108,101,62,1,0,0,0,115,94,0,0, + 0,4,24,4,2,8,8,8,8,4,2,4,3,16,4,14, + 77,14,21,14,16,8,37,8,17,8,11,14,8,8,11,8, + 12,8,16,8,36,14,101,16,26,10,45,14,72,8,17,8, + 17,8,30,8,37,8,42,8,15,14,75,14,79,14,13,8, + 9,8,9,10,47,8,16,4,1,8,2,8,32,6,3,8, + 16,10,15,14,37,8,27,10,37,8,7,8,35,8,8, }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h index a5a7c383d785e40..0ef1b45594fbf72 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -163,829 +163,828 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 95,112,97,116,104,95,106,111,105,110,62,0,0,0,115,6, 0,0,0,0,2,10,1,2,255,114,38,0,0,0,99,1, 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5, - 0,0,0,67,0,0,0,115,96,0,0,0,116,0,116,1, + 0,0,0,67,0,0,0,115,94,0,0,0,116,0,116,1, 131,1,100,1,107,2,114,36,124,0,160,2,116,3,161,1, 92,3,125,1,125,2,125,3,124,1,124,3,102,2,83,0, - 116,4,124,0,131,1,68,0,93,42,125,4,124,4,116,1, + 116,4,124,0,131,1,68,0,93,40,125,4,124,4,116,1, 118,0,114,44,124,0,106,5,124,4,100,1,100,2,141,2, 92,2,125,1,125,3,124,1,124,3,102,2,2,0,1,0, - 83,0,113,44,100,3,124,0,102,2,83,0,41,4,122,32, - 82,101,112,108,97,99,101,109,101,110,116,32,102,111,114,32, - 111,115,46,112,97,116,104,46,115,112,108,105,116,40,41,46, - 233,1,0,0,0,41,1,90,8,109,97,120,115,112,108,105, - 116,218,0,41,6,114,23,0,0,0,114,31,0,0,0,218, - 10,114,112,97,114,116,105,116,105,111,110,114,35,0,0,0, - 218,8,114,101,118,101,114,115,101,100,218,6,114,115,112,108, - 105,116,41,5,218,4,112,97,116,104,90,5,102,114,111,110, - 116,218,1,95,218,4,116,97,105,108,114,20,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,11, - 95,112,97,116,104,95,115,112,108,105,116,68,0,0,0,115, - 16,0,0,0,0,2,12,1,16,1,8,1,12,1,8,1, - 18,1,14,1,114,47,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,10,0,0,0,116,0,160,1,124,0,161,1,83, - 0,41,1,122,126,83,116,97,116,32,116,104,101,32,112,97, - 116,104,46,10,10,32,32,32,32,77,97,100,101,32,97,32, - 115,101,112,97,114,97,116,101,32,102,117,110,99,116,105,111, - 110,32,116,111,32,109,97,107,101,32,105,116,32,101,97,115, - 105,101,114,32,116,111,32,111,118,101,114,114,105,100,101,32, - 105,110,32,101,120,112,101,114,105,109,101,110,116,115,10,32, - 32,32,32,40,101,46,103,46,32,99,97,99,104,101,32,115, - 116,97,116,32,114,101,115,117,108,116,115,41,46,10,10,32, - 32,32,32,41,2,114,4,0,0,0,90,4,115,116,97,116, - 169,1,114,44,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,218,10,95,112,97,116,104,95,115,116, - 97,116,80,0,0,0,115,2,0,0,0,0,7,114,49,0, - 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,8,0,0,0,67,0,0,0,115,48,0,0,0, - 122,12,116,0,124,0,131,1,125,2,87,0,110,20,4,0, - 116,1,121,32,1,0,1,0,1,0,89,0,100,1,83,0, - 48,0,124,2,106,2,100,2,64,0,124,1,107,2,83,0, - 41,3,122,49,84,101,115,116,32,119,104,101,116,104,101,114, - 32,116,104,101,32,112,97,116,104,32,105,115,32,116,104,101, - 32,115,112,101,99,105,102,105,101,100,32,109,111,100,101,32, - 116,121,112,101,46,70,105,0,240,0,0,41,3,114,49,0, - 0,0,218,7,79,83,69,114,114,111,114,218,7,115,116,95, - 109,111,100,101,41,3,114,44,0,0,0,218,4,109,111,100, - 101,90,9,115,116,97,116,95,105,110,102,111,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,18,95,112,97, - 116,104,95,105,115,95,109,111,100,101,95,116,121,112,101,90, - 0,0,0,115,10,0,0,0,0,2,2,1,12,1,12,1, - 8,1,114,53,0,0,0,99,1,0,0,0,0,0,0,0, + 83,0,100,3,124,0,102,2,83,0,41,4,122,32,82,101, + 112,108,97,99,101,109,101,110,116,32,102,111,114,32,111,115, + 46,112,97,116,104,46,115,112,108,105,116,40,41,46,233,1, + 0,0,0,41,1,90,8,109,97,120,115,112,108,105,116,218, + 0,41,6,114,23,0,0,0,114,31,0,0,0,218,10,114, + 112,97,114,116,105,116,105,111,110,114,35,0,0,0,218,8, + 114,101,118,101,114,115,101,100,218,6,114,115,112,108,105,116, + 41,5,218,4,112,97,116,104,90,5,102,114,111,110,116,218, + 1,95,218,4,116,97,105,108,114,20,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,218,11,95,112, + 97,116,104,95,115,112,108,105,116,68,0,0,0,115,16,0, + 0,0,0,2,12,1,16,1,8,1,12,1,8,1,18,1, + 12,1,114,47,0,0,0,99,1,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,10,0,0,0,116,0,124,0,100,1,131,2,83,0,41, - 2,122,31,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,102,105,108, - 101,46,105,0,128,0,0,41,1,114,53,0,0,0,114,48, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,12,95,112,97,116,104,95,105,115,102,105,108,101, - 99,0,0,0,115,2,0,0,0,0,2,114,54,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,22,0,0,0,124,0, - 115,12,116,0,160,1,161,0,125,0,116,2,124,0,100,1, - 131,2,83,0,41,2,122,30,82,101,112,108,97,99,101,109, - 101,110,116,32,102,111,114,32,111,115,46,112,97,116,104,46, - 105,115,100,105,114,46,105,0,64,0,0,41,3,114,4,0, - 0,0,218,6,103,101,116,99,119,100,114,53,0,0,0,114, - 48,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,11,95,112,97,116,104,95,105,115,100,105,114, - 104,0,0,0,115,6,0,0,0,0,2,4,1,8,1,114, - 56,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,67,0,0,0,115,26,0, - 0,0,124,0,160,0,116,1,161,1,112,24,124,0,100,1, - 100,2,133,2,25,0,116,2,118,0,83,0,41,3,122,142, - 82,101,112,108,97,99,101,109,101,110,116,32,102,111,114,32, - 111,115,46,112,97,116,104,46,105,115,97,98,115,46,10,10, - 32,32,32,32,67,111,110,115,105,100,101,114,115,32,97,32, - 87,105,110,100,111,119,115,32,100,114,105,118,101,45,114,101, - 108,97,116,105,118,101,32,112,97,116,104,32,40,110,111,32, - 100,114,105,118,101,44,32,98,117,116,32,115,116,97,114,116, - 115,32,119,105,116,104,32,115,108,97,115,104,41,32,116,111, - 10,32,32,32,32,115,116,105,108,108,32,98,101,32,34,97, - 98,115,111,108,117,116,101,34,46,10,32,32,32,32,114,39, - 0,0,0,233,3,0,0,0,41,3,114,11,0,0,0,114, - 31,0,0,0,218,20,95,112,97,116,104,115,101,112,115,95, - 119,105,116,104,95,99,111,108,111,110,114,48,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,11, - 95,112,97,116,104,95,105,115,97,98,115,111,0,0,0,115, - 2,0,0,0,0,6,114,59,0,0,0,233,182,1,0,0, - 99,3,0,0,0,0,0,0,0,0,0,0,0,6,0,0, - 0,11,0,0,0,67,0,0,0,115,178,0,0,0,100,1, - 160,0,124,0,116,1,124,0,131,1,161,2,125,3,116,2, - 160,3,124,3,116,2,106,4,116,2,106,5,66,0,116,2, - 106,6,66,0,124,2,100,2,64,0,161,3,125,4,122,70, - 116,7,160,8,124,4,100,3,161,2,143,26,125,5,124,5, - 160,9,124,1,161,1,1,0,87,0,100,4,4,0,4,0, - 131,3,1,0,110,16,49,0,115,94,48,0,1,0,1,0, - 1,0,89,0,1,0,116,2,160,10,124,3,124,0,161,2, - 1,0,87,0,110,54,4,0,116,11,121,172,1,0,1,0, - 1,0,122,14,116,2,160,12,124,3,161,1,1,0,87,0, - 110,18,4,0,116,11,121,164,1,0,1,0,1,0,89,0, - 110,2,48,0,130,0,89,0,110,2,48,0,100,4,83,0, - 41,5,122,162,66,101,115,116,45,101,102,102,111,114,116,32, - 102,117,110,99,116,105,111,110,32,116,111,32,119,114,105,116, - 101,32,100,97,116,97,32,116,111,32,97,32,112,97,116,104, - 32,97,116,111,109,105,99,97,108,108,121,46,10,32,32,32, - 32,66,101,32,112,114,101,112,97,114,101,100,32,116,111,32, - 104,97,110,100,108,101,32,97,32,70,105,108,101,69,120,105, - 115,116,115,69,114,114,111,114,32,105,102,32,99,111,110,99, - 117,114,114,101,110,116,32,119,114,105,116,105,110,103,32,111, - 102,32,116,104,101,10,32,32,32,32,116,101,109,112,111,114, - 97,114,121,32,102,105,108,101,32,105,115,32,97,116,116,101, - 109,112,116,101,100,46,250,5,123,125,46,123,125,114,60,0, - 0,0,90,2,119,98,78,41,13,218,6,102,111,114,109,97, - 116,218,2,105,100,114,4,0,0,0,90,4,111,112,101,110, - 90,6,79,95,69,88,67,76,90,7,79,95,67,82,69,65, - 84,90,8,79,95,87,82,79,78,76,89,218,3,95,105,111, - 218,6,70,105,108,101,73,79,218,5,119,114,105,116,101,218, - 7,114,101,112,108,97,99,101,114,50,0,0,0,90,6,117, - 110,108,105,110,107,41,6,114,44,0,0,0,114,26,0,0, - 0,114,52,0,0,0,90,8,112,97,116,104,95,116,109,112, - 90,2,102,100,218,4,102,105,108,101,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,218,13,95,119,114,105,116, - 101,95,97,116,111,109,105,99,120,0,0,0,115,28,0,0, - 0,0,5,16,1,6,1,22,255,4,2,2,3,14,1,40, - 1,16,1,12,1,2,1,14,1,12,1,6,1,114,69,0, - 0,0,105,97,13,0,0,114,28,0,0,0,114,17,0,0, - 0,115,2,0,0,0,13,10,90,11,95,95,112,121,99,97, - 99,104,101,95,95,122,4,111,112,116,45,122,3,46,112,121, - 122,4,46,112,121,99,78,41,1,218,12,111,112,116,105,109, - 105,122,97,116,105,111,110,99,2,0,0,0,0,0,0,0, - 1,0,0,0,12,0,0,0,5,0,0,0,67,0,0,0, - 115,88,1,0,0,124,1,100,1,117,1,114,52,116,0,160, - 1,100,2,116,2,161,2,1,0,124,2,100,1,117,1,114, - 40,100,3,125,3,116,3,124,3,131,1,130,1,124,1,114, - 48,100,4,110,2,100,5,125,2,116,4,160,5,124,0,161, - 1,125,0,116,6,124,0,131,1,92,2,125,4,125,5,124, - 5,160,7,100,6,161,1,92,3,125,6,125,7,125,8,116, - 8,106,9,106,10,125,9,124,9,100,1,117,0,114,114,116, - 11,100,7,131,1,130,1,100,4,160,12,124,6,114,126,124, - 6,110,2,124,8,124,7,124,9,103,3,161,1,125,10,124, - 2,100,1,117,0,114,172,116,8,106,13,106,14,100,8,107, - 2,114,164,100,4,125,2,110,8,116,8,106,13,106,14,125, - 2,116,15,124,2,131,1,125,2,124,2,100,4,107,3,114, - 224,124,2,160,16,161,0,115,210,116,17,100,9,160,18,124, - 2,161,1,131,1,130,1,100,10,160,18,124,10,116,19,124, - 2,161,3,125,10,124,10,116,20,100,8,25,0,23,0,125, - 11,116,8,106,21,100,1,117,1,144,1,114,76,116,22,124, - 4,131,1,144,1,115,16,116,23,116,4,160,24,161,0,124, - 4,131,2,125,4,124,4,100,5,25,0,100,11,107,2,144, - 1,114,56,124,4,100,8,25,0,116,25,118,1,144,1,114, - 56,124,4,100,12,100,1,133,2,25,0,125,4,116,23,116, - 8,106,21,124,4,160,26,116,25,161,1,124,11,131,3,83, - 0,116,23,124,4,116,27,124,11,131,3,83,0,41,13,97, - 254,2,0,0,71,105,118,101,110,32,116,104,101,32,112,97, - 116,104,32,116,111,32,97,32,46,112,121,32,102,105,108,101, - 44,32,114,101,116,117,114,110,32,116,104,101,32,112,97,116, - 104,32,116,111,32,105,116,115,32,46,112,121,99,32,102,105, - 108,101,46,10,10,32,32,32,32,84,104,101,32,46,112,121, - 32,102,105,108,101,32,100,111,101,115,32,110,111,116,32,110, - 101,101,100,32,116,111,32,101,120,105,115,116,59,32,116,104, - 105,115,32,115,105,109,112,108,121,32,114,101,116,117,114,110, - 115,32,116,104,101,32,112,97,116,104,32,116,111,32,116,104, - 101,10,32,32,32,32,46,112,121,99,32,102,105,108,101,32, - 99,97,108,99,117,108,97,116,101,100,32,97,115,32,105,102, - 32,116,104,101,32,46,112,121,32,102,105,108,101,32,119,101, - 114,101,32,105,109,112,111,114,116,101,100,46,10,10,32,32, - 32,32,84,104,101,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,112,97,114,97,109,101,116,101,114,32,99, - 111,110,116,114,111,108,115,32,116,104,101,32,112,114,101,115, - 117,109,101,100,32,111,112,116,105,109,105,122,97,116,105,111, - 110,32,108,101,118,101,108,32,111,102,10,32,32,32,32,116, - 104,101,32,98,121,116,101,99,111,100,101,32,102,105,108,101, - 46,32,73,102,32,39,111,112,116,105,109,105,122,97,116,105, - 111,110,39,32,105,115,32,110,111,116,32,78,111,110,101,44, - 32,116,104,101,32,115,116,114,105,110,103,32,114,101,112,114, - 101,115,101,110,116,97,116,105,111,110,10,32,32,32,32,111, - 102,32,116,104,101,32,97,114,103,117,109,101,110,116,32,105, - 115,32,116,97,107,101,110,32,97,110,100,32,118,101,114,105, - 102,105,101,100,32,116,111,32,98,101,32,97,108,112,104,97, - 110,117,109,101,114,105,99,32,40,101,108,115,101,32,86,97, - 108,117,101,69,114,114,111,114,10,32,32,32,32,105,115,32, - 114,97,105,115,101,100,41,46,10,10,32,32,32,32,84,104, - 101,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,112,97,114,97,109,101,116,101,114,32,105,115,32,100,101, - 112,114,101,99,97,116,101,100,46,32,73,102,32,100,101,98, - 117,103,95,111,118,101,114,114,105,100,101,32,105,115,32,110, - 111,116,32,78,111,110,101,44,10,32,32,32,32,97,32,84, - 114,117,101,32,118,97,108,117,101,32,105,115,32,116,104,101, - 32,115,97,109,101,32,97,115,32,115,101,116,116,105,110,103, - 32,39,111,112,116,105,109,105,122,97,116,105,111,110,39,32, - 116,111,32,116,104,101,32,101,109,112,116,121,32,115,116,114, - 105,110,103,10,32,32,32,32,119,104,105,108,101,32,97,32, - 70,97,108,115,101,32,118,97,108,117,101,32,105,115,32,101, - 113,117,105,118,97,108,101,110,116,32,116,111,32,115,101,116, - 116,105,110,103,32,39,111,112,116,105,109,105,122,97,116,105, - 111,110,39,32,116,111,32,39,49,39,46,10,10,32,32,32, - 32,73,102,32,115,121,115,46,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,46,99,97,99,104,101,95,116,97,103, - 32,105,115,32,78,111,110,101,32,116,104,101,110,32,78,111, - 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, - 114,32,105,115,32,114,97,105,115,101,100,46,10,10,32,32, - 32,32,78,122,70,116,104,101,32,100,101,98,117,103,95,111, - 118,101,114,114,105,100,101,32,112,97,114,97,109,101,116,101, - 114,32,105,115,32,100,101,112,114,101,99,97,116,101,100,59, - 32,117,115,101,32,39,111,112,116,105,109,105,122,97,116,105, - 111,110,39,32,105,110,115,116,101,97,100,122,50,100,101,98, - 117,103,95,111,118,101,114,114,105,100,101,32,111,114,32,111, - 112,116,105,109,105,122,97,116,105,111,110,32,109,117,115,116, - 32,98,101,32,115,101,116,32,116,111,32,78,111,110,101,114, - 40,0,0,0,114,39,0,0,0,218,1,46,250,36,115,121, - 115,46,105,109,112,108,101,109,101,110,116,97,116,105,111,110, - 46,99,97,99,104,101,95,116,97,103,32,105,115,32,78,111, - 110,101,233,0,0,0,0,122,24,123,33,114,125,32,105,115, - 32,110,111,116,32,97,108,112,104,97,110,117,109,101,114,105, - 99,122,7,123,125,46,123,125,123,125,250,1,58,114,28,0, - 0,0,41,28,218,9,95,119,97,114,110,105,110,103,115,218, - 4,119,97,114,110,218,18,68,101,112,114,101,99,97,116,105, - 111,110,87,97,114,110,105,110,103,218,9,84,121,112,101,69, - 114,114,111,114,114,4,0,0,0,218,6,102,115,112,97,116, - 104,114,47,0,0,0,114,41,0,0,0,114,1,0,0,0, - 218,14,105,109,112,108,101,109,101,110,116,97,116,105,111,110, - 218,9,99,97,99,104,101,95,116,97,103,218,19,78,111,116, - 73,109,112,108,101,109,101,110,116,101,100,69,114,114,111,114, - 114,36,0,0,0,114,2,0,0,0,218,8,111,112,116,105, - 109,105,122,101,218,3,115,116,114,218,7,105,115,97,108,110, - 117,109,218,10,86,97,108,117,101,69,114,114,111,114,114,62, - 0,0,0,218,4,95,79,80,84,218,17,66,89,84,69,67, - 79,68,69,95,83,85,70,70,73,88,69,83,218,14,112,121, - 99,97,99,104,101,95,112,114,101,102,105,120,114,59,0,0, - 0,114,38,0,0,0,114,55,0,0,0,114,31,0,0,0, - 218,6,108,115,116,114,105,112,218,8,95,80,89,67,65,67, - 72,69,41,12,114,44,0,0,0,90,14,100,101,98,117,103, - 95,111,118,101,114,114,105,100,101,114,70,0,0,0,218,7, - 109,101,115,115,97,103,101,218,4,104,101,97,100,114,46,0, - 0,0,90,4,98,97,115,101,218,3,115,101,112,218,4,114, - 101,115,116,90,3,116,97,103,90,15,97,108,109,111,115,116, - 95,102,105,108,101,110,97,109,101,218,8,102,105,108,101,110, - 97,109,101,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,17,99,97,99,104,101,95,102,114,111,109,95,115, - 111,117,114,99,101,45,1,0,0,115,72,0,0,0,0,18, - 8,1,6,1,2,255,4,2,8,1,4,1,8,1,12,1, - 10,1,12,1,16,1,8,1,8,1,8,1,24,1,8,1, - 12,1,6,2,8,1,8,1,8,1,8,1,14,1,14,1, - 12,1,12,9,10,1,14,5,28,1,12,4,2,1,4,1, - 8,1,2,253,4,5,114,97,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,10,0,0,0,5,0,0,0, - 67,0,0,0,115,46,1,0,0,116,0,106,1,106,2,100, - 1,117,0,114,20,116,3,100,2,131,1,130,1,116,4,160, - 5,124,0,161,1,125,0,116,6,124,0,131,1,92,2,125, - 1,125,2,100,3,125,3,116,0,106,7,100,1,117,1,114, - 102,116,0,106,7,160,8,116,9,161,1,125,4,124,1,160, - 10,124,4,116,11,23,0,161,1,114,102,124,1,116,12,124, - 4,131,1,100,1,133,2,25,0,125,1,100,4,125,3,124, - 3,115,144,116,6,124,1,131,1,92,2,125,1,125,5,124, - 5,116,13,107,3,114,144,116,14,116,13,155,0,100,5,124, - 0,155,2,157,3,131,1,130,1,124,2,160,15,100,6,161, - 1,125,6,124,6,100,7,118,1,114,178,116,14,100,8,124, - 2,155,2,157,2,131,1,130,1,110,92,124,6,100,9,107, - 2,144,1,114,14,124,2,160,16,100,6,100,10,161,2,100, - 11,25,0,125,7,124,7,160,10,116,17,161,1,115,228,116, - 14,100,12,116,17,155,2,157,2,131,1,130,1,124,7,116, - 12,116,17,131,1,100,1,133,2,25,0,125,8,124,8,160, - 18,161,0,144,1,115,14,116,14,100,13,124,7,155,2,100, - 14,157,3,131,1,130,1,124,2,160,19,100,6,161,1,100, - 15,25,0,125,9,116,20,124,1,124,9,116,21,100,15,25, - 0,23,0,131,2,83,0,41,16,97,110,1,0,0,71,105, - 118,101,110,32,116,104,101,32,112,97,116,104,32,116,111,32, - 97,32,46,112,121,99,46,32,102,105,108,101,44,32,114,101, - 116,117,114,110,32,116,104,101,32,112,97,116,104,32,116,111, - 32,105,116,115,32,46,112,121,32,102,105,108,101,46,10,10, - 32,32,32,32,84,104,101,32,46,112,121,99,32,102,105,108, - 101,32,100,111,101,115,32,110,111,116,32,110,101,101,100,32, - 116,111,32,101,120,105,115,116,59,32,116,104,105,115,32,115, - 105,109,112,108,121,32,114,101,116,117,114,110,115,32,116,104, - 101,32,112,97,116,104,32,116,111,10,32,32,32,32,116,104, - 101,32,46,112,121,32,102,105,108,101,32,99,97,108,99,117, - 108,97,116,101,100,32,116,111,32,99,111,114,114,101,115,112, - 111,110,100,32,116,111,32,116,104,101,32,46,112,121,99,32, - 102,105,108,101,46,32,32,73,102,32,112,97,116,104,32,100, - 111,101,115,10,32,32,32,32,110,111,116,32,99,111,110,102, - 111,114,109,32,116,111,32,80,69,80,32,51,49,52,55,47, - 52,56,56,32,102,111,114,109,97,116,44,32,86,97,108,117, - 101,69,114,114,111,114,32,119,105,108,108,32,98,101,32,114, - 97,105,115,101,100,46,32,73,102,10,32,32,32,32,115,121, - 115,46,105,109,112,108,101,109,101,110,116,97,116,105,111,110, - 46,99,97,99,104,101,95,116,97,103,32,105,115,32,78,111, - 110,101,32,116,104,101,110,32,78,111,116,73,109,112,108,101, - 109,101,110,116,101,100,69,114,114,111,114,32,105,115,32,114, - 97,105,115,101,100,46,10,10,32,32,32,32,78,114,72,0, - 0,0,70,84,122,31,32,110,111,116,32,98,111,116,116,111, - 109,45,108,101,118,101,108,32,100,105,114,101,99,116,111,114, - 121,32,105,110,32,114,71,0,0,0,62,2,0,0,0,114, - 28,0,0,0,114,57,0,0,0,122,29,101,120,112,101,99, - 116,101,100,32,111,110,108,121,32,50,32,111,114,32,51,32, - 100,111,116,115,32,105,110,32,114,57,0,0,0,114,28,0, - 0,0,233,254,255,255,255,122,53,111,112,116,105,109,105,122, - 97,116,105,111,110,32,112,111,114,116,105,111,110,32,111,102, - 32,102,105,108,101,110,97,109,101,32,100,111,101,115,32,110, - 111,116,32,115,116,97,114,116,32,119,105,116,104,32,122,19, - 111,112,116,105,109,105,122,97,116,105,111,110,32,108,101,118, - 101,108,32,122,29,32,105,115,32,110,111,116,32,97,110,32, - 97,108,112,104,97,110,117,109,101,114,105,99,32,118,97,108, - 117,101,114,73,0,0,0,41,22,114,1,0,0,0,114,80, - 0,0,0,114,81,0,0,0,114,82,0,0,0,114,4,0, - 0,0,114,79,0,0,0,114,47,0,0,0,114,89,0,0, - 0,114,30,0,0,0,114,31,0,0,0,114,11,0,0,0, - 114,35,0,0,0,114,23,0,0,0,114,91,0,0,0,114, - 86,0,0,0,218,5,99,111,117,110,116,114,43,0,0,0, - 114,87,0,0,0,114,85,0,0,0,218,9,112,97,114,116, - 105,116,105,111,110,114,38,0,0,0,218,15,83,79,85,82, - 67,69,95,83,85,70,70,73,88,69,83,41,10,114,44,0, - 0,0,114,93,0,0,0,90,16,112,121,99,97,99,104,101, - 95,102,105,108,101,110,97,109,101,90,23,102,111,117,110,100, - 95,105,110,95,112,121,99,97,99,104,101,95,112,114,101,102, - 105,120,90,13,115,116,114,105,112,112,101,100,95,112,97,116, - 104,90,7,112,121,99,97,99,104,101,90,9,100,111,116,95, - 99,111,117,110,116,114,70,0,0,0,90,9,111,112,116,95, - 108,101,118,101,108,90,13,98,97,115,101,95,102,105,108,101, - 110,97,109,101,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,17,115,111,117,114,99,101,95,102,114,111,109, - 95,99,97,99,104,101,116,1,0,0,115,60,0,0,0,0, - 9,12,1,8,1,10,1,12,1,4,1,10,1,12,1,14, - 1,16,1,4,1,4,1,12,1,8,1,8,1,2,255,8, - 2,10,1,8,1,16,1,10,1,16,1,10,1,4,1,2, - 255,8,2,16,1,10,1,16,2,14,1,114,102,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,9,0,0,0,67,0,0,0,115,124,0,0,0,116,0, - 124,0,131,1,100,1,107,2,114,16,100,2,83,0,124,0, - 160,1,100,3,161,1,92,3,125,1,125,2,125,3,124,1, - 114,56,124,3,160,2,161,0,100,4,100,5,133,2,25,0, - 100,6,107,3,114,60,124,0,83,0,122,12,116,3,124,0, - 131,1,125,4,87,0,110,34,4,0,116,4,116,5,102,2, - 121,106,1,0,1,0,1,0,124,0,100,2,100,5,133,2, - 25,0,125,4,89,0,110,2,48,0,116,6,124,4,131,1, - 114,120,124,4,83,0,124,0,83,0,41,7,122,188,67,111, - 110,118,101,114,116,32,97,32,98,121,116,101,99,111,100,101, - 32,102,105,108,101,32,112,97,116,104,32,116,111,32,97,32, - 115,111,117,114,99,101,32,112,97,116,104,32,40,105,102,32, - 112,111,115,115,105,98,108,101,41,46,10,10,32,32,32,32, - 84,104,105,115,32,102,117,110,99,116,105,111,110,32,101,120, - 105,115,116,115,32,112,117,114,101,108,121,32,102,111,114,32, - 98,97,99,107,119,97,114,100,115,45,99,111,109,112,97,116, - 105,98,105,108,105,116,121,32,102,111,114,10,32,32,32,32, - 80,121,73,109,112,111,114,116,95,69,120,101,99,67,111,100, - 101,77,111,100,117,108,101,87,105,116,104,70,105,108,101,110, - 97,109,101,115,40,41,32,105,110,32,116,104,101,32,67,32, - 65,80,73,46,10,10,32,32,32,32,114,73,0,0,0,78, - 114,71,0,0,0,233,253,255,255,255,233,255,255,255,255,90, - 2,112,121,41,7,114,23,0,0,0,114,41,0,0,0,218, - 5,108,111,119,101,114,114,102,0,0,0,114,82,0,0,0, - 114,86,0,0,0,114,54,0,0,0,41,5,218,13,98,121, - 116,101,99,111,100,101,95,112,97,116,104,114,95,0,0,0, - 114,45,0,0,0,90,9,101,120,116,101,110,115,105,111,110, - 218,11,115,111,117,114,99,101,95,112,97,116,104,114,5,0, - 0,0,114,5,0,0,0,114,8,0,0,0,218,15,95,103, - 101,116,95,115,111,117,114,99,101,102,105,108,101,156,1,0, - 0,115,20,0,0,0,0,7,12,1,4,1,16,1,24,1, - 4,1,2,1,12,1,16,1,18,1,114,108,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 8,0,0,0,67,0,0,0,115,72,0,0,0,124,0,160, - 0,116,1,116,2,131,1,161,1,114,46,122,10,116,3,124, - 0,131,1,87,0,83,0,4,0,116,4,121,42,1,0,1, - 0,1,0,89,0,113,68,48,0,110,22,124,0,160,0,116, - 1,116,5,131,1,161,1,114,64,124,0,83,0,100,0,83, - 0,100,0,83,0,169,1,78,41,6,218,8,101,110,100,115, - 119,105,116,104,218,5,116,117,112,108,101,114,101,0,0,0, - 114,97,0,0,0,114,82,0,0,0,114,88,0,0,0,41, - 1,114,96,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,11,95,103,101,116,95,99,97,99,104, - 101,100,175,1,0,0,115,16,0,0,0,0,1,14,1,2, - 1,10,1,12,1,8,1,14,1,4,2,114,112,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,8,0,0,0,67,0,0,0,115,50,0,0,0,122,14, - 116,0,124,0,131,1,106,1,125,1,87,0,110,22,4,0, - 116,2,121,36,1,0,1,0,1,0,100,1,125,1,89,0, - 110,2,48,0,124,1,100,2,79,0,125,1,124,1,83,0, - 41,3,122,51,67,97,108,99,117,108,97,116,101,32,116,104, - 101,32,109,111,100,101,32,112,101,114,109,105,115,115,105,111, - 110,115,32,102,111,114,32,97,32,98,121,116,101,99,111,100, - 101,32,102,105,108,101,46,114,60,0,0,0,233,128,0,0, - 0,41,3,114,49,0,0,0,114,51,0,0,0,114,50,0, - 0,0,41,2,114,44,0,0,0,114,52,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,10,95, - 99,97,108,99,95,109,111,100,101,187,1,0,0,115,12,0, - 0,0,0,2,2,1,14,1,12,1,10,3,8,1,114,114, + 115,10,0,0,0,116,0,160,1,124,0,161,1,83,0,41, + 1,122,126,83,116,97,116,32,116,104,101,32,112,97,116,104, + 46,10,10,32,32,32,32,77,97,100,101,32,97,32,115,101, + 112,97,114,97,116,101,32,102,117,110,99,116,105,111,110,32, + 116,111,32,109,97,107,101,32,105,116,32,101,97,115,105,101, + 114,32,116,111,32,111,118,101,114,114,105,100,101,32,105,110, + 32,101,120,112,101,114,105,109,101,110,116,115,10,32,32,32, + 32,40,101,46,103,46,32,99,97,99,104,101,32,115,116,97, + 116,32,114,101,115,117,108,116,115,41,46,10,10,32,32,32, + 32,41,2,114,4,0,0,0,90,4,115,116,97,116,169,1, + 114,44,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,218,10,95,112,97,116,104,95,115,116,97,116, + 80,0,0,0,115,2,0,0,0,0,7,114,49,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,48,0,0,0,122,12, + 116,0,124,0,131,1,125,2,87,0,110,20,4,0,116,1, + 121,32,1,0,1,0,1,0,89,0,100,1,83,0,48,0, + 124,2,106,2,100,2,64,0,124,1,107,2,83,0,41,3, + 122,49,84,101,115,116,32,119,104,101,116,104,101,114,32,116, + 104,101,32,112,97,116,104,32,105,115,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,101,32,116,121, + 112,101,46,70,105,0,240,0,0,41,3,114,49,0,0,0, + 218,7,79,83,69,114,114,111,114,218,7,115,116,95,109,111, + 100,101,41,3,114,44,0,0,0,218,4,109,111,100,101,90, + 9,115,116,97,116,95,105,110,102,111,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,18,95,112,97,116,104, + 95,105,115,95,109,111,100,101,95,116,121,112,101,90,0,0, + 0,115,10,0,0,0,0,2,2,1,12,1,12,1,8,1, + 114,53,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,124,0,100,1,131,2,83,0,41,2,122, + 31,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, + 32,111,115,46,112,97,116,104,46,105,115,102,105,108,101,46, + 105,0,128,0,0,41,1,114,53,0,0,0,114,48,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 218,12,95,112,97,116,104,95,105,115,102,105,108,101,99,0, + 0,0,115,2,0,0,0,0,2,114,54,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, + 0,0,0,67,0,0,0,115,22,0,0,0,124,0,115,12, + 116,0,160,1,161,0,125,0,116,2,124,0,100,1,131,2, + 83,0,41,2,122,30,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, + 100,105,114,46,105,0,64,0,0,41,3,114,4,0,0,0, + 218,6,103,101,116,99,119,100,114,53,0,0,0,114,48,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, + 0,218,11,95,112,97,116,104,95,105,115,100,105,114,104,0, + 0,0,115,6,0,0,0,0,2,4,1,8,1,114,56,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,26,0,0,0, + 124,0,160,0,116,1,161,1,112,24,124,0,100,1,100,2, + 133,2,25,0,116,2,118,0,83,0,41,3,122,142,82,101, + 112,108,97,99,101,109,101,110,116,32,102,111,114,32,111,115, + 46,112,97,116,104,46,105,115,97,98,115,46,10,10,32,32, + 32,32,67,111,110,115,105,100,101,114,115,32,97,32,87,105, + 110,100,111,119,115,32,100,114,105,118,101,45,114,101,108,97, + 116,105,118,101,32,112,97,116,104,32,40,110,111,32,100,114, + 105,118,101,44,32,98,117,116,32,115,116,97,114,116,115,32, + 119,105,116,104,32,115,108,97,115,104,41,32,116,111,10,32, + 32,32,32,115,116,105,108,108,32,98,101,32,34,97,98,115, + 111,108,117,116,101,34,46,10,32,32,32,32,114,39,0,0, + 0,233,3,0,0,0,41,3,114,11,0,0,0,114,31,0, + 0,0,218,20,95,112,97,116,104,115,101,112,115,95,119,105, + 116,104,95,99,111,108,111,110,114,48,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,218,11,95,112, + 97,116,104,95,105,115,97,98,115,111,0,0,0,115,2,0, + 0,0,0,6,114,59,0,0,0,233,182,1,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,11, + 0,0,0,67,0,0,0,115,172,0,0,0,100,1,160,0, + 124,0,116,1,124,0,131,1,161,2,125,3,116,2,160,3, + 124,3,116,2,106,4,116,2,106,5,66,0,116,2,106,6, + 66,0,124,2,100,2,64,0,161,3,125,4,122,70,116,7, + 160,8,124,4,100,3,161,2,143,26,125,5,124,5,160,9, + 124,1,161,1,1,0,87,0,100,4,4,0,4,0,131,3, + 1,0,110,16,49,0,115,94,48,0,1,0,1,0,1,0, + 89,0,1,0,116,2,160,10,124,3,124,0,161,2,1,0, + 87,0,110,48,4,0,116,11,121,166,1,0,1,0,1,0, + 122,14,116,2,160,12,124,3,161,1,1,0,87,0,130,0, + 4,0,116,11,121,164,1,0,1,0,1,0,89,0,130,0, + 48,0,48,0,100,4,83,0,41,5,122,162,66,101,115,116, + 45,101,102,102,111,114,116,32,102,117,110,99,116,105,111,110, + 32,116,111,32,119,114,105,116,101,32,100,97,116,97,32,116, + 111,32,97,32,112,97,116,104,32,97,116,111,109,105,99,97, + 108,108,121,46,10,32,32,32,32,66,101,32,112,114,101,112, + 97,114,101,100,32,116,111,32,104,97,110,100,108,101,32,97, + 32,70,105,108,101,69,120,105,115,116,115,69,114,114,111,114, + 32,105,102,32,99,111,110,99,117,114,114,101,110,116,32,119, + 114,105,116,105,110,103,32,111,102,32,116,104,101,10,32,32, + 32,32,116,101,109,112,111,114,97,114,121,32,102,105,108,101, + 32,105,115,32,97,116,116,101,109,112,116,101,100,46,250,5, + 123,125,46,123,125,114,60,0,0,0,90,2,119,98,78,41, + 13,218,6,102,111,114,109,97,116,218,2,105,100,114,4,0, + 0,0,90,4,111,112,101,110,90,6,79,95,69,88,67,76, + 90,7,79,95,67,82,69,65,84,90,8,79,95,87,82,79, + 78,76,89,218,3,95,105,111,218,6,70,105,108,101,73,79, + 218,5,119,114,105,116,101,218,7,114,101,112,108,97,99,101, + 114,50,0,0,0,90,6,117,110,108,105,110,107,41,6,114, + 44,0,0,0,114,26,0,0,0,114,52,0,0,0,90,8, + 112,97,116,104,95,116,109,112,90,2,102,100,218,4,102,105, + 108,101,114,5,0,0,0,114,5,0,0,0,114,8,0,0, + 0,218,13,95,119,114,105,116,101,95,97,116,111,109,105,99, + 120,0,0,0,115,28,0,0,0,0,5,16,1,6,1,22, + 255,4,2,2,3,14,1,40,1,16,1,12,1,2,1,14, + 1,12,1,6,1,114,69,0,0,0,105,97,13,0,0,114, + 28,0,0,0,114,17,0,0,0,115,2,0,0,0,13,10, + 90,11,95,95,112,121,99,97,99,104,101,95,95,122,4,111, + 112,116,45,122,3,46,112,121,122,4,46,112,121,99,78,41, + 1,218,12,111,112,116,105,109,105,122,97,116,105,111,110,99, + 2,0,0,0,0,0,0,0,1,0,0,0,12,0,0,0, + 5,0,0,0,67,0,0,0,115,88,1,0,0,124,1,100, + 1,117,1,114,52,116,0,160,1,100,2,116,2,161,2,1, + 0,124,2,100,1,117,1,114,40,100,3,125,3,116,3,124, + 3,131,1,130,1,124,1,114,48,100,4,110,2,100,5,125, + 2,116,4,160,5,124,0,161,1,125,0,116,6,124,0,131, + 1,92,2,125,4,125,5,124,5,160,7,100,6,161,1,92, + 3,125,6,125,7,125,8,116,8,106,9,106,10,125,9,124, + 9,100,1,117,0,114,114,116,11,100,7,131,1,130,1,100, + 4,160,12,124,6,114,126,124,6,110,2,124,8,124,7,124, + 9,103,3,161,1,125,10,124,2,100,1,117,0,114,172,116, + 8,106,13,106,14,100,8,107,2,114,164,100,4,125,2,110, + 8,116,8,106,13,106,14,125,2,116,15,124,2,131,1,125, + 2,124,2,100,4,107,3,114,224,124,2,160,16,161,0,115, + 210,116,17,100,9,160,18,124,2,161,1,131,1,130,1,100, + 10,160,18,124,10,116,19,124,2,161,3,125,10,124,10,116, + 20,100,8,25,0,23,0,125,11,116,8,106,21,100,1,117, + 1,144,1,114,76,116,22,124,4,131,1,144,1,115,16,116, + 23,116,4,160,24,161,0,124,4,131,2,125,4,124,4,100, + 5,25,0,100,11,107,2,144,1,114,56,124,4,100,8,25, + 0,116,25,118,1,144,1,114,56,124,4,100,12,100,1,133, + 2,25,0,125,4,116,23,116,8,106,21,124,4,160,26,116, + 25,161,1,124,11,131,3,83,0,116,23,124,4,116,27,124, + 11,131,3,83,0,41,13,97,254,2,0,0,71,105,118,101, + 110,32,116,104,101,32,112,97,116,104,32,116,111,32,97,32, + 46,112,121,32,102,105,108,101,44,32,114,101,116,117,114,110, + 32,116,104,101,32,112,97,116,104,32,116,111,32,105,116,115, + 32,46,112,121,99,32,102,105,108,101,46,10,10,32,32,32, + 32,84,104,101,32,46,112,121,32,102,105,108,101,32,100,111, + 101,115,32,110,111,116,32,110,101,101,100,32,116,111,32,101, + 120,105,115,116,59,32,116,104,105,115,32,115,105,109,112,108, + 121,32,114,101,116,117,114,110,115,32,116,104,101,32,112,97, + 116,104,32,116,111,32,116,104,101,10,32,32,32,32,46,112, + 121,99,32,102,105,108,101,32,99,97,108,99,117,108,97,116, + 101,100,32,97,115,32,105,102,32,116,104,101,32,46,112,121, + 32,102,105,108,101,32,119,101,114,101,32,105,109,112,111,114, + 116,101,100,46,10,10,32,32,32,32,84,104,101,32,39,111, + 112,116,105,109,105,122,97,116,105,111,110,39,32,112,97,114, + 97,109,101,116,101,114,32,99,111,110,116,114,111,108,115,32, + 116,104,101,32,112,114,101,115,117,109,101,100,32,111,112,116, + 105,109,105,122,97,116,105,111,110,32,108,101,118,101,108,32, + 111,102,10,32,32,32,32,116,104,101,32,98,121,116,101,99, + 111,100,101,32,102,105,108,101,46,32,73,102,32,39,111,112, + 116,105,109,105,122,97,116,105,111,110,39,32,105,115,32,110, + 111,116,32,78,111,110,101,44,32,116,104,101,32,115,116,114, + 105,110,103,32,114,101,112,114,101,115,101,110,116,97,116,105, + 111,110,10,32,32,32,32,111,102,32,116,104,101,32,97,114, + 103,117,109,101,110,116,32,105,115,32,116,97,107,101,110,32, + 97,110,100,32,118,101,114,105,102,105,101,100,32,116,111,32, + 98,101,32,97,108,112,104,97,110,117,109,101,114,105,99,32, + 40,101,108,115,101,32,86,97,108,117,101,69,114,114,111,114, + 10,32,32,32,32,105,115,32,114,97,105,115,101,100,41,46, + 10,10,32,32,32,32,84,104,101,32,100,101,98,117,103,95, + 111,118,101,114,114,105,100,101,32,112,97,114,97,109,101,116, + 101,114,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 46,32,73,102,32,100,101,98,117,103,95,111,118,101,114,114, + 105,100,101,32,105,115,32,110,111,116,32,78,111,110,101,44, + 10,32,32,32,32,97,32,84,114,117,101,32,118,97,108,117, + 101,32,105,115,32,116,104,101,32,115,97,109,101,32,97,115, + 32,115,101,116,116,105,110,103,32,39,111,112,116,105,109,105, + 122,97,116,105,111,110,39,32,116,111,32,116,104,101,32,101, + 109,112,116,121,32,115,116,114,105,110,103,10,32,32,32,32, + 119,104,105,108,101,32,97,32,70,97,108,115,101,32,118,97, + 108,117,101,32,105,115,32,101,113,117,105,118,97,108,101,110, + 116,32,116,111,32,115,101,116,116,105,110,103,32,39,111,112, + 116,105,109,105,122,97,116,105,111,110,39,32,116,111,32,39, + 49,39,46,10,10,32,32,32,32,73,102,32,115,121,115,46, + 105,109,112,108,101,109,101,110,116,97,116,105,111,110,46,99, + 97,99,104,101,95,116,97,103,32,105,115,32,78,111,110,101, + 32,116,104,101,110,32,78,111,116,73,109,112,108,101,109,101, + 110,116,101,100,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,46,10,10,32,32,32,32,78,122,70,116,104,101, + 32,100,101,98,117,103,95,111,118,101,114,114,105,100,101,32, + 112,97,114,97,109,101,116,101,114,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,59,32,117,115,101,32,39,111,112, + 116,105,109,105,122,97,116,105,111,110,39,32,105,110,115,116, + 101,97,100,122,50,100,101,98,117,103,95,111,118,101,114,114, + 105,100,101,32,111,114,32,111,112,116,105,109,105,122,97,116, + 105,111,110,32,109,117,115,116,32,98,101,32,115,101,116,32, + 116,111,32,78,111,110,101,114,40,0,0,0,114,39,0,0, + 0,218,1,46,250,36,115,121,115,46,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,46,99,97,99,104,101,95,116, + 97,103,32,105,115,32,78,111,110,101,233,0,0,0,0,122, + 24,123,33,114,125,32,105,115,32,110,111,116,32,97,108,112, + 104,97,110,117,109,101,114,105,99,122,7,123,125,46,123,125, + 123,125,250,1,58,114,28,0,0,0,41,28,218,9,95,119, + 97,114,110,105,110,103,115,218,4,119,97,114,110,218,18,68, + 101,112,114,101,99,97,116,105,111,110,87,97,114,110,105,110, + 103,218,9,84,121,112,101,69,114,114,111,114,114,4,0,0, + 0,218,6,102,115,112,97,116,104,114,47,0,0,0,114,41, + 0,0,0,114,1,0,0,0,218,14,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,218,9,99,97,99,104,101,95, + 116,97,103,218,19,78,111,116,73,109,112,108,101,109,101,110, + 116,101,100,69,114,114,111,114,114,36,0,0,0,114,2,0, + 0,0,218,8,111,112,116,105,109,105,122,101,218,3,115,116, + 114,218,7,105,115,97,108,110,117,109,218,10,86,97,108,117, + 101,69,114,114,111,114,114,62,0,0,0,218,4,95,79,80, + 84,218,17,66,89,84,69,67,79,68,69,95,83,85,70,70, + 73,88,69,83,218,14,112,121,99,97,99,104,101,95,112,114, + 101,102,105,120,114,59,0,0,0,114,38,0,0,0,114,55, + 0,0,0,114,31,0,0,0,218,6,108,115,116,114,105,112, + 218,8,95,80,89,67,65,67,72,69,41,12,114,44,0,0, + 0,90,14,100,101,98,117,103,95,111,118,101,114,114,105,100, + 101,114,70,0,0,0,218,7,109,101,115,115,97,103,101,218, + 4,104,101,97,100,114,46,0,0,0,90,4,98,97,115,101, + 218,3,115,101,112,218,4,114,101,115,116,90,3,116,97,103, + 90,15,97,108,109,111,115,116,95,102,105,108,101,110,97,109, + 101,218,8,102,105,108,101,110,97,109,101,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,218,17,99,97,99,104, + 101,95,102,114,111,109,95,115,111,117,114,99,101,45,1,0, + 0,115,72,0,0,0,0,18,8,1,6,1,2,255,4,2, + 8,1,4,1,8,1,12,1,10,1,12,1,16,1,8,1, + 8,1,8,1,24,1,8,1,12,1,6,2,8,1,8,1, + 8,1,8,1,14,1,14,1,12,1,12,9,10,1,14,5, + 28,1,12,4,2,1,4,1,8,1,2,253,4,5,114,97, 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,8,0,0,0,3,0,0,0,115,66,0,0, - 0,100,6,135,0,102,1,100,2,100,3,132,9,125,1,122, - 10,116,0,106,1,125,2,87,0,110,26,4,0,116,2,121, - 50,1,0,1,0,1,0,100,4,100,5,132,0,125,2,89, - 0,110,2,48,0,124,2,124,1,136,0,131,2,1,0,124, - 1,83,0,41,7,122,252,68,101,99,111,114,97,116,111,114, - 32,116,111,32,118,101,114,105,102,121,32,116,104,97,116,32, - 116,104,101,32,109,111,100,117,108,101,32,98,101,105,110,103, - 32,114,101,113,117,101,115,116,101,100,32,109,97,116,99,104, - 101,115,32,116,104,101,32,111,110,101,32,116,104,101,10,32, - 32,32,32,108,111,97,100,101,114,32,99,97,110,32,104,97, - 110,100,108,101,46,10,10,32,32,32,32,84,104,101,32,102, - 105,114,115,116,32,97,114,103,117,109,101,110,116,32,40,115, - 101,108,102,41,32,109,117,115,116,32,100,101,102,105,110,101, - 32,95,110,97,109,101,32,119,104,105,99,104,32,116,104,101, - 32,115,101,99,111,110,100,32,97,114,103,117,109,101,110,116, - 32,105,115,10,32,32,32,32,99,111,109,112,97,114,101,100, - 32,97,103,97,105,110,115,116,46,32,73,102,32,116,104,101, - 32,99,111,109,112,97,114,105,115,111,110,32,102,97,105,108, - 115,32,116,104,101,110,32,73,109,112,111,114,116,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,99,2,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,4,0,0,0,31,0,0,0,115,72,0, - 0,0,124,1,100,0,117,0,114,16,124,0,106,0,125,1, - 110,32,124,0,106,0,124,1,107,3,114,48,116,1,100,1, - 124,0,106,0,124,1,102,2,22,0,124,1,100,2,141,2, - 130,1,136,0,124,0,124,1,103,2,124,2,162,1,82,0, - 105,0,124,3,164,1,142,1,83,0,41,3,78,122,30,108, - 111,97,100,101,114,32,102,111,114,32,37,115,32,99,97,110, - 110,111,116,32,104,97,110,100,108,101,32,37,115,169,1,218, - 4,110,97,109,101,41,2,114,116,0,0,0,218,11,73,109, - 112,111,114,116,69,114,114,111,114,41,4,218,4,115,101,108, - 102,114,116,0,0,0,218,4,97,114,103,115,218,6,107,119, - 97,114,103,115,169,1,218,6,109,101,116,104,111,100,114,5, - 0,0,0,114,8,0,0,0,218,19,95,99,104,101,99,107, - 95,110,97,109,101,95,119,114,97,112,112,101,114,207,1,0, - 0,115,18,0,0,0,0,1,8,1,8,1,10,1,4,1, - 8,255,2,1,2,255,6,2,122,40,95,99,104,101,99,107, - 95,110,97,109,101,46,60,108,111,99,97,108,115,62,46,95, - 99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112, - 101,114,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,7,0,0,0,83,0,0,0,115,56,0,0,0, - 100,1,68,0,93,32,125,2,116,0,124,1,124,2,131,2, - 114,4,116,1,124,0,124,2,116,2,124,1,124,2,131,2, - 131,3,1,0,113,4,124,0,106,3,160,4,124,1,106,3, - 161,1,1,0,100,0,83,0,41,2,78,41,4,218,10,95, - 95,109,111,100,117,108,101,95,95,218,8,95,95,110,97,109, - 101,95,95,218,12,95,95,113,117,97,108,110,97,109,101,95, - 95,218,7,95,95,100,111,99,95,95,41,5,218,7,104,97, - 115,97,116,116,114,218,7,115,101,116,97,116,116,114,218,7, - 103,101,116,97,116,116,114,218,8,95,95,100,105,99,116,95, - 95,218,6,117,112,100,97,116,101,41,3,90,3,110,101,119, - 90,3,111,108,100,114,67,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,218,5,95,119,114,97,112, - 218,1,0,0,115,8,0,0,0,0,1,8,1,10,1,20, - 1,122,26,95,99,104,101,99,107,95,110,97,109,101,46,60, - 108,111,99,97,108,115,62,46,95,119,114,97,112,41,1,78, - 41,3,218,10,95,98,111,111,116,115,116,114,97,112,114,133, - 0,0,0,218,9,78,97,109,101,69,114,114,111,114,41,3, - 114,122,0,0,0,114,123,0,0,0,114,133,0,0,0,114, - 5,0,0,0,114,121,0,0,0,114,8,0,0,0,218,11, - 95,99,104,101,99,107,95,110,97,109,101,199,1,0,0,115, - 14,0,0,0,0,8,14,7,2,1,10,1,12,2,14,5, - 10,1,114,136,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,6,0,0,0,67,0,0,0, - 115,60,0,0,0,124,0,160,0,124,1,161,1,92,2,125, - 2,125,3,124,2,100,1,117,0,114,56,116,1,124,3,131, - 1,114,56,100,2,125,4,116,2,160,3,124,4,160,4,124, - 3,100,3,25,0,161,1,116,5,161,2,1,0,124,2,83, - 0,41,4,122,155,84,114,121,32,116,111,32,102,105,110,100, - 32,97,32,108,111,97,100,101,114,32,102,111,114,32,116,104, - 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, - 108,101,32,98,121,32,100,101,108,101,103,97,116,105,110,103, - 32,116,111,10,32,32,32,32,115,101,108,102,46,102,105,110, - 100,95,108,111,97,100,101,114,40,41,46,10,10,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,32,105,110,32,102,97, - 118,111,114,32,111,102,32,102,105,110,100,101,114,46,102,105, - 110,100,95,115,112,101,99,40,41,46,10,10,32,32,32,32, - 78,122,44,78,111,116,32,105,109,112,111,114,116,105,110,103, - 32,100,105,114,101,99,116,111,114,121,32,123,125,58,32,109, - 105,115,115,105,110,103,32,95,95,105,110,105,116,95,95,114, - 73,0,0,0,41,6,218,11,102,105,110,100,95,108,111,97, - 100,101,114,114,23,0,0,0,114,75,0,0,0,114,76,0, - 0,0,114,62,0,0,0,218,13,73,109,112,111,114,116,87, - 97,114,110,105,110,103,41,5,114,118,0,0,0,218,8,102, - 117,108,108,110,97,109,101,218,6,108,111,97,100,101,114,218, - 8,112,111,114,116,105,111,110,115,218,3,109,115,103,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,17,95, - 102,105,110,100,95,109,111,100,117,108,101,95,115,104,105,109, - 227,1,0,0,115,10,0,0,0,0,10,14,1,16,1,4, - 1,22,1,114,143,0,0,0,99,3,0,0,0,0,0,0, - 0,0,0,0,0,6,0,0,0,4,0,0,0,67,0,0, - 0,115,166,0,0,0,124,0,100,1,100,2,133,2,25,0, - 125,3,124,3,116,0,107,3,114,64,100,3,124,1,155,2, - 100,4,124,3,155,2,157,4,125,4,116,1,160,2,100,5, - 124,4,161,2,1,0,116,3,124,4,102,1,105,0,124,2, - 164,1,142,1,130,1,116,4,124,0,131,1,100,6,107,0, - 114,106,100,7,124,1,155,2,157,2,125,4,116,1,160,2, - 100,5,124,4,161,2,1,0,116,5,124,4,131,1,130,1, - 116,6,124,0,100,2,100,8,133,2,25,0,131,1,125,5, - 124,5,100,9,64,0,114,162,100,10,124,5,155,2,100,11, - 124,1,155,2,157,4,125,4,116,3,124,4,102,1,105,0, - 124,2,164,1,142,1,130,1,124,5,83,0,41,12,97,84, - 2,0,0,80,101,114,102,111,114,109,32,98,97,115,105,99, - 32,118,97,108,105,100,105,116,121,32,99,104,101,99,107,105, - 110,103,32,111,102,32,97,32,112,121,99,32,104,101,97,100, - 101,114,32,97,110,100,32,114,101,116,117,114,110,32,116,104, - 101,32,102,108,97,103,115,32,102,105,101,108,100,44,10,32, - 32,32,32,119,104,105,99,104,32,100,101,116,101,114,109,105, - 110,101,115,32,104,111,119,32,116,104,101,32,112,121,99,32, - 115,104,111,117,108,100,32,98,101,32,102,117,114,116,104,101, - 114,32,118,97,108,105,100,97,116,101,100,32,97,103,97,105, - 110,115,116,32,116,104,101,32,115,111,117,114,99,101,46,10, - 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, - 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, - 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, - 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, - 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, - 113,117,105,114,101,100,44,32,116,104,111,117,103,104,46,41, - 10,10,32,32,32,32,42,110,97,109,101,42,32,105,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,32, - 109,111,100,117,108,101,32,98,101,105,110,103,32,105,109,112, - 111,114,116,101,100,46,32,73,116,32,105,115,32,117,115,101, - 100,32,102,111,114,32,108,111,103,103,105,110,103,46,10,10, - 32,32,32,32,42,101,120,99,95,100,101,116,97,105,108,115, - 42,32,105,115,32,97,32,100,105,99,116,105,111,110,97,114, - 121,32,112,97,115,115,101,100,32,116,111,32,73,109,112,111, - 114,116,69,114,114,111,114,32,105,102,32,105,116,32,114,97, - 105,115,101,100,32,102,111,114,10,32,32,32,32,105,109,112, - 114,111,118,101,100,32,100,101,98,117,103,103,105,110,103,46, - 10,10,32,32,32,32,73,109,112,111,114,116,69,114,114,111, - 114,32,105,115,32,114,97,105,115,101,100,32,119,104,101,110, - 32,116,104,101,32,109,97,103,105,99,32,110,117,109,98,101, - 114,32,105,115,32,105,110,99,111,114,114,101,99,116,32,111, - 114,32,119,104,101,110,32,116,104,101,32,102,108,97,103,115, - 10,32,32,32,32,102,105,101,108,100,32,105,115,32,105,110, - 118,97,108,105,100,46,32,69,79,70,69,114,114,111,114,32, - 105,115,32,114,97,105,115,101,100,32,119,104,101,110,32,116, - 104,101,32,100,97,116,97,32,105,115,32,102,111,117,110,100, - 32,116,111,32,98,101,32,116,114,117,110,99,97,116,101,100, - 46,10,10,32,32,32,32,78,114,16,0,0,0,122,20,98, - 97,100,32,109,97,103,105,99,32,110,117,109,98,101,114,32, - 105,110,32,122,2,58,32,250,2,123,125,233,16,0,0,0, - 122,40,114,101,97,99,104,101,100,32,69,79,70,32,119,104, - 105,108,101,32,114,101,97,100,105,110,103,32,112,121,99,32, - 104,101,97,100,101,114,32,111,102,32,233,8,0,0,0,233, - 252,255,255,255,122,14,105,110,118,97,108,105,100,32,102,108, - 97,103,115,32,122,4,32,105,110,32,41,7,218,12,77,65, - 71,73,67,95,78,85,77,66,69,82,114,134,0,0,0,218, - 16,95,118,101,114,98,111,115,101,95,109,101,115,115,97,103, - 101,114,117,0,0,0,114,23,0,0,0,218,8,69,79,70, - 69,114,114,111,114,114,27,0,0,0,41,6,114,26,0,0, - 0,114,116,0,0,0,218,11,101,120,99,95,100,101,116,97, - 105,108,115,90,5,109,97,103,105,99,114,92,0,0,0,114, - 2,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,13,95,99,108,97,115,115,105,102,121,95,112, - 121,99,244,1,0,0,115,28,0,0,0,0,16,12,1,8, - 1,16,1,12,1,16,1,12,1,10,1,12,1,8,1,16, - 2,8,1,16,1,16,1,114,152,0,0,0,99,5,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0, - 0,67,0,0,0,115,120,0,0,0,116,0,124,0,100,1, - 100,2,133,2,25,0,131,1,124,1,100,3,64,0,107,3, - 114,62,100,4,124,3,155,2,157,2,125,5,116,1,160,2, - 100,5,124,5,161,2,1,0,116,3,124,5,102,1,105,0, - 124,4,164,1,142,1,130,1,124,2,100,6,117,1,114,116, - 116,0,124,0,100,2,100,7,133,2,25,0,131,1,124,2, - 100,3,64,0,107,3,114,116,116,3,100,4,124,3,155,2, - 157,2,102,1,105,0,124,4,164,1,142,1,130,1,100,6, - 83,0,41,8,97,7,2,0,0,86,97,108,105,100,97,116, - 101,32,97,32,112,121,99,32,97,103,97,105,110,115,116,32, - 116,104,101,32,115,111,117,114,99,101,32,108,97,115,116,45, - 109,111,100,105,102,105,101,100,32,116,105,109,101,46,10,10, - 32,32,32,32,42,100,97,116,97,42,32,105,115,32,116,104, - 101,32,99,111,110,116,101,110,116,115,32,111,102,32,116,104, - 101,32,112,121,99,32,102,105,108,101,46,32,40,79,110,108, - 121,32,116,104,101,32,102,105,114,115,116,32,49,54,32,98, - 121,116,101,115,32,97,114,101,10,32,32,32,32,114,101,113, - 117,105,114,101,100,46,41,10,10,32,32,32,32,42,115,111, - 117,114,99,101,95,109,116,105,109,101,42,32,105,115,32,116, - 104,101,32,108,97,115,116,32,109,111,100,105,102,105,101,100, - 32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104, - 101,32,115,111,117,114,99,101,32,102,105,108,101,46,10,10, - 32,32,32,32,42,115,111,117,114,99,101,95,115,105,122,101, - 42,32,105,115,32,78,111,110,101,32,111,114,32,116,104,101, - 32,115,105,122,101,32,111,102,32,116,104,101,32,115,111,117, - 114,99,101,32,102,105,108,101,32,105,110,32,98,121,116,101, - 115,46,10,10,32,32,32,32,42,110,97,109,101,42,32,105, - 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,32,109,111,100,117,108,101,32,98,101,105,110,103,32,105, - 109,112,111,114,116,101,100,46,32,73,116,32,105,115,32,117, - 115,101,100,32,102,111,114,32,108,111,103,103,105,110,103,46, - 10,10,32,32,32,32,42,101,120,99,95,100,101,116,97,105, - 108,115,42,32,105,115,32,97,32,100,105,99,116,105,111,110, - 97,114,121,32,112,97,115,115,101,100,32,116,111,32,73,109, - 112,111,114,116,69,114,114,111,114,32,105,102,32,105,116,32, - 114,97,105,115,101,100,32,102,111,114,10,32,32,32,32,105, - 109,112,114,111,118,101,100,32,100,101,98,117,103,103,105,110, - 103,46,10,10,32,32,32,32,65,110,32,73,109,112,111,114, - 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 32,105,102,32,116,104,101,32,98,121,116,101,99,111,100,101, - 32,105,115,32,115,116,97,108,101,46,10,10,32,32,32,32, - 114,146,0,0,0,233,12,0,0,0,114,15,0,0,0,122, - 22,98,121,116,101,99,111,100,101,32,105,115,32,115,116,97, - 108,101,32,102,111,114,32,114,144,0,0,0,78,114,145,0, - 0,0,41,4,114,27,0,0,0,114,134,0,0,0,114,149, - 0,0,0,114,117,0,0,0,41,6,114,26,0,0,0,218, - 12,115,111,117,114,99,101,95,109,116,105,109,101,218,11,115, - 111,117,114,99,101,95,115,105,122,101,114,116,0,0,0,114, - 151,0,0,0,114,92,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,218,23,95,118,97,108,105,100, - 97,116,101,95,116,105,109,101,115,116,97,109,112,95,112,121, - 99,21,2,0,0,115,16,0,0,0,0,19,24,1,10,1, - 12,1,16,1,8,1,22,255,2,2,114,156,0,0,0,99, - 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 4,0,0,0,67,0,0,0,115,42,0,0,0,124,0,100, - 1,100,2,133,2,25,0,124,1,107,3,114,38,116,0,100, - 3,124,2,155,2,157,2,102,1,105,0,124,3,164,1,142, - 1,130,1,100,4,83,0,41,5,97,243,1,0,0,86,97, - 108,105,100,97,116,101,32,97,32,104,97,115,104,45,98,97, - 115,101,100,32,112,121,99,32,98,121,32,99,104,101,99,107, - 105,110,103,32,116,104,101,32,114,101,97,108,32,115,111,117, - 114,99,101,32,104,97,115,104,32,97,103,97,105,110,115,116, - 32,116,104,101,32,111,110,101,32,105,110,10,32,32,32,32, - 116,104,101,32,112,121,99,32,104,101,97,100,101,114,46,10, - 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, - 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, - 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, - 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, - 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, - 113,117,105,114,101,100,46,41,10,10,32,32,32,32,42,115, - 111,117,114,99,101,95,104,97,115,104,42,32,105,115,32,116, - 104,101,32,105,109,112,111,114,116,108,105,98,46,117,116,105, - 108,46,115,111,117,114,99,101,95,104,97,115,104,40,41,32, - 111,102,32,116,104,101,32,115,111,117,114,99,101,32,102,105, - 108,101,46,10,10,32,32,32,32,42,110,97,109,101,42,32, - 105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,116, - 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, - 105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,32, - 117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,103, - 46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,97, - 105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,111, - 110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,116, - 32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,32, - 105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,105, - 110,103,46,10,10,32,32,32,32,65,110,32,73,109,112,111, + 10,0,0,0,5,0,0,0,67,0,0,0,115,46,1,0, + 0,116,0,106,1,106,2,100,1,117,0,114,20,116,3,100, + 2,131,1,130,1,116,4,160,5,124,0,161,1,125,0,116, + 6,124,0,131,1,92,2,125,1,125,2,100,3,125,3,116, + 0,106,7,100,1,117,1,114,102,116,0,106,7,160,8,116, + 9,161,1,125,4,124,1,160,10,124,4,116,11,23,0,161, + 1,114,102,124,1,116,12,124,4,131,1,100,1,133,2,25, + 0,125,1,100,4,125,3,124,3,115,144,116,6,124,1,131, + 1,92,2,125,1,125,5,124,5,116,13,107,3,114,144,116, + 14,116,13,155,0,100,5,124,0,155,2,157,3,131,1,130, + 1,124,2,160,15,100,6,161,1,125,6,124,6,100,7,118, + 1,114,178,116,14,100,8,124,2,155,2,157,2,131,1,130, + 1,110,92,124,6,100,9,107,2,144,1,114,14,124,2,160, + 16,100,6,100,10,161,2,100,11,25,0,125,7,124,7,160, + 10,116,17,161,1,115,228,116,14,100,12,116,17,155,2,157, + 2,131,1,130,1,124,7,116,12,116,17,131,1,100,1,133, + 2,25,0,125,8,124,8,160,18,161,0,144,1,115,14,116, + 14,100,13,124,7,155,2,100,14,157,3,131,1,130,1,124, + 2,160,19,100,6,161,1,100,15,25,0,125,9,116,20,124, + 1,124,9,116,21,100,15,25,0,23,0,131,2,83,0,41, + 16,97,110,1,0,0,71,105,118,101,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,97,32,46,112,121,99,46,32, + 102,105,108,101,44,32,114,101,116,117,114,110,32,116,104,101, + 32,112,97,116,104,32,116,111,32,105,116,115,32,46,112,121, + 32,102,105,108,101,46,10,10,32,32,32,32,84,104,101,32, + 46,112,121,99,32,102,105,108,101,32,100,111,101,115,32,110, + 111,116,32,110,101,101,100,32,116,111,32,101,120,105,115,116, + 59,32,116,104,105,115,32,115,105,109,112,108,121,32,114,101, + 116,117,114,110,115,32,116,104,101,32,112,97,116,104,32,116, + 111,10,32,32,32,32,116,104,101,32,46,112,121,32,102,105, + 108,101,32,99,97,108,99,117,108,97,116,101,100,32,116,111, + 32,99,111,114,114,101,115,112,111,110,100,32,116,111,32,116, + 104,101,32,46,112,121,99,32,102,105,108,101,46,32,32,73, + 102,32,112,97,116,104,32,100,111,101,115,10,32,32,32,32, + 110,111,116,32,99,111,110,102,111,114,109,32,116,111,32,80, + 69,80,32,51,49,52,55,47,52,56,56,32,102,111,114,109, + 97,116,44,32,86,97,108,117,101,69,114,114,111,114,32,119, + 105,108,108,32,98,101,32,114,97,105,115,101,100,46,32,73, + 102,10,32,32,32,32,115,121,115,46,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,46,99,97,99,104,101,95,116, + 97,103,32,105,115,32,78,111,110,101,32,116,104,101,110,32, + 78,111,116,73,109,112,108,101,109,101,110,116,101,100,69,114, + 114,111,114,32,105,115,32,114,97,105,115,101,100,46,10,10, + 32,32,32,32,78,114,72,0,0,0,70,84,122,31,32,110, + 111,116,32,98,111,116,116,111,109,45,108,101,118,101,108,32, + 100,105,114,101,99,116,111,114,121,32,105,110,32,114,71,0, + 0,0,62,2,0,0,0,114,28,0,0,0,114,57,0,0, + 0,122,29,101,120,112,101,99,116,101,100,32,111,110,108,121, + 32,50,32,111,114,32,51,32,100,111,116,115,32,105,110,32, + 114,57,0,0,0,114,28,0,0,0,233,254,255,255,255,122, + 53,111,112,116,105,109,105,122,97,116,105,111,110,32,112,111, + 114,116,105,111,110,32,111,102,32,102,105,108,101,110,97,109, + 101,32,100,111,101,115,32,110,111,116,32,115,116,97,114,116, + 32,119,105,116,104,32,122,19,111,112,116,105,109,105,122,97, + 116,105,111,110,32,108,101,118,101,108,32,122,29,32,105,115, + 32,110,111,116,32,97,110,32,97,108,112,104,97,110,117,109, + 101,114,105,99,32,118,97,108,117,101,114,73,0,0,0,41, + 22,114,1,0,0,0,114,80,0,0,0,114,81,0,0,0, + 114,82,0,0,0,114,4,0,0,0,114,79,0,0,0,114, + 47,0,0,0,114,89,0,0,0,114,30,0,0,0,114,31, + 0,0,0,114,11,0,0,0,114,35,0,0,0,114,23,0, + 0,0,114,91,0,0,0,114,86,0,0,0,218,5,99,111, + 117,110,116,114,43,0,0,0,114,87,0,0,0,114,85,0, + 0,0,218,9,112,97,114,116,105,116,105,111,110,114,38,0, + 0,0,218,15,83,79,85,82,67,69,95,83,85,70,70,73, + 88,69,83,41,10,114,44,0,0,0,114,93,0,0,0,90, + 16,112,121,99,97,99,104,101,95,102,105,108,101,110,97,109, + 101,90,23,102,111,117,110,100,95,105,110,95,112,121,99,97, + 99,104,101,95,112,114,101,102,105,120,90,13,115,116,114,105, + 112,112,101,100,95,112,97,116,104,90,7,112,121,99,97,99, + 104,101,90,9,100,111,116,95,99,111,117,110,116,114,70,0, + 0,0,90,9,111,112,116,95,108,101,118,101,108,90,13,98, + 97,115,101,95,102,105,108,101,110,97,109,101,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,218,17,115,111,117, + 114,99,101,95,102,114,111,109,95,99,97,99,104,101,116,1, + 0,0,115,60,0,0,0,0,9,12,1,8,1,10,1,12, + 1,4,1,10,1,12,1,14,1,16,1,4,1,4,1,12, + 1,8,1,8,1,2,255,8,2,10,1,8,1,16,1,10, + 1,16,1,10,1,4,1,2,255,8,2,16,1,10,1,16, + 2,14,1,114,102,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,9,0,0,0,67,0,0, + 0,115,124,0,0,0,116,0,124,0,131,1,100,1,107,2, + 114,16,100,2,83,0,124,0,160,1,100,3,161,1,92,3, + 125,1,125,2,125,3,124,1,114,56,124,3,160,2,161,0, + 100,4,100,5,133,2,25,0,100,6,107,3,114,60,124,0, + 83,0,122,12,116,3,124,0,131,1,125,4,87,0,110,34, + 4,0,116,4,116,5,102,2,121,106,1,0,1,0,1,0, + 124,0,100,2,100,5,133,2,25,0,125,4,89,0,110,2, + 48,0,116,6,124,4,131,1,114,120,124,4,83,0,124,0, + 83,0,41,7,122,188,67,111,110,118,101,114,116,32,97,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,32,112,97, + 116,104,32,116,111,32,97,32,115,111,117,114,99,101,32,112, + 97,116,104,32,40,105,102,32,112,111,115,115,105,98,108,101, + 41,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, + 99,116,105,111,110,32,101,120,105,115,116,115,32,112,117,114, + 101,108,121,32,102,111,114,32,98,97,99,107,119,97,114,100, + 115,45,99,111,109,112,97,116,105,98,105,108,105,116,121,32, + 102,111,114,10,32,32,32,32,80,121,73,109,112,111,114,116, + 95,69,120,101,99,67,111,100,101,77,111,100,117,108,101,87, + 105,116,104,70,105,108,101,110,97,109,101,115,40,41,32,105, + 110,32,116,104,101,32,67,32,65,80,73,46,10,10,32,32, + 32,32,114,73,0,0,0,78,114,71,0,0,0,233,253,255, + 255,255,233,255,255,255,255,90,2,112,121,41,7,114,23,0, + 0,0,114,41,0,0,0,218,5,108,111,119,101,114,114,102, + 0,0,0,114,82,0,0,0,114,86,0,0,0,114,54,0, + 0,0,41,5,218,13,98,121,116,101,99,111,100,101,95,112, + 97,116,104,114,95,0,0,0,114,45,0,0,0,90,9,101, + 120,116,101,110,115,105,111,110,218,11,115,111,117,114,99,101, + 95,112,97,116,104,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,218,15,95,103,101,116,95,115,111,117,114,99, + 101,102,105,108,101,156,1,0,0,115,20,0,0,0,0,7, + 12,1,4,1,16,1,24,1,4,1,2,1,12,1,16,1, + 18,1,114,108,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,8,0,0,0,67,0,0,0, + 115,70,0,0,0,124,0,160,0,116,1,116,2,131,1,161, + 1,114,44,122,10,116,3,124,0,131,1,87,0,83,0,4, + 0,116,4,121,42,1,0,1,0,1,0,89,0,110,24,48, + 0,124,0,160,0,116,1,116,5,131,1,161,1,114,62,124, + 0,83,0,100,0,83,0,100,0,83,0,169,1,78,41,6, + 218,8,101,110,100,115,119,105,116,104,218,5,116,117,112,108, + 101,114,101,0,0,0,114,97,0,0,0,114,82,0,0,0, + 114,88,0,0,0,41,1,114,96,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,218,11,95,103,101, + 116,95,99,97,99,104,101,100,175,1,0,0,115,16,0,0, + 0,0,1,14,1,2,1,10,1,12,1,6,1,14,1,4, + 2,114,112,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, + 50,0,0,0,122,14,116,0,124,0,131,1,106,1,125,1, + 87,0,110,22,4,0,116,2,121,36,1,0,1,0,1,0, + 100,1,125,1,89,0,110,2,48,0,124,1,100,2,79,0, + 125,1,124,1,83,0,41,3,122,51,67,97,108,99,117,108, + 97,116,101,32,116,104,101,32,109,111,100,101,32,112,101,114, + 109,105,115,115,105,111,110,115,32,102,111,114,32,97,32,98, + 121,116,101,99,111,100,101,32,102,105,108,101,46,114,60,0, + 0,0,233,128,0,0,0,41,3,114,49,0,0,0,114,51, + 0,0,0,114,50,0,0,0,41,2,114,44,0,0,0,114, + 52,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,10,95,99,97,108,99,95,109,111,100,101,187, + 1,0,0,115,12,0,0,0,0,2,2,1,14,1,12,1, + 10,3,8,1,114,114,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,8,0,0,0,3,0, + 0,0,115,66,0,0,0,100,6,135,0,102,1,100,2,100, + 3,132,9,125,1,122,10,116,0,106,1,125,2,87,0,110, + 26,4,0,116,2,121,50,1,0,1,0,1,0,100,4,100, + 5,132,0,125,2,89,0,110,2,48,0,124,2,124,1,136, + 0,131,2,1,0,124,1,83,0,41,7,122,252,68,101,99, + 111,114,97,116,111,114,32,116,111,32,118,101,114,105,102,121, + 32,116,104,97,116,32,116,104,101,32,109,111,100,117,108,101, + 32,98,101,105,110,103,32,114,101,113,117,101,115,116,101,100, + 32,109,97,116,99,104,101,115,32,116,104,101,32,111,110,101, + 32,116,104,101,10,32,32,32,32,108,111,97,100,101,114,32, + 99,97,110,32,104,97,110,100,108,101,46,10,10,32,32,32, + 32,84,104,101,32,102,105,114,115,116,32,97,114,103,117,109, + 101,110,116,32,40,115,101,108,102,41,32,109,117,115,116,32, + 100,101,102,105,110,101,32,95,110,97,109,101,32,119,104,105, + 99,104,32,116,104,101,32,115,101,99,111,110,100,32,97,114, + 103,117,109,101,110,116,32,105,115,10,32,32,32,32,99,111, + 109,112,97,114,101,100,32,97,103,97,105,110,115,116,46,32, + 73,102,32,116,104,101,32,99,111,109,112,97,114,105,115,111, + 110,32,102,97,105,108,115,32,116,104,101,110,32,73,109,112, + 111,114,116,69,114,114,111,114,32,105,115,32,114,97,105,115, + 101,100,46,10,10,32,32,32,32,78,99,2,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,31, + 0,0,0,115,72,0,0,0,124,1,100,0,117,0,114,16, + 124,0,106,0,125,1,110,32,124,0,106,0,124,1,107,3, + 114,48,116,1,100,1,124,0,106,0,124,1,102,2,22,0, + 124,1,100,2,141,2,130,1,136,0,124,0,124,1,103,2, + 124,2,162,1,82,0,105,0,124,3,164,1,142,1,83,0, + 41,3,78,122,30,108,111,97,100,101,114,32,102,111,114,32, + 37,115,32,99,97,110,110,111,116,32,104,97,110,100,108,101, + 32,37,115,169,1,218,4,110,97,109,101,41,2,114,116,0, + 0,0,218,11,73,109,112,111,114,116,69,114,114,111,114,41, + 4,218,4,115,101,108,102,114,116,0,0,0,218,4,97,114, + 103,115,218,6,107,119,97,114,103,115,169,1,218,6,109,101, + 116,104,111,100,114,5,0,0,0,114,8,0,0,0,218,19, + 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, + 112,101,114,207,1,0,0,115,18,0,0,0,0,1,8,1, + 8,1,10,1,4,1,8,255,2,1,2,255,6,2,122,40, + 95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,99, + 97,108,115,62,46,95,99,104,101,99,107,95,110,97,109,101, + 95,119,114,97,112,112,101,114,99,2,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,7,0,0,0,83,0,0, + 0,115,56,0,0,0,100,1,68,0,93,32,125,2,116,0, + 124,1,124,2,131,2,114,4,116,1,124,0,124,2,116,2, + 124,1,124,2,131,2,131,3,1,0,113,4,124,0,106,3, + 160,4,124,1,106,3,161,1,1,0,100,0,83,0,41,2, + 78,41,4,218,10,95,95,109,111,100,117,108,101,95,95,218, + 8,95,95,110,97,109,101,95,95,218,12,95,95,113,117,97, + 108,110,97,109,101,95,95,218,7,95,95,100,111,99,95,95, + 41,5,218,7,104,97,115,97,116,116,114,218,7,115,101,116, + 97,116,116,114,218,7,103,101,116,97,116,116,114,218,8,95, + 95,100,105,99,116,95,95,218,6,117,112,100,97,116,101,41, + 3,90,3,110,101,119,90,3,111,108,100,114,67,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, + 5,95,119,114,97,112,218,1,0,0,115,8,0,0,0,0, + 1,8,1,10,1,20,1,122,26,95,99,104,101,99,107,95, + 110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,119, + 114,97,112,41,1,78,41,3,218,10,95,98,111,111,116,115, + 116,114,97,112,114,133,0,0,0,218,9,78,97,109,101,69, + 114,114,111,114,41,3,114,122,0,0,0,114,123,0,0,0, + 114,133,0,0,0,114,5,0,0,0,114,121,0,0,0,114, + 8,0,0,0,218,11,95,99,104,101,99,107,95,110,97,109, + 101,199,1,0,0,115,14,0,0,0,0,8,14,7,2,1, + 10,1,12,2,14,5,10,1,114,136,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0, + 0,0,67,0,0,0,115,60,0,0,0,124,0,160,0,124, + 1,161,1,92,2,125,2,125,3,124,2,100,1,117,0,114, + 56,116,1,124,3,131,1,114,56,100,2,125,4,116,2,160, + 3,124,4,160,4,124,3,100,3,25,0,161,1,116,5,161, + 2,1,0,124,2,83,0,41,4,122,155,84,114,121,32,116, + 111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32, + 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, + 100,32,109,111,100,117,108,101,32,98,121,32,100,101,108,101, + 103,97,116,105,110,103,32,116,111,10,32,32,32,32,115,101, + 108,102,46,102,105,110,100,95,108,111,97,100,101,114,40,41, + 46,10,10,32,32,32,32,84,104,105,115,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 32,105,110,32,102,97,118,111,114,32,111,102,32,102,105,110, + 100,101,114,46,102,105,110,100,95,115,112,101,99,40,41,46, + 10,10,32,32,32,32,78,122,44,78,111,116,32,105,109,112, + 111,114,116,105,110,103,32,100,105,114,101,99,116,111,114,121, + 32,123,125,58,32,109,105,115,115,105,110,103,32,95,95,105, + 110,105,116,95,95,114,73,0,0,0,41,6,218,11,102,105, + 110,100,95,108,111,97,100,101,114,114,23,0,0,0,114,75, + 0,0,0,114,76,0,0,0,114,62,0,0,0,218,13,73, + 109,112,111,114,116,87,97,114,110,105,110,103,41,5,114,118, + 0,0,0,218,8,102,117,108,108,110,97,109,101,218,6,108, + 111,97,100,101,114,218,8,112,111,114,116,105,111,110,115,218, + 3,109,115,103,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,17,95,102,105,110,100,95,109,111,100,117,108, + 101,95,115,104,105,109,227,1,0,0,115,10,0,0,0,0, + 10,14,1,16,1,4,1,22,1,114,143,0,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4, + 0,0,0,67,0,0,0,115,166,0,0,0,124,0,100,1, + 100,2,133,2,25,0,125,3,124,3,116,0,107,3,114,64, + 100,3,124,1,155,2,100,4,124,3,155,2,157,4,125,4, + 116,1,160,2,100,5,124,4,161,2,1,0,116,3,124,4, + 102,1,105,0,124,2,164,1,142,1,130,1,116,4,124,0, + 131,1,100,6,107,0,114,106,100,7,124,1,155,2,157,2, + 125,4,116,1,160,2,100,5,124,4,161,2,1,0,116,5, + 124,4,131,1,130,1,116,6,124,0,100,2,100,8,133,2, + 25,0,131,1,125,5,124,5,100,9,64,0,114,162,100,10, + 124,5,155,2,100,11,124,1,155,2,157,4,125,4,116,3, + 124,4,102,1,105,0,124,2,164,1,142,1,130,1,124,5, + 83,0,41,12,97,84,2,0,0,80,101,114,102,111,114,109, + 32,98,97,115,105,99,32,118,97,108,105,100,105,116,121,32, + 99,104,101,99,107,105,110,103,32,111,102,32,97,32,112,121, + 99,32,104,101,97,100,101,114,32,97,110,100,32,114,101,116, + 117,114,110,32,116,104,101,32,102,108,97,103,115,32,102,105, + 101,108,100,44,10,32,32,32,32,119,104,105,99,104,32,100, + 101,116,101,114,109,105,110,101,115,32,104,111,119,32,116,104, + 101,32,112,121,99,32,115,104,111,117,108,100,32,98,101,32, + 102,117,114,116,104,101,114,32,118,97,108,105,100,97,116,101, + 100,32,97,103,97,105,110,115,116,32,116,104,101,32,115,111, + 117,114,99,101,46,10,10,32,32,32,32,42,100,97,116,97, + 42,32,105,115,32,116,104,101,32,99,111,110,116,101,110,116, + 115,32,111,102,32,116,104,101,32,112,121,99,32,102,105,108, + 101,46,32,40,79,110,108,121,32,116,104,101,32,102,105,114, + 115,116,32,49,54,32,98,121,116,101,115,32,97,114,101,10, + 32,32,32,32,114,101,113,117,105,114,101,100,44,32,116,104, + 111,117,103,104,46,41,10,10,32,32,32,32,42,110,97,109, + 101,42,32,105,115,32,116,104,101,32,110,97,109,101,32,111, + 102,32,116,104,101,32,109,111,100,117,108,101,32,98,101,105, + 110,103,32,105,109,112,111,114,116,101,100,46,32,73,116,32, + 105,115,32,117,115,101,100,32,102,111,114,32,108,111,103,103, + 105,110,103,46,10,10,32,32,32,32,42,101,120,99,95,100, + 101,116,97,105,108,115,42,32,105,115,32,97,32,100,105,99, + 116,105,111,110,97,114,121,32,112,97,115,115,101,100,32,116, + 111,32,73,109,112,111,114,116,69,114,114,111,114,32,105,102, + 32,105,116,32,114,97,105,115,101,100,32,102,111,114,10,32, + 32,32,32,105,109,112,114,111,118,101,100,32,100,101,98,117, + 103,103,105,110,103,46,10,10,32,32,32,32,73,109,112,111, 114,116,69,114,114,111,114,32,105,115,32,114,97,105,115,101, - 100,32,105,102,32,116,104,101,32,98,121,116,101,99,111,100, - 101,32,105,115,32,115,116,97,108,101,46,10,10,32,32,32, - 32,114,146,0,0,0,114,145,0,0,0,122,46,104,97,115, - 104,32,105,110,32,98,121,116,101,99,111,100,101,32,100,111, - 101,115,110,39,116,32,109,97,116,99,104,32,104,97,115,104, - 32,111,102,32,115,111,117,114,99,101,32,78,41,1,114,117, - 0,0,0,41,4,114,26,0,0,0,218,11,115,111,117,114, - 99,101,95,104,97,115,104,114,116,0,0,0,114,151,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 218,18,95,118,97,108,105,100,97,116,101,95,104,97,115,104, - 95,112,121,99,49,2,0,0,115,12,0,0,0,0,17,16, - 1,2,1,8,255,4,2,2,254,114,158,0,0,0,99,4, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5, - 0,0,0,67,0,0,0,115,80,0,0,0,116,0,160,1, - 124,0,161,1,125,4,116,2,124,4,116,3,131,2,114,56, - 116,4,160,5,100,1,124,2,161,2,1,0,124,3,100,2, - 117,1,114,52,116,6,160,7,124,4,124,3,161,2,1,0, - 124,4,83,0,116,8,100,3,160,9,124,2,161,1,124,1, - 124,2,100,4,141,3,130,1,100,2,83,0,41,5,122,35, - 67,111,109,112,105,108,101,32,98,121,116,101,99,111,100,101, - 32,97,115,32,102,111,117,110,100,32,105,110,32,97,32,112, - 121,99,46,122,21,99,111,100,101,32,111,98,106,101,99,116, - 32,102,114,111,109,32,123,33,114,125,78,122,23,78,111,110, - 45,99,111,100,101,32,111,98,106,101,99,116,32,105,110,32, - 123,33,114,125,169,2,114,116,0,0,0,114,44,0,0,0, - 41,10,218,7,109,97,114,115,104,97,108,90,5,108,111,97, - 100,115,218,10,105,115,105,110,115,116,97,110,99,101,218,10, - 95,99,111,100,101,95,116,121,112,101,114,134,0,0,0,114, - 149,0,0,0,218,4,95,105,109,112,90,16,95,102,105,120, - 95,99,111,95,102,105,108,101,110,97,109,101,114,117,0,0, - 0,114,62,0,0,0,41,5,114,26,0,0,0,114,116,0, - 0,0,114,106,0,0,0,114,107,0,0,0,218,4,99,111, - 100,101,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,17,95,99,111,109,112,105,108,101,95,98,121,116,101, - 99,111,100,101,73,2,0,0,115,18,0,0,0,0,2,10, - 1,10,1,12,1,8,1,12,1,4,2,10,1,4,255,114, - 165,0,0,0,114,73,0,0,0,99,3,0,0,0,0,0, - 0,0,0,0,0,0,4,0,0,0,5,0,0,0,67,0, - 0,0,115,70,0,0,0,116,0,116,1,131,1,125,3,124, - 3,160,2,116,3,100,1,131,1,161,1,1,0,124,3,160, - 2,116,3,124,1,131,1,161,1,1,0,124,3,160,2,116, - 3,124,2,131,1,161,1,1,0,124,3,160,2,116,4,160, - 5,124,0,161,1,161,1,1,0,124,3,83,0,41,2,122, - 43,80,114,111,100,117,99,101,32,116,104,101,32,100,97,116, - 97,32,102,111,114,32,97,32,116,105,109,101,115,116,97,109, - 112,45,98,97,115,101,100,32,112,121,99,46,114,73,0,0, - 0,41,6,218,9,98,121,116,101,97,114,114,97,121,114,148, - 0,0,0,218,6,101,120,116,101,110,100,114,21,0,0,0, - 114,160,0,0,0,218,5,100,117,109,112,115,41,4,114,164, - 0,0,0,218,5,109,116,105,109,101,114,155,0,0,0,114, - 26,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,22,95,99,111,100,101,95,116,111,95,116,105, - 109,101,115,116,97,109,112,95,112,121,99,86,2,0,0,115, - 12,0,0,0,0,2,8,1,14,1,14,1,14,1,16,1, - 114,170,0,0,0,84,99,3,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,5,0,0,0,67,0,0,0,115, - 80,0,0,0,116,0,116,1,131,1,125,3,100,1,124,2, - 100,1,62,0,66,0,125,4,124,3,160,2,116,3,124,4, - 131,1,161,1,1,0,116,4,124,1,131,1,100,2,107,2, - 115,50,74,0,130,1,124,3,160,2,124,1,161,1,1,0, - 124,3,160,2,116,5,160,6,124,0,161,1,161,1,1,0, - 124,3,83,0,41,3,122,38,80,114,111,100,117,99,101,32, - 116,104,101,32,100,97,116,97,32,102,111,114,32,97,32,104, - 97,115,104,45,98,97,115,101,100,32,112,121,99,46,114,39, - 0,0,0,114,146,0,0,0,41,7,114,166,0,0,0,114, - 148,0,0,0,114,167,0,0,0,114,21,0,0,0,114,23, - 0,0,0,114,160,0,0,0,114,168,0,0,0,41,5,114, - 164,0,0,0,114,157,0,0,0,90,7,99,104,101,99,107, - 101,100,114,26,0,0,0,114,2,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,17,95,99,111, - 100,101,95,116,111,95,104,97,115,104,95,112,121,99,96,2, - 0,0,115,14,0,0,0,0,2,8,1,12,1,14,1,16, - 1,10,1,16,1,114,171,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,67, - 0,0,0,115,62,0,0,0,100,1,100,2,108,0,125,1, - 116,1,160,2,124,0,161,1,106,3,125,2,124,1,160,4, - 124,2,161,1,125,3,116,1,160,5,100,2,100,3,161,2, - 125,4,124,4,160,6,124,0,160,6,124,3,100,1,25,0, - 161,1,161,1,83,0,41,4,122,121,68,101,99,111,100,101, - 32,98,121,116,101,115,32,114,101,112,114,101,115,101,110,116, - 105,110,103,32,115,111,117,114,99,101,32,99,111,100,101,32, - 97,110,100,32,114,101,116,117,114,110,32,116,104,101,32,115, - 116,114,105,110,103,46,10,10,32,32,32,32,85,110,105,118, - 101,114,115,97,108,32,110,101,119,108,105,110,101,32,115,117, - 112,112,111,114,116,32,105,115,32,117,115,101,100,32,105,110, - 32,116,104,101,32,100,101,99,111,100,105,110,103,46,10,32, - 32,32,32,114,73,0,0,0,78,84,41,7,218,8,116,111, - 107,101,110,105,122,101,114,64,0,0,0,90,7,66,121,116, - 101,115,73,79,90,8,114,101,97,100,108,105,110,101,90,15, - 100,101,116,101,99,116,95,101,110,99,111,100,105,110,103,90, - 25,73,110,99,114,101,109,101,110,116,97,108,78,101,119,108, - 105,110,101,68,101,99,111,100,101,114,218,6,100,101,99,111, - 100,101,41,5,218,12,115,111,117,114,99,101,95,98,121,116, - 101,115,114,172,0,0,0,90,21,115,111,117,114,99,101,95, - 98,121,116,101,115,95,114,101,97,100,108,105,110,101,218,8, - 101,110,99,111,100,105,110,103,90,15,110,101,119,108,105,110, - 101,95,100,101,99,111,100,101,114,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,218,13,100,101,99,111,100,101, - 95,115,111,117,114,99,101,107,2,0,0,115,10,0,0,0, - 0,5,8,1,12,1,10,1,12,1,114,176,0,0,0,169, - 2,114,140,0,0,0,218,26,115,117,98,109,111,100,117,108, - 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, - 110,115,99,2,0,0,0,0,0,0,0,2,0,0,0,9, - 0,0,0,8,0,0,0,67,0,0,0,115,12,1,0,0, - 124,1,100,1,117,0,114,58,100,2,125,1,116,0,124,2, - 100,3,131,2,114,68,122,14,124,2,160,1,124,0,161,1, - 125,1,87,0,113,68,4,0,116,2,121,54,1,0,1,0, - 1,0,89,0,113,68,48,0,110,10,116,3,160,4,124,1, - 161,1,125,1,116,5,106,6,124,0,124,2,124,1,100,4, - 141,3,125,4,100,5,124,4,95,7,124,2,100,1,117,0, - 114,152,116,8,131,0,68,0,93,42,92,2,125,5,125,6, - 124,1,160,9,116,10,124,6,131,1,161,1,114,104,124,5, - 124,0,124,1,131,2,125,2,124,2,124,4,95,11,1,0, - 113,152,113,104,100,1,83,0,124,3,116,12,117,0,114,216, - 116,0,124,2,100,6,131,2,114,222,122,14,124,2,160,13, - 124,0,161,1,125,7,87,0,110,18,4,0,116,2,121,202, - 1,0,1,0,1,0,89,0,113,222,48,0,124,7,114,222, - 103,0,124,4,95,14,110,6,124,3,124,4,95,14,124,4, - 106,14,103,0,107,2,144,1,114,8,124,1,144,1,114,8, - 116,15,124,1,131,1,100,7,25,0,125,8,124,4,106,14, - 160,16,124,8,161,1,1,0,124,4,83,0,41,8,97,61, - 1,0,0,82,101,116,117,114,110,32,97,32,109,111,100,117, - 108,101,32,115,112,101,99,32,98,97,115,101,100,32,111,110, - 32,97,32,102,105,108,101,32,108,111,99,97,116,105,111,110, - 46,10,10,32,32,32,32,84,111,32,105,110,100,105,99,97, - 116,101,32,116,104,97,116,32,116,104,101,32,109,111,100,117, - 108,101,32,105,115,32,97,32,112,97,99,107,97,103,101,44, - 32,115,101,116,10,32,32,32,32,115,117,98,109,111,100,117, - 108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,105, - 111,110,115,32,116,111,32,97,32,108,105,115,116,32,111,102, - 32,100,105,114,101,99,116,111,114,121,32,112,97,116,104,115, - 46,32,32,65,110,10,32,32,32,32,101,109,112,116,121,32, - 108,105,115,116,32,105,115,32,115,117,102,102,105,99,105,101, - 110,116,44,32,116,104,111,117,103,104,32,105,116,115,32,110, - 111,116,32,111,116,104,101,114,119,105,115,101,32,117,115,101, - 102,117,108,32,116,111,32,116,104,101,10,32,32,32,32,105, - 109,112,111,114,116,32,115,121,115,116,101,109,46,10,10,32, - 32,32,32,84,104,101,32,108,111,97,100,101,114,32,109,117, - 115,116,32,116,97,107,101,32,97,32,115,112,101,99,32,97, - 115,32,105,116,115,32,111,110,108,121,32,95,95,105,110,105, - 116,95,95,40,41,32,97,114,103,46,10,10,32,32,32,32, - 78,122,9,60,117,110,107,110,111,119,110,62,218,12,103,101, - 116,95,102,105,108,101,110,97,109,101,169,1,218,6,111,114, - 105,103,105,110,84,218,10,105,115,95,112,97,99,107,97,103, - 101,114,73,0,0,0,41,17,114,128,0,0,0,114,179,0, - 0,0,114,117,0,0,0,114,4,0,0,0,114,79,0,0, - 0,114,134,0,0,0,218,10,77,111,100,117,108,101,83,112, - 101,99,90,13,95,115,101,116,95,102,105,108,101,97,116,116, - 114,218,27,95,103,101,116,95,115,117,112,112,111,114,116,101, - 100,95,102,105,108,101,95,108,111,97,100,101,114,115,114,110, - 0,0,0,114,111,0,0,0,114,140,0,0,0,218,9,95, - 80,79,80,85,76,65,84,69,114,182,0,0,0,114,178,0, - 0,0,114,47,0,0,0,218,6,97,112,112,101,110,100,41, - 9,114,116,0,0,0,90,8,108,111,99,97,116,105,111,110, - 114,140,0,0,0,114,178,0,0,0,218,4,115,112,101,99, - 218,12,108,111,97,100,101,114,95,99,108,97,115,115,218,8, - 115,117,102,102,105,120,101,115,114,182,0,0,0,90,7,100, - 105,114,110,97,109,101,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,23,115,112,101,99,95,102,114,111,109, - 95,102,105,108,101,95,108,111,99,97,116,105,111,110,124,2, - 0,0,115,62,0,0,0,0,12,8,4,4,1,10,2,2, - 1,14,1,12,1,8,2,10,8,16,1,6,3,8,1,14, - 1,14,1,10,1,6,1,6,2,4,3,8,2,10,1,2, - 1,14,1,12,1,6,2,4,1,8,2,6,1,12,1,6, - 1,12,1,12,2,114,190,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64, - 0,0,0,115,80,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,100,2,90,4,100,3,90,5,100,4,90,6, - 101,7,100,5,100,6,132,0,131,1,90,8,101,7,100,7, - 100,8,132,0,131,1,90,9,101,7,100,14,100,10,100,11, - 132,1,131,1,90,10,101,7,100,15,100,12,100,13,132,1, - 131,1,90,11,100,9,83,0,41,16,218,21,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, - 100,101,114,32,102,111,114,32,109,111,100,117,108,101,115,32, - 100,101,99,108,97,114,101,100,32,105,110,32,116,104,101,32, - 87,105,110,100,111,119,115,32,114,101,103,105,115,116,114,121, - 46,122,59,83,111,102,116,119,97,114,101,92,80,121,116,104, - 111,110,92,80,121,116,104,111,110,67,111,114,101,92,123,115, - 121,115,95,118,101,114,115,105,111,110,125,92,77,111,100,117, - 108,101,115,92,123,102,117,108,108,110,97,109,101,125,122,65, - 83,111,102,116,119,97,114,101,92,80,121,116,104,111,110,92, - 80,121,116,104,111,110,67,111,114,101,92,123,115,121,115,95, - 118,101,114,115,105,111,110,125,92,77,111,100,117,108,101,115, - 92,123,102,117,108,108,110,97,109,101,125,92,68,101,98,117, - 103,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,54,0,0,0, - 122,16,116,0,160,1,116,0,106,2,124,1,161,2,87,0, - 83,0,4,0,116,3,121,48,1,0,1,0,1,0,116,0, - 160,1,116,0,106,4,124,1,161,2,6,0,89,0,83,0, - 48,0,100,0,83,0,114,109,0,0,0,41,5,218,6,119, + 100,32,119,104,101,110,32,116,104,101,32,109,97,103,105,99, + 32,110,117,109,98,101,114,32,105,115,32,105,110,99,111,114, + 114,101,99,116,32,111,114,32,119,104,101,110,32,116,104,101, + 32,102,108,97,103,115,10,32,32,32,32,102,105,101,108,100, + 32,105,115,32,105,110,118,97,108,105,100,46,32,69,79,70, + 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,32, + 119,104,101,110,32,116,104,101,32,100,97,116,97,32,105,115, + 32,102,111,117,110,100,32,116,111,32,98,101,32,116,114,117, + 110,99,97,116,101,100,46,10,10,32,32,32,32,78,114,16, + 0,0,0,122,20,98,97,100,32,109,97,103,105,99,32,110, + 117,109,98,101,114,32,105,110,32,122,2,58,32,250,2,123, + 125,233,16,0,0,0,122,40,114,101,97,99,104,101,100,32, + 69,79,70,32,119,104,105,108,101,32,114,101,97,100,105,110, + 103,32,112,121,99,32,104,101,97,100,101,114,32,111,102,32, + 233,8,0,0,0,233,252,255,255,255,122,14,105,110,118,97, + 108,105,100,32,102,108,97,103,115,32,122,4,32,105,110,32, + 41,7,218,12,77,65,71,73,67,95,78,85,77,66,69,82, + 114,134,0,0,0,218,16,95,118,101,114,98,111,115,101,95, + 109,101,115,115,97,103,101,114,117,0,0,0,114,23,0,0, + 0,218,8,69,79,70,69,114,114,111,114,114,27,0,0,0, + 41,6,114,26,0,0,0,114,116,0,0,0,218,11,101,120, + 99,95,100,101,116,97,105,108,115,90,5,109,97,103,105,99, + 114,92,0,0,0,114,2,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,13,95,99,108,97,115, + 115,105,102,121,95,112,121,99,244,1,0,0,115,28,0,0, + 0,0,16,12,1,8,1,16,1,12,1,16,1,12,1,10, + 1,12,1,8,1,16,2,8,1,16,1,16,1,114,152,0, + 0,0,99,5,0,0,0,0,0,0,0,0,0,0,0,6, + 0,0,0,4,0,0,0,67,0,0,0,115,120,0,0,0, + 116,0,124,0,100,1,100,2,133,2,25,0,131,1,124,1, + 100,3,64,0,107,3,114,62,100,4,124,3,155,2,157,2, + 125,5,116,1,160,2,100,5,124,5,161,2,1,0,116,3, + 124,5,102,1,105,0,124,4,164,1,142,1,130,1,124,2, + 100,6,117,1,114,116,116,0,124,0,100,2,100,7,133,2, + 25,0,131,1,124,2,100,3,64,0,107,3,114,116,116,3, + 100,4,124,3,155,2,157,2,102,1,105,0,124,4,164,1, + 142,1,130,1,100,6,83,0,41,8,97,7,2,0,0,86, + 97,108,105,100,97,116,101,32,97,32,112,121,99,32,97,103, + 97,105,110,115,116,32,116,104,101,32,115,111,117,114,99,101, + 32,108,97,115,116,45,109,111,100,105,102,105,101,100,32,116, + 105,109,101,46,10,10,32,32,32,32,42,100,97,116,97,42, + 32,105,115,32,116,104,101,32,99,111,110,116,101,110,116,115, + 32,111,102,32,116,104,101,32,112,121,99,32,102,105,108,101, + 46,32,40,79,110,108,121,32,116,104,101,32,102,105,114,115, + 116,32,49,54,32,98,121,116,101,115,32,97,114,101,10,32, + 32,32,32,114,101,113,117,105,114,101,100,46,41,10,10,32, + 32,32,32,42,115,111,117,114,99,101,95,109,116,105,109,101, + 42,32,105,115,32,116,104,101,32,108,97,115,116,32,109,111, + 100,105,102,105,101,100,32,116,105,109,101,115,116,97,109,112, + 32,111,102,32,116,104,101,32,115,111,117,114,99,101,32,102, + 105,108,101,46,10,10,32,32,32,32,42,115,111,117,114,99, + 101,95,115,105,122,101,42,32,105,115,32,78,111,110,101,32, + 111,114,32,116,104,101,32,115,105,122,101,32,111,102,32,116, + 104,101,32,115,111,117,114,99,101,32,102,105,108,101,32,105, + 110,32,98,121,116,101,115,46,10,10,32,32,32,32,42,110, + 97,109,101,42,32,105,115,32,116,104,101,32,110,97,109,101, + 32,111,102,32,116,104,101,32,109,111,100,117,108,101,32,98, + 101,105,110,103,32,105,109,112,111,114,116,101,100,46,32,73, + 116,32,105,115,32,117,115,101,100,32,102,111,114,32,108,111, + 103,103,105,110,103,46,10,10,32,32,32,32,42,101,120,99, + 95,100,101,116,97,105,108,115,42,32,105,115,32,97,32,100, + 105,99,116,105,111,110,97,114,121,32,112,97,115,115,101,100, + 32,116,111,32,73,109,112,111,114,116,69,114,114,111,114,32, + 105,102,32,105,116,32,114,97,105,115,101,100,32,102,111,114, + 10,32,32,32,32,105,109,112,114,111,118,101,100,32,100,101, + 98,117,103,103,105,110,103,46,10,10,32,32,32,32,65,110, + 32,73,109,112,111,114,116,69,114,114,111,114,32,105,115,32, + 114,97,105,115,101,100,32,105,102,32,116,104,101,32,98,121, + 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,46, + 10,10,32,32,32,32,114,146,0,0,0,233,12,0,0,0, + 114,15,0,0,0,122,22,98,121,116,101,99,111,100,101,32, + 105,115,32,115,116,97,108,101,32,102,111,114,32,114,144,0, + 0,0,78,114,145,0,0,0,41,4,114,27,0,0,0,114, + 134,0,0,0,114,149,0,0,0,114,117,0,0,0,41,6, + 114,26,0,0,0,218,12,115,111,117,114,99,101,95,109,116, + 105,109,101,218,11,115,111,117,114,99,101,95,115,105,122,101, + 114,116,0,0,0,114,151,0,0,0,114,92,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,23, + 95,118,97,108,105,100,97,116,101,95,116,105,109,101,115,116, + 97,109,112,95,112,121,99,21,2,0,0,115,16,0,0,0, + 0,19,24,1,10,1,12,1,16,1,8,1,22,255,2,2, + 114,156,0,0,0,99,4,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,42, + 0,0,0,124,0,100,1,100,2,133,2,25,0,124,1,107, + 3,114,38,116,0,100,3,124,2,155,2,157,2,102,1,105, + 0,124,3,164,1,142,1,130,1,100,4,83,0,41,5,97, + 243,1,0,0,86,97,108,105,100,97,116,101,32,97,32,104, + 97,115,104,45,98,97,115,101,100,32,112,121,99,32,98,121, + 32,99,104,101,99,107,105,110,103,32,116,104,101,32,114,101, + 97,108,32,115,111,117,114,99,101,32,104,97,115,104,32,97, + 103,97,105,110,115,116,32,116,104,101,32,111,110,101,32,105, + 110,10,32,32,32,32,116,104,101,32,112,121,99,32,104,101, + 97,100,101,114,46,10,10,32,32,32,32,42,100,97,116,97, + 42,32,105,115,32,116,104,101,32,99,111,110,116,101,110,116, + 115,32,111,102,32,116,104,101,32,112,121,99,32,102,105,108, + 101,46,32,40,79,110,108,121,32,116,104,101,32,102,105,114, + 115,116,32,49,54,32,98,121,116,101,115,32,97,114,101,10, + 32,32,32,32,114,101,113,117,105,114,101,100,46,41,10,10, + 32,32,32,32,42,115,111,117,114,99,101,95,104,97,115,104, + 42,32,105,115,32,116,104,101,32,105,109,112,111,114,116,108, + 105,98,46,117,116,105,108,46,115,111,117,114,99,101,95,104, + 97,115,104,40,41,32,111,102,32,116,104,101,32,115,111,117, + 114,99,101,32,102,105,108,101,46,10,10,32,32,32,32,42, + 110,97,109,101,42,32,105,115,32,116,104,101,32,110,97,109, + 101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,32, + 98,101,105,110,103,32,105,109,112,111,114,116,101,100,46,32, + 73,116,32,105,115,32,117,115,101,100,32,102,111,114,32,108, + 111,103,103,105,110,103,46,10,10,32,32,32,32,42,101,120, + 99,95,100,101,116,97,105,108,115,42,32,105,115,32,97,32, + 100,105,99,116,105,111,110,97,114,121,32,112,97,115,115,101, + 100,32,116,111,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,102,32,105,116,32,114,97,105,115,101,100,32,102,111, + 114,10,32,32,32,32,105,109,112,114,111,118,101,100,32,100, + 101,98,117,103,103,105,110,103,46,10,10,32,32,32,32,65, + 110,32,73,109,112,111,114,116,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,32,105,102,32,116,104,101,32,98, + 121,116,101,99,111,100,101,32,105,115,32,115,116,97,108,101, + 46,10,10,32,32,32,32,114,146,0,0,0,114,145,0,0, + 0,122,46,104,97,115,104,32,105,110,32,98,121,116,101,99, + 111,100,101,32,100,111,101,115,110,39,116,32,109,97,116,99, + 104,32,104,97,115,104,32,111,102,32,115,111,117,114,99,101, + 32,78,41,1,114,117,0,0,0,41,4,114,26,0,0,0, + 218,11,115,111,117,114,99,101,95,104,97,115,104,114,116,0, + 0,0,114,151,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,218,18,95,118,97,108,105,100,97,116, + 101,95,104,97,115,104,95,112,121,99,49,2,0,0,115,12, + 0,0,0,0,17,16,1,2,1,8,255,4,2,2,254,114, + 158,0,0,0,99,4,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,5,0,0,0,67,0,0,0,115,80,0, + 0,0,116,0,160,1,124,0,161,1,125,4,116,2,124,4, + 116,3,131,2,114,56,116,4,160,5,100,1,124,2,161,2, + 1,0,124,3,100,2,117,1,114,52,116,6,160,7,124,4, + 124,3,161,2,1,0,124,4,83,0,116,8,100,3,160,9, + 124,2,161,1,124,1,124,2,100,4,141,3,130,1,100,2, + 83,0,41,5,122,35,67,111,109,112,105,108,101,32,98,121, + 116,101,99,111,100,101,32,97,115,32,102,111,117,110,100,32, + 105,110,32,97,32,112,121,99,46,122,21,99,111,100,101,32, + 111,98,106,101,99,116,32,102,114,111,109,32,123,33,114,125, + 78,122,23,78,111,110,45,99,111,100,101,32,111,98,106,101, + 99,116,32,105,110,32,123,33,114,125,169,2,114,116,0,0, + 0,114,44,0,0,0,41,10,218,7,109,97,114,115,104,97, + 108,90,5,108,111,97,100,115,218,10,105,115,105,110,115,116, + 97,110,99,101,218,10,95,99,111,100,101,95,116,121,112,101, + 114,134,0,0,0,114,149,0,0,0,218,4,95,105,109,112, + 90,16,95,102,105,120,95,99,111,95,102,105,108,101,110,97, + 109,101,114,117,0,0,0,114,62,0,0,0,41,5,114,26, + 0,0,0,114,116,0,0,0,114,106,0,0,0,114,107,0, + 0,0,218,4,99,111,100,101,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,218,17,95,99,111,109,112,105,108, + 101,95,98,121,116,101,99,111,100,101,73,2,0,0,115,18, + 0,0,0,0,2,10,1,10,1,12,1,8,1,12,1,4, + 2,10,1,4,255,114,165,0,0,0,114,73,0,0,0,99, + 3,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 5,0,0,0,67,0,0,0,115,70,0,0,0,116,0,116, + 1,131,1,125,3,124,3,160,2,116,3,100,1,131,1,161, + 1,1,0,124,3,160,2,116,3,124,1,131,1,161,1,1, + 0,124,3,160,2,116,3,124,2,131,1,161,1,1,0,124, + 3,160,2,116,4,160,5,124,0,161,1,161,1,1,0,124, + 3,83,0,41,2,122,43,80,114,111,100,117,99,101,32,116, + 104,101,32,100,97,116,97,32,102,111,114,32,97,32,116,105, + 109,101,115,116,97,109,112,45,98,97,115,101,100,32,112,121, + 99,46,114,73,0,0,0,41,6,218,9,98,121,116,101,97, + 114,114,97,121,114,148,0,0,0,218,6,101,120,116,101,110, + 100,114,21,0,0,0,114,160,0,0,0,218,5,100,117,109, + 112,115,41,4,114,164,0,0,0,218,5,109,116,105,109,101, + 114,155,0,0,0,114,26,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,22,95,99,111,100,101, + 95,116,111,95,116,105,109,101,115,116,97,109,112,95,112,121, + 99,86,2,0,0,115,12,0,0,0,0,2,8,1,14,1, + 14,1,14,1,16,1,114,170,0,0,0,84,99,3,0,0, + 0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0, + 0,67,0,0,0,115,80,0,0,0,116,0,116,1,131,1, + 125,3,100,1,124,2,100,1,62,0,66,0,125,4,124,3, + 160,2,116,3,124,4,131,1,161,1,1,0,116,4,124,1, + 131,1,100,2,107,2,115,50,74,0,130,1,124,3,160,2, + 124,1,161,1,1,0,124,3,160,2,116,5,160,6,124,0, + 161,1,161,1,1,0,124,3,83,0,41,3,122,38,80,114, + 111,100,117,99,101,32,116,104,101,32,100,97,116,97,32,102, + 111,114,32,97,32,104,97,115,104,45,98,97,115,101,100,32, + 112,121,99,46,114,39,0,0,0,114,146,0,0,0,41,7, + 114,166,0,0,0,114,148,0,0,0,114,167,0,0,0,114, + 21,0,0,0,114,23,0,0,0,114,160,0,0,0,114,168, + 0,0,0,41,5,114,164,0,0,0,114,157,0,0,0,90, + 7,99,104,101,99,107,101,100,114,26,0,0,0,114,2,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, + 0,218,17,95,99,111,100,101,95,116,111,95,104,97,115,104, + 95,112,121,99,96,2,0,0,115,14,0,0,0,0,2,8, + 1,12,1,14,1,16,1,10,1,16,1,114,171,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,6,0,0,0,67,0,0,0,115,62,0,0,0,100,1, + 100,2,108,0,125,1,116,1,160,2,124,0,161,1,106,3, + 125,2,124,1,160,4,124,2,161,1,125,3,116,1,160,5, + 100,2,100,3,161,2,125,4,124,4,160,6,124,0,160,6, + 124,3,100,1,25,0,161,1,161,1,83,0,41,4,122,121, + 68,101,99,111,100,101,32,98,121,116,101,115,32,114,101,112, + 114,101,115,101,110,116,105,110,103,32,115,111,117,114,99,101, + 32,99,111,100,101,32,97,110,100,32,114,101,116,117,114,110, + 32,116,104,101,32,115,116,114,105,110,103,46,10,10,32,32, + 32,32,85,110,105,118,101,114,115,97,108,32,110,101,119,108, + 105,110,101,32,115,117,112,112,111,114,116,32,105,115,32,117, + 115,101,100,32,105,110,32,116,104,101,32,100,101,99,111,100, + 105,110,103,46,10,32,32,32,32,114,73,0,0,0,78,84, + 41,7,218,8,116,111,107,101,110,105,122,101,114,64,0,0, + 0,90,7,66,121,116,101,115,73,79,90,8,114,101,97,100, + 108,105,110,101,90,15,100,101,116,101,99,116,95,101,110,99, + 111,100,105,110,103,90,25,73,110,99,114,101,109,101,110,116, + 97,108,78,101,119,108,105,110,101,68,101,99,111,100,101,114, + 218,6,100,101,99,111,100,101,41,5,218,12,115,111,117,114, + 99,101,95,98,121,116,101,115,114,172,0,0,0,90,21,115, + 111,117,114,99,101,95,98,121,116,101,115,95,114,101,97,100, + 108,105,110,101,218,8,101,110,99,111,100,105,110,103,90,15, + 110,101,119,108,105,110,101,95,100,101,99,111,100,101,114,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,13, + 100,101,99,111,100,101,95,115,111,117,114,99,101,107,2,0, + 0,115,10,0,0,0,0,5,8,1,12,1,10,1,12,1, + 114,176,0,0,0,169,2,114,140,0,0,0,218,26,115,117, + 98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108, + 111,99,97,116,105,111,110,115,99,2,0,0,0,0,0,0, + 0,2,0,0,0,9,0,0,0,8,0,0,0,67,0,0, + 0,115,10,1,0,0,124,1,100,1,117,0,114,56,100,2, + 125,1,116,0,124,2,100,3,131,2,114,66,122,14,124,2, + 160,1,124,0,161,1,125,1,87,0,110,28,4,0,116,2, + 121,54,1,0,1,0,1,0,89,0,110,12,48,0,116,3, + 160,4,124,1,161,1,125,1,116,5,106,6,124,0,124,2, + 124,1,100,4,141,3,125,4,100,5,124,4,95,7,124,2, + 100,1,117,0,114,150,116,8,131,0,68,0,93,42,92,2, + 125,5,125,6,124,1,160,9,116,10,124,6,131,1,161,1, + 114,102,124,5,124,0,124,1,131,2,125,2,124,2,124,4, + 95,11,1,0,113,150,113,102,100,1,83,0,124,3,116,12, + 117,0,114,214,116,0,124,2,100,6,131,2,114,220,122,14, + 124,2,160,13,124,0,161,1,125,7,87,0,110,18,4,0, + 116,2,121,200,1,0,1,0,1,0,89,0,110,20,48,0, + 124,7,114,220,103,0,124,4,95,14,110,6,124,3,124,4, + 95,14,124,4,106,14,103,0,107,2,144,1,114,6,124,1, + 144,1,114,6,116,15,124,1,131,1,100,7,25,0,125,8, + 124,4,106,14,160,16,124,8,161,1,1,0,124,4,83,0, + 41,8,97,61,1,0,0,82,101,116,117,114,110,32,97,32, + 109,111,100,117,108,101,32,115,112,101,99,32,98,97,115,101, + 100,32,111,110,32,97,32,102,105,108,101,32,108,111,99,97, + 116,105,111,110,46,10,10,32,32,32,32,84,111,32,105,110, + 100,105,99,97,116,101,32,116,104,97,116,32,116,104,101,32, + 109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,107, + 97,103,101,44,32,115,101,116,10,32,32,32,32,115,117,98, + 109,111,100,117,108,101,95,115,101,97,114,99,104,95,108,111, + 99,97,116,105,111,110,115,32,116,111,32,97,32,108,105,115, + 116,32,111,102,32,100,105,114,101,99,116,111,114,121,32,112, + 97,116,104,115,46,32,32,65,110,10,32,32,32,32,101,109, + 112,116,121,32,108,105,115,116,32,105,115,32,115,117,102,102, + 105,99,105,101,110,116,44,32,116,104,111,117,103,104,32,105, + 116,115,32,110,111,116,32,111,116,104,101,114,119,105,115,101, + 32,117,115,101,102,117,108,32,116,111,32,116,104,101,10,32, + 32,32,32,105,109,112,111,114,116,32,115,121,115,116,101,109, + 46,10,10,32,32,32,32,84,104,101,32,108,111,97,100,101, + 114,32,109,117,115,116,32,116,97,107,101,32,97,32,115,112, + 101,99,32,97,115,32,105,116,115,32,111,110,108,121,32,95, + 95,105,110,105,116,95,95,40,41,32,97,114,103,46,10,10, + 32,32,32,32,78,122,9,60,117,110,107,110,111,119,110,62, + 218,12,103,101,116,95,102,105,108,101,110,97,109,101,169,1, + 218,6,111,114,105,103,105,110,84,218,10,105,115,95,112,97, + 99,107,97,103,101,114,73,0,0,0,41,17,114,128,0,0, + 0,114,179,0,0,0,114,117,0,0,0,114,4,0,0,0, + 114,79,0,0,0,114,134,0,0,0,218,10,77,111,100,117, + 108,101,83,112,101,99,90,13,95,115,101,116,95,102,105,108, + 101,97,116,116,114,218,27,95,103,101,116,95,115,117,112,112, + 111,114,116,101,100,95,102,105,108,101,95,108,111,97,100,101, + 114,115,114,110,0,0,0,114,111,0,0,0,114,140,0,0, + 0,218,9,95,80,79,80,85,76,65,84,69,114,182,0,0, + 0,114,178,0,0,0,114,47,0,0,0,218,6,97,112,112, + 101,110,100,41,9,114,116,0,0,0,90,8,108,111,99,97, + 116,105,111,110,114,140,0,0,0,114,178,0,0,0,218,4, + 115,112,101,99,218,12,108,111,97,100,101,114,95,99,108,97, + 115,115,218,8,115,117,102,102,105,120,101,115,114,182,0,0, + 0,90,7,100,105,114,110,97,109,101,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,124,2,0,0,115,62,0,0,0,0,12,8,4,4, + 1,10,2,2,1,14,1,12,1,6,2,10,8,16,1,6, + 3,8,1,14,1,14,1,10,1,6,1,6,2,4,3,8, + 2,10,1,2,1,14,1,12,1,6,2,4,1,8,2,6, + 1,12,1,6,1,12,1,12,2,114,190,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,64,0,0,0,115,80,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,90,4,100,3,90,5, + 100,4,90,6,101,7,100,5,100,6,132,0,131,1,90,8, + 101,7,100,7,100,8,132,0,131,1,90,9,101,7,100,14, + 100,10,100,11,132,1,131,1,90,10,101,7,100,15,100,12, + 100,13,132,1,131,1,90,11,100,9,83,0,41,16,218,21, + 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, + 105,110,100,101,114,122,62,77,101,116,97,32,112,97,116,104, + 32,102,105,110,100,101,114,32,102,111,114,32,109,111,100,117, + 108,101,115,32,100,101,99,108,97,114,101,100,32,105,110,32, + 116,104,101,32,87,105,110,100,111,119,115,32,114,101,103,105, + 115,116,114,121,46,122,59,83,111,102,116,119,97,114,101,92, + 80,121,116,104,111,110,92,80,121,116,104,111,110,67,111,114, + 101,92,123,115,121,115,95,118,101,114,115,105,111,110,125,92, + 77,111,100,117,108,101,115,92,123,102,117,108,108,110,97,109, + 101,125,122,65,83,111,102,116,119,97,114,101,92,80,121,116, + 104,111,110,92,80,121,116,104,111,110,67,111,114,101,92,123, + 115,121,115,95,118,101,114,115,105,111,110,125,92,77,111,100, + 117,108,101,115,92,123,102,117,108,108,110,97,109,101,125,92, + 68,101,98,117,103,70,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, + 50,0,0,0,122,16,116,0,160,1,116,0,106,2,124,1, + 161,2,87,0,83,0,4,0,116,3,121,48,1,0,1,0, + 1,0,116,0,160,1,116,0,106,4,124,1,161,2,6,0, + 89,0,83,0,48,0,114,109,0,0,0,41,5,218,6,119, 105,110,114,101,103,90,7,79,112,101,110,75,101,121,90,17, 72,75,69,89,95,67,85,82,82,69,78,84,95,85,83,69, 82,114,50,0,0,0,90,18,72,75,69,89,95,76,79,67, @@ -1025,1666 +1024,1664 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,111,119,115,82,101,103,105,115,116,114,121,70,105,110,100, 101,114,46,95,115,101,97,114,99,104,95,114,101,103,105,115, 116,114,121,78,99,4,0,0,0,0,0,0,0,0,0,0, - 0,8,0,0,0,8,0,0,0,67,0,0,0,115,120,0, + 0,8,0,0,0,8,0,0,0,67,0,0,0,115,118,0, 0,0,124,0,160,0,124,1,161,1,125,4,124,4,100,0, 117,0,114,22,100,0,83,0,122,12,116,1,124,4,131,1, 1,0,87,0,110,20,4,0,116,2,121,54,1,0,1,0, 1,0,89,0,100,0,83,0,48,0,116,3,131,0,68,0, - 93,52,92,2,125,5,125,6,124,4,160,4,116,5,124,6, + 93,50,92,2,125,5,125,6,124,4,160,4,116,5,124,6, 131,1,161,1,114,62,116,6,106,7,124,1,124,5,124,1, 124,4,131,2,124,4,100,1,141,3,125,7,124,7,2,0, - 1,0,83,0,113,62,100,0,83,0,41,2,78,114,180,0, - 0,0,41,8,114,200,0,0,0,114,49,0,0,0,114,50, - 0,0,0,114,184,0,0,0,114,110,0,0,0,114,111,0, - 0,0,114,134,0,0,0,218,16,115,112,101,99,95,102,114, - 111,109,95,108,111,97,100,101,114,41,8,114,193,0,0,0, - 114,139,0,0,0,114,44,0,0,0,218,6,116,97,114,103, - 101,116,114,199,0,0,0,114,140,0,0,0,114,189,0,0, + 1,0,83,0,100,0,83,0,41,2,78,114,180,0,0,0, + 41,8,114,200,0,0,0,114,49,0,0,0,114,50,0,0, + 0,114,184,0,0,0,114,110,0,0,0,114,111,0,0,0, + 114,134,0,0,0,218,16,115,112,101,99,95,102,114,111,109, + 95,108,111,97,100,101,114,41,8,114,193,0,0,0,114,139, + 0,0,0,114,44,0,0,0,218,6,116,97,114,103,101,116, + 114,199,0,0,0,114,140,0,0,0,114,189,0,0,0,114, + 187,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,9,102,105,110,100,95,115,112,101,99,226,2, + 0,0,115,28,0,0,0,0,2,10,1,8,1,4,1,2, + 1,12,1,12,1,8,1,14,1,14,1,6,1,8,1,2, + 254,6,3,122,31,87,105,110,100,111,119,115,82,101,103,105, + 115,116,114,121,70,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, + 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, + 100,1,117,1,114,26,124,3,106,1,83,0,100,1,83,0, + 41,2,122,108,70,105,110,100,32,109,111,100,117,108,101,32, + 110,97,109,101,100,32,105,110,32,116,104,101,32,114,101,103, + 105,115,116,114,121,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110, + 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, + 78,169,2,114,203,0,0,0,114,140,0,0,0,169,4,114, + 193,0,0,0,114,139,0,0,0,114,44,0,0,0,114,187, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,242, + 2,0,0,115,8,0,0,0,0,7,12,1,8,1,6,2, + 122,33,87,105,110,100,111,119,115,82,101,103,105,115,116,114, + 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, + 117,108,101,41,2,78,78,41,1,78,41,12,114,125,0,0, + 0,114,124,0,0,0,114,126,0,0,0,114,127,0,0,0, + 114,197,0,0,0,114,196,0,0,0,114,195,0,0,0,218, + 11,99,108,97,115,115,109,101,116,104,111,100,114,194,0,0, + 0,114,200,0,0,0,114,203,0,0,0,114,206,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,191,0,0,0,192,2,0,0,115,28,0, + 0,0,8,2,4,3,2,255,2,4,2,255,2,3,4,2, + 2,1,10,6,2,1,10,14,2,1,12,15,2,1,114,191, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,64,0,0,0,115,48,0,0, + 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, + 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,100, + 7,132,0,90,6,100,8,100,9,132,0,90,7,100,10,83, + 0,41,11,218,13,95,76,111,97,100,101,114,66,97,115,105, + 99,115,122,83,66,97,115,101,32,99,108,97,115,115,32,111, + 102,32,99,111,109,109,111,110,32,99,111,100,101,32,110,101, + 101,100,101,100,32,98,121,32,98,111,116,104,32,83,111,117, + 114,99,101,76,111,97,100,101,114,32,97,110,100,10,32,32, + 32,32,83,111,117,114,99,101,108,101,115,115,70,105,108,101, + 76,111,97,100,101,114,46,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,4,0,0,0,67,0,0,0, + 115,64,0,0,0,116,0,124,0,160,1,124,1,161,1,131, + 1,100,1,25,0,125,2,124,2,160,2,100,2,100,1,161, + 2,100,3,25,0,125,3,124,1,160,3,100,2,161,1,100, + 4,25,0,125,4,124,3,100,5,107,2,111,62,124,4,100, + 5,107,3,83,0,41,6,122,141,67,111,110,99,114,101,116, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,73,110,115,112,101,99,116,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,101,32,98,121,32, + 99,104,101,99,107,105,110,103,32,105,102,10,32,32,32,32, + 32,32,32,32,116,104,101,32,112,97,116,104,32,114,101,116, + 117,114,110,101,100,32,98,121,32,103,101,116,95,102,105,108, + 101,110,97,109,101,32,104,97,115,32,97,32,102,105,108,101, + 110,97,109,101,32,111,102,32,39,95,95,105,110,105,116,95, + 95,46,112,121,39,46,114,39,0,0,0,114,71,0,0,0, + 114,73,0,0,0,114,28,0,0,0,218,8,95,95,105,110, + 105,116,95,95,41,4,114,47,0,0,0,114,179,0,0,0, + 114,43,0,0,0,114,41,0,0,0,41,5,114,118,0,0, + 0,114,139,0,0,0,114,96,0,0,0,90,13,102,105,108, + 101,110,97,109,101,95,98,97,115,101,90,9,116,97,105,108, + 95,110,97,109,101,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,182,0,0,0,5,3,0,0,115,8,0, + 0,0,0,3,18,1,16,1,14,1,122,24,95,76,111,97, + 100,101,114,66,97,115,105,99,115,46,105,115,95,112,97,99, + 107,97,103,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,169,2,122,42,85,115,101,32,100,101, + 102,97,117,108,116,32,115,101,109,97,110,116,105,99,115,32, + 102,111,114,32,109,111,100,117,108,101,32,99,114,101,97,116, + 105,111,110,46,78,114,5,0,0,0,169,2,114,118,0,0, 0,114,187,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,9,102,105,110,100,95,115,112,101,99, - 226,2,0,0,115,28,0,0,0,0,2,10,1,8,1,4, - 1,2,1,12,1,12,1,8,1,14,1,14,1,6,1,8, - 1,2,254,6,3,122,31,87,105,110,100,111,119,115,82,101, - 103,105,115,116,114,121,70,105,110,100,101,114,46,102,105,110, - 100,95,115,112,101,99,99,3,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,4,0,0,0,67,0,0,0,115, - 34,0,0,0,124,0,160,0,124,1,124,2,161,2,125,3, - 124,3,100,1,117,1,114,26,124,3,106,1,83,0,100,1, - 83,0,100,1,83,0,41,2,122,108,70,105,110,100,32,109, - 111,100,117,108,101,32,110,97,109,101,100,32,105,110,32,116, - 104,101,32,114,101,103,105,115,116,114,121,46,10,10,32,32, - 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,85,115,101,32,101,120,101,99,95,109,111,100,117,108, - 101,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, - 32,32,32,32,32,32,78,169,2,114,203,0,0,0,114,140, - 0,0,0,169,4,114,193,0,0,0,114,139,0,0,0,114, - 44,0,0,0,114,187,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,218,11,102,105,110,100,95,109, - 111,100,117,108,101,242,2,0,0,115,8,0,0,0,0,7, - 12,1,8,1,6,2,122,33,87,105,110,100,111,119,115,82, - 101,103,105,115,116,114,121,70,105,110,100,101,114,46,102,105, - 110,100,95,109,111,100,117,108,101,41,2,78,78,41,1,78, - 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,127,0,0,0,114,197,0,0,0,114,196,0,0,0, - 114,195,0,0,0,218,11,99,108,97,115,115,109,101,116,104, - 111,100,114,194,0,0,0,114,200,0,0,0,114,203,0,0, - 0,114,206,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,191,0,0,0,192, - 2,0,0,115,28,0,0,0,8,2,4,3,2,255,2,4, - 2,255,2,3,4,2,2,1,10,6,2,1,10,14,2,1, - 12,15,2,1,114,191,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,48,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, - 0,90,7,100,10,83,0,41,11,218,13,95,76,111,97,100, - 101,114,66,97,115,105,99,115,122,83,66,97,115,101,32,99, - 108,97,115,115,32,111,102,32,99,111,109,109,111,110,32,99, - 111,100,101,32,110,101,101,100,101,100,32,98,121,32,98,111, - 116,104,32,83,111,117,114,99,101,76,111,97,100,101,114,32, - 97,110,100,10,32,32,32,32,83,111,117,114,99,101,108,101, - 115,115,70,105,108,101,76,111,97,100,101,114,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0, - 0,0,67,0,0,0,115,64,0,0,0,116,0,124,0,160, - 1,124,1,161,1,131,1,100,1,25,0,125,2,124,2,160, - 2,100,2,100,1,161,2,100,3,25,0,125,3,124,1,160, - 3,100,2,161,1,100,4,25,0,125,4,124,3,100,5,107, - 2,111,62,124,4,100,5,107,3,83,0,41,6,122,141,67, - 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, - 116,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97, - 103,101,32,98,121,32,99,104,101,99,107,105,110,103,32,105, - 102,10,32,32,32,32,32,32,32,32,116,104,101,32,112,97, - 116,104,32,114,101,116,117,114,110,101,100,32,98,121,32,103, - 101,116,95,102,105,108,101,110,97,109,101,32,104,97,115,32, - 97,32,102,105,108,101,110,97,109,101,32,111,102,32,39,95, - 95,105,110,105,116,95,95,46,112,121,39,46,114,39,0,0, - 0,114,71,0,0,0,114,73,0,0,0,114,28,0,0,0, - 218,8,95,95,105,110,105,116,95,95,41,4,114,47,0,0, - 0,114,179,0,0,0,114,43,0,0,0,114,41,0,0,0, - 41,5,114,118,0,0,0,114,139,0,0,0,114,96,0,0, - 0,90,13,102,105,108,101,110,97,109,101,95,98,97,115,101, - 90,9,116,97,105,108,95,110,97,109,101,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,182,0,0,0,5, - 3,0,0,115,8,0,0,0,0,3,18,1,16,1,14,1, - 122,24,95,76,111,97,100,101,114,66,97,115,105,99,115,46, - 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, + 114,8,0,0,0,218,13,99,114,101,97,116,101,95,109,111, + 100,117,108,101,13,3,0,0,115,2,0,0,0,0,1,122, + 27,95,76,111,97,100,101,114,66,97,115,105,99,115,46,99, + 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,5,0,0, + 0,67,0,0,0,115,56,0,0,0,124,0,160,0,124,1, + 106,1,161,1,125,2,124,2,100,1,117,0,114,36,116,2, + 100,2,160,3,124,1,106,1,161,1,131,1,130,1,116,4, + 160,5,116,6,124,2,124,1,106,7,161,3,1,0,100,1, + 83,0,41,3,122,19,69,120,101,99,117,116,101,32,116,104, + 101,32,109,111,100,117,108,101,46,78,122,52,99,97,110,110, + 111,116,32,108,111,97,100,32,109,111,100,117,108,101,32,123, + 33,114,125,32,119,104,101,110,32,103,101,116,95,99,111,100, + 101,40,41,32,114,101,116,117,114,110,115,32,78,111,110,101, + 41,8,218,8,103,101,116,95,99,111,100,101,114,125,0,0, + 0,114,117,0,0,0,114,62,0,0,0,114,134,0,0,0, + 218,25,95,99,97,108,108,95,119,105,116,104,95,102,114,97, + 109,101,115,95,114,101,109,111,118,101,100,218,4,101,120,101, + 99,114,131,0,0,0,41,3,114,118,0,0,0,218,6,109, + 111,100,117,108,101,114,164,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,11,101,120,101,99,95, + 109,111,100,117,108,101,16,3,0,0,115,12,0,0,0,0, + 2,12,1,8,1,6,1,4,255,6,2,122,25,95,76,111, + 97,100,101,114,66,97,115,105,99,115,46,101,120,101,99,95, + 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 12,0,0,0,116,0,160,1,124,0,124,1,161,2,83,0, + 41,1,122,26,84,104,105,115,32,109,111,100,117,108,101,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,41,2, + 114,134,0,0,0,218,17,95,108,111,97,100,95,109,111,100, + 117,108,101,95,115,104,105,109,169,2,114,118,0,0,0,114, + 139,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, + 24,3,0,0,115,2,0,0,0,0,2,122,25,95,76,111, + 97,100,101,114,66,97,115,105,99,115,46,108,111,97,100,95, + 109,111,100,117,108,101,78,41,8,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,182,0, + 0,0,114,212,0,0,0,114,217,0,0,0,114,220,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,208,0,0,0,0,3,0,0,115,10, + 0,0,0,8,2,4,3,8,8,8,3,8,8,114,208,0, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,74,0,0,0, + 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, + 100,3,100,4,132,0,90,4,100,5,100,6,132,0,90,5, + 100,7,100,8,132,0,90,6,100,9,100,10,132,0,90,7, + 100,11,100,12,156,1,100,13,100,14,132,2,90,8,100,15, + 100,16,132,0,90,9,100,17,83,0,41,18,218,12,83,111, + 117,114,99,101,76,111,97,100,101,114,99,2,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,169,2,122,42, - 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, - 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, - 32,99,114,101,97,116,105,111,110,46,78,114,5,0,0,0, - 169,2,114,118,0,0,0,114,187,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,13,3,0,0,115,2, - 0,0,0,0,1,122,27,95,76,111,97,100,101,114,66,97, - 115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, - 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, - 117,0,114,36,116,2,100,2,160,3,124,1,106,1,161,1, - 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, - 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, - 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, - 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, - 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, - 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, - 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, - 100,101,114,125,0,0,0,114,117,0,0,0,114,62,0,0, - 0,114,134,0,0,0,218,25,95,99,97,108,108,95,119,105, - 116,104,95,102,114,97,109,101,115,95,114,101,109,111,118,101, - 100,218,4,101,120,101,99,114,131,0,0,0,41,3,114,118, - 0,0,0,218,6,109,111,100,117,108,101,114,164,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 11,101,120,101,99,95,109,111,100,117,108,101,16,3,0,0, - 115,12,0,0,0,0,2,12,1,8,1,6,1,4,255,6, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,115,8,0,0,0,116,0,130,1,100,1,83,0, + 41,2,122,165,79,112,116,105,111,110,97,108,32,109,101,116, + 104,111,100,32,116,104,97,116,32,114,101,116,117,114,110,115, + 32,116,104,101,32,109,111,100,105,102,105,99,97,116,105,111, + 110,32,116,105,109,101,32,40,97,110,32,105,110,116,41,32, + 102,111,114,32,116,104,101,10,32,32,32,32,32,32,32,32, + 115,112,101,99,105,102,105,101,100,32,112,97,116,104,32,40, + 97,32,115,116,114,41,46,10,10,32,32,32,32,32,32,32, + 32,82,97,105,115,101,115,32,79,83,69,114,114,111,114,32, + 119,104,101,110,32,116,104,101,32,112,97,116,104,32,99,97, + 110,110,111,116,32,98,101,32,104,97,110,100,108,101,100,46, + 10,32,32,32,32,32,32,32,32,78,41,1,114,50,0,0, + 0,169,2,114,118,0,0,0,114,44,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,218,10,112,97, + 116,104,95,109,116,105,109,101,31,3,0,0,115,2,0,0, + 0,0,6,122,23,83,111,117,114,99,101,76,111,97,100,101, + 114,46,112,97,116,104,95,109,116,105,109,101,99,2,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, - 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, - 111,100,117,108,101,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,41,2,114,134,0,0,0,218,17,95,108,111, - 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, - 114,118,0,0,0,114,139,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,218,11,108,111,97,100,95, - 109,111,100,117,108,101,24,3,0,0,115,2,0,0,0,0, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,182,0,0,0,114,212,0,0,0,114,217,0, - 0,0,114,220,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,208,0,0,0, - 0,3,0,0,115,10,0,0,0,8,2,4,3,8,8,8, - 3,8,8,114,208,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,74,0,0,0,101,0,90,1,100,0,90,2,100,1, - 100,2,132,0,90,3,100,3,100,4,132,0,90,4,100,5, - 100,6,132,0,90,5,100,7,100,8,132,0,90,6,100,9, - 100,10,132,0,90,7,100,11,100,12,156,1,100,13,100,14, - 132,2,90,8,100,15,100,16,132,0,90,9,100,17,83,0, - 41,18,218,12,83,111,117,114,99,101,76,111,97,100,101,114, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,8,0,0,0,116,0, - 130,1,100,1,83,0,41,2,122,165,79,112,116,105,111,110, - 97,108,32,109,101,116,104,111,100,32,116,104,97,116,32,114, - 101,116,117,114,110,115,32,116,104,101,32,109,111,100,105,102, - 105,99,97,116,105,111,110,32,116,105,109,101,32,40,97,110, - 32,105,110,116,41,32,102,111,114,32,116,104,101,10,32,32, - 32,32,32,32,32,32,115,112,101,99,105,102,105,101,100,32, - 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, - 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83, - 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112, - 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97, - 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,78, - 41,1,114,50,0,0,0,169,2,114,118,0,0,0,114,44, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,10,112,97,116,104,95,109,116,105,109,101,31,3, - 0,0,115,2,0,0,0,0,6,122,23,83,111,117,114,99, - 101,76,111,97,100,101,114,46,112,97,116,104,95,109,116,105, - 109,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,67,0,0,0,115,14,0,0,0, - 100,1,124,0,160,0,124,1,161,1,105,1,83,0,41,2, - 97,158,1,0,0,79,112,116,105,111,110,97,108,32,109,101, - 116,104,111,100,32,114,101,116,117,114,110,105,110,103,32,97, - 32,109,101,116,97,100,97,116,97,32,100,105,99,116,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 10,32,32,32,32,32,32,32,32,112,97,116,104,32,40,97, - 32,115,116,114,41,46,10,10,32,32,32,32,32,32,32,32, - 80,111,115,115,105,98,108,101,32,107,101,121,115,58,10,32, - 32,32,32,32,32,32,32,45,32,39,109,116,105,109,101,39, - 32,40,109,97,110,100,97,116,111,114,121,41,32,105,115,32, - 116,104,101,32,110,117,109,101,114,105,99,32,116,105,109,101, - 115,116,97,109,112,32,111,102,32,108,97,115,116,32,115,111, - 117,114,99,101,10,32,32,32,32,32,32,32,32,32,32,99, - 111,100,101,32,109,111,100,105,102,105,99,97,116,105,111,110, - 59,10,32,32,32,32,32,32,32,32,45,32,39,115,105,122, - 101,39,32,40,111,112,116,105,111,110,97,108,41,32,105,115, - 32,116,104,101,32,115,105,122,101,32,105,110,32,98,121,116, - 101,115,32,111,102,32,116,104,101,32,115,111,117,114,99,101, - 32,99,111,100,101,46,10,10,32,32,32,32,32,32,32,32, - 73,109,112,108,101,109,101,110,116,105,110,103,32,116,104,105, - 115,32,109,101,116,104,111,100,32,97,108,108,111,119,115,32, - 116,104,101,32,108,111,97,100,101,114,32,116,111,32,114,101, - 97,100,32,98,121,116,101,99,111,100,101,32,102,105,108,101, - 115,46,10,32,32,32,32,32,32,32,32,82,97,105,115,101, - 115,32,79,83,69,114,114,111,114,32,119,104,101,110,32,116, - 104,101,32,112,97,116,104,32,99,97,110,110,111,116,32,98, - 101,32,104,97,110,100,108,101,100,46,10,32,32,32,32,32, - 32,32,32,114,169,0,0,0,41,1,114,223,0,0,0,114, - 222,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,10,112,97,116,104,95,115,116,97,116,115,39, - 3,0,0,115,2,0,0,0,0,12,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,112,97,116,104,95,115,116, - 97,116,115,99,4,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,4,0,0,0,67,0,0,0,115,12,0,0, - 0,124,0,160,0,124,2,124,3,161,2,83,0,41,1,122, - 228,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, - 32,119,104,105,99,104,32,119,114,105,116,101,115,32,100,97, - 116,97,32,40,98,121,116,101,115,41,32,116,111,32,97,32, - 102,105,108,101,32,112,97,116,104,32,40,97,32,115,116,114, - 41,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, - 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, - 116,104,111,100,32,97,108,108,111,119,115,32,102,111,114,32, - 116,104,101,32,119,114,105,116,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,115,111,117,114, - 99,101,32,112,97,116,104,32,105,115,32,110,101,101,100,101, - 100,32,105,110,32,111,114,100,101,114,32,116,111,32,99,111, - 114,114,101,99,116,108,121,32,116,114,97,110,115,102,101,114, - 32,112,101,114,109,105,115,115,105,111,110,115,10,32,32,32, - 32,32,32,32,32,41,1,218,8,115,101,116,95,100,97,116, - 97,41,4,114,118,0,0,0,114,107,0,0,0,90,10,99, - 97,99,104,101,95,112,97,116,104,114,26,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,15,95, - 99,97,99,104,101,95,98,121,116,101,99,111,100,101,53,3, - 0,0,115,2,0,0,0,0,8,122,28,83,111,117,114,99, - 101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,98, - 121,116,101,99,111,100,101,99,3,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,83,0,41,2,122,150,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, - 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40, - 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101, - 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, - 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, - 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, - 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32, - 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99, - 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, - 32,32,32,78,114,5,0,0,0,41,3,114,118,0,0,0, - 114,44,0,0,0,114,26,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,225,0,0,0,63,3, - 0,0,115,2,0,0,0,0,1,122,21,83,111,117,114,99, - 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, - 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,10,0,0,0,67,0,0,0,115,84,0,0,0,124,0, - 160,0,124,1,161,1,125,2,122,14,124,0,160,1,124,2, - 161,1,125,3,87,0,110,50,4,0,116,2,121,74,1,0, - 125,4,1,0,122,26,116,3,100,1,124,1,100,2,141,2, - 124,4,130,2,87,0,89,0,100,3,125,4,126,4,110,10, - 100,3,125,4,126,4,48,0,48,0,116,4,124,3,131,1, - 83,0,41,4,122,52,67,111,110,99,114,101,116,101,32,105, + 0,67,0,0,0,115,14,0,0,0,100,1,124,0,160,0, + 124,1,161,1,105,1,83,0,41,2,97,158,1,0,0,79, + 112,116,105,111,110,97,108,32,109,101,116,104,111,100,32,114, + 101,116,117,114,110,105,110,103,32,97,32,109,101,116,97,100, + 97,116,97,32,100,105,99,116,32,102,111,114,32,116,104,101, + 32,115,112,101,99,105,102,105,101,100,10,32,32,32,32,32, + 32,32,32,112,97,116,104,32,40,97,32,115,116,114,41,46, + 10,10,32,32,32,32,32,32,32,32,80,111,115,115,105,98, + 108,101,32,107,101,121,115,58,10,32,32,32,32,32,32,32, + 32,45,32,39,109,116,105,109,101,39,32,40,109,97,110,100, + 97,116,111,114,121,41,32,105,115,32,116,104,101,32,110,117, + 109,101,114,105,99,32,116,105,109,101,115,116,97,109,112,32, + 111,102,32,108,97,115,116,32,115,111,117,114,99,101,10,32, + 32,32,32,32,32,32,32,32,32,99,111,100,101,32,109,111, + 100,105,102,105,99,97,116,105,111,110,59,10,32,32,32,32, + 32,32,32,32,45,32,39,115,105,122,101,39,32,40,111,112, + 116,105,111,110,97,108,41,32,105,115,32,116,104,101,32,115, + 105,122,101,32,105,110,32,98,121,116,101,115,32,111,102,32, + 116,104,101,32,115,111,117,114,99,101,32,99,111,100,101,46, + 10,10,32,32,32,32,32,32,32,32,73,109,112,108,101,109, + 101,110,116,105,110,103,32,116,104,105,115,32,109,101,116,104, + 111,100,32,97,108,108,111,119,115,32,116,104,101,32,108,111, + 97,100,101,114,32,116,111,32,114,101,97,100,32,98,121,116, + 101,99,111,100,101,32,102,105,108,101,115,46,10,32,32,32, + 32,32,32,32,32,82,97,105,115,101,115,32,79,83,69,114, + 114,111,114,32,119,104,101,110,32,116,104,101,32,112,97,116, + 104,32,99,97,110,110,111,116,32,98,101,32,104,97,110,100, + 108,101,100,46,10,32,32,32,32,32,32,32,32,114,169,0, + 0,0,41,1,114,223,0,0,0,114,222,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,218,10,112, + 97,116,104,95,115,116,97,116,115,39,3,0,0,115,2,0, + 0,0,0,12,122,23,83,111,117,114,99,101,76,111,97,100, + 101,114,46,112,97,116,104,95,115,116,97,116,115,99,4,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0, + 0,0,67,0,0,0,115,12,0,0,0,124,0,160,0,124, + 2,124,3,161,2,83,0,41,1,122,228,79,112,116,105,111, + 110,97,108,32,109,101,116,104,111,100,32,119,104,105,99,104, + 32,119,114,105,116,101,115,32,100,97,116,97,32,40,98,121, + 116,101,115,41,32,116,111,32,97,32,102,105,108,101,32,112, + 97,116,104,32,40,97,32,115,116,114,41,46,10,10,32,32, + 32,32,32,32,32,32,73,109,112,108,101,109,101,110,116,105, + 110,103,32,116,104,105,115,32,109,101,116,104,111,100,32,97, + 108,108,111,119,115,32,102,111,114,32,116,104,101,32,119,114, + 105,116,105,110,103,32,111,102,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,115,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,115,111,117,114,99,101,32,112,97,116, + 104,32,105,115,32,110,101,101,100,101,100,32,105,110,32,111, + 114,100,101,114,32,116,111,32,99,111,114,114,101,99,116,108, + 121,32,116,114,97,110,115,102,101,114,32,112,101,114,109,105, + 115,115,105,111,110,115,10,32,32,32,32,32,32,32,32,41, + 1,218,8,115,101,116,95,100,97,116,97,41,4,114,118,0, + 0,0,114,107,0,0,0,90,10,99,97,99,104,101,95,112, + 97,116,104,114,26,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,218,15,95,99,97,99,104,101,95, + 98,121,116,101,99,111,100,101,53,3,0,0,115,2,0,0, + 0,0,8,122,28,83,111,117,114,99,101,76,111,97,100,101, + 114,46,95,99,97,99,104,101,95,98,121,116,101,99,111,100, + 101,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,83,0,41,2,122,150,79,112,116,105,111,110,97,108,32, + 109,101,116,104,111,100,32,119,104,105,99,104,32,119,114,105, + 116,101,115,32,100,97,116,97,32,40,98,121,116,101,115,41, + 32,116,111,32,97,32,102,105,108,101,32,112,97,116,104,32, + 40,97,32,115,116,114,41,46,10,10,32,32,32,32,32,32, + 32,32,73,109,112,108,101,109,101,110,116,105,110,103,32,116, + 104,105,115,32,109,101,116,104,111,100,32,97,108,108,111,119, + 115,32,102,111,114,32,116,104,101,32,119,114,105,116,105,110, + 103,32,111,102,32,98,121,116,101,99,111,100,101,32,102,105, + 108,101,115,46,10,32,32,32,32,32,32,32,32,78,114,5, + 0,0,0,41,3,114,118,0,0,0,114,44,0,0,0,114, + 26,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,114,225,0,0,0,63,3,0,0,115,2,0,0, + 0,0,1,122,21,83,111,117,114,99,101,76,111,97,100,101, + 114,46,115,101,116,95,100,97,116,97,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,10,0,0,0,67, + 0,0,0,115,84,0,0,0,124,0,160,0,124,1,161,1, + 125,2,122,14,124,0,160,1,124,2,161,1,125,3,87,0, + 110,50,4,0,116,2,121,74,1,0,125,4,1,0,122,26, + 116,3,100,1,124,1,100,2,141,2,124,4,130,2,87,0, + 89,0,100,3,125,4,126,4,110,10,100,3,125,4,126,4, + 48,0,48,0,116,4,124,3,131,1,83,0,41,4,122,52, + 67,111,110,99,114,101,116,101,32,105,109,112,108,101,109,101, + 110,116,97,116,105,111,110,32,111,102,32,73,110,115,112,101, + 99,116,76,111,97,100,101,114,46,103,101,116,95,115,111,117, + 114,99,101,46,122,39,115,111,117,114,99,101,32,110,111,116, + 32,97,118,97,105,108,97,98,108,101,32,116,104,114,111,117, + 103,104,32,103,101,116,95,100,97,116,97,40,41,114,115,0, + 0,0,78,41,5,114,179,0,0,0,218,8,103,101,116,95, + 100,97,116,97,114,50,0,0,0,114,117,0,0,0,114,176, + 0,0,0,41,5,114,118,0,0,0,114,139,0,0,0,114, + 44,0,0,0,114,174,0,0,0,218,3,101,120,99,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,218,10,103, + 101,116,95,115,111,117,114,99,101,70,3,0,0,115,20,0, + 0,0,0,2,10,1,2,1,14,1,14,1,4,1,2,255, + 4,1,2,255,24,2,122,23,83,111,117,114,99,101,76,111, + 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,114, + 104,0,0,0,41,1,218,9,95,111,112,116,105,109,105,122, + 101,99,3,0,0,0,0,0,0,0,1,0,0,0,4,0, + 0,0,8,0,0,0,67,0,0,0,115,22,0,0,0,116, + 0,106,1,116,2,124,1,124,2,100,1,100,2,124,3,100, + 3,141,6,83,0,41,4,122,130,82,101,116,117,114,110,32, + 116,104,101,32,99,111,100,101,32,111,98,106,101,99,116,32, + 99,111,109,112,105,108,101,100,32,102,114,111,109,32,115,111, + 117,114,99,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,101,32,39,100,97,116,97,39,32,97,114,103,117,109,101, + 110,116,32,99,97,110,32,98,101,32,97,110,121,32,111,98, + 106,101,99,116,32,116,121,112,101,32,116,104,97,116,32,99, + 111,109,112,105,108,101,40,41,32,115,117,112,112,111,114,116, + 115,46,10,32,32,32,32,32,32,32,32,114,215,0,0,0, + 84,41,2,218,12,100,111,110,116,95,105,110,104,101,114,105, + 116,114,83,0,0,0,41,3,114,134,0,0,0,114,214,0, + 0,0,218,7,99,111,109,112,105,108,101,41,4,114,118,0, + 0,0,114,26,0,0,0,114,44,0,0,0,114,230,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 218,14,115,111,117,114,99,101,95,116,111,95,99,111,100,101, + 80,3,0,0,115,6,0,0,0,0,5,12,1,4,255,122, + 27,83,111,117,114,99,101,76,111,97,100,101,114,46,115,111, + 117,114,99,101,95,116,111,95,99,111,100,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,15,0,0,0,9,0,0, + 0,67,0,0,0,115,24,2,0,0,124,0,160,0,124,1, + 161,1,125,2,100,1,125,3,100,1,125,4,100,1,125,5, + 100,2,125,6,100,3,125,7,122,12,116,1,124,2,131,1, + 125,8,87,0,110,24,4,0,116,2,121,66,1,0,1,0, + 1,0,100,1,125,8,89,0,144,1,110,42,48,0,122,14, + 124,0,160,3,124,2,161,1,125,9,87,0,110,20,4,0, + 116,4,121,102,1,0,1,0,1,0,89,0,144,1,110,6, + 48,0,116,5,124,9,100,4,25,0,131,1,125,3,122,14, + 124,0,160,6,124,8,161,1,125,10,87,0,110,18,4,0, + 116,4,121,148,1,0,1,0,1,0,89,0,110,216,48,0, + 124,1,124,8,100,5,156,2,125,11,122,148,116,7,124,10, + 124,1,124,11,131,3,125,12,116,8,124,10,131,1,100,6, + 100,1,133,2,25,0,125,13,124,12,100,7,64,0,100,8, + 107,3,125,6,124,6,144,1,114,30,124,12,100,9,64,0, + 100,8,107,3,125,7,116,9,106,10,100,10,107,3,144,1, + 114,50,124,7,115,248,116,9,106,10,100,11,107,2,144,1, + 114,50,124,0,160,6,124,2,161,1,125,4,116,9,160,11, + 116,12,124,4,161,2,125,5,116,13,124,10,124,5,124,1, + 124,11,131,4,1,0,110,20,116,14,124,10,124,3,124,9, + 100,12,25,0,124,1,124,11,131,5,1,0,87,0,110,24, + 4,0,116,15,116,16,102,2,144,1,121,76,1,0,1,0, + 1,0,89,0,110,32,48,0,116,17,160,18,100,13,124,8, + 124,2,161,3,1,0,116,19,124,13,124,1,124,8,124,2, + 100,14,141,4,83,0,124,4,100,1,117,0,144,1,114,128, + 124,0,160,6,124,2,161,1,125,4,124,0,160,20,124,4, + 124,2,161,2,125,14,116,17,160,18,100,15,124,2,161,2, + 1,0,116,21,106,22,144,2,115,20,124,8,100,1,117,1, + 144,2,114,20,124,3,100,1,117,1,144,2,114,20,124,6, + 144,1,114,220,124,5,100,1,117,0,144,1,114,206,116,9, + 160,11,124,4,161,1,125,5,116,23,124,14,124,5,124,7, + 131,3,125,10,110,16,116,24,124,14,124,3,116,25,124,4, + 131,1,131,3,125,10,122,18,124,0,160,26,124,2,124,8, + 124,10,161,3,1,0,87,0,110,20,4,0,116,2,144,2, + 121,18,1,0,1,0,1,0,89,0,110,2,48,0,124,14, + 83,0,41,16,122,190,67,111,110,99,114,101,116,101,32,105, 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,103, - 101,116,95,115,111,117,114,99,101,46,122,39,115,111,117,114, - 99,101,32,110,111,116,32,97,118,97,105,108,97,98,108,101, - 32,116,104,114,111,117,103,104,32,103,101,116,95,100,97,116, - 97,40,41,114,115,0,0,0,78,41,5,114,179,0,0,0, - 218,8,103,101,116,95,100,97,116,97,114,50,0,0,0,114, - 117,0,0,0,114,176,0,0,0,41,5,114,118,0,0,0, - 114,139,0,0,0,114,44,0,0,0,114,174,0,0,0,218, - 3,101,120,99,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,70, - 3,0,0,115,20,0,0,0,0,2,10,1,2,1,14,1, - 14,1,4,1,2,255,4,1,2,255,24,2,122,23,83,111, - 117,114,99,101,76,111,97,100,101,114,46,103,101,116,95,115, - 111,117,114,99,101,114,104,0,0,0,41,1,218,9,95,111, - 112,116,105,109,105,122,101,99,3,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,8,0,0,0,67,0,0,0, - 115,22,0,0,0,116,0,106,1,116,2,124,1,124,2,100, - 1,100,2,124,3,100,3,141,6,83,0,41,4,122,130,82, - 101,116,117,114,110,32,116,104,101,32,99,111,100,101,32,111, - 98,106,101,99,116,32,99,111,109,112,105,108,101,100,32,102, - 114,111,109,32,115,111,117,114,99,101,46,10,10,32,32,32, - 32,32,32,32,32,84,104,101,32,39,100,97,116,97,39,32, - 97,114,103,117,109,101,110,116,32,99,97,110,32,98,101,32, - 97,110,121,32,111,98,106,101,99,116,32,116,121,112,101,32, - 116,104,97,116,32,99,111,109,112,105,108,101,40,41,32,115, - 117,112,112,111,114,116,115,46,10,32,32,32,32,32,32,32, - 32,114,215,0,0,0,84,41,2,218,12,100,111,110,116,95, - 105,110,104,101,114,105,116,114,83,0,0,0,41,3,114,134, - 0,0,0,114,214,0,0,0,218,7,99,111,109,112,105,108, - 101,41,4,114,118,0,0,0,114,26,0,0,0,114,44,0, - 0,0,114,230,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,218,14,115,111,117,114,99,101,95,116, - 111,95,99,111,100,101,80,3,0,0,115,6,0,0,0,0, - 5,12,1,4,255,122,27,83,111,117,114,99,101,76,111,97, - 100,101,114,46,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,15, - 0,0,0,9,0,0,0,67,0,0,0,115,24,2,0,0, - 124,0,160,0,124,1,161,1,125,2,100,1,125,3,100,1, - 125,4,100,1,125,5,100,2,125,6,100,3,125,7,122,12, - 116,1,124,2,131,1,125,8,87,0,110,24,4,0,116,2, - 121,66,1,0,1,0,1,0,100,1,125,8,89,0,144,1, - 110,42,48,0,122,14,124,0,160,3,124,2,161,1,125,9, - 87,0,110,20,4,0,116,4,121,102,1,0,1,0,1,0, - 89,0,144,1,110,6,48,0,116,5,124,9,100,4,25,0, - 131,1,125,3,122,14,124,0,160,6,124,8,161,1,125,10, - 87,0,110,18,4,0,116,4,121,148,1,0,1,0,1,0, - 89,0,110,216,48,0,124,1,124,8,100,5,156,2,125,11, - 122,148,116,7,124,10,124,1,124,11,131,3,125,12,116,8, - 124,10,131,1,100,6,100,1,133,2,25,0,125,13,124,12, - 100,7,64,0,100,8,107,3,125,6,124,6,144,1,114,30, - 124,12,100,9,64,0,100,8,107,3,125,7,116,9,106,10, - 100,10,107,3,144,1,114,50,124,7,115,248,116,9,106,10, - 100,11,107,2,144,1,114,50,124,0,160,6,124,2,161,1, - 125,4,116,9,160,11,116,12,124,4,161,2,125,5,116,13, - 124,10,124,5,124,1,124,11,131,4,1,0,110,20,116,14, - 124,10,124,3,124,9,100,12,25,0,124,1,124,11,131,5, - 1,0,87,0,110,24,4,0,116,15,116,16,102,2,144,1, - 121,76,1,0,1,0,1,0,89,0,110,32,48,0,116,17, - 160,18,100,13,124,8,124,2,161,3,1,0,116,19,124,13, - 124,1,124,8,124,2,100,14,141,4,83,0,124,4,100,1, - 117,0,144,1,114,128,124,0,160,6,124,2,161,1,125,4, - 124,0,160,20,124,4,124,2,161,2,125,14,116,17,160,18, - 100,15,124,2,161,2,1,0,116,21,106,22,144,2,115,20, - 124,8,100,1,117,1,144,2,114,20,124,3,100,1,117,1, - 144,2,114,20,124,6,144,1,114,220,124,5,100,1,117,0, - 144,1,114,206,116,9,160,11,124,4,161,1,125,5,116,23, - 124,14,124,5,124,7,131,3,125,10,110,16,116,24,124,14, - 124,3,116,25,124,4,131,1,131,3,125,10,122,18,124,0, - 160,26,124,2,124,8,124,10,161,3,1,0,87,0,110,20, - 4,0,116,2,144,2,121,18,1,0,1,0,1,0,89,0, - 110,2,48,0,124,14,83,0,41,16,122,190,67,111,110,99, - 114,101,116,101,32,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,32,111,102,32,73,110,115,112,101,99,116,76,111, - 97,100,101,114,46,103,101,116,95,99,111,100,101,46,10,10, - 32,32,32,32,32,32,32,32,82,101,97,100,105,110,103,32, - 111,102,32,98,121,116,101,99,111,100,101,32,114,101,113,117, - 105,114,101,115,32,112,97,116,104,95,115,116,97,116,115,32, - 116,111,32,98,101,32,105,109,112,108,101,109,101,110,116,101, - 100,46,32,84,111,32,119,114,105,116,101,10,32,32,32,32, - 32,32,32,32,98,121,116,101,99,111,100,101,44,32,115,101, - 116,95,100,97,116,97,32,109,117,115,116,32,97,108,115,111, - 32,98,101,32,105,109,112,108,101,109,101,110,116,101,100,46, - 10,10,32,32,32,32,32,32,32,32,78,70,84,114,169,0, - 0,0,114,159,0,0,0,114,145,0,0,0,114,39,0,0, - 0,114,73,0,0,0,114,28,0,0,0,90,5,110,101,118, - 101,114,90,6,97,108,119,97,121,115,218,4,115,105,122,101, - 122,13,123,125,32,109,97,116,99,104,101,115,32,123,125,41, - 3,114,116,0,0,0,114,106,0,0,0,114,107,0,0,0, - 122,19,99,111,100,101,32,111,98,106,101,99,116,32,102,114, - 111,109,32,123,125,41,27,114,179,0,0,0,114,97,0,0, - 0,114,82,0,0,0,114,224,0,0,0,114,50,0,0,0, - 114,18,0,0,0,114,227,0,0,0,114,152,0,0,0,218, - 10,109,101,109,111,114,121,118,105,101,119,114,163,0,0,0, - 90,21,99,104,101,99,107,95,104,97,115,104,95,98,97,115, - 101,100,95,112,121,99,115,114,157,0,0,0,218,17,95,82, - 65,87,95,77,65,71,73,67,95,78,85,77,66,69,82,114, - 158,0,0,0,114,156,0,0,0,114,117,0,0,0,114,150, - 0,0,0,114,134,0,0,0,114,149,0,0,0,114,165,0, - 0,0,114,233,0,0,0,114,1,0,0,0,218,19,100,111, - 110,116,95,119,114,105,116,101,95,98,121,116,101,99,111,100, - 101,114,171,0,0,0,114,170,0,0,0,114,23,0,0,0, - 114,226,0,0,0,41,15,114,118,0,0,0,114,139,0,0, - 0,114,107,0,0,0,114,154,0,0,0,114,174,0,0,0, - 114,157,0,0,0,90,10,104,97,115,104,95,98,97,115,101, - 100,90,12,99,104,101,99,107,95,115,111,117,114,99,101,114, - 106,0,0,0,218,2,115,116,114,26,0,0,0,114,151,0, - 0,0,114,2,0,0,0,90,10,98,121,116,101,115,95,100, - 97,116,97,90,11,99,111,100,101,95,111,98,106,101,99,116, + 101,116,95,99,111,100,101,46,10,10,32,32,32,32,32,32, + 32,32,82,101,97,100,105,110,103,32,111,102,32,98,121,116, + 101,99,111,100,101,32,114,101,113,117,105,114,101,115,32,112, + 97,116,104,95,115,116,97,116,115,32,116,111,32,98,101,32, + 105,109,112,108,101,109,101,110,116,101,100,46,32,84,111,32, + 119,114,105,116,101,10,32,32,32,32,32,32,32,32,98,121, + 116,101,99,111,100,101,44,32,115,101,116,95,100,97,116,97, + 32,109,117,115,116,32,97,108,115,111,32,98,101,32,105,109, + 112,108,101,109,101,110,116,101,100,46,10,10,32,32,32,32, + 32,32,32,32,78,70,84,114,169,0,0,0,114,159,0,0, + 0,114,145,0,0,0,114,39,0,0,0,114,73,0,0,0, + 114,28,0,0,0,90,5,110,101,118,101,114,90,6,97,108, + 119,97,121,115,218,4,115,105,122,101,122,13,123,125,32,109, + 97,116,99,104,101,115,32,123,125,41,3,114,116,0,0,0, + 114,106,0,0,0,114,107,0,0,0,122,19,99,111,100,101, + 32,111,98,106,101,99,116,32,102,114,111,109,32,123,125,41, + 27,114,179,0,0,0,114,97,0,0,0,114,82,0,0,0, + 114,224,0,0,0,114,50,0,0,0,114,18,0,0,0,114, + 227,0,0,0,114,152,0,0,0,218,10,109,101,109,111,114, + 121,118,105,101,119,114,163,0,0,0,90,21,99,104,101,99, + 107,95,104,97,115,104,95,98,97,115,101,100,95,112,121,99, + 115,114,157,0,0,0,218,17,95,82,65,87,95,77,65,71, + 73,67,95,78,85,77,66,69,82,114,158,0,0,0,114,156, + 0,0,0,114,117,0,0,0,114,150,0,0,0,114,134,0, + 0,0,114,149,0,0,0,114,165,0,0,0,114,233,0,0, + 0,114,1,0,0,0,218,19,100,111,110,116,95,119,114,105, + 116,101,95,98,121,116,101,99,111,100,101,114,171,0,0,0, + 114,170,0,0,0,114,23,0,0,0,114,226,0,0,0,41, + 15,114,118,0,0,0,114,139,0,0,0,114,107,0,0,0, + 114,154,0,0,0,114,174,0,0,0,114,157,0,0,0,90, + 10,104,97,115,104,95,98,97,115,101,100,90,12,99,104,101, + 99,107,95,115,111,117,114,99,101,114,106,0,0,0,218,2, + 115,116,114,26,0,0,0,114,151,0,0,0,114,2,0,0, + 0,90,10,98,121,116,101,115,95,100,97,116,97,90,11,99, + 111,100,101,95,111,98,106,101,99,116,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,213,0,0,0,88,3, + 0,0,115,152,0,0,0,0,7,10,1,4,1,4,1,4, + 1,4,1,4,1,2,1,12,1,12,1,12,2,2,1,14, + 1,12,1,8,2,12,1,2,1,14,1,12,1,6,3,2, + 1,2,254,6,4,2,1,12,1,16,1,12,1,6,1,12, + 1,12,1,2,255,2,2,8,254,4,3,10,1,4,1,2, + 1,2,254,4,4,8,1,2,255,6,3,2,1,2,1,2, + 1,6,1,2,1,2,251,8,7,18,1,6,2,8,1,2, + 255,4,2,6,1,2,1,2,254,6,3,10,1,10,1,12, + 1,12,1,18,1,6,255,4,2,6,1,10,1,10,1,14, + 2,6,1,6,255,4,2,2,1,18,1,14,1,6,1,122, + 21,83,111,117,114,99,101,76,111,97,100,101,114,46,103,101, + 116,95,99,111,100,101,78,41,10,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,223,0,0,0,114,224,0, + 0,0,114,226,0,0,0,114,225,0,0,0,114,229,0,0, + 0,114,233,0,0,0,114,213,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 213,0,0,0,88,3,0,0,115,152,0,0,0,0,7,10, - 1,4,1,4,1,4,1,4,1,4,1,2,1,12,1,12, - 1,12,2,2,1,14,1,12,1,8,2,12,1,2,1,14, - 1,12,1,6,3,2,1,2,254,6,4,2,1,12,1,16, - 1,12,1,6,1,12,1,12,1,2,255,2,2,8,254,4, - 3,10,1,4,1,2,1,2,254,4,4,8,1,2,255,6, - 3,2,1,2,1,2,1,6,1,2,1,2,251,8,7,18, - 1,6,2,8,1,2,255,4,2,6,1,2,1,2,254,6, - 3,10,1,10,1,12,1,12,1,18,1,6,255,4,2,6, - 1,10,1,10,1,14,2,6,1,6,255,4,2,2,1,18, - 1,14,1,6,1,122,21,83,111,117,114,99,101,76,111,97, - 100,101,114,46,103,101,116,95,99,111,100,101,78,41,10,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,223, - 0,0,0,114,224,0,0,0,114,226,0,0,0,114,225,0, - 0,0,114,229,0,0,0,114,233,0,0,0,114,213,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,221,0,0,0,29,3,0,0,115,14, - 0,0,0,8,2,8,8,8,14,8,10,8,7,8,10,14, - 8,114,221,0,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,115, - 92,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, - 100,6,100,7,132,0,90,6,101,7,135,0,102,1,100,8, - 100,9,132,8,131,1,90,8,101,7,100,10,100,11,132,0, - 131,1,90,9,100,12,100,13,132,0,90,10,101,7,100,14, - 100,15,132,0,131,1,90,11,135,0,4,0,90,12,83,0, - 41,16,218,10,70,105,108,101,76,111,97,100,101,114,122,103, - 66,97,115,101,32,102,105,108,101,32,108,111,97,100,101,114, - 32,99,108,97,115,115,32,119,104,105,99,104,32,105,109,112, - 108,101,109,101,110,116,115,32,116,104,101,32,108,111,97,100, - 101,114,32,112,114,111,116,111,99,111,108,32,109,101,116,104, - 111,100,115,32,116,104,97,116,10,32,32,32,32,114,101,113, - 117,105,114,101,32,102,105,108,101,32,115,121,115,116,101,109, - 32,117,115,97,103,101,46,99,3,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,2,0,0,0,67,0,0,0, - 115,16,0,0,0,124,1,124,0,95,0,124,2,124,0,95, - 1,100,1,83,0,41,2,122,75,67,97,99,104,101,32,116, - 104,101,32,109,111,100,117,108,101,32,110,97,109,101,32,97, - 110,100,32,116,104,101,32,112,97,116,104,32,116,111,32,116, - 104,101,32,102,105,108,101,32,102,111,117,110,100,32,98,121, - 32,116,104,101,10,32,32,32,32,32,32,32,32,102,105,110, - 100,101,114,46,78,114,159,0,0,0,41,3,114,118,0,0, - 0,114,139,0,0,0,114,44,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,209,0,0,0,178, - 3,0,0,115,4,0,0,0,0,3,6,1,122,19,70,105, - 108,101,76,111,97,100,101,114,46,95,95,105,110,105,116,95, - 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,2,0,0,0,67,0,0,0,115,24,0,0,0,124, - 0,106,0,124,1,106,0,107,2,111,22,124,0,106,1,124, - 1,106,1,107,2,83,0,114,109,0,0,0,169,2,218,9, - 95,95,99,108,97,115,115,95,95,114,131,0,0,0,169,2, - 114,118,0,0,0,90,5,111,116,104,101,114,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,6,95,95,101, - 113,95,95,184,3,0,0,115,6,0,0,0,0,1,12,1, - 10,255,122,17,70,105,108,101,76,111,97,100,101,114,46,95, - 95,101,113,95,95,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,20, - 0,0,0,116,0,124,0,106,1,131,1,116,0,124,0,106, - 2,131,1,65,0,83,0,114,109,0,0,0,169,3,218,4, - 104,97,115,104,114,116,0,0,0,114,44,0,0,0,169,1, - 114,118,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,8,95,95,104,97,115,104,95,95,188,3, - 0,0,115,2,0,0,0,0,1,122,19,70,105,108,101,76, - 111,97,100,101,114,46,95,95,104,97,115,104,95,95,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,3,0,0,0,115,16,0,0,0,116,0,116,1, - 124,0,131,2,160,2,124,1,161,1,83,0,41,1,122,100, - 76,111,97,100,32,97,32,109,111,100,117,108,101,32,102,114, - 111,109,32,97,32,102,105,108,101,46,10,10,32,32,32,32, - 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, - 85,115,101,32,101,120,101,99,95,109,111,100,117,108,101,40, - 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, - 32,32,32,32,41,3,218,5,115,117,112,101,114,114,239,0, - 0,0,114,220,0,0,0,114,219,0,0,0,169,1,114,241, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,220,0, - 0,0,191,3,0,0,115,2,0,0,0,0,10,122,22,70, - 105,108,101,76,111,97,100,101,114,46,108,111,97,100,95,109, - 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,6, - 0,0,0,124,0,106,0,83,0,169,1,122,58,82,101,116, - 117,114,110,32,116,104,101,32,112,97,116,104,32,116,111,32, - 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,32, - 97,115,32,102,111,117,110,100,32,98,121,32,116,104,101,32, - 102,105,110,100,101,114,46,114,48,0,0,0,114,219,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,179,0,0,0,203,3,0,0,115,2,0,0,0,0,3, - 122,23,70,105,108,101,76,111,97,100,101,114,46,103,101,116, - 95,102,105,108,101,110,97,109,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,8,0,0,0,67,0, - 0,0,115,126,0,0,0,116,0,124,0,116,1,116,2,102, - 2,131,2,114,70,116,3,160,4,116,5,124,1,131,1,161, - 1,143,24,125,2,124,2,160,6,161,0,87,0,2,0,100, - 1,4,0,4,0,131,3,1,0,83,0,49,0,115,58,48, - 0,1,0,1,0,1,0,89,0,1,0,110,52,116,3,160, - 7,124,1,100,2,161,2,143,24,125,2,124,2,160,6,161, - 0,87,0,2,0,100,1,4,0,4,0,131,3,1,0,83, - 0,49,0,115,112,48,0,1,0,1,0,1,0,89,0,1, - 0,100,1,83,0,41,3,122,39,82,101,116,117,114,110,32, - 116,104,101,32,100,97,116,97,32,102,114,111,109,32,112,97, - 116,104,32,97,115,32,114,97,119,32,98,121,116,101,115,46, - 78,218,1,114,41,8,114,161,0,0,0,114,221,0,0,0, - 218,19,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,114,64,0,0,0,90,9,111,112,101,110, - 95,99,111,100,101,114,84,0,0,0,90,4,114,101,97,100, - 114,65,0,0,0,41,3,114,118,0,0,0,114,44,0,0, - 0,114,68,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,227,0,0,0,208,3,0,0,115,10, - 0,0,0,0,2,14,1,16,1,40,2,14,1,122,19,70, - 105,108,101,76,111,97,100,101,114,46,103,101,116,95,100,97, - 116,97,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,20,0,0,0, - 100,1,100,2,108,0,109,1,125,2,1,0,124,2,124,0, - 131,1,83,0,41,3,78,114,73,0,0,0,41,1,218,10, - 70,105,108,101,82,101,97,100,101,114,41,2,90,17,105,109, - 112,111,114,116,108,105,98,46,114,101,97,100,101,114,115,114, - 253,0,0,0,41,3,114,118,0,0,0,114,216,0,0,0, - 114,253,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,19,103,101,116,95,114,101,115,111,117,114, - 99,101,95,114,101,97,100,101,114,217,3,0,0,115,4,0, - 0,0,0,2,12,1,122,30,70,105,108,101,76,111,97,100, - 101,114,46,103,101,116,95,114,101,115,111,117,114,99,101,95, - 114,101,97,100,101,114,41,13,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,209,0,0, - 0,114,243,0,0,0,114,247,0,0,0,114,136,0,0,0, - 114,220,0,0,0,114,179,0,0,0,114,227,0,0,0,114, - 254,0,0,0,90,13,95,95,99,108,97,115,115,99,101,108, - 108,95,95,114,5,0,0,0,114,5,0,0,0,114,249,0, - 0,0,114,8,0,0,0,114,239,0,0,0,173,3,0,0, - 115,22,0,0,0,8,2,4,3,8,6,8,4,8,3,2, - 1,14,11,2,1,10,4,8,9,2,1,114,239,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,64,0,0,0,115,46,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, - 90,4,100,4,100,5,132,0,90,5,100,6,100,7,156,1, - 100,8,100,9,132,2,90,6,100,10,83,0,41,11,218,16, - 83,111,117,114,99,101,70,105,108,101,76,111,97,100,101,114, - 122,62,67,111,110,99,114,101,116,101,32,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,32,111,102,32,83,111,117, - 114,99,101,76,111,97,100,101,114,32,117,115,105,110,103,32, - 116,104,101,32,102,105,108,101,32,115,121,115,116,101,109,46, - 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,3,0,0,0,67,0,0,0,115,22,0,0,0,116,0, - 124,1,131,1,125,2,124,2,106,1,124,2,106,2,100,1, - 156,2,83,0,41,2,122,33,82,101,116,117,114,110,32,116, - 104,101,32,109,101,116,97,100,97,116,97,32,102,111,114,32, - 116,104,101,32,112,97,116,104,46,41,2,114,169,0,0,0, - 114,234,0,0,0,41,3,114,49,0,0,0,218,8,115,116, - 95,109,116,105,109,101,90,7,115,116,95,115,105,122,101,41, - 3,114,118,0,0,0,114,44,0,0,0,114,238,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 224,0,0,0,227,3,0,0,115,4,0,0,0,0,2,8, - 1,122,27,83,111,117,114,99,101,70,105,108,101,76,111,97, - 100,101,114,46,112,97,116,104,95,115,116,97,116,115,99,4, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5, - 0,0,0,67,0,0,0,115,24,0,0,0,116,0,124,1, - 131,1,125,4,124,0,106,1,124,2,124,3,124,4,100,1, - 141,3,83,0,41,2,78,169,1,218,5,95,109,111,100,101, - 41,2,114,114,0,0,0,114,225,0,0,0,41,5,114,118, - 0,0,0,114,107,0,0,0,114,106,0,0,0,114,26,0, - 0,0,114,52,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,226,0,0,0,232,3,0,0,115, - 4,0,0,0,0,2,8,1,122,32,83,111,117,114,99,101, - 70,105,108,101,76,111,97,100,101,114,46,95,99,97,99,104, - 101,95,98,121,116,101,99,111,100,101,114,60,0,0,0,114, - 1,1,0,0,99,3,0,0,0,0,0,0,0,1,0,0, - 0,9,0,0,0,11,0,0,0,67,0,0,0,115,252,0, - 0,0,116,0,124,1,131,1,92,2,125,4,125,5,103,0, - 125,6,124,4,114,52,116,1,124,4,131,1,115,52,116,0, - 124,4,131,1,92,2,125,4,125,7,124,6,160,2,124,7, - 161,1,1,0,113,16,116,3,124,6,131,1,68,0,93,104, - 125,7,116,4,124,4,124,7,131,2,125,4,122,14,116,5, - 160,6,124,4,161,1,1,0,87,0,113,60,4,0,116,7, - 121,110,1,0,1,0,1,0,89,0,113,60,89,0,113,60, - 4,0,116,8,121,162,1,0,125,8,1,0,122,30,116,9, - 160,10,100,1,124,4,124,8,161,3,1,0,87,0,89,0, - 100,2,125,8,126,8,1,0,100,2,83,0,100,2,125,8, - 126,8,48,0,48,0,113,60,122,28,116,11,124,1,124,2, - 124,3,131,3,1,0,116,9,160,10,100,3,124,1,161,2, - 1,0,87,0,110,52,4,0,116,8,144,0,121,246,1,0, - 125,8,1,0,122,26,116,9,160,10,100,1,124,1,124,8, - 161,3,1,0,87,0,89,0,100,2,125,8,126,8,110,10, - 100,2,125,8,126,8,48,0,48,0,100,2,83,0,41,4, - 122,27,87,114,105,116,101,32,98,121,116,101,115,32,100,97, - 116,97,32,116,111,32,97,32,102,105,108,101,46,122,27,99, - 111,117,108,100,32,110,111,116,32,99,114,101,97,116,101,32, - 123,33,114,125,58,32,123,33,114,125,78,122,12,99,114,101, - 97,116,101,100,32,123,33,114,125,41,12,114,47,0,0,0, - 114,56,0,0,0,114,186,0,0,0,114,42,0,0,0,114, - 38,0,0,0,114,4,0,0,0,90,5,109,107,100,105,114, - 218,15,70,105,108,101,69,120,105,115,116,115,69,114,114,111, - 114,114,50,0,0,0,114,134,0,0,0,114,149,0,0,0, - 114,69,0,0,0,41,9,114,118,0,0,0,114,44,0,0, - 0,114,26,0,0,0,114,2,1,0,0,218,6,112,97,114, - 101,110,116,114,96,0,0,0,114,37,0,0,0,114,33,0, - 0,0,114,228,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,225,0,0,0,237,3,0,0,115, - 46,0,0,0,0,2,12,1,4,2,12,1,12,1,12,2, - 12,1,10,1,2,1,14,1,12,2,8,1,14,3,6,1, - 4,255,4,2,28,1,2,1,12,1,16,1,16,2,8,1, - 2,255,122,25,83,111,117,114,99,101,70,105,108,101,76,111, - 97,100,101,114,46,115,101,116,95,100,97,116,97,78,41,7, - 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, - 127,0,0,0,114,224,0,0,0,114,226,0,0,0,114,225, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,255,0,0,0,223,3,0,0, - 115,8,0,0,0,8,2,4,2,8,5,8,5,114,255,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,64,0,0,0,115,32,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, - 132,0,90,4,100,4,100,5,132,0,90,5,100,6,83,0, - 41,7,218,20,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,122,45,76,111,97,100,101,114, - 32,119,104,105,99,104,32,104,97,110,100,108,101,115,32,115, - 111,117,114,99,101,108,101,115,115,32,102,105,108,101,32,105, - 109,112,111,114,116,115,46,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,68,0,0,0,124,0,160,0,124,1,161,1,125,2,124, - 0,160,1,124,2,161,1,125,3,124,1,124,2,100,1,156, - 2,125,4,116,2,124,3,124,1,124,4,131,3,1,0,116, - 3,116,4,124,3,131,1,100,2,100,0,133,2,25,0,124, - 1,124,2,100,3,141,3,83,0,41,4,78,114,159,0,0, - 0,114,145,0,0,0,41,2,114,116,0,0,0,114,106,0, - 0,0,41,5,114,179,0,0,0,114,227,0,0,0,114,152, - 0,0,0,114,165,0,0,0,114,235,0,0,0,41,5,114, - 118,0,0,0,114,139,0,0,0,114,44,0,0,0,114,26, - 0,0,0,114,151,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,213,0,0,0,16,4,0,0, - 115,22,0,0,0,0,1,10,1,10,4,2,1,2,254,6, - 4,12,1,2,1,14,1,2,1,2,253,122,29,83,111,117, - 114,99,101,108,101,115,115,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,39, - 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,116, - 104,101,114,101,32,105,115,32,110,111,32,115,111,117,114,99, - 101,32,99,111,100,101,46,78,114,5,0,0,0,114,219,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,229,0,0,0,32,4,0,0,115,2,0,0,0,0, - 2,122,31,83,111,117,114,99,101,108,101,115,115,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,78,41,6,114,125,0,0,0,114,124,0,0,0,114, - 126,0,0,0,114,127,0,0,0,114,213,0,0,0,114,229, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,5,1,0,0,12,4,0,0, - 115,6,0,0,0,8,2,4,2,8,16,114,5,1,0,0, + 221,0,0,0,29,3,0,0,115,14,0,0,0,8,2,8, + 8,8,14,8,10,8,7,8,10,14,8,114,221,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,64,0,0,0,115,92,0,0,0,101,0, + 0,4,0,0,0,0,0,0,0,115,92,0,0,0,101,0, 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, - 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, - 90,8,100,12,100,13,132,0,90,9,100,14,100,15,132,0, - 90,10,100,16,100,17,132,0,90,11,101,12,100,18,100,19, - 132,0,131,1,90,13,100,20,83,0,41,21,114,252,0,0, - 0,122,93,76,111,97,100,101,114,32,102,111,114,32,101,120, - 116,101,110,115,105,111,110,32,109,111,100,117,108,101,115,46, - 10,10,32,32,32,32,84,104,101,32,99,111,110,115,116,114, - 117,99,116,111,114,32,105,115,32,100,101,115,105,103,110,101, - 100,32,116,111,32,119,111,114,107,32,119,105,116,104,32,70, - 105,108,101,70,105,110,100,101,114,46,10,10,32,32,32,32, - 99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,2,0,0,0,67,0,0,0,115,16,0,0,0,124,1, - 124,0,95,0,124,2,124,0,95,1,100,0,83,0,114,109, - 0,0,0,114,159,0,0,0,41,3,114,118,0,0,0,114, - 116,0,0,0,114,44,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,209,0,0,0,49,4,0, - 0,115,4,0,0,0,0,1,6,1,122,28,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 95,95,105,110,105,116,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, - 0,115,24,0,0,0,124,0,106,0,124,1,106,0,107,2, - 111,22,124,0,106,1,124,1,106,1,107,2,83,0,114,109, - 0,0,0,114,240,0,0,0,114,242,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,8,0,0,0,114,243,0,0, - 0,53,4,0,0,115,6,0,0,0,0,1,12,1,10,255, - 122,26,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,46,95,95,101,113,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,20,0,0,0,116,0,124,0,106,1, - 131,1,116,0,124,0,106,2,131,1,65,0,83,0,114,109, - 0,0,0,114,244,0,0,0,114,246,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,8,0,0,0,114,247,0,0, - 0,57,4,0,0,115,2,0,0,0,0,1,122,28,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,5,0,0,0,67, - 0,0,0,115,36,0,0,0,116,0,160,1,116,2,106,3, - 124,1,161,2,125,2,116,0,160,4,100,1,124,1,106,5, - 124,0,106,6,161,3,1,0,124,2,83,0,41,2,122,38, - 67,114,101,97,116,101,32,97,110,32,117,110,105,116,105,97, - 108,105,122,101,100,32,101,120,116,101,110,115,105,111,110,32, - 109,111,100,117,108,101,122,38,101,120,116,101,110,115,105,111, - 110,32,109,111,100,117,108,101,32,123,33,114,125,32,108,111, - 97,100,101,100,32,102,114,111,109,32,123,33,114,125,41,7, - 114,134,0,0,0,114,214,0,0,0,114,163,0,0,0,90, - 14,99,114,101,97,116,101,95,100,121,110,97,109,105,99,114, - 149,0,0,0,114,116,0,0,0,114,44,0,0,0,41,3, - 114,118,0,0,0,114,187,0,0,0,114,216,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,212, - 0,0,0,60,4,0,0,115,14,0,0,0,0,2,4,1, - 6,255,4,2,6,1,8,255,4,2,122,33,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,5,0, - 0,0,67,0,0,0,115,36,0,0,0,116,0,160,1,116, - 2,106,3,124,1,161,2,1,0,116,0,160,4,100,1,124, - 0,106,5,124,0,106,6,161,3,1,0,100,2,83,0,41, - 3,122,30,73,110,105,116,105,97,108,105,122,101,32,97,110, - 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,122,40,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,32,123,33,114,125,32,101,120,101,99,117,116,101, - 100,32,102,114,111,109,32,123,33,114,125,78,41,7,114,134, - 0,0,0,114,214,0,0,0,114,163,0,0,0,90,12,101, - 120,101,99,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,116,0,0,0,114,44,0,0,0,169,2,114,118,0,0, - 0,114,216,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,217,0,0,0,68,4,0,0,115,8, - 0,0,0,0,2,14,1,6,1,8,255,122,31,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,3,0,0,0,115,36,0,0,0,116,0,124,0,106,1, - 131,1,100,1,25,0,137,0,116,2,135,0,102,1,100,2, - 100,3,132,8,116,3,68,0,131,1,131,1,83,0,41,4, - 122,49,82,101,116,117,114,110,32,84,114,117,101,32,105,102, - 32,116,104,101,32,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,105,115,32,97,32,112,97,99,107,97, - 103,101,46,114,39,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,51,0,0, - 0,115,26,0,0,0,124,0,93,18,125,1,136,0,100,0, - 124,1,23,0,107,2,86,0,1,0,113,2,100,1,83,0, - 41,2,114,209,0,0,0,78,114,5,0,0,0,169,2,114, - 32,0,0,0,218,6,115,117,102,102,105,120,169,1,90,9, - 102,105,108,101,95,110,97,109,101,114,5,0,0,0,114,8, - 0,0,0,218,9,60,103,101,110,101,120,112,114,62,77,4, - 0,0,115,4,0,0,0,4,1,2,255,122,49,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,105,115,95,112,97,99,107,97,103,101,46,60,108,111,99, - 97,108,115,62,46,60,103,101,110,101,120,112,114,62,41,4, - 114,47,0,0,0,114,44,0,0,0,218,3,97,110,121,218, - 18,69,88,84,69,78,83,73,79,78,95,83,85,70,70,73, - 88,69,83,114,219,0,0,0,114,5,0,0,0,114,9,1, - 0,0,114,8,0,0,0,114,182,0,0,0,74,4,0,0, - 115,8,0,0,0,0,2,14,1,12,1,2,255,122,30,69, - 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,122,63,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,97,110,32,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,99,97,110,110,111,116,32,99,114,101, - 97,116,101,32,97,32,99,111,100,101,32,111,98,106,101,99, - 116,46,78,114,5,0,0,0,114,219,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,8,0,0,0,114,213,0,0, - 0,80,4,0,0,115,2,0,0,0,0,2,122,28,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,53, - 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,101, - 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,115, - 32,104,97,118,101,32,110,111,32,115,111,117,114,99,101,32, - 99,111,100,101,46,78,114,5,0,0,0,114,219,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 229,0,0,0,84,4,0,0,115,2,0,0,0,0,2,122, - 30,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99, + 90,6,101,7,135,0,102,1,100,8,100,9,132,8,131,1, + 90,8,101,7,100,10,100,11,132,0,131,1,90,9,100,12, + 100,13,132,0,90,10,101,7,100,14,100,15,132,0,131,1, + 90,11,135,0,4,0,90,12,83,0,41,16,218,10,70,105, + 108,101,76,111,97,100,101,114,122,103,66,97,115,101,32,102, + 105,108,101,32,108,111,97,100,101,114,32,99,108,97,115,115, + 32,119,104,105,99,104,32,105,109,112,108,101,109,101,110,116, + 115,32,116,104,101,32,108,111,97,100,101,114,32,112,114,111, + 116,111,99,111,108,32,109,101,116,104,111,100,115,32,116,104, + 97,116,10,32,32,32,32,114,101,113,117,105,114,101,32,102, + 105,108,101,32,115,121,115,116,101,109,32,117,115,97,103,101, + 46,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, + 1,124,0,95,0,124,2,124,0,95,1,100,1,83,0,41, + 2,122,75,67,97,99,104,101,32,116,104,101,32,109,111,100, + 117,108,101,32,110,97,109,101,32,97,110,100,32,116,104,101, + 32,112,97,116,104,32,116,111,32,116,104,101,32,102,105,108, + 101,32,102,111,117,110,100,32,98,121,32,116,104,101,10,32, + 32,32,32,32,32,32,32,102,105,110,100,101,114,46,78,114, + 159,0,0,0,41,3,114,118,0,0,0,114,139,0,0,0, + 114,44,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,209,0,0,0,178,3,0,0,115,4,0, + 0,0,0,3,6,1,122,19,70,105,108,101,76,111,97,100, + 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, + 67,0,0,0,115,24,0,0,0,124,0,106,0,124,1,106, + 0,107,2,111,22,124,0,106,1,124,1,106,1,107,2,83, + 0,114,109,0,0,0,169,2,218,9,95,95,99,108,97,115, + 115,95,95,114,131,0,0,0,169,2,114,118,0,0,0,90, + 5,111,116,104,101,114,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,6,95,95,101,113,95,95,184,3,0, + 0,115,6,0,0,0,0,1,12,1,10,255,122,17,70,105, + 108,101,76,111,97,100,101,114,46,95,95,101,113,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,20,0,0,0,116,0,124, + 0,106,1,131,1,116,0,124,0,106,2,131,1,65,0,83, + 0,114,109,0,0,0,169,3,218,4,104,97,115,104,114,116, + 0,0,0,114,44,0,0,0,169,1,114,118,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,8, + 95,95,104,97,115,104,95,95,188,3,0,0,115,2,0,0, + 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, + 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, + 0,115,16,0,0,0,116,0,116,1,124,0,131,2,160,2, + 124,1,161,1,83,0,41,1,122,100,76,111,97,100,32,97, + 32,109,111,100,117,108,101,32,102,114,111,109,32,97,32,102, + 105,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120, + 101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,41,3, + 218,5,115,117,112,101,114,114,239,0,0,0,114,220,0,0, + 0,114,219,0,0,0,169,1,114,241,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,220,0,0,0,191,3,0,0, + 115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,97, + 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, 1,0,0,0,67,0,0,0,115,6,0,0,0,124,0,106, - 0,83,0,114,250,0,0,0,114,48,0,0,0,114,219,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,179,0,0,0,88,4,0,0,115,2,0,0,0,0, - 3,122,32,69,120,116,101,110,115,105,111,110,70,105,108,101, + 0,83,0,169,1,122,58,82,101,116,117,114,110,32,116,104, + 101,32,112,97,116,104,32,116,111,32,116,104,101,32,115,111, + 117,114,99,101,32,102,105,108,101,32,97,115,32,102,111,117, + 110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,114, + 46,114,48,0,0,0,114,219,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,179,0,0,0,203, + 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, - 97,109,101,78,41,14,114,125,0,0,0,114,124,0,0,0, - 114,126,0,0,0,114,127,0,0,0,114,209,0,0,0,114, - 243,0,0,0,114,247,0,0,0,114,212,0,0,0,114,217, - 0,0,0,114,182,0,0,0,114,213,0,0,0,114,229,0, - 0,0,114,136,0,0,0,114,179,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,252,0,0,0,41,4,0,0,115,22,0,0,0,8,2, - 4,6,8,4,8,4,8,3,8,8,8,6,8,6,8,4, - 8,4,2,1,114,252,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,104,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, - 0,90,7,100,10,100,11,132,0,90,8,100,12,100,13,132, - 0,90,9,100,14,100,15,132,0,90,10,100,16,100,17,132, - 0,90,11,100,18,100,19,132,0,90,12,100,20,100,21,132, - 0,90,13,100,22,100,23,132,0,90,14,100,24,83,0,41, - 25,218,14,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,97,38,1,0,0,82,101,112,114,101,115,101,110,116,115, - 32,97,32,110,97,109,101,115,112,97,99,101,32,112,97,99, - 107,97,103,101,39,115,32,112,97,116,104,46,32,32,73,116, - 32,117,115,101,115,32,116,104,101,32,109,111,100,117,108,101, - 32,110,97,109,101,10,32,32,32,32,116,111,32,102,105,110, - 100,32,105,116,115,32,112,97,114,101,110,116,32,109,111,100, - 117,108,101,44,32,97,110,100,32,102,114,111,109,32,116,104, - 101,114,101,32,105,116,32,108,111,111,107,115,32,117,112,32, - 116,104,101,32,112,97,114,101,110,116,39,115,10,32,32,32, - 32,95,95,112,97,116,104,95,95,46,32,32,87,104,101,110, - 32,116,104,105,115,32,99,104,97,110,103,101,115,44,32,116, - 104,101,32,109,111,100,117,108,101,39,115,32,111,119,110,32, - 112,97,116,104,32,105,115,32,114,101,99,111,109,112,117,116, - 101,100,44,10,32,32,32,32,117,115,105,110,103,32,112,97, - 116,104,95,102,105,110,100,101,114,46,32,32,70,111,114,32, - 116,111,112,45,108,101,118,101,108,32,109,111,100,117,108,101, - 115,44,32,116,104,101,32,112,97,114,101,110,116,32,109,111, - 100,117,108,101,39,115,32,112,97,116,104,10,32,32,32,32, - 105,115,32,115,121,115,46,112,97,116,104,46,99,4,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, - 0,67,0,0,0,115,36,0,0,0,124,1,124,0,95,0, - 124,2,124,0,95,1,116,2,124,0,160,3,161,0,131,1, - 124,0,95,4,124,3,124,0,95,5,100,0,83,0,114,109, - 0,0,0,41,6,218,5,95,110,97,109,101,218,5,95,112, - 97,116,104,114,111,0,0,0,218,16,95,103,101,116,95,112, - 97,114,101,110,116,95,112,97,116,104,218,17,95,108,97,115, - 116,95,112,97,114,101,110,116,95,112,97,116,104,218,12,95, - 112,97,116,104,95,102,105,110,100,101,114,169,4,114,118,0, - 0,0,114,116,0,0,0,114,44,0,0,0,90,11,112,97, - 116,104,95,102,105,110,100,101,114,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,209,0,0,0,101,4,0, - 0,115,8,0,0,0,0,1,6,1,6,1,14,1,122,23, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0, - 115,38,0,0,0,124,0,106,0,160,1,100,1,161,1,92, - 3,125,1,125,2,125,3,124,2,100,2,107,2,114,30,100, - 3,83,0,124,1,100,4,102,2,83,0,41,5,122,62,82, - 101,116,117,114,110,115,32,97,32,116,117,112,108,101,32,111, - 102,32,40,112,97,114,101,110,116,45,109,111,100,117,108,101, - 45,110,97,109,101,44,32,112,97,114,101,110,116,45,112,97, - 116,104,45,97,116,116,114,45,110,97,109,101,41,114,71,0, - 0,0,114,40,0,0,0,41,2,114,1,0,0,0,114,44, - 0,0,0,90,8,95,95,112,97,116,104,95,95,41,2,114, - 14,1,0,0,114,41,0,0,0,41,4,114,118,0,0,0, - 114,4,1,0,0,218,3,100,111,116,90,2,109,101,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,23,95, - 102,105,110,100,95,112,97,114,101,110,116,95,112,97,116,104, - 95,110,97,109,101,115,107,4,0,0,115,8,0,0,0,0, - 2,18,1,8,2,4,3,122,38,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,102,105,110,100,95,112,97, - 114,101,110,116,95,112,97,116,104,95,110,97,109,101,115,99, - 1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,28,0,0,0,124,0,160, - 0,161,0,92,2,125,1,125,2,116,1,116,2,106,3,124, - 1,25,0,124,2,131,2,83,0,114,109,0,0,0,41,4, - 114,21,1,0,0,114,130,0,0,0,114,1,0,0,0,218, - 7,109,111,100,117,108,101,115,41,3,114,118,0,0,0,90, - 18,112,97,114,101,110,116,95,109,111,100,117,108,101,95,110, - 97,109,101,90,14,112,97,116,104,95,97,116,116,114,95,110, - 97,109,101,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,16,1,0,0,117,4,0,0,115,4,0,0,0, - 0,1,12,1,122,31,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,103,101,116,95,112,97,114,101,110,116, - 95,112,97,116,104,99,1,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,80, - 0,0,0,116,0,124,0,160,1,161,0,131,1,125,1,124, - 1,124,0,106,2,107,3,114,74,124,0,160,3,124,0,106, - 4,124,1,161,2,125,2,124,2,100,0,117,1,114,68,124, - 2,106,5,100,0,117,0,114,68,124,2,106,6,114,68,124, - 2,106,6,124,0,95,7,124,1,124,0,95,2,124,0,106, - 7,83,0,114,109,0,0,0,41,8,114,111,0,0,0,114, - 16,1,0,0,114,17,1,0,0,114,18,1,0,0,114,14, - 1,0,0,114,140,0,0,0,114,178,0,0,0,114,15,1, - 0,0,41,3,114,118,0,0,0,90,11,112,97,114,101,110, - 116,95,112,97,116,104,114,187,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,218,12,95,114,101,99, - 97,108,99,117,108,97,116,101,121,4,0,0,115,16,0,0, - 0,0,2,12,1,10,1,14,3,18,1,6,1,8,1,6, - 1,122,27,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,114,101,99,97,108,99,117,108,97,116,101,99,1, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,12,0,0,0,116,0,124,0, - 160,1,161,0,131,1,83,0,114,109,0,0,0,41,2,218, - 4,105,116,101,114,114,23,1,0,0,114,246,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,8, - 95,95,105,116,101,114,95,95,134,4,0,0,115,2,0,0, - 0,0,1,122,23,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,95,105,116,101,114,95,95,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, - 0,67,0,0,0,115,12,0,0,0,124,0,160,0,161,0, - 124,1,25,0,83,0,114,109,0,0,0,169,1,114,23,1, - 0,0,41,2,114,118,0,0,0,218,5,105,110,100,101,120, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 11,95,95,103,101,116,105,116,101,109,95,95,137,4,0,0, - 115,2,0,0,0,0,1,122,26,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,95,103,101,116,105,116,101, - 109,95,95,99,3,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,14,0,0, - 0,124,2,124,0,106,0,124,1,60,0,100,0,83,0,114, - 109,0,0,0,41,1,114,15,1,0,0,41,3,114,118,0, - 0,0,114,27,1,0,0,114,44,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,11,95,95,115, - 101,116,105,116,101,109,95,95,140,4,0,0,115,2,0,0, - 0,0,1,122,26,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,95,115,101,116,105,116,101,109,95,95,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,12,0,0,0,116,0,124, - 0,160,1,161,0,131,1,83,0,114,109,0,0,0,41,2, - 114,23,0,0,0,114,23,1,0,0,114,246,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,7, - 95,95,108,101,110,95,95,143,4,0,0,115,2,0,0,0, - 0,1,122,22,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,95,108,101,110,95,95,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,12,0,0,0,100,1,160,0,124,0,106,1, - 161,1,83,0,41,2,78,122,20,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,40,123,33,114,125,41,41,2,114, - 62,0,0,0,114,15,1,0,0,114,246,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,8,95, - 95,114,101,112,114,95,95,146,4,0,0,115,2,0,0,0, - 0,1,122,23,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,95,114,101,112,114,95,95,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,12,0,0,0,124,1,124,0,160,0,161, - 0,118,0,83,0,114,109,0,0,0,114,26,1,0,0,169, - 2,114,118,0,0,0,218,4,105,116,101,109,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,12,95,95,99, - 111,110,116,97,105,110,115,95,95,149,4,0,0,115,2,0, - 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,95,99,111,110,116,97,105,110,115,95, - 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,124, - 0,106,0,160,1,124,1,161,1,1,0,100,0,83,0,114, - 109,0,0,0,41,2,114,15,1,0,0,114,186,0,0,0, - 114,32,1,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,186,0,0,0,152,4,0,0,115,2,0, - 0,0,0,1,122,21,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,97,112,112,101,110,100,78,41,15,114,125, - 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, - 0,0,114,209,0,0,0,114,21,1,0,0,114,16,1,0, - 0,114,23,1,0,0,114,25,1,0,0,114,28,1,0,0, - 114,29,1,0,0,114,30,1,0,0,114,31,1,0,0,114, - 34,1,0,0,114,186,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,13,1, - 0,0,94,4,0,0,115,24,0,0,0,8,1,4,6,8, - 6,8,10,8,4,8,13,8,3,8,3,8,3,8,3,8, - 3,8,3,114,13,1,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,80,0,0,0,101,0,90,1,100,0,90,2,100,1, - 100,2,132,0,90,3,101,4,100,3,100,4,132,0,131,1, - 90,5,100,5,100,6,132,0,90,6,100,7,100,8,132,0, - 90,7,100,9,100,10,132,0,90,8,100,11,100,12,132,0, - 90,9,100,13,100,14,132,0,90,10,100,15,100,16,132,0, - 90,11,100,17,83,0,41,18,218,16,95,78,97,109,101,115, - 112,97,99,101,76,111,97,100,101,114,99,4,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, - 0,0,0,115,18,0,0,0,116,0,124,1,124,2,124,3, - 131,3,124,0,95,1,100,0,83,0,114,109,0,0,0,41, - 2,114,13,1,0,0,114,15,1,0,0,114,19,1,0,0, + 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,8,0,0,0,67,0,0,0,115,126,0,0, + 0,116,0,124,0,116,1,116,2,102,2,131,2,114,70,116, + 3,160,4,116,5,124,1,131,1,161,1,143,24,125,2,124, + 2,160,6,161,0,87,0,2,0,100,1,4,0,4,0,131, + 3,1,0,83,0,49,0,115,58,48,0,1,0,1,0,1, + 0,89,0,1,0,110,52,116,3,160,7,124,1,100,2,161, + 2,143,24,125,2,124,2,160,6,161,0,87,0,2,0,100, + 1,4,0,4,0,131,3,1,0,83,0,49,0,115,112,48, + 0,1,0,1,0,1,0,89,0,1,0,100,1,83,0,41, + 3,122,39,82,101,116,117,114,110,32,116,104,101,32,100,97, + 116,97,32,102,114,111,109,32,112,97,116,104,32,97,115,32, + 114,97,119,32,98,121,116,101,115,46,78,218,1,114,41,8, + 114,161,0,0,0,114,221,0,0,0,218,19,69,120,116,101, + 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,114, + 64,0,0,0,90,9,111,112,101,110,95,99,111,100,101,114, + 84,0,0,0,90,4,114,101,97,100,114,65,0,0,0,41, + 3,114,118,0,0,0,114,44,0,0,0,114,68,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 209,0,0,0,158,4,0,0,115,2,0,0,0,0,1,122, - 25,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,12,0,0,0,100,1,160,0,124,1,106,1, - 161,1,83,0,41,2,122,115,82,101,116,117,114,110,32,114, - 101,112,114,32,102,111,114,32,116,104,101,32,109,111,100,117, - 108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,101, - 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, - 99,97,116,101,100,46,32,32,84,104,101,32,105,109,112,111, - 114,116,32,109,97,99,104,105,110,101,114,121,32,100,111,101, - 115,32,116,104,101,32,106,111,98,32,105,116,115,101,108,102, - 46,10,10,32,32,32,32,32,32,32,32,122,25,60,109,111, - 100,117,108,101,32,123,33,114,125,32,40,110,97,109,101,115, - 112,97,99,101,41,62,41,2,114,62,0,0,0,114,125,0, - 0,0,41,2,114,193,0,0,0,114,216,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,11,109, - 111,100,117,108,101,95,114,101,112,114,161,4,0,0,115,2, - 0,0,0,0,7,122,28,95,78,97,109,101,115,112,97,99, - 101,76,111,97,100,101,114,46,109,111,100,117,108,101,95,114, - 101,112,114,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,83,0,41,2,78,84,114,5,0,0,0,114,219, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,182,0,0,0,170,4,0,0,115,2,0,0,0, - 0,1,122,27,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,78,114,40,0,0,0,114,5,0,0,0,114,219, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,229,0,0,0,173,4,0,0,115,2,0,0,0, - 0,1,122,27,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 6,0,0,0,67,0,0,0,115,16,0,0,0,116,0,100, - 1,100,2,100,3,100,4,100,5,141,4,83,0,41,6,78, - 114,40,0,0,0,122,8,60,115,116,114,105,110,103,62,114, - 215,0,0,0,84,41,1,114,231,0,0,0,41,1,114,232, + 227,0,0,0,208,3,0,0,115,10,0,0,0,0,2,14, + 1,16,1,40,2,14,1,122,19,70,105,108,101,76,111,97, + 100,101,114,46,103,101,116,95,100,97,116,97,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0, + 0,67,0,0,0,115,20,0,0,0,100,1,100,2,108,0, + 109,1,125,2,1,0,124,2,124,0,131,1,83,0,41,3, + 78,114,73,0,0,0,41,1,218,10,70,105,108,101,82,101, + 97,100,101,114,41,2,90,17,105,109,112,111,114,116,108,105, + 98,46,114,101,97,100,101,114,115,114,253,0,0,0,41,3, + 114,118,0,0,0,114,216,0,0,0,114,253,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,19, + 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, + 100,101,114,217,3,0,0,115,4,0,0,0,0,2,12,1, + 122,30,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, + 41,13,114,125,0,0,0,114,124,0,0,0,114,126,0,0, + 0,114,127,0,0,0,114,209,0,0,0,114,243,0,0,0, + 114,247,0,0,0,114,136,0,0,0,114,220,0,0,0,114, + 179,0,0,0,114,227,0,0,0,114,254,0,0,0,90,13, + 95,95,99,108,97,115,115,99,101,108,108,95,95,114,5,0, + 0,0,114,5,0,0,0,114,249,0,0,0,114,8,0,0, + 0,114,239,0,0,0,173,3,0,0,115,22,0,0,0,8, + 2,4,3,8,6,8,4,8,3,2,1,14,11,2,1,10, + 4,8,9,2,1,114,239,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, + 0,0,0,115,46,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,100,6,100,7,156,1,100,8,100,9,132,2, + 90,6,100,10,83,0,41,11,218,16,83,111,117,114,99,101, + 70,105,108,101,76,111,97,100,101,114,122,62,67,111,110,99, + 114,101,116,101,32,105,109,112,108,101,109,101,110,116,97,116, + 105,111,110,32,111,102,32,83,111,117,114,99,101,76,111,97, + 100,101,114,32,117,115,105,110,103,32,116,104,101,32,102,105, + 108,101,32,115,121,115,116,101,109,46,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,22,0,0,0,116,0,124,1,131,1,125,2, + 124,2,106,1,124,2,106,2,100,1,156,2,83,0,41,2, + 122,33,82,101,116,117,114,110,32,116,104,101,32,109,101,116, + 97,100,97,116,97,32,102,111,114,32,116,104,101,32,112,97, + 116,104,46,41,2,114,169,0,0,0,114,234,0,0,0,41, + 3,114,49,0,0,0,218,8,115,116,95,109,116,105,109,101, + 90,7,115,116,95,115,105,122,101,41,3,114,118,0,0,0, + 114,44,0,0,0,114,238,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,224,0,0,0,227,3, + 0,0,115,4,0,0,0,0,2,8,1,122,27,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,46,112,97, + 116,104,95,115,116,97,116,115,99,4,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,5,0,0,0,67,0,0, + 0,115,24,0,0,0,116,0,124,1,131,1,125,4,124,0, + 106,1,124,2,124,3,124,4,100,1,141,3,83,0,41,2, + 78,169,1,218,5,95,109,111,100,101,41,2,114,114,0,0, + 0,114,225,0,0,0,41,5,114,118,0,0,0,114,107,0, + 0,0,114,106,0,0,0,114,26,0,0,0,114,52,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 114,226,0,0,0,232,3,0,0,115,4,0,0,0,0,2, + 8,1,122,32,83,111,117,114,99,101,70,105,108,101,76,111, + 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, + 99,111,100,101,114,60,0,0,0,114,1,1,0,0,99,3, + 0,0,0,0,0,0,0,1,0,0,0,9,0,0,0,11, + 0,0,0,67,0,0,0,115,248,0,0,0,116,0,124,1, + 131,1,92,2,125,4,125,5,103,0,125,6,124,4,114,52, + 116,1,124,4,131,1,115,52,116,0,124,4,131,1,92,2, + 125,4,125,7,124,6,160,2,124,7,161,1,1,0,113,16, + 116,3,124,6,131,1,68,0,93,102,125,7,116,4,124,4, + 124,7,131,2,125,4,122,14,116,5,160,6,124,4,161,1, + 1,0,87,0,113,60,4,0,116,7,121,110,1,0,1,0, + 1,0,89,0,113,60,89,0,113,60,4,0,116,8,121,162, + 1,0,125,8,1,0,122,30,116,9,160,10,100,1,124,4, + 124,8,161,3,1,0,87,0,89,0,100,2,125,8,126,8, + 1,0,100,2,83,0,100,2,125,8,126,8,48,0,48,0, + 122,28,116,11,124,1,124,2,124,3,131,3,1,0,116,9, + 160,10,100,3,124,1,161,2,1,0,87,0,110,50,4,0, + 116,8,121,242,1,0,125,8,1,0,122,26,116,9,160,10, + 100,1,124,1,124,8,161,3,1,0,87,0,89,0,100,2, + 125,8,126,8,110,10,100,2,125,8,126,8,48,0,48,0, + 100,2,83,0,41,4,122,27,87,114,105,116,101,32,98,121, + 116,101,115,32,100,97,116,97,32,116,111,32,97,32,102,105, + 108,101,46,122,27,99,111,117,108,100,32,110,111,116,32,99, + 114,101,97,116,101,32,123,33,114,125,58,32,123,33,114,125, + 78,122,12,99,114,101,97,116,101,100,32,123,33,114,125,41, + 12,114,47,0,0,0,114,56,0,0,0,114,186,0,0,0, + 114,42,0,0,0,114,38,0,0,0,114,4,0,0,0,90, + 5,109,107,100,105,114,218,15,70,105,108,101,69,120,105,115, + 116,115,69,114,114,111,114,114,50,0,0,0,114,134,0,0, + 0,114,149,0,0,0,114,69,0,0,0,41,9,114,118,0, + 0,0,114,44,0,0,0,114,26,0,0,0,114,2,1,0, + 0,218,6,112,97,114,101,110,116,114,96,0,0,0,114,37, + 0,0,0,114,33,0,0,0,114,228,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,114,225,0,0, + 0,237,3,0,0,115,46,0,0,0,0,2,12,1,4,2, + 12,1,12,1,12,2,12,1,10,1,2,1,14,1,12,2, + 8,1,14,3,6,1,4,255,4,2,26,1,2,1,12,1, + 16,1,14,2,8,1,2,255,122,25,83,111,117,114,99,101, + 70,105,108,101,76,111,97,100,101,114,46,115,101,116,95,100, + 97,116,97,78,41,7,114,125,0,0,0,114,124,0,0,0, + 114,126,0,0,0,114,127,0,0,0,114,224,0,0,0,114, + 226,0,0,0,114,225,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,255,0, + 0,0,223,3,0,0,115,8,0,0,0,8,2,4,2,8, + 5,8,5,114,255,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, + 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, + 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, + 90,5,100,6,83,0,41,7,218,20,83,111,117,114,99,101, + 108,101,115,115,70,105,108,101,76,111,97,100,101,114,122,45, + 76,111,97,100,101,114,32,119,104,105,99,104,32,104,97,110, + 100,108,101,115,32,115,111,117,114,99,101,108,101,115,115,32, + 102,105,108,101,32,105,109,112,111,114,116,115,46,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0, + 0,0,67,0,0,0,115,68,0,0,0,124,0,160,0,124, + 1,161,1,125,2,124,0,160,1,124,2,161,1,125,3,124, + 1,124,2,100,1,156,2,125,4,116,2,124,3,124,1,124, + 4,131,3,1,0,116,3,116,4,124,3,131,1,100,2,100, + 0,133,2,25,0,124,1,124,2,100,3,141,3,83,0,41, + 4,78,114,159,0,0,0,114,145,0,0,0,41,2,114,116, + 0,0,0,114,106,0,0,0,41,5,114,179,0,0,0,114, + 227,0,0,0,114,152,0,0,0,114,165,0,0,0,114,235, + 0,0,0,41,5,114,118,0,0,0,114,139,0,0,0,114, + 44,0,0,0,114,26,0,0,0,114,151,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,213,0, + 0,0,16,4,0,0,115,22,0,0,0,0,1,10,1,10, + 4,2,1,2,254,6,4,12,1,2,1,14,1,2,1,2, + 253,122,29,83,111,117,114,99,101,108,101,115,115,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,122,39,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,116,104,101,114,101,32,105,115,32,110,111, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,5, 0,0,0,114,219,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,213,0,0,0,176,4,0,0, - 115,2,0,0,0,0,1,122,25,95,78,97,109,101,115,112, - 97,99,101,76,111,97,100,101,114,46,103,101,116,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,1,83,0,114,210,0,0,0,114,5,0,0,0,114,211, + 0,0,114,8,0,0,0,114,229,0,0,0,32,4,0,0, + 115,2,0,0,0,0,2,122,31,83,111,117,114,99,101,108, + 101,115,115,70,105,108,101,76,111,97,100,101,114,46,103,101, + 116,95,115,111,117,114,99,101,78,41,6,114,125,0,0,0, + 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, + 213,0,0,0,114,229,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,5,1, + 0,0,12,4,0,0,115,6,0,0,0,8,2,4,2,8, + 16,114,5,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, + 92,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, + 100,6,100,7,132,0,90,6,100,8,100,9,132,0,90,7, + 100,10,100,11,132,0,90,8,100,12,100,13,132,0,90,9, + 100,14,100,15,132,0,90,10,100,16,100,17,132,0,90,11, + 101,12,100,18,100,19,132,0,131,1,90,13,100,20,83,0, + 41,21,114,252,0,0,0,122,93,76,111,97,100,101,114,32, + 102,111,114,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,115,46,10,10,32,32,32,32,84,104,101,32, + 99,111,110,115,116,114,117,99,116,111,114,32,105,115,32,100, + 101,115,105,103,110,101,100,32,116,111,32,119,111,114,107,32, + 119,105,116,104,32,70,105,108,101,70,105,110,100,101,114,46, + 10,10,32,32,32,32,99,3,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115, + 16,0,0,0,124,1,124,0,95,0,124,2,124,0,95,1, + 100,0,83,0,114,109,0,0,0,114,159,0,0,0,41,3, + 114,118,0,0,0,114,116,0,0,0,114,44,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,209, + 0,0,0,49,4,0,0,115,4,0,0,0,0,1,6,1, + 122,28,69,120,116,101,110,115,105,111,110,70,105,108,101,76, + 111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, + 0,0,0,67,0,0,0,115,24,0,0,0,124,0,106,0, + 124,1,106,0,107,2,111,22,124,0,106,1,124,1,106,1, + 107,2,83,0,114,109,0,0,0,114,240,0,0,0,114,242, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,212,0,0,0,179,4,0,0,115,2,0,0,0, - 0,1,122,30,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, + 0,0,114,243,0,0,0,53,4,0,0,115,6,0,0,0, + 0,1,12,1,10,255,122,26,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,95,95,101,113, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,20,0,0,0, + 116,0,124,0,106,1,131,1,116,0,124,0,106,2,131,1, + 65,0,83,0,114,109,0,0,0,114,244,0,0,0,114,246, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,114,247,0,0,0,57,4,0,0,115,2,0,0,0, + 0,1,122,28,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,95,95,104,97,115,104,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,5,0,0,0,67,0,0,0,115,36,0,0,0,116,0, + 160,1,116,2,106,3,124,1,161,2,125,2,116,0,160,4, + 100,1,124,1,106,5,124,0,106,6,161,3,1,0,124,2, + 83,0,41,2,122,38,67,114,101,97,116,101,32,97,110,32, + 117,110,105,116,105,97,108,105,122,101,100,32,101,120,116,101, + 110,115,105,111,110,32,109,111,100,117,108,101,122,38,101,120, + 116,101,110,115,105,111,110,32,109,111,100,117,108,101,32,123, + 33,114,125,32,108,111,97,100,101,100,32,102,114,111,109,32, + 123,33,114,125,41,7,114,134,0,0,0,114,214,0,0,0, + 114,163,0,0,0,90,14,99,114,101,97,116,101,95,100,121, + 110,97,109,105,99,114,149,0,0,0,114,116,0,0,0,114, + 44,0,0,0,41,3,114,118,0,0,0,114,187,0,0,0, + 114,216,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,212,0,0,0,60,4,0,0,115,14,0, + 0,0,0,2,4,1,6,255,4,2,6,1,8,255,4,2, + 122,33,69,120,116,101,110,115,105,111,110,70,105,108,101,76, + 111,97,100,101,114,46,99,114,101,97,116,101,95,109,111,100, + 117,108,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,5,0,0,0,67,0,0,0,115,36,0,0, + 0,116,0,160,1,116,2,106,3,124,1,161,2,1,0,116, + 0,160,4,100,1,124,0,106,5,124,0,106,6,161,3,1, + 0,100,2,83,0,41,3,122,30,73,110,105,116,105,97,108, + 105,122,101,32,97,110,32,101,120,116,101,110,115,105,111,110, + 32,109,111,100,117,108,101,122,40,101,120,116,101,110,115,105, + 111,110,32,109,111,100,117,108,101,32,123,33,114,125,32,101, + 120,101,99,117,116,101,100,32,102,114,111,109,32,123,33,114, + 125,78,41,7,114,134,0,0,0,114,214,0,0,0,114,163, + 0,0,0,90,12,101,120,101,99,95,100,121,110,97,109,105, + 99,114,149,0,0,0,114,116,0,0,0,114,44,0,0,0, + 169,2,114,118,0,0,0,114,216,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,114,217,0,0,0, + 68,4,0,0,115,8,0,0,0,0,2,14,1,6,1,8, + 255,122,31,69,120,116,101,110,115,105,111,110,70,105,108,101, + 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117, 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,0,83,0,114,109,0,0,0,114,5,0,0,0,114,6, - 1,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,217,0,0,0,182,4,0,0,115,2,0,0,0, - 0,1,122,28,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,101,120,101,99,95,109,111,100,117,108,101, + 0,0,0,4,0,0,0,3,0,0,0,115,36,0,0,0, + 116,0,124,0,106,1,131,1,100,1,25,0,137,0,116,2, + 135,0,102,1,100,2,100,3,132,8,116,3,68,0,131,1, + 131,1,83,0,41,4,122,49,82,101,116,117,114,110,32,84, + 114,117,101,32,105,102,32,116,104,101,32,101,120,116,101,110, + 115,105,111,110,32,109,111,100,117,108,101,32,105,115,32,97, + 32,112,97,99,107,97,103,101,46,114,39,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,51,0,0,0,115,26,0,0,0,124,0,93,18, + 125,1,136,0,100,0,124,1,23,0,107,2,86,0,1,0, + 113,2,100,1,83,0,41,2,114,209,0,0,0,78,114,5, + 0,0,0,169,2,114,32,0,0,0,218,6,115,117,102,102, + 105,120,169,1,90,9,102,105,108,101,95,110,97,109,101,114, + 5,0,0,0,114,8,0,0,0,218,9,60,103,101,110,101, + 120,112,114,62,77,4,0,0,115,4,0,0,0,4,1,2, + 255,122,49,69,120,116,101,110,115,105,111,110,70,105,108,101, + 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, + 101,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, + 120,112,114,62,41,4,114,47,0,0,0,114,44,0,0,0, + 218,3,97,110,121,218,18,69,88,84,69,78,83,73,79,78, + 95,83,85,70,70,73,88,69,83,114,219,0,0,0,114,5, + 0,0,0,114,9,1,0,0,114,8,0,0,0,114,182,0, + 0,0,74,4,0,0,115,8,0,0,0,0,2,14,1,12, + 1,2,255,122,30,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, + 97,103,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,83,0,41,2,122,63,82,101,116,117,114,110,32, + 78,111,110,101,32,97,115,32,97,110,32,101,120,116,101,110, + 115,105,111,110,32,109,111,100,117,108,101,32,99,97,110,110, + 111,116,32,99,114,101,97,116,101,32,97,32,99,111,100,101, + 32,111,98,106,101,99,116,46,78,114,5,0,0,0,114,219, + 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,114,213,0,0,0,80,4,0,0,115,2,0,0,0, + 0,2,122,28,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,4,0,0,0,67,0,0,0,115,26,0,0,0,116,0, - 160,1,100,1,124,0,106,2,161,2,1,0,116,0,160,3, - 124,0,124,1,161,2,83,0,41,2,122,98,76,111,97,100, - 32,97,32,110,97,109,101,115,112,97,99,101,32,109,111,100, - 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120, - 101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116, - 101,97,100,46,10,10,32,32,32,32,32,32,32,32,122,38, - 110,97,109,101,115,112,97,99,101,32,109,111,100,117,108,101, - 32,108,111,97,100,101,100,32,119,105,116,104,32,112,97,116, - 104,32,123,33,114,125,41,4,114,134,0,0,0,114,149,0, - 0,0,114,15,1,0,0,114,218,0,0,0,114,219,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,220,0,0,0,185,4,0,0,115,8,0,0,0,0,7, - 6,1,4,255,4,2,122,28,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, - 100,117,108,101,78,41,12,114,125,0,0,0,114,124,0,0, - 0,114,126,0,0,0,114,209,0,0,0,114,207,0,0,0, - 114,36,1,0,0,114,182,0,0,0,114,229,0,0,0,114, - 213,0,0,0,114,212,0,0,0,114,217,0,0,0,114,220, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,35,1,0,0,157,4,0,0, - 115,18,0,0,0,8,1,8,3,2,1,10,8,8,3,8, - 3,8,3,8,3,8,3,114,35,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,118,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,101,4,100,2,100,3,132,0,131,1, - 90,5,101,4,100,4,100,5,132,0,131,1,90,6,101,4, - 100,6,100,7,132,0,131,1,90,7,101,4,100,8,100,9, - 132,0,131,1,90,8,101,4,100,19,100,11,100,12,132,1, - 131,1,90,9,101,4,100,20,100,13,100,14,132,1,131,1, - 90,10,101,4,100,21,100,15,100,16,132,1,131,1,90,11, - 101,4,100,17,100,18,132,0,131,1,90,12,100,10,83,0, - 41,22,218,10,80,97,116,104,70,105,110,100,101,114,122,62, - 77,101,116,97,32,112,97,116,104,32,102,105,110,100,101,114, - 32,102,111,114,32,115,121,115,46,112,97,116,104,32,97,110, - 100,32,112,97,99,107,97,103,101,32,95,95,112,97,116,104, - 95,95,32,97,116,116,114,105,98,117,116,101,115,46,99,1, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, - 0,0,0,67,0,0,0,115,64,0,0,0,116,0,116,1, - 106,2,160,3,161,0,131,1,68,0,93,44,92,2,125,1, - 125,2,124,2,100,1,117,0,114,40,116,1,106,2,124,1, - 61,0,113,14,116,4,124,2,100,2,131,2,114,14,124,2, - 160,5,161,0,1,0,113,14,100,1,83,0,41,3,122,125, - 67,97,108,108,32,116,104,101,32,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,40,41,32,109,101,116, - 104,111,100,32,111,110,32,97,108,108,32,112,97,116,104,32, - 101,110,116,114,121,32,102,105,110,100,101,114,115,10,32,32, - 32,32,32,32,32,32,115,116,111,114,101,100,32,105,110,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,115,32,40,119,104,101,114,101,32, - 105,109,112,108,101,109,101,110,116,101,100,41,46,78,218,17, - 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, - 115,41,6,218,4,108,105,115,116,114,1,0,0,0,218,19, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,218,5,105,116,101,109,115,114,128,0,0,0,114, - 38,1,0,0,41,3,114,193,0,0,0,114,116,0,0,0, - 218,6,102,105,110,100,101,114,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,38,1,0,0,203,4,0,0, - 115,10,0,0,0,0,4,22,1,8,1,10,1,10,1,122, - 28,80,97,116,104,70,105,110,100,101,114,46,105,110,118,97, - 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,9,0, - 0,0,67,0,0,0,115,82,0,0,0,116,0,106,1,100, - 1,117,1,114,28,116,0,106,1,115,28,116,2,160,3,100, - 2,116,4,161,2,1,0,116,0,106,1,68,0,93,42,125, - 2,122,14,124,2,124,1,131,1,87,0,2,0,1,0,83, - 0,4,0,116,5,121,74,1,0,1,0,1,0,89,0,113, - 34,89,0,113,34,48,0,113,34,100,1,83,0,41,3,122, - 46,83,101,97,114,99,104,32,115,121,115,46,112,97,116,104, - 95,104,111,111,107,115,32,102,111,114,32,97,32,102,105,110, - 100,101,114,32,102,111,114,32,39,112,97,116,104,39,46,78, - 122,23,115,121,115,46,112,97,116,104,95,104,111,111,107,115, - 32,105,115,32,101,109,112,116,121,41,6,114,1,0,0,0, - 218,10,112,97,116,104,95,104,111,111,107,115,114,75,0,0, - 0,114,76,0,0,0,114,138,0,0,0,114,117,0,0,0, - 41,3,114,193,0,0,0,114,44,0,0,0,90,4,104,111, - 111,107,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,11,95,112,97,116,104,95,104,111,111,107,115,213,4, - 0,0,115,16,0,0,0,0,3,16,1,12,1,10,1,2, - 1,14,1,12,1,12,2,122,22,80,97,116,104,70,105,110, - 100,101,114,46,95,112,97,116,104,95,104,111,111,107,115,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 8,0,0,0,67,0,0,0,115,100,0,0,0,124,1,100, - 1,107,2,114,42,122,12,116,0,160,1,161,0,125,1,87, - 0,110,20,4,0,116,2,121,40,1,0,1,0,1,0,89, - 0,100,2,83,0,48,0,122,14,116,3,106,4,124,1,25, - 0,125,2,87,0,110,38,4,0,116,5,121,94,1,0,1, - 0,1,0,124,0,160,6,124,1,161,1,125,2,124,2,116, - 3,106,4,124,1,60,0,89,0,110,2,48,0,124,2,83, - 0,41,3,122,210,71,101,116,32,116,104,101,32,102,105,110, - 100,101,114,32,102,111,114,32,116,104,101,32,112,97,116,104, - 32,101,110,116,114,121,32,102,114,111,109,32,115,121,115,46, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,46,10,10,32,32,32,32,32,32,32,32,73,102, - 32,116,104,101,32,112,97,116,104,32,101,110,116,114,121,32, - 105,115,32,110,111,116,32,105,110,32,116,104,101,32,99,97, - 99,104,101,44,32,102,105,110,100,32,116,104,101,32,97,112, - 112,114,111,112,114,105,97,116,101,32,102,105,110,100,101,114, - 10,32,32,32,32,32,32,32,32,97,110,100,32,99,97,99, - 104,101,32,105,116,46,32,73,102,32,110,111,32,102,105,110, - 100,101,114,32,105,115,32,97,118,97,105,108,97,98,108,101, - 44,32,115,116,111,114,101,32,78,111,110,101,46,10,10,32, - 32,32,32,32,32,32,32,114,40,0,0,0,78,41,7,114, - 4,0,0,0,114,55,0,0,0,218,17,70,105,108,101,78, - 111,116,70,111,117,110,100,69,114,114,111,114,114,1,0,0, - 0,114,40,1,0,0,218,8,75,101,121,69,114,114,111,114, - 114,44,1,0,0,41,3,114,193,0,0,0,114,44,0,0, - 0,114,42,1,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,20,95,112,97,116,104,95,105,109,112, - 111,114,116,101,114,95,99,97,99,104,101,226,4,0,0,115, - 22,0,0,0,0,8,8,1,2,1,12,1,12,3,8,1, - 2,1,14,1,12,1,10,1,16,1,122,31,80,97,116,104, - 70,105,110,100,101,114,46,95,112,97,116,104,95,105,109,112, - 111,114,116,101,114,95,99,97,99,104,101,99,3,0,0,0, - 0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0, - 67,0,0,0,115,82,0,0,0,116,0,124,2,100,1,131, - 2,114,26,124,2,160,1,124,1,161,1,92,2,125,3,125, - 4,110,14,124,2,160,2,124,1,161,1,125,3,103,0,125, - 4,124,3,100,0,117,1,114,60,116,3,160,4,124,1,124, - 3,161,2,83,0,116,3,160,5,124,1,100,0,161,2,125, - 5,124,4,124,5,95,6,124,5,83,0,41,2,78,114,137, - 0,0,0,41,7,114,128,0,0,0,114,137,0,0,0,114, - 206,0,0,0,114,134,0,0,0,114,201,0,0,0,114,183, - 0,0,0,114,178,0,0,0,41,6,114,193,0,0,0,114, - 139,0,0,0,114,42,1,0,0,114,140,0,0,0,114,141, - 0,0,0,114,187,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,218,16,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,248,4,0,0,115,18,0, - 0,0,0,4,10,1,16,2,10,1,4,1,8,1,12,1, - 12,1,6,1,122,27,80,97,116,104,70,105,110,100,101,114, - 46,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, - 99,78,99,4,0,0,0,0,0,0,0,0,0,0,0,9, - 0,0,0,5,0,0,0,67,0,0,0,115,166,0,0,0, - 103,0,125,4,124,2,68,0,93,134,125,5,116,0,124,5, - 116,1,116,2,102,2,131,2,115,28,113,8,124,0,160,3, - 124,5,161,1,125,6,124,6,100,1,117,1,114,8,116,4, - 124,6,100,2,131,2,114,70,124,6,160,5,124,1,124,3, - 161,2,125,7,110,12,124,0,160,6,124,1,124,6,161,2, - 125,7,124,7,100,1,117,0,114,92,113,8,124,7,106,7, - 100,1,117,1,114,110,124,7,2,0,1,0,83,0,124,7, - 106,8,125,8,124,8,100,1,117,0,114,132,116,9,100,3, - 131,1,130,1,124,4,160,10,124,8,161,1,1,0,113,8, - 116,11,160,12,124,1,100,1,161,2,125,7,124,4,124,7, - 95,8,124,7,83,0,41,4,122,63,70,105,110,100,32,116, - 104,101,32,108,111,97,100,101,114,32,111,114,32,110,97,109, - 101,115,112,97,99,101,95,112,97,116,104,32,102,111,114,32, - 116,104,105,115,32,109,111,100,117,108,101,47,112,97,99,107, - 97,103,101,32,110,97,109,101,46,78,114,203,0,0,0,122, - 19,115,112,101,99,32,109,105,115,115,105,110,103,32,108,111, - 97,100,101,114,41,13,114,161,0,0,0,114,84,0,0,0, - 218,5,98,121,116,101,115,114,47,1,0,0,114,128,0,0, - 0,114,203,0,0,0,114,48,1,0,0,114,140,0,0,0, - 114,178,0,0,0,114,117,0,0,0,114,167,0,0,0,114, - 134,0,0,0,114,183,0,0,0,41,9,114,193,0,0,0, - 114,139,0,0,0,114,44,0,0,0,114,202,0,0,0,218, - 14,110,97,109,101,115,112,97,99,101,95,112,97,116,104,90, - 5,101,110,116,114,121,114,42,1,0,0,114,187,0,0,0, - 114,141,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,9,95,103,101,116,95,115,112,101,99,7, - 5,0,0,115,40,0,0,0,0,5,4,1,8,1,14,1, - 2,1,10,1,8,1,10,1,14,2,12,1,8,1,2,1, - 10,1,8,1,6,1,8,1,8,5,12,2,12,1,6,1, - 122,20,80,97,116,104,70,105,110,100,101,114,46,95,103,101, - 116,95,115,112,101,99,99,4,0,0,0,0,0,0,0,0, - 0,0,0,6,0,0,0,5,0,0,0,67,0,0,0,115, - 100,0,0,0,124,2,100,1,117,0,114,14,116,0,106,1, - 125,2,124,0,160,2,124,1,124,2,124,3,161,3,125,4, - 124,4,100,1,117,0,114,40,100,1,83,0,124,4,106,3, - 100,1,117,0,114,92,124,4,106,4,125,5,124,5,114,86, - 100,1,124,4,95,5,116,6,124,1,124,5,124,0,106,2, - 131,3,124,4,95,4,124,4,83,0,100,1,83,0,110,4, - 124,4,83,0,100,1,83,0,41,2,122,141,84,114,121,32, - 116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,102, - 111,114,32,39,102,117,108,108,110,97,109,101,39,32,111,110, - 32,115,121,115,46,112,97,116,104,32,111,114,32,39,112,97, - 116,104,39,46,10,10,32,32,32,32,32,32,32,32,84,104, - 101,32,115,101,97,114,99,104,32,105,115,32,98,97,115,101, - 100,32,111,110,32,115,121,115,46,112,97,116,104,95,104,111, - 111,107,115,32,97,110,100,32,115,121,115,46,112,97,116,104, - 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,46, - 10,32,32,32,32,32,32,32,32,78,41,7,114,1,0,0, - 0,114,44,0,0,0,114,51,1,0,0,114,140,0,0,0, - 114,178,0,0,0,114,181,0,0,0,114,13,1,0,0,41, - 6,114,193,0,0,0,114,139,0,0,0,114,44,0,0,0, - 114,202,0,0,0,114,187,0,0,0,114,50,1,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,203, - 0,0,0,39,5,0,0,115,26,0,0,0,0,6,8,1, - 6,1,14,1,8,1,4,1,10,1,6,1,4,3,6,1, - 16,1,4,2,6,2,122,20,80,97,116,104,70,105,110,100, - 101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, - 0,67,0,0,0,115,30,0,0,0,124,0,160,0,124,1, - 124,2,161,2,125,3,124,3,100,1,117,0,114,24,100,1, - 83,0,124,3,106,1,83,0,41,2,122,170,102,105,110,100, - 32,116,104,101,32,109,111,100,117,108,101,32,111,110,32,115, - 121,115,46,112,97,116,104,32,111,114,32,39,112,97,116,104, - 39,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, - 97,116,104,95,104,111,111,107,115,32,97,110,100,10,32,32, - 32,32,32,32,32,32,115,121,115,46,112,97,116,104,95,105, - 109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,101, - 99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, - 32,32,32,32,32,32,78,114,204,0,0,0,114,205,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,206,0,0,0,63,5,0,0,115,8,0,0,0,0,8, - 12,1,8,1,4,1,122,22,80,97,116,104,70,105,110,100, - 101,114,46,102,105,110,100,95,109,111,100,117,108,101,99,1, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4, - 0,0,0,79,0,0,0,115,28,0,0,0,100,1,100,2, - 108,0,109,1,125,3,1,0,124,3,106,2,124,1,105,0, - 124,2,164,1,142,1,83,0,41,3,97,32,1,0,0,10, - 32,32,32,32,32,32,32,32,70,105,110,100,32,100,105,115, - 116,114,105,98,117,116,105,111,110,115,46,10,10,32,32,32, - 32,32,32,32,32,82,101,116,117,114,110,32,97,110,32,105, - 116,101,114,97,98,108,101,32,111,102,32,97,108,108,32,68, - 105,115,116,114,105,98,117,116,105,111,110,32,105,110,115,116, - 97,110,99,101,115,32,99,97,112,97,98,108,101,32,111,102, - 10,32,32,32,32,32,32,32,32,108,111,97,100,105,110,103, - 32,116,104,101,32,109,101,116,97,100,97,116,97,32,102,111, - 114,32,112,97,99,107,97,103,101,115,32,109,97,116,99,104, - 105,110,103,32,96,96,99,111,110,116,101,120,116,46,110,97, - 109,101,96,96,10,32,32,32,32,32,32,32,32,40,111,114, - 32,97,108,108,32,110,97,109,101,115,32,105,102,32,96,96, - 78,111,110,101,96,96,32,105,110,100,105,99,97,116,101,100, - 41,32,97,108,111,110,103,32,116,104,101,32,112,97,116,104, - 115,32,105,110,32,116,104,101,32,108,105,115,116,10,32,32, - 32,32,32,32,32,32,111,102,32,100,105,114,101,99,116,111, - 114,105,101,115,32,96,96,99,111,110,116,101,120,116,46,112, - 97,116,104,96,96,46,10,32,32,32,32,32,32,32,32,114, - 73,0,0,0,41,1,218,18,77,101,116,97,100,97,116,97, - 80,97,116,104,70,105,110,100,101,114,41,3,90,18,105,109, - 112,111,114,116,108,105,98,46,109,101,116,97,100,97,116,97, - 114,52,1,0,0,218,18,102,105,110,100,95,100,105,115,116, - 114,105,98,117,116,105,111,110,115,41,4,114,193,0,0,0, - 114,119,0,0,0,114,120,0,0,0,114,52,1,0,0,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,53, - 1,0,0,76,5,0,0,115,4,0,0,0,0,10,12,1, - 122,29,80,97,116,104,70,105,110,100,101,114,46,102,105,110, - 100,95,100,105,115,116,114,105,98,117,116,105,111,110,115,41, - 1,78,41,2,78,78,41,1,78,41,13,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, - 207,0,0,0,114,38,1,0,0,114,44,1,0,0,114,47, - 1,0,0,114,48,1,0,0,114,51,1,0,0,114,203,0, - 0,0,114,206,0,0,0,114,53,1,0,0,114,5,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,37,1,0,0,199,4,0,0,115,34,0,0,0,8,2, - 4,2,2,1,10,9,2,1,10,12,2,1,10,21,2,1, - 10,14,2,1,12,31,2,1,12,23,2,1,12,12,2,1, - 114,37,1,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,90, - 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, - 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,101, - 6,90,7,100,6,100,7,132,0,90,8,100,8,100,9,132, - 0,90,9,100,19,100,11,100,12,132,1,90,10,100,13,100, - 14,132,0,90,11,101,12,100,15,100,16,132,0,131,1,90, - 13,100,17,100,18,132,0,90,14,100,10,83,0,41,20,218, - 10,70,105,108,101,70,105,110,100,101,114,122,172,70,105,108, - 101,45,98,97,115,101,100,32,102,105,110,100,101,114,46,10, - 10,32,32,32,32,73,110,116,101,114,97,99,116,105,111,110, - 115,32,119,105,116,104,32,116,104,101,32,102,105,108,101,32, - 115,121,115,116,101,109,32,97,114,101,32,99,97,99,104,101, - 100,32,102,111,114,32,112,101,114,102,111,114,109,97,110,99, - 101,44,32,98,101,105,110,103,10,32,32,32,32,114,101,102, - 114,101,115,104,101,100,32,119,104,101,110,32,116,104,101,32, - 100,105,114,101,99,116,111,114,121,32,116,104,101,32,102,105, - 110,100,101,114,32,105,115,32,104,97,110,100,108,105,110,103, - 32,104,97,115,32,98,101,101,110,32,109,111,100,105,102,105, - 101,100,46,10,10,32,32,32,32,99,2,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,6,0,0,0,7,0, - 0,0,115,84,0,0,0,103,0,125,3,124,2,68,0,93, - 32,92,2,137,0,125,4,124,3,160,0,135,0,102,1,100, - 1,100,2,132,8,124,4,68,0,131,1,161,1,1,0,113, - 8,124,3,124,0,95,1,124,1,112,54,100,3,124,0,95, - 2,100,4,124,0,95,3,116,4,131,0,124,0,95,5,116, - 4,131,0,124,0,95,6,100,5,83,0,41,6,122,154,73, - 110,105,116,105,97,108,105,122,101,32,119,105,116,104,32,116, - 104,101,32,112,97,116,104,32,116,111,32,115,101,97,114,99, - 104,32,111,110,32,97,110,100,32,97,32,118,97,114,105,97, - 98,108,101,32,110,117,109,98,101,114,32,111,102,10,32,32, - 32,32,32,32,32,32,50,45,116,117,112,108,101,115,32,99, - 111,110,116,97,105,110,105,110,103,32,116,104,101,32,108,111, - 97,100,101,114,32,97,110,100,32,116,104,101,32,102,105,108, - 101,32,115,117,102,102,105,120,101,115,32,116,104,101,32,108, - 111,97,100,101,114,10,32,32,32,32,32,32,32,32,114,101, - 99,111,103,110,105,122,101,115,46,99,1,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,3,0,0,0,51,0, - 0,0,115,22,0,0,0,124,0,93,14,125,1,124,1,136, - 0,102,2,86,0,1,0,113,2,100,0,83,0,114,109,0, - 0,0,114,5,0,0,0,114,7,1,0,0,169,1,114,140, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,10,1, - 0,0,105,5,0,0,243,0,0,0,0,122,38,70,105,108, - 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, - 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, - 112,114,62,114,71,0,0,0,114,104,0,0,0,78,41,7, - 114,167,0,0,0,218,8,95,108,111,97,100,101,114,115,114, - 44,0,0,0,218,11,95,112,97,116,104,95,109,116,105,109, - 101,218,3,115,101,116,218,11,95,112,97,116,104,95,99,97, - 99,104,101,218,19,95,114,101,108,97,120,101,100,95,112,97, - 116,104,95,99,97,99,104,101,41,5,114,118,0,0,0,114, - 44,0,0,0,218,14,108,111,97,100,101,114,95,100,101,116, - 97,105,108,115,90,7,108,111,97,100,101,114,115,114,189,0, - 0,0,114,5,0,0,0,114,55,1,0,0,114,8,0,0, - 0,114,209,0,0,0,99,5,0,0,115,16,0,0,0,0, - 4,4,1,12,1,26,1,6,2,10,1,6,1,8,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,2,0,0,0,67,0,0,0,115,10,0, - 0,0,100,1,124,0,95,0,100,2,83,0,41,3,122,31, - 73,110,118,97,108,105,100,97,116,101,32,116,104,101,32,100, - 105,114,101,99,116,111,114,121,32,109,116,105,109,101,46,114, - 104,0,0,0,78,41,1,114,58,1,0,0,114,246,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,122,53,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,101,120,116,101,110,115,105,111,110,32,109, + 111,100,117,108,101,115,32,104,97,118,101,32,110,111,32,115, + 111,117,114,99,101,32,99,111,100,101,46,78,114,5,0,0, + 0,114,219,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,229,0,0,0,84,4,0,0,115,2, + 0,0,0,0,2,122,30,69,120,116,101,110,115,105,111,110, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,115, + 111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,6, + 0,0,0,124,0,106,0,83,0,114,250,0,0,0,114,48, + 0,0,0,114,219,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,179,0,0,0,88,4,0,0, + 115,2,0,0,0,0,3,122,32,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,102,105,108,101,110,97,109,101,78,41,14,114,125,0,0, + 0,114,124,0,0,0,114,126,0,0,0,114,127,0,0,0, + 114,209,0,0,0,114,243,0,0,0,114,247,0,0,0,114, + 212,0,0,0,114,217,0,0,0,114,182,0,0,0,114,213, + 0,0,0,114,229,0,0,0,114,136,0,0,0,114,179,0, + 0,0,114,5,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,114,252,0,0,0,41,4,0,0,115, + 22,0,0,0,8,2,4,6,8,4,8,4,8,3,8,8, + 8,6,8,6,8,4,8,4,2,1,114,252,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,64,0,0,0,115,104,0,0,0,101,0,90, + 1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90, + 4,100,4,100,5,132,0,90,5,100,6,100,7,132,0,90, + 6,100,8,100,9,132,0,90,7,100,10,100,11,132,0,90, + 8,100,12,100,13,132,0,90,9,100,14,100,15,132,0,90, + 10,100,16,100,17,132,0,90,11,100,18,100,19,132,0,90, + 12,100,20,100,21,132,0,90,13,100,22,100,23,132,0,90, + 14,100,24,83,0,41,25,218,14,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,97,38,1,0,0,82,101,112,114, + 101,115,101,110,116,115,32,97,32,110,97,109,101,115,112,97, + 99,101,32,112,97,99,107,97,103,101,39,115,32,112,97,116, + 104,46,32,32,73,116,32,117,115,101,115,32,116,104,101,32, + 109,111,100,117,108,101,32,110,97,109,101,10,32,32,32,32, + 116,111,32,102,105,110,100,32,105,116,115,32,112,97,114,101, + 110,116,32,109,111,100,117,108,101,44,32,97,110,100,32,102, + 114,111,109,32,116,104,101,114,101,32,105,116,32,108,111,111, + 107,115,32,117,112,32,116,104,101,32,112,97,114,101,110,116, + 39,115,10,32,32,32,32,95,95,112,97,116,104,95,95,46, + 32,32,87,104,101,110,32,116,104,105,115,32,99,104,97,110, + 103,101,115,44,32,116,104,101,32,109,111,100,117,108,101,39, + 115,32,111,119,110,32,112,97,116,104,32,105,115,32,114,101, + 99,111,109,112,117,116,101,100,44,10,32,32,32,32,117,115, + 105,110,103,32,112,97,116,104,95,102,105,110,100,101,114,46, + 32,32,70,111,114,32,116,111,112,45,108,101,118,101,108,32, + 109,111,100,117,108,101,115,44,32,116,104,101,32,112,97,114, + 101,110,116,32,109,111,100,117,108,101,39,115,32,112,97,116, + 104,10,32,32,32,32,105,115,32,115,121,115,46,112,97,116, + 104,46,99,4,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,36,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,116,2,124,0, + 160,3,161,0,131,1,124,0,95,4,124,3,124,0,95,5, + 100,0,83,0,114,109,0,0,0,41,6,218,5,95,110,97, + 109,101,218,5,95,112,97,116,104,114,111,0,0,0,218,16, + 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, + 218,17,95,108,97,115,116,95,112,97,114,101,110,116,95,112, + 97,116,104,218,12,95,112,97,116,104,95,102,105,110,100,101, + 114,169,4,114,118,0,0,0,114,116,0,0,0,114,44,0, + 0,0,90,11,112,97,116,104,95,102,105,110,100,101,114,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,209, + 0,0,0,101,4,0,0,115,8,0,0,0,0,1,6,1, + 6,1,14,1,122,23,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,0, + 0,0,67,0,0,0,115,38,0,0,0,124,0,106,0,160, + 1,100,1,161,1,92,3,125,1,125,2,125,3,124,2,100, + 2,107,2,114,30,100,3,83,0,124,1,100,4,102,2,83, + 0,41,5,122,62,82,101,116,117,114,110,115,32,97,32,116, + 117,112,108,101,32,111,102,32,40,112,97,114,101,110,116,45, + 109,111,100,117,108,101,45,110,97,109,101,44,32,112,97,114, + 101,110,116,45,112,97,116,104,45,97,116,116,114,45,110,97, + 109,101,41,114,71,0,0,0,114,40,0,0,0,41,2,114, + 1,0,0,0,114,44,0,0,0,90,8,95,95,112,97,116, + 104,95,95,41,2,114,14,1,0,0,114,41,0,0,0,41, + 4,114,118,0,0,0,114,4,1,0,0,218,3,100,111,116, + 90,2,109,101,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,23,95,102,105,110,100,95,112,97,114,101,110, + 116,95,112,97,116,104,95,110,97,109,101,115,107,4,0,0, + 115,8,0,0,0,0,2,18,1,8,2,4,3,122,38,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,102, + 105,110,100,95,112,97,114,101,110,116,95,112,97,116,104,95, + 110,97,109,101,115,99,1,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,28, + 0,0,0,124,0,160,0,161,0,92,2,125,1,125,2,116, + 1,116,2,106,3,124,1,25,0,124,2,131,2,83,0,114, + 109,0,0,0,41,4,114,21,1,0,0,114,130,0,0,0, + 114,1,0,0,0,218,7,109,111,100,117,108,101,115,41,3, + 114,118,0,0,0,90,18,112,97,114,101,110,116,95,109,111, + 100,117,108,101,95,110,97,109,101,90,14,112,97,116,104,95, + 97,116,116,114,95,110,97,109,101,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,16,1,0,0,117,4,0, + 0,115,4,0,0,0,0,1,12,1,122,31,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,103,101,116,95, + 112,97,114,101,110,116,95,112,97,116,104,99,1,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, + 67,0,0,0,115,80,0,0,0,116,0,124,0,160,1,161, + 0,131,1,125,1,124,1,124,0,106,2,107,3,114,74,124, + 0,160,3,124,0,106,4,124,1,161,2,125,2,124,2,100, + 0,117,1,114,68,124,2,106,5,100,0,117,0,114,68,124, + 2,106,6,114,68,124,2,106,6,124,0,95,7,124,1,124, + 0,95,2,124,0,106,7,83,0,114,109,0,0,0,41,8, + 114,111,0,0,0,114,16,1,0,0,114,17,1,0,0,114, + 18,1,0,0,114,14,1,0,0,114,140,0,0,0,114,178, + 0,0,0,114,15,1,0,0,41,3,114,118,0,0,0,90, + 11,112,97,114,101,110,116,95,112,97,116,104,114,187,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,38,1,0,0,113,5,0,0,115,2,0,0,0,0,2, - 122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,118, - 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, - 0,0,0,67,0,0,0,115,42,0,0,0,124,0,160,0, - 124,1,161,1,125,2,124,2,100,1,117,0,114,26,100,1, - 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, - 103,0,102,2,83,0,41,2,122,197,84,114,121,32,116,111, - 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,32, - 110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,32, - 32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,111, - 110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,97, - 100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,114, - 116,105,111,110,115,41,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, - 41,3,114,203,0,0,0,114,140,0,0,0,114,178,0,0, - 0,41,3,114,118,0,0,0,114,139,0,0,0,114,187,0, + 218,12,95,114,101,99,97,108,99,117,108,97,116,101,121,4, + 0,0,115,16,0,0,0,0,2,12,1,10,1,14,3,18, + 1,6,1,8,1,6,1,122,27,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,46,95,114,101,99,97,108,99,117, + 108,97,116,101,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,12,0, + 0,0,116,0,124,0,160,1,161,0,131,1,83,0,114,109, + 0,0,0,41,2,218,4,105,116,101,114,114,23,1,0,0, + 114,246,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,218,8,95,95,105,116,101,114,95,95,134,4, + 0,0,115,2,0,0,0,0,1,122,23,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,95,105,116,101,114, + 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,2,0,0,0,67,0,0,0,115,12,0,0,0, + 124,0,160,0,161,0,124,1,25,0,83,0,114,109,0,0, + 0,169,1,114,23,1,0,0,41,2,114,118,0,0,0,218, + 5,105,110,100,101,120,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,11,95,95,103,101,116,105,116,101,109, + 95,95,137,4,0,0,115,2,0,0,0,0,1,122,26,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, + 103,101,116,105,116,101,109,95,95,99,3,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,0, + 0,0,115,14,0,0,0,124,2,124,0,106,0,124,1,60, + 0,100,0,83,0,114,109,0,0,0,41,1,114,15,1,0, + 0,41,3,114,118,0,0,0,114,27,1,0,0,114,44,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,137,0,0,0,119,5,0,0,115,8,0,0,0,0, - 7,10,1,8,1,8,1,122,22,70,105,108,101,70,105,110, - 100,101,114,46,102,105,110,100,95,108,111,97,100,101,114,99, - 6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, - 6,0,0,0,67,0,0,0,115,26,0,0,0,124,1,124, - 2,124,3,131,2,125,6,116,0,124,2,124,3,124,6,124, - 4,100,1,141,4,83,0,41,2,78,114,177,0,0,0,41, - 1,114,190,0,0,0,41,7,114,118,0,0,0,114,188,0, - 0,0,114,139,0,0,0,114,44,0,0,0,90,4,115,109, - 115,108,114,202,0,0,0,114,140,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,51,1,0,0, - 131,5,0,0,115,8,0,0,0,0,1,10,1,8,1,2, - 255,122,20,70,105,108,101,70,105,110,100,101,114,46,95,103, - 101,116,95,115,112,101,99,78,99,3,0,0,0,0,0,0, - 0,0,0,0,0,14,0,0,0,8,0,0,0,67,0,0, - 0,115,96,1,0,0,100,1,125,3,124,1,160,0,100,2, - 161,1,100,3,25,0,125,4,122,24,116,1,124,0,106,2, - 112,34,116,3,160,4,161,0,131,1,106,5,125,5,87,0, - 110,22,4,0,116,6,121,64,1,0,1,0,1,0,100,4, - 125,5,89,0,110,2,48,0,124,5,124,0,106,7,107,3, - 114,90,124,0,160,8,161,0,1,0,124,5,124,0,95,7, - 116,9,131,0,114,112,124,0,106,10,125,6,124,4,160,11, - 161,0,125,7,110,10,124,0,106,12,125,6,124,4,125,7, - 124,7,124,6,118,0,114,216,116,13,124,0,106,2,124,4, - 131,2,125,8,124,0,106,14,68,0,93,58,92,2,125,9, - 125,10,100,5,124,9,23,0,125,11,116,13,124,8,124,11, - 131,2,125,12,116,15,124,12,131,1,114,148,124,0,160,16, - 124,10,124,1,124,12,124,8,103,1,124,2,161,5,2,0, - 1,0,83,0,113,148,116,17,124,8,131,1,125,3,124,0, - 106,14,68,0,93,82,92,2,125,9,125,10,116,13,124,0, - 106,2,124,4,124,9,23,0,131,2,125,12,116,18,106,19, - 100,6,124,12,100,3,100,7,141,3,1,0,124,7,124,9, - 23,0,124,6,118,0,114,222,116,15,124,12,131,1,114,222, - 124,0,160,16,124,10,124,1,124,12,100,8,124,2,161,5, - 2,0,1,0,83,0,113,222,124,3,144,1,114,92,116,18, - 160,19,100,9,124,8,161,2,1,0,116,18,160,20,124,1, - 100,8,161,2,125,13,124,8,103,1,124,13,95,21,124,13, - 83,0,100,8,83,0,41,10,122,111,84,114,121,32,116,111, + 0,218,11,95,95,115,101,116,105,116,101,109,95,95,140,4, + 0,0,115,2,0,0,0,0,1,122,26,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,95,115,101,116,105, + 116,101,109,95,95,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,12, + 0,0,0,116,0,124,0,160,1,161,0,131,1,83,0,114, + 109,0,0,0,41,2,114,23,0,0,0,114,23,1,0,0, + 114,246,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,218,7,95,95,108,101,110,95,95,143,4,0, + 0,115,2,0,0,0,0,1,122,22,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,95,108,101,110,95,95, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, + 160,0,124,0,106,1,161,1,83,0,41,2,78,122,20,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,40,123,33, + 114,125,41,41,2,114,62,0,0,0,114,15,1,0,0,114, + 246,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,8,95,95,114,101,112,114,95,95,146,4,0, + 0,115,2,0,0,0,0,1,122,23,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,95,114,101,112,114,95, + 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,124, + 1,124,0,160,0,161,0,118,0,83,0,114,109,0,0,0, + 114,26,1,0,0,169,2,114,118,0,0,0,218,4,105,116, + 101,109,114,5,0,0,0,114,5,0,0,0,114,8,0,0, + 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,149, + 4,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,99,111,110, + 116,97,105,110,115,95,95,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,16,0,0,0,124,0,106,0,160,1,124,1,161,1,1, + 0,100,0,83,0,114,109,0,0,0,41,2,114,15,1,0, + 0,114,186,0,0,0,114,32,1,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,186,0,0,0,152, + 4,0,0,115,2,0,0,0,0,1,122,21,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,97,112,112,101,110, + 100,78,41,15,114,125,0,0,0,114,124,0,0,0,114,126, + 0,0,0,114,127,0,0,0,114,209,0,0,0,114,21,1, + 0,0,114,16,1,0,0,114,23,1,0,0,114,25,1,0, + 0,114,28,1,0,0,114,29,1,0,0,114,30,1,0,0, + 114,31,1,0,0,114,34,1,0,0,114,186,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,114,13,1,0,0,94,4,0,0,115,24,0,0, + 0,8,1,4,6,8,6,8,10,8,4,8,13,8,3,8, + 3,8,3,8,3,8,3,8,3,114,13,1,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,64,0,0,0,115,80,0,0,0,101,0,90,1, + 100,0,90,2,100,1,100,2,132,0,90,3,101,4,100,3, + 100,4,132,0,131,1,90,5,100,5,100,6,132,0,90,6, + 100,7,100,8,132,0,90,7,100,9,100,10,132,0,90,8, + 100,11,100,12,132,0,90,9,100,13,100,14,132,0,90,10, + 100,15,100,16,132,0,90,11,100,17,83,0,41,18,218,16, + 95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,114, + 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,4,0,0,0,67,0,0,0,115,18,0,0,0,116,0, + 124,1,124,2,124,3,131,3,124,0,95,1,100,0,83,0, + 114,109,0,0,0,41,2,114,13,1,0,0,114,15,1,0, + 0,114,19,1,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,209,0,0,0,158,4,0,0,115,2, + 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, + 160,0,124,1,106,1,161,1,83,0,41,2,122,115,82,101, + 116,117,114,110,32,114,101,112,114,32,102,111,114,32,116,104, + 101,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, + 32,32,32,84,104,101,32,109,101,116,104,111,100,32,105,115, + 32,100,101,112,114,101,99,97,116,101,100,46,32,32,84,104, + 101,32,105,109,112,111,114,116,32,109,97,99,104,105,110,101, + 114,121,32,100,111,101,115,32,116,104,101,32,106,111,98,32, + 105,116,115,101,108,102,46,10,10,32,32,32,32,32,32,32, + 32,122,25,60,109,111,100,117,108,101,32,123,33,114,125,32, + 40,110,97,109,101,115,112,97,99,101,41,62,41,2,114,62, + 0,0,0,114,125,0,0,0,41,2,114,193,0,0,0,114, + 216,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,11,109,111,100,117,108,101,95,114,101,112,114, + 161,4,0,0,115,2,0,0,0,0,7,122,28,95,78,97, + 109,101,115,112,97,99,101,76,111,97,100,101,114,46,109,111, + 100,117,108,101,95,114,101,112,114,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,78,84,114, + 5,0,0,0,114,219,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,182,0,0,0,170,4,0, + 0,115,2,0,0,0,0,1,122,27,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,46,105,115,95,112,97, + 99,107,97,103,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,78,114,40,0,0,0,114, + 5,0,0,0,114,219,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,229,0,0,0,173,4,0, + 0,115,2,0,0,0,0,1,122,27,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,46,103,101,116,95,115, + 111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,6,0,0,0,67,0,0,0,115,16, + 0,0,0,116,0,100,1,100,2,100,3,100,4,100,5,141, + 4,83,0,41,6,78,114,40,0,0,0,122,8,60,115,116, + 114,105,110,103,62,114,215,0,0,0,84,41,1,114,231,0, + 0,0,41,1,114,232,0,0,0,114,219,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,213,0, + 0,0,176,4,0,0,115,2,0,0,0,0,1,122,25,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,1,83,0,114,210,0,0,0,114, + 5,0,0,0,114,211,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,212,0,0,0,179,4,0, + 0,115,2,0,0,0,0,1,122,30,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,46,99,114,101,97,116, + 101,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,0,83,0,114,109,0,0,0,114, + 5,0,0,0,114,6,1,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,217,0,0,0,182,4,0, + 0,115,2,0,0,0,0,1,122,28,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,46,101,120,101,99,95, + 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 26,0,0,0,116,0,160,1,100,1,124,0,106,2,161,2, + 1,0,116,0,160,3,124,0,124,1,161,2,83,0,41,2, + 122,98,76,111,97,100,32,97,32,110,97,109,101,115,112,97, + 99,101,32,109,111,100,117,108,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, + 85,115,101,32,101,120,101,99,95,109,111,100,117,108,101,40, + 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, + 32,32,32,32,122,38,110,97,109,101,115,112,97,99,101,32, + 109,111,100,117,108,101,32,108,111,97,100,101,100,32,119,105, + 116,104,32,112,97,116,104,32,123,33,114,125,41,4,114,134, + 0,0,0,114,149,0,0,0,114,15,1,0,0,114,218,0, + 0,0,114,219,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,114,220,0,0,0,185,4,0,0,115, + 8,0,0,0,0,7,6,1,4,255,4,2,122,28,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,108, + 111,97,100,95,109,111,100,117,108,101,78,41,12,114,125,0, + 0,0,114,124,0,0,0,114,126,0,0,0,114,209,0,0, + 0,114,207,0,0,0,114,36,1,0,0,114,182,0,0,0, + 114,229,0,0,0,114,213,0,0,0,114,212,0,0,0,114, + 217,0,0,0,114,220,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,35,1, + 0,0,157,4,0,0,115,18,0,0,0,8,1,8,3,2, + 1,10,8,8,3,8,3,8,3,8,3,8,3,114,35,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,64,0,0,0,115,118,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,101,4,100,2, + 100,3,132,0,131,1,90,5,101,4,100,4,100,5,132,0, + 131,1,90,6,101,4,100,6,100,7,132,0,131,1,90,7, + 101,4,100,8,100,9,132,0,131,1,90,8,101,4,100,19, + 100,11,100,12,132,1,131,1,90,9,101,4,100,20,100,13, + 100,14,132,1,131,1,90,10,101,4,100,21,100,15,100,16, + 132,1,131,1,90,11,101,4,100,17,100,18,132,0,131,1, + 90,12,100,10,83,0,41,22,218,10,80,97,116,104,70,105, + 110,100,101,114,122,62,77,101,116,97,32,112,97,116,104,32, + 102,105,110,100,101,114,32,102,111,114,32,115,121,115,46,112, + 97,116,104,32,97,110,100,32,112,97,99,107,97,103,101,32, + 95,95,112,97,116,104,95,95,32,97,116,116,114,105,98,117, + 116,101,115,46,99,1,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,4,0,0,0,67,0,0,0,115,64,0, + 0,0,116,0,116,1,106,2,160,3,161,0,131,1,68,0, + 93,44,92,2,125,1,125,2,124,2,100,1,117,0,114,40, + 116,1,106,2,124,1,61,0,113,14,116,4,124,2,100,2, + 131,2,114,14,124,2,160,5,161,0,1,0,113,14,100,1, + 83,0,41,3,122,125,67,97,108,108,32,116,104,101,32,105, + 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, + 40,41,32,109,101,116,104,111,100,32,111,110,32,97,108,108, + 32,112,97,116,104,32,101,110,116,114,121,32,102,105,110,100, + 101,114,115,10,32,32,32,32,32,32,32,32,115,116,111,114, + 101,100,32,105,110,32,115,121,115,46,112,97,116,104,95,105, + 109,112,111,114,116,101,114,95,99,97,99,104,101,115,32,40, + 119,104,101,114,101,32,105,109,112,108,101,109,101,110,116,101, + 100,41,46,78,218,17,105,110,118,97,108,105,100,97,116,101, + 95,99,97,99,104,101,115,41,6,218,4,108,105,115,116,114, + 1,0,0,0,218,19,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,218,5,105,116,101,109,115, + 114,128,0,0,0,114,38,1,0,0,41,3,114,193,0,0, + 0,114,116,0,0,0,218,6,102,105,110,100,101,114,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,38,1, + 0,0,203,4,0,0,115,10,0,0,0,0,4,22,1,8, + 1,10,1,10,1,122,28,80,97,116,104,70,105,110,100,101, + 114,46,105,110,118,97,108,105,100,97,116,101,95,99,97,99, + 104,101,115,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,9,0,0,0,67,0,0,0,115,80,0,0, + 0,116,0,106,1,100,1,117,1,114,28,116,0,106,1,115, + 28,116,2,160,3,100,2,116,4,161,2,1,0,116,0,106, + 1,68,0,93,40,125,2,122,14,124,2,124,1,131,1,87, + 0,2,0,1,0,83,0,4,0,116,5,121,74,1,0,1, + 0,1,0,89,0,113,34,89,0,113,34,48,0,100,1,83, + 0,41,3,122,46,83,101,97,114,99,104,32,115,121,115,46, + 112,97,116,104,95,104,111,111,107,115,32,102,111,114,32,97, + 32,102,105,110,100,101,114,32,102,111,114,32,39,112,97,116, + 104,39,46,78,122,23,115,121,115,46,112,97,116,104,95,104, + 111,111,107,115,32,105,115,32,101,109,112,116,121,41,6,114, + 1,0,0,0,218,10,112,97,116,104,95,104,111,111,107,115, + 114,75,0,0,0,114,76,0,0,0,114,138,0,0,0,114, + 117,0,0,0,41,3,114,193,0,0,0,114,44,0,0,0, + 90,4,104,111,111,107,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,11,95,112,97,116,104,95,104,111,111, + 107,115,213,4,0,0,115,16,0,0,0,0,3,16,1,12, + 1,10,1,2,1,14,1,12,1,10,2,122,22,80,97,116, + 104,70,105,110,100,101,114,46,95,112,97,116,104,95,104,111, + 111,107,115,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,8,0,0,0,67,0,0,0,115,100,0,0, + 0,124,1,100,1,107,2,114,42,122,12,116,0,160,1,161, + 0,125,1,87,0,110,20,4,0,116,2,121,40,1,0,1, + 0,1,0,89,0,100,2,83,0,48,0,122,14,116,3,106, + 4,124,1,25,0,125,2,87,0,110,38,4,0,116,5,121, + 94,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, + 2,124,2,116,3,106,4,124,1,60,0,89,0,110,2,48, + 0,124,2,83,0,41,3,122,210,71,101,116,32,116,104,101, + 32,102,105,110,100,101,114,32,102,111,114,32,116,104,101,32, + 112,97,116,104,32,101,110,116,114,121,32,102,114,111,109,32, + 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,46,10,10,32,32,32,32,32,32, + 32,32,73,102,32,116,104,101,32,112,97,116,104,32,101,110, + 116,114,121,32,105,115,32,110,111,116,32,105,110,32,116,104, + 101,32,99,97,99,104,101,44,32,102,105,110,100,32,116,104, + 101,32,97,112,112,114,111,112,114,105,97,116,101,32,102,105, + 110,100,101,114,10,32,32,32,32,32,32,32,32,97,110,100, + 32,99,97,99,104,101,32,105,116,46,32,73,102,32,110,111, + 32,102,105,110,100,101,114,32,105,115,32,97,118,97,105,108, + 97,98,108,101,44,32,115,116,111,114,101,32,78,111,110,101, + 46,10,10,32,32,32,32,32,32,32,32,114,40,0,0,0, + 78,41,7,114,4,0,0,0,114,55,0,0,0,218,17,70, + 105,108,101,78,111,116,70,111,117,110,100,69,114,114,111,114, + 114,1,0,0,0,114,40,1,0,0,218,8,75,101,121,69, + 114,114,111,114,114,44,1,0,0,41,3,114,193,0,0,0, + 114,44,0,0,0,114,42,1,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,20,95,112,97,116,104, + 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,226, + 4,0,0,115,22,0,0,0,0,8,8,1,2,1,12,1, + 12,3,8,1,2,1,14,1,12,1,10,1,16,1,122,31, + 80,97,116,104,70,105,110,100,101,114,46,95,112,97,116,104, + 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,99, + 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, + 4,0,0,0,67,0,0,0,115,82,0,0,0,116,0,124, + 2,100,1,131,2,114,26,124,2,160,1,124,1,161,1,92, + 2,125,3,125,4,110,14,124,2,160,2,124,1,161,1,125, + 3,103,0,125,4,124,3,100,0,117,1,114,60,116,3,160, + 4,124,1,124,3,161,2,83,0,116,3,160,5,124,1,100, + 0,161,2,125,5,124,4,124,5,95,6,124,5,83,0,41, + 2,78,114,137,0,0,0,41,7,114,128,0,0,0,114,137, + 0,0,0,114,206,0,0,0,114,134,0,0,0,114,201,0, + 0,0,114,183,0,0,0,114,178,0,0,0,41,6,114,193, + 0,0,0,114,139,0,0,0,114,42,1,0,0,114,140,0, + 0,0,114,141,0,0,0,114,187,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,218,16,95,108,101, + 103,97,99,121,95,103,101,116,95,115,112,101,99,248,4,0, + 0,115,18,0,0,0,0,4,10,1,16,2,10,1,4,1, + 8,1,12,1,12,1,6,1,122,27,80,97,116,104,70,105, + 110,100,101,114,46,95,108,101,103,97,99,121,95,103,101,116, + 95,115,112,101,99,78,99,4,0,0,0,0,0,0,0,0, + 0,0,0,9,0,0,0,5,0,0,0,67,0,0,0,115, + 166,0,0,0,103,0,125,4,124,2,68,0,93,134,125,5, + 116,0,124,5,116,1,116,2,102,2,131,2,115,28,113,8, + 124,0,160,3,124,5,161,1,125,6,124,6,100,1,117,1, + 114,8,116,4,124,6,100,2,131,2,114,70,124,6,160,5, + 124,1,124,3,161,2,125,7,110,12,124,0,160,6,124,1, + 124,6,161,2,125,7,124,7,100,1,117,0,114,92,113,8, + 124,7,106,7,100,1,117,1,114,110,124,7,2,0,1,0, + 83,0,124,7,106,8,125,8,124,8,100,1,117,0,114,132, + 116,9,100,3,131,1,130,1,124,4,160,10,124,8,161,1, + 1,0,113,8,116,11,160,12,124,1,100,1,161,2,125,7, + 124,4,124,7,95,8,124,7,83,0,41,4,122,63,70,105, + 110,100,32,116,104,101,32,108,111,97,100,101,114,32,111,114, + 32,110,97,109,101,115,112,97,99,101,95,112,97,116,104,32, + 102,111,114,32,116,104,105,115,32,109,111,100,117,108,101,47, + 112,97,99,107,97,103,101,32,110,97,109,101,46,78,114,203, + 0,0,0,122,19,115,112,101,99,32,109,105,115,115,105,110, + 103,32,108,111,97,100,101,114,41,13,114,161,0,0,0,114, + 84,0,0,0,218,5,98,121,116,101,115,114,47,1,0,0, + 114,128,0,0,0,114,203,0,0,0,114,48,1,0,0,114, + 140,0,0,0,114,178,0,0,0,114,117,0,0,0,114,167, + 0,0,0,114,134,0,0,0,114,183,0,0,0,41,9,114, + 193,0,0,0,114,139,0,0,0,114,44,0,0,0,114,202, + 0,0,0,218,14,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,90,5,101,110,116,114,121,114,42,1,0,0,114, + 187,0,0,0,114,141,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,218,9,95,103,101,116,95,115, + 112,101,99,7,5,0,0,115,40,0,0,0,0,5,4,1, + 8,1,14,1,2,1,10,1,8,1,10,1,14,2,12,1, + 8,1,2,1,10,1,8,1,6,1,8,1,8,5,12,2, + 12,1,6,1,122,20,80,97,116,104,70,105,110,100,101,114, + 46,95,103,101,116,95,115,112,101,99,99,4,0,0,0,0, + 0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,67, + 0,0,0,115,94,0,0,0,124,2,100,1,117,0,114,14, + 116,0,106,1,125,2,124,0,160,2,124,1,124,2,124,3, + 161,3,125,4,124,4,100,1,117,0,114,40,100,1,83,0, + 124,4,106,3,100,1,117,0,114,90,124,4,106,4,125,5, + 124,5,114,86,100,1,124,4,95,5,116,6,124,1,124,5, + 124,0,106,2,131,3,124,4,95,4,124,4,83,0,100,1, + 83,0,124,4,83,0,41,2,122,141,84,114,121,32,116,111, 32,102,105,110,100,32,97,32,115,112,101,99,32,102,111,114, + 32,39,102,117,108,108,110,97,109,101,39,32,111,110,32,115, + 121,115,46,112,97,116,104,32,111,114,32,39,112,97,116,104, + 39,46,10,10,32,32,32,32,32,32,32,32,84,104,101,32, + 115,101,97,114,99,104,32,105,115,32,98,97,115,101,100,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,97,110,100,32,115,121,115,46,112,97,116,104,95,105, + 109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,32, + 32,32,32,32,32,32,32,78,41,7,114,1,0,0,0,114, + 44,0,0,0,114,51,1,0,0,114,140,0,0,0,114,178, + 0,0,0,114,181,0,0,0,114,13,1,0,0,41,6,114, + 193,0,0,0,114,139,0,0,0,114,44,0,0,0,114,202, + 0,0,0,114,187,0,0,0,114,50,1,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,114,203,0,0, + 0,39,5,0,0,115,26,0,0,0,0,6,8,1,6,1, + 14,1,8,1,4,1,10,1,6,1,4,3,6,1,16,1, + 4,2,4,2,122,20,80,97,116,104,70,105,110,100,101,114, + 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,30,0,0,0,124,0,160,0,124,1,124,2, + 161,2,125,3,124,3,100,1,117,0,114,24,100,1,83,0, + 124,3,106,1,83,0,41,2,122,170,102,105,110,100,32,116, + 104,101,32,109,111,100,117,108,101,32,111,110,32,115,121,115, + 46,112,97,116,104,32,111,114,32,39,112,97,116,104,39,32, + 98,97,115,101,100,32,111,110,32,115,121,115,46,112,97,116, + 104,95,104,111,111,107,115,32,97,110,100,10,32,32,32,32, + 32,32,32,32,115,121,115,46,112,97,116,104,95,105,109,112, + 111,114,116,101,114,95,99,97,99,104,101,46,10,10,32,32, + 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, + 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, + 32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40, + 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, + 32,32,32,32,78,114,204,0,0,0,114,205,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,206, + 0,0,0,63,5,0,0,115,8,0,0,0,0,8,12,1, + 8,1,4,1,122,22,80,97,116,104,70,105,110,100,101,114, + 46,102,105,110,100,95,109,111,100,117,108,101,99,1,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, + 0,79,0,0,0,115,28,0,0,0,100,1,100,2,108,0, + 109,1,125,3,1,0,124,3,106,2,124,1,105,0,124,2, + 164,1,142,1,83,0,41,3,97,32,1,0,0,10,32,32, + 32,32,32,32,32,32,70,105,110,100,32,100,105,115,116,114, + 105,98,117,116,105,111,110,115,46,10,10,32,32,32,32,32, + 32,32,32,82,101,116,117,114,110,32,97,110,32,105,116,101, + 114,97,98,108,101,32,111,102,32,97,108,108,32,68,105,115, + 116,114,105,98,117,116,105,111,110,32,105,110,115,116,97,110, + 99,101,115,32,99,97,112,97,98,108,101,32,111,102,10,32, + 32,32,32,32,32,32,32,108,111,97,100,105,110,103,32,116, + 104,101,32,109,101,116,97,100,97,116,97,32,102,111,114,32, + 112,97,99,107,97,103,101,115,32,109,97,116,99,104,105,110, + 103,32,96,96,99,111,110,116,101,120,116,46,110,97,109,101, + 96,96,10,32,32,32,32,32,32,32,32,40,111,114,32,97, + 108,108,32,110,97,109,101,115,32,105,102,32,96,96,78,111, + 110,101,96,96,32,105,110,100,105,99,97,116,101,100,41,32, + 97,108,111,110,103,32,116,104,101,32,112,97,116,104,115,32, + 105,110,32,116,104,101,32,108,105,115,116,10,32,32,32,32, + 32,32,32,32,111,102,32,100,105,114,101,99,116,111,114,105, + 101,115,32,96,96,99,111,110,116,101,120,116,46,112,97,116, + 104,96,96,46,10,32,32,32,32,32,32,32,32,114,73,0, + 0,0,41,1,218,18,77,101,116,97,100,97,116,97,80,97, + 116,104,70,105,110,100,101,114,41,3,90,18,105,109,112,111, + 114,116,108,105,98,46,109,101,116,97,100,97,116,97,114,52, + 1,0,0,218,18,102,105,110,100,95,100,105,115,116,114,105, + 98,117,116,105,111,110,115,41,4,114,193,0,0,0,114,119, + 0,0,0,114,120,0,0,0,114,52,1,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,114,53,1,0, + 0,76,5,0,0,115,4,0,0,0,0,10,12,1,122,29, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 100,105,115,116,114,105,98,117,116,105,111,110,115,41,1,78, + 41,2,78,78,41,1,78,41,13,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,207,0, + 0,0,114,38,1,0,0,114,44,1,0,0,114,47,1,0, + 0,114,48,1,0,0,114,51,1,0,0,114,203,0,0,0, + 114,206,0,0,0,114,53,1,0,0,114,5,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,37, + 1,0,0,199,4,0,0,115,34,0,0,0,8,2,4,2, + 2,1,10,9,2,1,10,12,2,1,10,21,2,1,10,14, + 2,1,12,31,2,1,12,23,2,1,12,12,2,1,114,37, + 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,64,0,0,0,115,90,0,0, + 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, + 3,132,0,90,4,100,4,100,5,132,0,90,5,101,6,90, + 7,100,6,100,7,132,0,90,8,100,8,100,9,132,0,90, + 9,100,19,100,11,100,12,132,1,90,10,100,13,100,14,132, + 0,90,11,101,12,100,15,100,16,132,0,131,1,90,13,100, + 17,100,18,132,0,90,14,100,10,83,0,41,20,218,10,70, + 105,108,101,70,105,110,100,101,114,122,172,70,105,108,101,45, + 98,97,115,101,100,32,102,105,110,100,101,114,46,10,10,32, + 32,32,32,73,110,116,101,114,97,99,116,105,111,110,115,32, + 119,105,116,104,32,116,104,101,32,102,105,108,101,32,115,121, + 115,116,101,109,32,97,114,101,32,99,97,99,104,101,100,32, + 102,111,114,32,112,101,114,102,111,114,109,97,110,99,101,44, + 32,98,101,105,110,103,10,32,32,32,32,114,101,102,114,101, + 115,104,101,100,32,119,104,101,110,32,116,104,101,32,100,105, + 114,101,99,116,111,114,121,32,116,104,101,32,102,105,110,100, + 101,114,32,105,115,32,104,97,110,100,108,105,110,103,32,104, + 97,115,32,98,101,101,110,32,109,111,100,105,102,105,101,100, + 46,10,10,32,32,32,32,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0, + 115,84,0,0,0,103,0,125,3,124,2,68,0,93,32,92, + 2,137,0,125,4,124,3,160,0,135,0,102,1,100,1,100, + 2,132,8,124,4,68,0,131,1,161,1,1,0,113,8,124, + 3,124,0,95,1,124,1,112,54,100,3,124,0,95,2,100, + 4,124,0,95,3,116,4,131,0,124,0,95,5,116,4,131, + 0,124,0,95,6,100,5,83,0,41,6,122,154,73,110,105, + 116,105,97,108,105,122,101,32,119,105,116,104,32,116,104,101, + 32,112,97,116,104,32,116,111,32,115,101,97,114,99,104,32, + 111,110,32,97,110,100,32,97,32,118,97,114,105,97,98,108, + 101,32,110,117,109,98,101,114,32,111,102,10,32,32,32,32, + 32,32,32,32,50,45,116,117,112,108,101,115,32,99,111,110, + 116,97,105,110,105,110,103,32,116,104,101,32,108,111,97,100, + 101,114,32,97,110,100,32,116,104,101,32,102,105,108,101,32, + 115,117,102,102,105,120,101,115,32,116,104,101,32,108,111,97, + 100,101,114,10,32,32,32,32,32,32,32,32,114,101,99,111, + 103,110,105,122,101,115,46,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,51,0,0,0, + 115,22,0,0,0,124,0,93,14,125,1,124,1,136,0,102, + 2,86,0,1,0,113,2,100,0,83,0,114,109,0,0,0, + 114,5,0,0,0,114,7,1,0,0,169,1,114,140,0,0, + 0,114,5,0,0,0,114,8,0,0,0,114,10,1,0,0, + 105,5,0,0,243,0,0,0,0,122,38,70,105,108,101,70, + 105,110,100,101,114,46,95,95,105,110,105,116,95,95,46,60, + 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, + 62,114,71,0,0,0,114,104,0,0,0,78,41,7,114,167, + 0,0,0,218,8,95,108,111,97,100,101,114,115,114,44,0, + 0,0,218,11,95,112,97,116,104,95,109,116,105,109,101,218, + 3,115,101,116,218,11,95,112,97,116,104,95,99,97,99,104, + 101,218,19,95,114,101,108,97,120,101,100,95,112,97,116,104, + 95,99,97,99,104,101,41,5,114,118,0,0,0,114,44,0, + 0,0,218,14,108,111,97,100,101,114,95,100,101,116,97,105, + 108,115,90,7,108,111,97,100,101,114,115,114,189,0,0,0, + 114,5,0,0,0,114,55,1,0,0,114,8,0,0,0,114, + 209,0,0,0,99,5,0,0,115,16,0,0,0,0,4,4, + 1,12,1,26,1,6,2,10,1,6,1,8,1,122,19,70, + 105,108,101,70,105,110,100,101,114,46,95,95,105,110,105,116, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,2,0,0,0,67,0,0,0,115,10,0,0,0, + 100,1,124,0,95,0,100,2,83,0,41,3,122,31,73,110, + 118,97,108,105,100,97,116,101,32,116,104,101,32,100,105,114, + 101,99,116,111,114,121,32,109,116,105,109,101,46,114,104,0, + 0,0,78,41,1,114,58,1,0,0,114,246,0,0,0,114, + 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,38, + 1,0,0,113,5,0,0,115,2,0,0,0,0,2,122,28, + 70,105,108,101,70,105,110,100,101,114,46,105,110,118,97,108, + 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, + 0,67,0,0,0,115,42,0,0,0,124,0,160,0,124,1, + 161,1,125,2,124,2,100,1,117,0,114,26,100,1,103,0, + 102,2,83,0,124,2,106,1,124,2,106,2,112,38,103,0, + 102,2,83,0,41,2,122,197,84,114,121,32,116,111,32,102, + 105,110,100,32,97,32,108,111,97,100,101,114,32,102,111,114, 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,109, - 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, - 82,101,116,117,114,110,115,32,116,104,101,32,109,97,116,99, - 104,105,110,103,32,115,112,101,99,44,32,111,114,32,78,111, - 110,101,32,105,102,32,110,111,116,32,102,111,117,110,100,46, - 10,32,32,32,32,32,32,32,32,70,114,71,0,0,0,114, - 28,0,0,0,114,104,0,0,0,114,209,0,0,0,122,9, - 116,114,121,105,110,103,32,123,125,41,1,90,9,118,101,114, - 98,111,115,105,116,121,78,122,25,112,111,115,115,105,98,108, - 101,32,110,97,109,101,115,112,97,99,101,32,102,111,114,32, - 123,125,41,22,114,41,0,0,0,114,49,0,0,0,114,44, - 0,0,0,114,4,0,0,0,114,55,0,0,0,114,0,1, - 0,0,114,50,0,0,0,114,58,1,0,0,218,11,95,102, - 105,108,108,95,99,97,99,104,101,114,9,0,0,0,114,61, - 1,0,0,114,105,0,0,0,114,60,1,0,0,114,38,0, - 0,0,114,57,1,0,0,114,54,0,0,0,114,51,1,0, - 0,114,56,0,0,0,114,134,0,0,0,114,149,0,0,0, - 114,183,0,0,0,114,178,0,0,0,41,14,114,118,0,0, - 0,114,139,0,0,0,114,202,0,0,0,90,12,105,115,95, - 110,97,109,101,115,112,97,99,101,90,11,116,97,105,108,95, - 109,111,100,117,108,101,114,169,0,0,0,90,5,99,97,99, - 104,101,90,12,99,97,99,104,101,95,109,111,100,117,108,101, - 90,9,98,97,115,101,95,112,97,116,104,114,8,1,0,0, - 114,188,0,0,0,90,13,105,110,105,116,95,102,105,108,101, - 110,97,109,101,90,9,102,117,108,108,95,112,97,116,104,114, - 187,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,114,203,0,0,0,136,5,0,0,115,72,0,0, - 0,0,5,4,1,14,1,2,1,24,1,12,1,10,1,10, - 1,8,1,6,2,6,1,6,1,10,2,6,1,4,2,8, - 1,12,1,14,1,8,1,10,1,8,1,26,4,8,2,14, - 1,16,1,16,1,12,1,8,1,10,1,4,255,10,2,6, - 1,12,1,12,1,8,1,4,1,122,20,70,105,108,101,70, - 105,110,100,101,114,46,102,105,110,100,95,115,112,101,99,99, - 1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0, - 10,0,0,0,67,0,0,0,115,188,0,0,0,124,0,106, - 0,125,1,122,22,116,1,160,2,124,1,112,22,116,1,160, - 3,161,0,161,1,125,2,87,0,110,28,4,0,116,4,116, - 5,116,6,102,3,121,56,1,0,1,0,1,0,103,0,125, - 2,89,0,110,2,48,0,116,7,106,8,160,9,100,1,161, - 1,115,82,116,10,124,2,131,1,124,0,95,11,110,74,116, - 10,131,0,125,3,124,2,68,0,93,56,125,4,124,4,160, - 12,100,2,161,1,92,3,125,5,125,6,125,7,124,6,114, - 134,100,3,160,13,124,5,124,7,160,14,161,0,161,2,125, - 8,110,4,124,5,125,8,124,3,160,15,124,8,161,1,1, - 0,113,92,124,3,124,0,95,11,116,7,106,8,160,9,116, - 16,161,1,114,184,100,4,100,5,132,0,124,2,68,0,131, - 1,124,0,95,17,100,6,83,0,41,7,122,68,70,105,108, - 108,32,116,104,101,32,99,97,99,104,101,32,111,102,32,112, - 111,116,101,110,116,105,97,108,32,109,111,100,117,108,101,115, - 32,97,110,100,32,112,97,99,107,97,103,101,115,32,102,111, - 114,32,116,104,105,115,32,100,105,114,101,99,116,111,114,121, - 46,114,0,0,0,0,114,71,0,0,0,114,61,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,4,0,0,0,83,0,0,0,115,20,0,0,0,104,0, - 124,0,93,12,125,1,124,1,160,0,161,0,146,2,113,4, - 83,0,114,5,0,0,0,41,1,114,105,0,0,0,41,2, - 114,32,0,0,0,90,2,102,110,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,218,9,60,115,101,116,99,111, - 109,112,62,213,5,0,0,114,56,1,0,0,122,41,70,105, - 108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,99, - 97,99,104,101,46,60,108,111,99,97,108,115,62,46,60,115, - 101,116,99,111,109,112,62,78,41,18,114,44,0,0,0,114, - 4,0,0,0,90,7,108,105,115,116,100,105,114,114,55,0, - 0,0,114,45,1,0,0,218,15,80,101,114,109,105,115,115, - 105,111,110,69,114,114,111,114,218,18,78,111,116,65,68,105, - 114,101,99,116,111,114,121,69,114,114,111,114,114,1,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,59,1,0,0, - 114,60,1,0,0,114,100,0,0,0,114,62,0,0,0,114, - 105,0,0,0,218,3,97,100,100,114,12,0,0,0,114,61, - 1,0,0,41,9,114,118,0,0,0,114,44,0,0,0,90, - 8,99,111,110,116,101,110,116,115,90,21,108,111,119,101,114, - 95,115,117,102,102,105,120,95,99,111,110,116,101,110,116,115, - 114,33,1,0,0,114,116,0,0,0,114,20,1,0,0,114, - 8,1,0,0,90,8,110,101,119,95,110,97,109,101,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,63,1, - 0,0,184,5,0,0,115,34,0,0,0,0,2,6,1,2, - 1,22,1,18,3,10,3,12,1,12,7,6,1,8,1,16, - 1,4,1,18,2,4,1,12,1,6,1,12,1,122,22,70, - 105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95, - 99,97,99,104,101,99,1,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,7,0,0,0,115,18, - 0,0,0,135,0,135,1,102,2,100,1,100,2,132,8,125, - 2,124,2,83,0,41,3,97,20,1,0,0,65,32,99,108, - 97,115,115,32,109,101,116,104,111,100,32,119,104,105,99,104, - 32,114,101,116,117,114,110,115,32,97,32,99,108,111,115,117, - 114,101,32,116,111,32,117,115,101,32,111,110,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,10,32,32,32,32,32, - 32,32,32,119,104,105,99,104,32,119,105,108,108,32,114,101, - 116,117,114,110,32,97,110,32,105,110,115,116,97,110,99,101, - 32,117,115,105,110,103,32,116,104,101,32,115,112,101,99,105, - 102,105,101,100,32,108,111,97,100,101,114,115,32,97,110,100, - 32,116,104,101,32,112,97,116,104,10,32,32,32,32,32,32, - 32,32,99,97,108,108,101,100,32,111,110,32,116,104,101,32, - 99,108,111,115,117,114,101,46,10,10,32,32,32,32,32,32, - 32,32,73,102,32,116,104,101,32,112,97,116,104,32,99,97, - 108,108,101,100,32,111,110,32,116,104,101,32,99,108,111,115, - 117,114,101,32,105,115,32,110,111,116,32,97,32,100,105,114, - 101,99,116,111,114,121,44,32,73,109,112,111,114,116,69,114, - 114,111,114,32,105,115,10,32,32,32,32,32,32,32,32,114, - 97,105,115,101,100,46,10,10,32,32,32,32,32,32,32,32, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,4,0,0,0,19,0,0,0,115,36,0,0,0,116,0, - 124,0,131,1,115,20,116,1,100,1,124,0,100,2,141,2, - 130,1,136,0,124,0,103,1,136,1,162,1,82,0,142,0, - 83,0,41,3,122,45,80,97,116,104,32,104,111,111,107,32, - 102,111,114,32,105,109,112,111,114,116,108,105,98,46,109,97, - 99,104,105,110,101,114,121,46,70,105,108,101,70,105,110,100, - 101,114,46,122,30,111,110,108,121,32,100,105,114,101,99,116, - 111,114,105,101,115,32,97,114,101,32,115,117,112,112,111,114, - 116,101,100,114,48,0,0,0,41,2,114,56,0,0,0,114, - 117,0,0,0,114,48,0,0,0,169,2,114,193,0,0,0, - 114,62,1,0,0,114,5,0,0,0,114,8,0,0,0,218, - 24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,70, - 105,108,101,70,105,110,100,101,114,225,5,0,0,115,6,0, - 0,0,0,2,8,1,12,1,122,54,70,105,108,101,70,105, - 110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,60, - 108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,111, - 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, - 114,5,0,0,0,41,3,114,193,0,0,0,114,62,1,0, - 0,114,69,1,0,0,114,5,0,0,0,114,68,1,0,0, - 114,8,0,0,0,218,9,112,97,116,104,95,104,111,111,107, - 215,5,0,0,115,4,0,0,0,0,10,14,6,122,20,70, - 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, - 111,111,107,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,12,0,0, - 0,100,1,160,0,124,0,106,1,161,1,83,0,41,2,78, - 122,16,70,105,108,101,70,105,110,100,101,114,40,123,33,114, - 125,41,41,2,114,62,0,0,0,114,44,0,0,0,114,246, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,31,1,0,0,233,5,0,0,115,2,0,0,0, - 0,1,122,19,70,105,108,101,70,105,110,100,101,114,46,95, - 95,114,101,112,114,95,95,41,1,78,41,15,114,125,0,0, - 0,114,124,0,0,0,114,126,0,0,0,114,127,0,0,0, - 114,209,0,0,0,114,38,1,0,0,114,143,0,0,0,114, - 206,0,0,0,114,137,0,0,0,114,51,1,0,0,114,203, - 0,0,0,114,63,1,0,0,114,207,0,0,0,114,70,1, - 0,0,114,31,1,0,0,114,5,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,54,1,0,0, - 90,5,0,0,115,22,0,0,0,8,2,4,7,8,14,8, - 4,4,2,8,12,8,5,10,48,8,31,2,1,10,17,114, - 54,1,0,0,99,4,0,0,0,0,0,0,0,0,0,0, - 0,6,0,0,0,8,0,0,0,67,0,0,0,115,144,0, - 0,0,124,0,160,0,100,1,161,1,125,4,124,0,160,0, - 100,2,161,1,125,5,124,4,115,66,124,5,114,36,124,5, - 106,1,125,4,110,30,124,2,124,3,107,2,114,56,116,2, - 124,1,124,2,131,2,125,4,110,10,116,3,124,1,124,2, - 131,2,125,4,124,5,115,84,116,4,124,1,124,2,124,4, - 100,3,141,3,125,5,122,36,124,5,124,0,100,2,60,0, - 124,4,124,0,100,1,60,0,124,2,124,0,100,4,60,0, - 124,3,124,0,100,5,60,0,87,0,110,18,4,0,116,5, - 121,138,1,0,1,0,1,0,89,0,110,2,48,0,100,0, - 83,0,41,6,78,218,10,95,95,108,111,97,100,101,114,95, - 95,218,8,95,95,115,112,101,99,95,95,114,55,1,0,0, - 90,8,95,95,102,105,108,101,95,95,90,10,95,95,99,97, - 99,104,101,100,95,95,41,6,218,3,103,101,116,114,140,0, - 0,0,114,5,1,0,0,114,255,0,0,0,114,190,0,0, - 0,218,9,69,120,99,101,112,116,105,111,110,41,6,90,2, - 110,115,114,116,0,0,0,90,8,112,97,116,104,110,97,109, - 101,90,9,99,112,97,116,104,110,97,109,101,114,140,0,0, - 0,114,187,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,14,95,102,105,120,95,117,112,95,109, - 111,100,117,108,101,239,5,0,0,115,34,0,0,0,0,2, - 10,1,10,1,4,1,4,1,8,1,8,1,12,2,10,1, - 4,1,14,1,2,1,8,1,8,1,8,1,12,1,12,2, - 114,75,1,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,38, - 0,0,0,116,0,116,1,160,2,161,0,102,2,125,0,116, - 3,116,4,102,2,125,1,116,5,116,6,102,2,125,2,124, - 0,124,1,124,2,103,3,83,0,41,1,122,95,82,101,116, - 117,114,110,115,32,97,32,108,105,115,116,32,111,102,32,102, - 105,108,101,45,98,97,115,101,100,32,109,111,100,117,108,101, - 32,108,111,97,100,101,114,115,46,10,10,32,32,32,32,69, - 97,99,104,32,105,116,101,109,32,105,115,32,97,32,116,117, - 112,108,101,32,40,108,111,97,100,101,114,44,32,115,117,102, - 102,105,120,101,115,41,46,10,32,32,32,32,41,7,114,252, - 0,0,0,114,163,0,0,0,218,18,101,120,116,101,110,115, - 105,111,110,95,115,117,102,102,105,120,101,115,114,255,0,0, - 0,114,101,0,0,0,114,5,1,0,0,114,88,0,0,0, - 41,3,90,10,101,120,116,101,110,115,105,111,110,115,90,6, - 115,111,117,114,99,101,90,8,98,121,116,101,99,111,100,101, + 111,100,117,108,101,44,32,111,114,32,116,104,101,32,110,97, + 109,101,115,112,97,99,101,10,32,32,32,32,32,32,32,32, + 112,97,99,107,97,103,101,32,112,111,114,116,105,111,110,115, + 46,32,82,101,116,117,114,110,115,32,40,108,111,97,100,101, + 114,44,32,108,105,115,116,45,111,102,45,112,111,114,116,105, + 111,110,115,41,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,102, + 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,32,32,32,32,78,41,3, + 114,203,0,0,0,114,140,0,0,0,114,178,0,0,0,41, + 3,114,118,0,0,0,114,139,0,0,0,114,187,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 184,0,0,0,6,6,0,0,115,8,0,0,0,0,5,12, - 1,8,1,8,1,114,184,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,10,0,0,0,9,0,0,0,67, - 0,0,0,115,132,1,0,0,124,0,97,0,116,0,106,1, - 97,1,116,0,106,2,97,2,116,1,106,3,116,4,25,0, - 125,1,100,1,100,2,103,1,102,2,100,3,100,4,100,2, - 103,2,102,2,102,2,125,2,124,2,68,0,93,108,92,2, - 125,3,125,4,116,5,100,5,100,6,132,0,124,4,68,0, - 131,1,131,1,115,82,74,0,130,1,124,4,100,7,25,0, - 125,5,124,3,116,1,106,3,118,0,114,116,116,1,106,3, - 124,3,25,0,125,6,1,0,113,170,113,52,122,20,116,0, - 160,6,124,3,161,1,125,6,87,0,1,0,113,170,87,0, - 113,52,4,0,116,7,121,158,1,0,1,0,1,0,89,0, - 113,52,89,0,113,52,48,0,113,52,116,7,100,8,131,1, - 130,1,116,8,124,1,100,9,124,6,131,3,1,0,116,8, - 124,1,100,10,124,5,131,3,1,0,116,8,124,1,100,11, - 100,12,160,9,124,4,161,1,131,3,1,0,116,8,124,1, - 100,13,100,14,100,15,132,0,124,4,68,0,131,1,131,3, - 1,0,103,0,100,16,162,1,125,7,124,3,100,3,107,2, - 144,1,114,6,124,7,160,10,100,17,161,1,1,0,124,7, - 68,0,93,52,125,8,124,8,116,1,106,3,118,1,144,1, - 114,38,116,0,160,6,124,8,161,1,125,9,110,10,116,1, - 106,3,124,8,25,0,125,9,116,8,124,1,124,8,124,9, - 131,3,1,0,144,1,113,10,116,8,124,1,100,18,116,11, - 131,0,131,3,1,0,116,12,160,13,116,2,160,14,161,0, - 161,1,1,0,124,3,100,3,107,2,144,1,114,128,116,15, - 160,10,100,19,161,1,1,0,100,20,116,12,118,0,144,1, - 114,128,100,21,116,16,95,17,100,22,83,0,41,23,122,205, - 83,101,116,117,112,32,116,104,101,32,112,97,116,104,45,98, - 97,115,101,100,32,105,109,112,111,114,116,101,114,115,32,102, - 111,114,32,105,109,112,111,114,116,108,105,98,32,98,121,32, - 105,109,112,111,114,116,105,110,103,32,110,101,101,100,101,100, - 10,32,32,32,32,98,117,105,108,116,45,105,110,32,109,111, - 100,117,108,101,115,32,97,110,100,32,105,110,106,101,99,116, - 105,110,103,32,116,104,101,109,32,105,110,116,111,32,116,104, - 101,32,103,108,111,98,97,108,32,110,97,109,101,115,112,97, - 99,101,46,10,10,32,32,32,32,79,116,104,101,114,32,99, - 111,109,112,111,110,101,110,116,115,32,97,114,101,32,101,120, - 116,114,97,99,116,101,100,32,102,114,111,109,32,116,104,101, - 32,99,111,114,101,32,98,111,111,116,115,116,114,97,112,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,90,5,112, - 111,115,105,120,250,1,47,90,2,110,116,250,1,92,99,1, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,115,0,0,0,115,26,0,0,0,124,0,93,18, - 125,1,116,0,124,1,131,1,100,0,107,2,86,0,1,0, - 113,2,100,1,83,0,41,2,114,39,0,0,0,78,41,1, - 114,23,0,0,0,41,2,114,32,0,0,0,114,94,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,10,1,0,0,35,6,0,0,114,56,1,0,0,122,25, - 95,115,101,116,117,112,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,114,73,0,0,0,122,30, - 105,109,112,111,114,116,108,105,98,32,114,101,113,117,105,114, - 101,115,32,112,111,115,105,120,32,111,114,32,110,116,114,4, - 0,0,0,114,35,0,0,0,114,31,0,0,0,114,40,0, - 0,0,114,58,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,4,0,0,0,83,0,0,0, - 115,22,0,0,0,104,0,124,0,93,14,125,1,100,0,124, - 1,155,0,157,2,146,2,113,4,83,0,41,1,114,74,0, - 0,0,114,5,0,0,0,41,2,114,32,0,0,0,218,1, - 115,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,64,1,0,0,52,6,0,0,114,56,1,0,0,122,25, - 95,115,101,116,117,112,46,60,108,111,99,97,108,115,62,46, - 60,115,101,116,99,111,109,112,62,41,3,114,64,0,0,0, - 114,75,0,0,0,114,160,0,0,0,114,192,0,0,0,114, - 9,0,0,0,122,4,46,112,121,119,122,6,95,100,46,112, - 121,100,84,78,41,18,114,134,0,0,0,114,1,0,0,0, - 114,163,0,0,0,114,22,1,0,0,114,125,0,0,0,218, - 3,97,108,108,90,18,95,98,117,105,108,116,105,110,95,102, - 114,111,109,95,110,97,109,101,114,117,0,0,0,114,129,0, - 0,0,114,36,0,0,0,114,186,0,0,0,114,14,0,0, - 0,114,12,1,0,0,114,167,0,0,0,114,76,1,0,0, - 114,101,0,0,0,114,191,0,0,0,114,195,0,0,0,41, - 10,218,17,95,98,111,111,116,115,116,114,97,112,95,109,111, - 100,117,108,101,90,11,115,101,108,102,95,109,111,100,117,108, - 101,90,10,111,115,95,100,101,116,97,105,108,115,90,10,98, - 117,105,108,116,105,110,95,111,115,114,31,0,0,0,114,35, - 0,0,0,90,9,111,115,95,109,111,100,117,108,101,90,13, - 98,117,105,108,116,105,110,95,110,97,109,101,115,90,12,98, - 117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,105, - 108,116,105,110,95,109,111,100,117,108,101,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,218,6,95,115,101,116, - 117,112,17,6,0,0,115,70,0,0,0,0,8,4,1,6, - 1,6,2,10,3,22,1,12,2,22,1,8,1,10,1,10, - 1,6,2,2,1,10,1,10,1,12,1,12,2,8,2,12, - 1,12,1,18,1,22,3,8,1,10,1,10,1,8,1,12, - 1,12,2,10,1,16,3,14,1,14,1,10,1,10,1,10, - 1,114,82,1,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, - 50,0,0,0,116,0,124,0,131,1,1,0,116,1,131,0, - 125,1,116,2,106,3,160,4,116,5,106,6,124,1,142,0, - 103,1,161,1,1,0,116,2,106,7,160,8,116,9,161,1, - 1,0,100,1,83,0,41,2,122,41,73,110,115,116,97,108, - 108,32,116,104,101,32,112,97,116,104,45,98,97,115,101,100, - 32,105,109,112,111,114,116,32,99,111,109,112,111,110,101,110, - 116,115,46,78,41,10,114,82,1,0,0,114,184,0,0,0, - 114,1,0,0,0,114,43,1,0,0,114,167,0,0,0,114, - 54,1,0,0,114,70,1,0,0,218,9,109,101,116,97,95, - 112,97,116,104,114,186,0,0,0,114,37,1,0,0,41,2, - 114,81,1,0,0,90,17,115,117,112,112,111,114,116,101,100, - 95,108,111,97,100,101,114,115,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,218,8,95,105,110,115,116,97,108, - 108,74,6,0,0,115,8,0,0,0,0,2,8,1,6,1, - 20,1,114,84,1,0,0,41,1,114,60,0,0,0,41,1, - 78,41,3,78,78,78,41,2,114,73,0,0,0,114,73,0, - 0,0,41,1,84,41,1,78,41,1,78,41,63,114,127,0, - 0,0,114,13,0,0,0,90,37,95,67,65,83,69,95,73, - 78,83,69,78,83,73,84,73,86,69,95,80,76,65,84,70, - 79,82,77,83,95,66,89,84,69,83,95,75,69,89,114,12, - 0,0,0,114,14,0,0,0,114,21,0,0,0,114,27,0, - 0,0,114,29,0,0,0,114,38,0,0,0,114,47,0,0, - 0,114,49,0,0,0,114,53,0,0,0,114,54,0,0,0, - 114,56,0,0,0,114,59,0,0,0,114,69,0,0,0,218, - 4,116,121,112,101,218,8,95,95,99,111,100,101,95,95,114, - 162,0,0,0,114,19,0,0,0,114,148,0,0,0,114,18, - 0,0,0,114,24,0,0,0,114,236,0,0,0,114,91,0, - 0,0,114,87,0,0,0,114,101,0,0,0,114,88,0,0, - 0,90,23,68,69,66,85,71,95,66,89,84,69,67,79,68, - 69,95,83,85,70,70,73,88,69,83,90,27,79,80,84,73, - 77,73,90,69,68,95,66,89,84,69,67,79,68,69,95,83, - 85,70,70,73,88,69,83,114,97,0,0,0,114,102,0,0, - 0,114,108,0,0,0,114,112,0,0,0,114,114,0,0,0, - 114,136,0,0,0,114,143,0,0,0,114,152,0,0,0,114, - 156,0,0,0,114,158,0,0,0,114,165,0,0,0,114,170, - 0,0,0,114,171,0,0,0,114,176,0,0,0,218,6,111, - 98,106,101,99,116,114,185,0,0,0,114,190,0,0,0,114, - 191,0,0,0,114,208,0,0,0,114,221,0,0,0,114,239, - 0,0,0,114,255,0,0,0,114,5,1,0,0,114,12,1, - 0,0,114,252,0,0,0,114,13,1,0,0,114,35,1,0, - 0,114,37,1,0,0,114,54,1,0,0,114,75,1,0,0, - 114,184,0,0,0,114,82,1,0,0,114,84,1,0,0,114, - 5,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,8,60,109,111,100,117,108,101,62,1,0,0, - 0,115,126,0,0,0,4,22,4,1,4,1,2,1,2,255, - 4,4,8,17,8,5,8,5,8,6,8,6,8,12,8,10, - 8,9,8,5,8,7,8,9,10,22,10,127,0,20,16,1, - 12,2,4,1,4,2,6,2,6,2,8,2,16,71,8,40, - 8,19,8,12,8,12,8,28,8,17,8,33,8,28,8,24, - 10,13,10,10,10,11,8,14,6,3,4,1,2,255,12,68, - 14,64,14,29,16,127,0,17,14,50,18,45,18,26,4,3, - 18,53,14,63,14,42,14,127,0,20,14,127,0,22,10,23, - 8,11,8,57, + 137,0,0,0,119,5,0,0,115,8,0,0,0,0,7,10, + 1,8,1,8,1,122,22,70,105,108,101,70,105,110,100,101, + 114,46,102,105,110,100,95,108,111,97,100,101,114,99,6,0, + 0,0,0,0,0,0,0,0,0,0,7,0,0,0,6,0, + 0,0,67,0,0,0,115,26,0,0,0,124,1,124,2,124, + 3,131,2,125,6,116,0,124,2,124,3,124,6,124,4,100, + 1,141,4,83,0,41,2,78,114,177,0,0,0,41,1,114, + 190,0,0,0,41,7,114,118,0,0,0,114,188,0,0,0, + 114,139,0,0,0,114,44,0,0,0,90,4,115,109,115,108, + 114,202,0,0,0,114,140,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,51,1,0,0,131,5, + 0,0,115,8,0,0,0,0,1,10,1,8,1,2,255,122, + 20,70,105,108,101,70,105,110,100,101,114,46,95,103,101,116, + 95,115,112,101,99,78,99,3,0,0,0,0,0,0,0,0, + 0,0,0,14,0,0,0,8,0,0,0,67,0,0,0,115, + 92,1,0,0,100,1,125,3,124,1,160,0,100,2,161,1, + 100,3,25,0,125,4,122,24,116,1,124,0,106,2,112,34, + 116,3,160,4,161,0,131,1,106,5,125,5,87,0,110,22, + 4,0,116,6,121,64,1,0,1,0,1,0,100,4,125,5, + 89,0,110,2,48,0,124,5,124,0,106,7,107,3,114,90, + 124,0,160,8,161,0,1,0,124,5,124,0,95,7,116,9, + 131,0,114,112,124,0,106,10,125,6,124,4,160,11,161,0, + 125,7,110,10,124,0,106,12,125,6,124,4,125,7,124,7, + 124,6,118,0,114,214,116,13,124,0,106,2,124,4,131,2, + 125,8,124,0,106,14,68,0,93,56,92,2,125,9,125,10, + 100,5,124,9,23,0,125,11,116,13,124,8,124,11,131,2, + 125,12,116,15,124,12,131,1,114,148,124,0,160,16,124,10, + 124,1,124,12,124,8,103,1,124,2,161,5,2,0,1,0, + 83,0,116,17,124,8,131,1,125,3,124,0,106,14,68,0, + 93,80,92,2,125,9,125,10,116,13,124,0,106,2,124,4, + 124,9,23,0,131,2,125,12,116,18,106,19,100,6,124,12, + 100,3,100,7,141,3,1,0,124,7,124,9,23,0,124,6, + 118,0,114,220,116,15,124,12,131,1,114,220,124,0,160,16, + 124,10,124,1,124,12,100,8,124,2,161,5,2,0,1,0, + 83,0,124,3,144,1,114,88,116,18,160,19,100,9,124,8, + 161,2,1,0,116,18,160,20,124,1,100,8,161,2,125,13, + 124,8,103,1,124,13,95,21,124,13,83,0,100,8,83,0, + 41,10,122,111,84,114,121,32,116,111,32,102,105,110,100,32, + 97,32,115,112,101,99,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,46, + 10,10,32,32,32,32,32,32,32,32,82,101,116,117,114,110, + 115,32,116,104,101,32,109,97,116,99,104,105,110,103,32,115, + 112,101,99,44,32,111,114,32,78,111,110,101,32,105,102,32, + 110,111,116,32,102,111,117,110,100,46,10,32,32,32,32,32, + 32,32,32,70,114,71,0,0,0,114,28,0,0,0,114,104, + 0,0,0,114,209,0,0,0,122,9,116,114,121,105,110,103, + 32,123,125,41,1,90,9,118,101,114,98,111,115,105,116,121, + 78,122,25,112,111,115,115,105,98,108,101,32,110,97,109,101, + 115,112,97,99,101,32,102,111,114,32,123,125,41,22,114,41, + 0,0,0,114,49,0,0,0,114,44,0,0,0,114,4,0, + 0,0,114,55,0,0,0,114,0,1,0,0,114,50,0,0, + 0,114,58,1,0,0,218,11,95,102,105,108,108,95,99,97, + 99,104,101,114,9,0,0,0,114,61,1,0,0,114,105,0, + 0,0,114,60,1,0,0,114,38,0,0,0,114,57,1,0, + 0,114,54,0,0,0,114,51,1,0,0,114,56,0,0,0, + 114,134,0,0,0,114,149,0,0,0,114,183,0,0,0,114, + 178,0,0,0,41,14,114,118,0,0,0,114,139,0,0,0, + 114,202,0,0,0,90,12,105,115,95,110,97,109,101,115,112, + 97,99,101,90,11,116,97,105,108,95,109,111,100,117,108,101, + 114,169,0,0,0,90,5,99,97,99,104,101,90,12,99,97, + 99,104,101,95,109,111,100,117,108,101,90,9,98,97,115,101, + 95,112,97,116,104,114,8,1,0,0,114,188,0,0,0,90, + 13,105,110,105,116,95,102,105,108,101,110,97,109,101,90,9, + 102,117,108,108,95,112,97,116,104,114,187,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,203,0, + 0,0,136,5,0,0,115,72,0,0,0,0,5,4,1,14, + 1,2,1,24,1,12,1,10,1,10,1,8,1,6,2,6, + 1,6,1,10,2,6,1,4,2,8,1,12,1,14,1,8, + 1,10,1,8,1,24,4,8,2,14,1,16,1,16,1,12, + 1,8,1,10,1,4,255,8,2,6,1,12,1,12,1,8, + 1,4,1,122,20,70,105,108,101,70,105,110,100,101,114,46, + 102,105,110,100,95,115,112,101,99,99,1,0,0,0,0,0, + 0,0,0,0,0,0,9,0,0,0,10,0,0,0,67,0, + 0,0,115,188,0,0,0,124,0,106,0,125,1,122,22,116, + 1,160,2,124,1,112,22,116,1,160,3,161,0,161,1,125, + 2,87,0,110,28,4,0,116,4,116,5,116,6,102,3,121, + 56,1,0,1,0,1,0,103,0,125,2,89,0,110,2,48, + 0,116,7,106,8,160,9,100,1,161,1,115,82,116,10,124, + 2,131,1,124,0,95,11,110,74,116,10,131,0,125,3,124, + 2,68,0,93,56,125,4,124,4,160,12,100,2,161,1,92, + 3,125,5,125,6,125,7,124,6,114,134,100,3,160,13,124, + 5,124,7,160,14,161,0,161,2,125,8,110,4,124,5,125, + 8,124,3,160,15,124,8,161,1,1,0,113,92,124,3,124, + 0,95,11,116,7,106,8,160,9,116,16,161,1,114,184,100, + 4,100,5,132,0,124,2,68,0,131,1,124,0,95,17,100, + 6,83,0,41,7,122,68,70,105,108,108,32,116,104,101,32, + 99,97,99,104,101,32,111,102,32,112,111,116,101,110,116,105, + 97,108,32,109,111,100,117,108,101,115,32,97,110,100,32,112, + 97,99,107,97,103,101,115,32,102,111,114,32,116,104,105,115, + 32,100,105,114,101,99,116,111,114,121,46,114,0,0,0,0, + 114,71,0,0,0,114,61,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,83, + 0,0,0,115,20,0,0,0,104,0,124,0,93,12,125,1, + 124,1,160,0,161,0,146,2,113,4,83,0,114,5,0,0, + 0,41,1,114,105,0,0,0,41,2,114,32,0,0,0,90, + 2,102,110,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,218,9,60,115,101,116,99,111,109,112,62,213,5,0, + 0,114,56,1,0,0,122,41,70,105,108,101,70,105,110,100, + 101,114,46,95,102,105,108,108,95,99,97,99,104,101,46,60, + 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, + 62,78,41,18,114,44,0,0,0,114,4,0,0,0,90,7, + 108,105,115,116,100,105,114,114,55,0,0,0,114,45,1,0, + 0,218,15,80,101,114,109,105,115,115,105,111,110,69,114,114, + 111,114,218,18,78,111,116,65,68,105,114,101,99,116,111,114, + 121,69,114,114,111,114,114,1,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,59,1,0,0,114,60,1,0,0,114, + 100,0,0,0,114,62,0,0,0,114,105,0,0,0,218,3, + 97,100,100,114,12,0,0,0,114,61,1,0,0,41,9,114, + 118,0,0,0,114,44,0,0,0,90,8,99,111,110,116,101, + 110,116,115,90,21,108,111,119,101,114,95,115,117,102,102,105, + 120,95,99,111,110,116,101,110,116,115,114,33,1,0,0,114, + 116,0,0,0,114,20,1,0,0,114,8,1,0,0,90,8, + 110,101,119,95,110,97,109,101,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,63,1,0,0,184,5,0,0, + 115,34,0,0,0,0,2,6,1,2,1,22,1,18,3,10, + 3,12,1,12,7,6,1,8,1,16,1,4,1,18,2,4, + 1,12,1,6,1,12,1,122,22,70,105,108,101,70,105,110, + 100,101,114,46,95,102,105,108,108,95,99,97,99,104,101,99, + 1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,7,0,0,0,115,18,0,0,0,135,0,135, + 1,102,2,100,1,100,2,132,8,125,2,124,2,83,0,41, + 3,97,20,1,0,0,65,32,99,108,97,115,115,32,109,101, + 116,104,111,100,32,119,104,105,99,104,32,114,101,116,117,114, + 110,115,32,97,32,99,108,111,115,117,114,101,32,116,111,32, + 117,115,101,32,111,110,32,115,121,115,46,112,97,116,104,95, + 104,111,111,107,10,32,32,32,32,32,32,32,32,119,104,105, + 99,104,32,119,105,108,108,32,114,101,116,117,114,110,32,97, + 110,32,105,110,115,116,97,110,99,101,32,117,115,105,110,103, + 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,108, + 111,97,100,101,114,115,32,97,110,100,32,116,104,101,32,112, + 97,116,104,10,32,32,32,32,32,32,32,32,99,97,108,108, + 101,100,32,111,110,32,116,104,101,32,99,108,111,115,117,114, + 101,46,10,10,32,32,32,32,32,32,32,32,73,102,32,116, + 104,101,32,112,97,116,104,32,99,97,108,108,101,100,32,111, + 110,32,116,104,101,32,99,108,111,115,117,114,101,32,105,115, + 32,110,111,116,32,97,32,100,105,114,101,99,116,111,114,121, + 44,32,73,109,112,111,114,116,69,114,114,111,114,32,105,115, + 10,32,32,32,32,32,32,32,32,114,97,105,115,101,100,46, + 10,10,32,32,32,32,32,32,32,32,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,19, + 0,0,0,115,36,0,0,0,116,0,124,0,131,1,115,20, + 116,1,100,1,124,0,100,2,141,2,130,1,136,0,124,0, + 103,1,136,1,162,1,82,0,142,0,83,0,41,3,122,45, + 80,97,116,104,32,104,111,111,107,32,102,111,114,32,105,109, + 112,111,114,116,108,105,98,46,109,97,99,104,105,110,101,114, + 121,46,70,105,108,101,70,105,110,100,101,114,46,122,30,111, + 110,108,121,32,100,105,114,101,99,116,111,114,105,101,115,32, + 97,114,101,32,115,117,112,112,111,114,116,101,100,114,48,0, + 0,0,41,2,114,56,0,0,0,114,117,0,0,0,114,48, + 0,0,0,169,2,114,193,0,0,0,114,62,1,0,0,114, + 5,0,0,0,114,8,0,0,0,218,24,112,97,116,104,95, + 104,111,111,107,95,102,111,114,95,70,105,108,101,70,105,110, + 100,101,114,225,5,0,0,115,6,0,0,0,0,2,8,1, + 12,1,122,54,70,105,108,101,70,105,110,100,101,114,46,112, + 97,116,104,95,104,111,111,107,46,60,108,111,99,97,108,115, + 62,46,112,97,116,104,95,104,111,111,107,95,102,111,114,95, + 70,105,108,101,70,105,110,100,101,114,114,5,0,0,0,41, + 3,114,193,0,0,0,114,62,1,0,0,114,69,1,0,0, + 114,5,0,0,0,114,68,1,0,0,114,8,0,0,0,218, + 9,112,97,116,104,95,104,111,111,107,215,5,0,0,115,4, + 0,0,0,0,10,14,6,122,20,70,105,108,101,70,105,110, + 100,101,114,46,112,97,116,104,95,104,111,111,107,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, + 0,0,67,0,0,0,115,12,0,0,0,100,1,160,0,124, + 0,106,1,161,1,83,0,41,2,78,122,16,70,105,108,101, + 70,105,110,100,101,114,40,123,33,114,125,41,41,2,114,62, + 0,0,0,114,44,0,0,0,114,246,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,114,31,1,0, + 0,233,5,0,0,115,2,0,0,0,0,1,122,19,70,105, + 108,101,70,105,110,100,101,114,46,95,95,114,101,112,114,95, + 95,41,1,78,41,15,114,125,0,0,0,114,124,0,0,0, + 114,126,0,0,0,114,127,0,0,0,114,209,0,0,0,114, + 38,1,0,0,114,143,0,0,0,114,206,0,0,0,114,137, + 0,0,0,114,51,1,0,0,114,203,0,0,0,114,63,1, + 0,0,114,207,0,0,0,114,70,1,0,0,114,31,1,0, + 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,54,1,0,0,90,5,0,0,115,22, + 0,0,0,8,2,4,7,8,14,8,4,4,2,8,12,8, + 5,10,48,8,31,2,1,10,17,114,54,1,0,0,99,4, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,8, + 0,0,0,67,0,0,0,115,144,0,0,0,124,0,160,0, + 100,1,161,1,125,4,124,0,160,0,100,2,161,1,125,5, + 124,4,115,66,124,5,114,36,124,5,106,1,125,4,110,30, + 124,2,124,3,107,2,114,56,116,2,124,1,124,2,131,2, + 125,4,110,10,116,3,124,1,124,2,131,2,125,4,124,5, + 115,84,116,4,124,1,124,2,124,4,100,3,141,3,125,5, + 122,36,124,5,124,0,100,2,60,0,124,4,124,0,100,1, + 60,0,124,2,124,0,100,4,60,0,124,3,124,0,100,5, + 60,0,87,0,110,18,4,0,116,5,121,138,1,0,1,0, + 1,0,89,0,110,2,48,0,100,0,83,0,41,6,78,218, + 10,95,95,108,111,97,100,101,114,95,95,218,8,95,95,115, + 112,101,99,95,95,114,55,1,0,0,90,8,95,95,102,105, + 108,101,95,95,90,10,95,95,99,97,99,104,101,100,95,95, + 41,6,218,3,103,101,116,114,140,0,0,0,114,5,1,0, + 0,114,255,0,0,0,114,190,0,0,0,218,9,69,120,99, + 101,112,116,105,111,110,41,6,90,2,110,115,114,116,0,0, + 0,90,8,112,97,116,104,110,97,109,101,90,9,99,112,97, + 116,104,110,97,109,101,114,140,0,0,0,114,187,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, + 14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,239, + 5,0,0,115,34,0,0,0,0,2,10,1,10,1,4,1, + 4,1,8,1,8,1,12,2,10,1,4,1,14,1,2,1, + 8,1,8,1,8,1,12,1,12,2,114,75,1,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,67,0,0,0,115,38,0,0,0,116,0,116, + 1,160,2,161,0,102,2,125,0,116,3,116,4,102,2,125, + 1,116,5,116,6,102,2,125,2,124,0,124,1,124,2,103, + 3,83,0,41,1,122,95,82,101,116,117,114,110,115,32,97, + 32,108,105,115,116,32,111,102,32,102,105,108,101,45,98,97, + 115,101,100,32,109,111,100,117,108,101,32,108,111,97,100,101, + 114,115,46,10,10,32,32,32,32,69,97,99,104,32,105,116, + 101,109,32,105,115,32,97,32,116,117,112,108,101,32,40,108, + 111,97,100,101,114,44,32,115,117,102,102,105,120,101,115,41, + 46,10,32,32,32,32,41,7,114,252,0,0,0,114,163,0, + 0,0,218,18,101,120,116,101,110,115,105,111,110,95,115,117, + 102,102,105,120,101,115,114,255,0,0,0,114,101,0,0,0, + 114,5,1,0,0,114,88,0,0,0,41,3,90,10,101,120, + 116,101,110,115,105,111,110,115,90,6,115,111,117,114,99,101, + 90,8,98,121,116,101,99,111,100,101,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,184,0,0,0,6,6, + 0,0,115,8,0,0,0,0,5,12,1,8,1,8,1,114, + 184,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,10,0,0,0,9,0,0,0,67,0,0,0,115,130,1, + 0,0,124,0,97,0,116,0,106,1,97,1,116,0,106,2, + 97,2,116,1,106,3,116,4,25,0,125,1,100,1,100,2, + 103,1,102,2,100,3,100,4,100,2,103,2,102,2,102,2, + 125,2,124,2,68,0,93,106,92,2,125,3,125,4,116,5, + 100,5,100,6,132,0,124,4,68,0,131,1,131,1,115,82, + 74,0,130,1,124,4,100,7,25,0,125,5,124,3,116,1, + 106,3,118,0,114,116,116,1,106,3,124,3,25,0,125,6, + 1,0,113,168,113,52,122,20,116,0,160,6,124,3,161,1, + 125,6,87,0,1,0,113,168,87,0,113,52,4,0,116,7, + 121,158,1,0,1,0,1,0,89,0,113,52,89,0,113,52, + 48,0,116,7,100,8,131,1,130,1,116,8,124,1,100,9, + 124,6,131,3,1,0,116,8,124,1,100,10,124,5,131,3, + 1,0,116,8,124,1,100,11,100,12,160,9,124,4,161,1, + 131,3,1,0,116,8,124,1,100,13,100,14,100,15,132,0, + 124,4,68,0,131,1,131,3,1,0,103,0,100,16,162,1, + 125,7,124,3,100,3,107,2,144,1,114,4,124,7,160,10, + 100,17,161,1,1,0,124,7,68,0,93,52,125,8,124,8, + 116,1,106,3,118,1,144,1,114,36,116,0,160,6,124,8, + 161,1,125,9,110,10,116,1,106,3,124,8,25,0,125,9, + 116,8,124,1,124,8,124,9,131,3,1,0,144,1,113,8, + 116,8,124,1,100,18,116,11,131,0,131,3,1,0,116,12, + 160,13,116,2,160,14,161,0,161,1,1,0,124,3,100,3, + 107,2,144,1,114,126,116,15,160,10,100,19,161,1,1,0, + 100,20,116,12,118,0,144,1,114,126,100,21,116,16,95,17, + 100,22,83,0,41,23,122,205,83,101,116,117,112,32,116,104, + 101,32,112,97,116,104,45,98,97,115,101,100,32,105,109,112, + 111,114,116,101,114,115,32,102,111,114,32,105,109,112,111,114, + 116,108,105,98,32,98,121,32,105,109,112,111,114,116,105,110, + 103,32,110,101,101,100,101,100,10,32,32,32,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,110, + 100,32,105,110,106,101,99,116,105,110,103,32,116,104,101,109, + 32,105,110,116,111,32,116,104,101,32,103,108,111,98,97,108, + 32,110,97,109,101,115,112,97,99,101,46,10,10,32,32,32, + 32,79,116,104,101,114,32,99,111,109,112,111,110,101,110,116, + 115,32,97,114,101,32,101,120,116,114,97,99,116,101,100,32, + 102,114,111,109,32,116,104,101,32,99,111,114,101,32,98,111, + 111,116,115,116,114,97,112,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,90,5,112,111,115,105,120,250,1,47,90, + 2,110,116,250,1,92,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,115,0,0,0,115, + 26,0,0,0,124,0,93,18,125,1,116,0,124,1,131,1, + 100,0,107,2,86,0,1,0,113,2,100,1,83,0,41,2, + 114,39,0,0,0,78,41,1,114,23,0,0,0,41,2,114, + 32,0,0,0,114,94,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,10,1,0,0,35,6,0, + 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, + 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, + 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, + 98,32,114,101,113,117,105,114,101,115,32,112,111,115,105,120, + 32,111,114,32,110,116,114,4,0,0,0,114,35,0,0,0, + 114,31,0,0,0,114,40,0,0,0,114,58,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, + 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, + 4,83,0,41,1,114,74,0,0,0,114,5,0,0,0,41, + 2,114,32,0,0,0,218,1,115,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,64,1,0,0,52,6,0, + 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, + 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, + 62,41,3,114,64,0,0,0,114,75,0,0,0,114,160,0, + 0,0,114,192,0,0,0,114,9,0,0,0,122,4,46,112, + 121,119,122,6,95,100,46,112,121,100,84,78,41,18,114,134, + 0,0,0,114,1,0,0,0,114,163,0,0,0,114,22,1, + 0,0,114,125,0,0,0,218,3,97,108,108,90,18,95,98, + 117,105,108,116,105,110,95,102,114,111,109,95,110,97,109,101, + 114,117,0,0,0,114,129,0,0,0,114,36,0,0,0,114, + 186,0,0,0,114,14,0,0,0,114,12,1,0,0,114,167, + 0,0,0,114,76,1,0,0,114,101,0,0,0,114,191,0, + 0,0,114,195,0,0,0,41,10,218,17,95,98,111,111,116, + 115,116,114,97,112,95,109,111,100,117,108,101,90,11,115,101, + 108,102,95,109,111,100,117,108,101,90,10,111,115,95,100,101, + 116,97,105,108,115,90,10,98,117,105,108,116,105,110,95,111, + 115,114,31,0,0,0,114,35,0,0,0,90,9,111,115,95, + 109,111,100,117,108,101,90,13,98,117,105,108,116,105,110,95, + 110,97,109,101,115,90,12,98,117,105,108,116,105,110,95,110, + 97,109,101,90,14,98,117,105,108,116,105,110,95,109,111,100, + 117,108,101,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,218,6,95,115,101,116,117,112,17,6,0,0,115,70, + 0,0,0,0,8,4,1,6,1,6,2,10,3,22,1,12, + 2,22,1,8,1,10,1,10,1,6,2,2,1,10,1,10, + 1,12,1,10,2,8,2,12,1,12,1,18,1,22,3,8, + 1,10,1,10,1,8,1,12,1,12,2,10,1,16,3,14, + 1,14,1,10,1,10,1,10,1,114,82,1,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,67,0,0,0,115,50,0,0,0,116,0,124,0, + 131,1,1,0,116,1,131,0,125,1,116,2,106,3,160,4, + 116,5,106,6,124,1,142,0,103,1,161,1,1,0,116,2, + 106,7,160,8,116,9,161,1,1,0,100,1,83,0,41,2, + 122,41,73,110,115,116,97,108,108,32,116,104,101,32,112,97, + 116,104,45,98,97,115,101,100,32,105,109,112,111,114,116,32, + 99,111,109,112,111,110,101,110,116,115,46,78,41,10,114,82, + 1,0,0,114,184,0,0,0,114,1,0,0,0,114,43,1, + 0,0,114,167,0,0,0,114,54,1,0,0,114,70,1,0, + 0,218,9,109,101,116,97,95,112,97,116,104,114,186,0,0, + 0,114,37,1,0,0,41,2,114,81,1,0,0,90,17,115, + 117,112,112,111,114,116,101,100,95,108,111,97,100,101,114,115, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, + 8,95,105,110,115,116,97,108,108,74,6,0,0,115,8,0, + 0,0,0,2,8,1,6,1,20,1,114,84,1,0,0,41, + 1,114,60,0,0,0,41,1,78,41,3,78,78,78,41,2, + 114,73,0,0,0,114,73,0,0,0,41,1,84,41,1,78, + 41,1,78,41,63,114,127,0,0,0,114,13,0,0,0,90, + 37,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, + 86,69,95,80,76,65,84,70,79,82,77,83,95,66,89,84, + 69,83,95,75,69,89,114,12,0,0,0,114,14,0,0,0, + 114,21,0,0,0,114,27,0,0,0,114,29,0,0,0,114, + 38,0,0,0,114,47,0,0,0,114,49,0,0,0,114,53, + 0,0,0,114,54,0,0,0,114,56,0,0,0,114,59,0, + 0,0,114,69,0,0,0,218,4,116,121,112,101,218,8,95, + 95,99,111,100,101,95,95,114,162,0,0,0,114,19,0,0, + 0,114,148,0,0,0,114,18,0,0,0,114,24,0,0,0, + 114,236,0,0,0,114,91,0,0,0,114,87,0,0,0,114, + 101,0,0,0,114,88,0,0,0,90,23,68,69,66,85,71, + 95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, + 69,83,90,27,79,80,84,73,77,73,90,69,68,95,66,89, + 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,114, + 97,0,0,0,114,102,0,0,0,114,108,0,0,0,114,112, + 0,0,0,114,114,0,0,0,114,136,0,0,0,114,143,0, + 0,0,114,152,0,0,0,114,156,0,0,0,114,158,0,0, + 0,114,165,0,0,0,114,170,0,0,0,114,171,0,0,0, + 114,176,0,0,0,218,6,111,98,106,101,99,116,114,185,0, + 0,0,114,190,0,0,0,114,191,0,0,0,114,208,0,0, + 0,114,221,0,0,0,114,239,0,0,0,114,255,0,0,0, + 114,5,1,0,0,114,12,1,0,0,114,252,0,0,0,114, + 13,1,0,0,114,35,1,0,0,114,37,1,0,0,114,54, + 1,0,0,114,75,1,0,0,114,184,0,0,0,114,82,1, + 0,0,114,84,1,0,0,114,5,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,218,8,60,109,111, + 100,117,108,101,62,1,0,0,0,115,126,0,0,0,4,22, + 4,1,4,1,2,1,2,255,4,4,8,17,8,5,8,5, + 8,6,8,6,8,12,8,10,8,9,8,5,8,7,8,9, + 10,22,10,127,0,20,16,1,12,2,4,1,4,2,6,2, + 6,2,8,2,16,71,8,40,8,19,8,12,8,12,8,28, + 8,17,8,33,8,28,8,24,10,13,10,10,10,11,8,14, + 6,3,4,1,2,255,12,68,14,64,14,29,16,127,0,17, + 14,50,18,45,18,26,4,3,18,53,14,63,14,42,14,127, + 0,20,14,127,0,22,10,23,8,11,8,57, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index be7d24fe1df257c..a70d7d2fe780706 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -502,460 +502,459 @@ const unsigned char _Py_M__zipimport[] = { 0,0,114,9,0,0,0,114,10,0,0,0,114,37,0,0, 0,53,1,0,0,115,4,0,0,0,0,4,8,2,114,37, 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 7,0,0,0,4,0,0,0,67,0,0,0,115,56,0,0, + 7,0,0,0,4,0,0,0,67,0,0,0,115,54,0,0, 0,116,0,124,0,124,1,131,2,125,2,116,1,68,0,93, - 36,92,3,125,3,125,4,125,5,124,2,124,3,23,0,125, + 34,92,3,125,3,125,4,125,5,124,2,124,3,23,0,125, 6,124,6,124,0,106,2,118,0,114,14,124,5,2,0,1, - 0,83,0,113,14,100,0,83,0,114,86,0,0,0,41,3, - 114,36,0,0,0,218,16,95,122,105,112,95,115,101,97,114, - 99,104,111,114,100,101,114,114,28,0,0,0,41,7,114,32, - 0,0,0,114,38,0,0,0,114,13,0,0,0,218,6,115, - 117,102,102,105,120,218,10,105,115,98,121,116,101,99,111,100, - 101,114,47,0,0,0,114,63,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,114,35,0,0,0,62, - 1,0,0,115,12,0,0,0,0,1,10,1,14,1,8,1, - 10,1,10,1,114,35,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,26,0,0,0,9,0,0,0,67,0, - 0,0,115,2,5,0,0,122,14,116,0,160,1,124,0,161, - 1,125,1,87,0,110,36,4,0,116,2,121,50,1,0,1, - 0,1,0,116,3,100,1,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,89,0,110,2,48,0,124,1,144,4,143, - 164,1,0,122,36,124,1,160,4,116,5,11,0,100,3,161, - 2,1,0,124,1,160,6,161,0,125,2,124,1,160,7,116, - 5,161,1,125,3,87,0,110,36,4,0,116,2,121,132,1, - 0,1,0,1,0,116,3,100,4,124,0,155,2,157,2,124, - 0,100,2,141,2,130,1,89,0,110,2,48,0,116,8,124, - 3,131,1,116,5,107,3,114,164,116,3,100,4,124,0,155, - 2,157,2,124,0,100,2,141,2,130,1,124,3,100,0,100, - 5,133,2,25,0,116,9,107,3,144,1,114,170,122,24,124, - 1,160,4,100,6,100,3,161,2,1,0,124,1,160,6,161, - 0,125,4,87,0,110,36,4,0,116,2,121,242,1,0,1, - 0,1,0,116,3,100,4,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,89,0,110,2,48,0,116,10,124,4,116, - 11,24,0,116,5,24,0,100,6,131,2,125,5,122,22,124, - 1,160,4,124,5,161,1,1,0,124,1,160,7,161,0,125, - 6,87,0,110,38,4,0,116,2,144,1,121,66,1,0,1, + 0,83,0,100,0,83,0,114,86,0,0,0,41,3,114,36, + 0,0,0,218,16,95,122,105,112,95,115,101,97,114,99,104, + 111,114,100,101,114,114,28,0,0,0,41,7,114,32,0,0, + 0,114,38,0,0,0,114,13,0,0,0,218,6,115,117,102, + 102,105,120,218,10,105,115,98,121,116,101,99,111,100,101,114, + 47,0,0,0,114,63,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,114,35,0,0,0,62,1,0, + 0,115,12,0,0,0,0,1,10,1,14,1,8,1,10,1, + 8,1,114,35,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,26,0,0,0,9,0,0,0,67,0,0,0, + 115,2,5,0,0,122,14,116,0,160,1,124,0,161,1,125, + 1,87,0,110,36,4,0,116,2,121,50,1,0,1,0,1, + 0,116,3,100,1,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,89,0,110,2,48,0,124,1,144,4,143,164,1, + 0,122,36,124,1,160,4,116,5,11,0,100,3,161,2,1, + 0,124,1,160,6,161,0,125,2,124,1,160,7,116,5,161, + 1,125,3,87,0,110,36,4,0,116,2,121,132,1,0,1, 0,1,0,116,3,100,4,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,89,0,110,2,48,0,124,6,160,12,116, - 9,161,1,125,7,124,7,100,6,107,0,144,1,114,106,116, - 3,100,7,124,0,155,2,157,2,124,0,100,2,141,2,130, - 1,124,6,124,7,124,7,116,5,23,0,133,2,25,0,125, - 3,116,8,124,3,131,1,116,5,107,3,144,1,114,154,116, - 3,100,8,124,0,155,2,157,2,124,0,100,2,141,2,130, - 1,124,4,116,8,124,6,131,1,24,0,124,7,23,0,125, - 2,116,13,124,3,100,9,100,10,133,2,25,0,131,1,125, - 8,116,13,124,3,100,10,100,11,133,2,25,0,131,1,125, - 9,124,2,124,8,107,0,144,1,114,230,116,3,100,12,124, - 0,155,2,157,2,124,0,100,2,141,2,130,1,124,2,124, - 9,107,0,144,2,114,2,116,3,100,13,124,0,155,2,157, - 2,124,0,100,2,141,2,130,1,124,2,124,8,56,0,125, - 2,124,2,124,9,24,0,125,10,124,10,100,6,107,0,144, - 2,114,46,116,3,100,14,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,105,0,125,11,100,6,125,12,122,14,124, - 1,160,4,124,2,161,1,1,0,87,0,110,38,4,0,116, - 2,144,2,121,106,1,0,1,0,1,0,116,3,100,4,124, + 2,141,2,130,1,89,0,110,2,48,0,116,8,124,3,131, + 1,116,5,107,3,114,164,116,3,100,4,124,0,155,2,157, + 2,124,0,100,2,141,2,130,1,124,3,100,0,100,5,133, + 2,25,0,116,9,107,3,144,1,114,170,122,24,124,1,160, + 4,100,6,100,3,161,2,1,0,124,1,160,6,161,0,125, + 4,87,0,110,36,4,0,116,2,121,242,1,0,1,0,1, + 0,116,3,100,4,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,89,0,110,2,48,0,116,10,124,4,116,11,24, + 0,116,5,24,0,100,6,131,2,125,5,122,22,124,1,160, + 4,124,5,161,1,1,0,124,1,160,7,161,0,125,6,87, + 0,110,38,4,0,116,2,144,1,121,66,1,0,1,0,1, + 0,116,3,100,4,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,89,0,110,2,48,0,124,6,160,12,116,9,161, + 1,125,7,124,7,100,6,107,0,144,1,114,106,116,3,100, + 7,124,0,155,2,157,2,124,0,100,2,141,2,130,1,124, + 6,124,7,124,7,116,5,23,0,133,2,25,0,125,3,116, + 8,124,3,131,1,116,5,107,3,144,1,114,154,116,3,100, + 8,124,0,155,2,157,2,124,0,100,2,141,2,130,1,124, + 4,116,8,124,6,131,1,24,0,124,7,23,0,125,2,116, + 13,124,3,100,9,100,10,133,2,25,0,131,1,125,8,116, + 13,124,3,100,10,100,11,133,2,25,0,131,1,125,9,124, + 2,124,8,107,0,144,1,114,230,116,3,100,12,124,0,155, + 2,157,2,124,0,100,2,141,2,130,1,124,2,124,9,107, + 0,144,2,114,2,116,3,100,13,124,0,155,2,157,2,124, + 0,100,2,141,2,130,1,124,2,124,8,56,0,125,2,124, + 2,124,9,24,0,125,10,124,10,100,6,107,0,144,2,114, + 46,116,3,100,14,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,105,0,125,11,100,6,125,12,122,14,124,1,160, + 4,124,2,161,1,1,0,87,0,110,38,4,0,116,2,144, + 2,121,106,1,0,1,0,1,0,116,3,100,4,124,0,155, + 2,157,2,124,0,100,2,141,2,130,1,89,0,110,2,48, + 0,124,1,160,7,100,15,161,1,125,3,116,8,124,3,131, + 1,100,5,107,0,144,2,114,140,116,14,100,16,131,1,130, + 1,124,3,100,0,100,5,133,2,25,0,100,17,107,3,144, + 2,114,162,144,4,113,208,116,8,124,3,131,1,100,15,107, + 3,144,2,114,184,116,14,100,16,131,1,130,1,116,15,124, + 3,100,18,100,19,133,2,25,0,131,1,125,13,116,15,124, + 3,100,19,100,9,133,2,25,0,131,1,125,14,116,15,124, + 3,100,9,100,20,133,2,25,0,131,1,125,15,116,15,124, + 3,100,20,100,10,133,2,25,0,131,1,125,16,116,13,124, + 3,100,10,100,11,133,2,25,0,131,1,125,17,116,13,124, + 3,100,11,100,21,133,2,25,0,131,1,125,18,116,13,124, + 3,100,21,100,22,133,2,25,0,131,1,125,4,116,15,124, + 3,100,22,100,23,133,2,25,0,131,1,125,19,116,15,124, + 3,100,23,100,24,133,2,25,0,131,1,125,20,116,15,124, + 3,100,24,100,25,133,2,25,0,131,1,125,21,116,13,124, + 3,100,26,100,15,133,2,25,0,131,1,125,22,124,19,124, + 20,23,0,124,21,23,0,125,8,124,22,124,9,107,4,144, + 3,114,144,116,3,100,27,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,124,22,124,10,55,0,125,22,122,14,124, + 1,160,7,124,19,161,1,125,23,87,0,110,38,4,0,116, + 2,144,3,121,204,1,0,1,0,1,0,116,3,100,4,124, 0,155,2,157,2,124,0,100,2,141,2,130,1,89,0,110, - 2,48,0,124,1,160,7,100,15,161,1,125,3,116,8,124, - 3,131,1,100,5,107,0,144,2,114,140,116,14,100,16,131, - 1,130,1,124,3,100,0,100,5,133,2,25,0,100,17,107, - 3,144,2,114,162,144,4,113,208,116,8,124,3,131,1,100, - 15,107,3,144,2,114,184,116,14,100,16,131,1,130,1,116, - 15,124,3,100,18,100,19,133,2,25,0,131,1,125,13,116, - 15,124,3,100,19,100,9,133,2,25,0,131,1,125,14,116, - 15,124,3,100,9,100,20,133,2,25,0,131,1,125,15,116, - 15,124,3,100,20,100,10,133,2,25,0,131,1,125,16,116, - 13,124,3,100,10,100,11,133,2,25,0,131,1,125,17,116, - 13,124,3,100,11,100,21,133,2,25,0,131,1,125,18,116, - 13,124,3,100,21,100,22,133,2,25,0,131,1,125,4,116, - 15,124,3,100,22,100,23,133,2,25,0,131,1,125,19,116, - 15,124,3,100,23,100,24,133,2,25,0,131,1,125,20,116, - 15,124,3,100,24,100,25,133,2,25,0,131,1,125,21,116, - 13,124,3,100,26,100,15,133,2,25,0,131,1,125,22,124, - 19,124,20,23,0,124,21,23,0,125,8,124,22,124,9,107, - 4,144,3,114,144,116,3,100,27,124,0,155,2,157,2,124, - 0,100,2,141,2,130,1,124,22,124,10,55,0,125,22,122, - 14,124,1,160,7,124,19,161,1,125,23,87,0,110,38,4, - 0,116,2,144,3,121,204,1,0,1,0,1,0,116,3,100, - 4,124,0,155,2,157,2,124,0,100,2,141,2,130,1,89, - 0,110,2,48,0,116,8,124,23,131,1,124,19,107,3,144, - 3,114,238,116,3,100,4,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,122,50,116,8,124,1,160,7,124,8,124, - 19,24,0,161,1,131,1,124,8,124,19,24,0,107,3,144, - 4,114,30,116,3,100,4,124,0,155,2,157,2,124,0,100, - 2,141,2,130,1,87,0,110,38,4,0,116,2,144,4,121, - 70,1,0,1,0,1,0,116,3,100,4,124,0,155,2,157, - 2,124,0,100,2,141,2,130,1,89,0,110,2,48,0,124, - 13,100,28,64,0,144,4,114,92,124,23,160,16,161,0,125, - 23,110,52,122,14,124,23,160,16,100,29,161,1,125,23,87, - 0,110,36,4,0,116,17,144,4,121,142,1,0,1,0,1, - 0,124,23,160,16,100,30,161,1,160,18,116,19,161,1,125, - 23,89,0,110,2,48,0,124,23,160,20,100,31,116,21,161, - 2,125,23,116,22,160,23,124,0,124,23,161,2,125,24,124, - 24,124,14,124,18,124,4,124,22,124,15,124,16,124,17,102, - 8,125,25,124,25,124,11,124,23,60,0,124,12,100,32,55, - 0,125,12,144,2,113,108,87,0,100,0,4,0,4,0,131, - 3,1,0,110,18,49,0,144,4,115,230,48,0,1,0,1, - 0,1,0,89,0,1,0,116,24,160,25,100,33,124,12,124, - 0,161,3,1,0,124,11,83,0,41,34,78,122,21,99,97, - 110,39,116,32,111,112,101,110,32,90,105,112,32,102,105,108, - 101,58,32,114,12,0,0,0,114,84,0,0,0,250,21,99, - 97,110,39,116,32,114,101,97,100,32,90,105,112,32,102,105, - 108,101,58,32,233,4,0,0,0,114,0,0,0,0,122,16, - 110,111,116,32,97,32,90,105,112,32,102,105,108,101,58,32, - 122,18,99,111,114,114,117,112,116,32,90,105,112,32,102,105, - 108,101,58,32,233,12,0,0,0,233,16,0,0,0,233,20, - 0,0,0,122,28,98,97,100,32,99,101,110,116,114,97,108, - 32,100,105,114,101,99,116,111,114,121,32,115,105,122,101,58, - 32,122,30,98,97,100,32,99,101,110,116,114,97,108,32,100, - 105,114,101,99,116,111,114,121,32,111,102,102,115,101,116,58, - 32,122,38,98,97,100,32,99,101,110,116,114,97,108,32,100, - 105,114,101,99,116,111,114,121,32,115,105,122,101,32,111,114, - 32,111,102,102,115,101,116,58,32,233,46,0,0,0,250,27, - 69,79,70,32,114,101,97,100,32,119,104,101,114,101,32,110, - 111,116,32,101,120,112,101,99,116,101,100,115,4,0,0,0, - 80,75,1,2,233,8,0,0,0,233,10,0,0,0,233,14, - 0,0,0,233,24,0,0,0,233,28,0,0,0,233,30,0, - 0,0,233,32,0,0,0,233,34,0,0,0,233,42,0,0, - 0,122,25,98,97,100,32,108,111,99,97,108,32,104,101,97, - 100,101,114,32,111,102,102,115,101,116,58,32,105,0,8,0, - 0,218,5,97,115,99,105,105,90,6,108,97,116,105,110,49, - 250,1,47,114,5,0,0,0,122,33,122,105,112,105,109,112, - 111,114,116,58,32,102,111,117,110,100,32,123,125,32,110,97, - 109,101,115,32,105,110,32,123,33,114,125,41,26,218,3,95, - 105,111,218,9,111,112,101,110,95,99,111,100,101,114,22,0, - 0,0,114,3,0,0,0,218,4,115,101,101,107,218,20,69, - 78,68,95,67,69,78,84,82,65,76,95,68,73,82,95,83, - 73,90,69,90,4,116,101,108,108,218,4,114,101,97,100,114, - 51,0,0,0,218,18,83,84,82,73,78,71,95,69,78,68, - 95,65,82,67,72,73,86,69,218,3,109,97,120,218,15,77, - 65,88,95,67,79,77,77,69,78,84,95,76,69,78,218,5, - 114,102,105,110,100,114,2,0,0,0,218,8,69,79,70,69, - 114,114,111,114,114,1,0,0,0,114,62,0,0,0,218,18, - 85,110,105,99,111,100,101,68,101,99,111,100,101,69,114,114, - 111,114,218,9,116,114,97,110,115,108,97,116,101,218,11,99, - 112,52,51,55,95,116,97,98,108,101,114,19,0,0,0,114, - 20,0,0,0,114,21,0,0,0,114,30,0,0,0,114,76, - 0,0,0,114,77,0,0,0,41,26,114,29,0,0,0,218, - 2,102,112,90,15,104,101,97,100,101,114,95,112,111,115,105, - 116,105,111,110,218,6,98,117,102,102,101,114,218,9,102,105, - 108,101,95,115,105,122,101,90,17,109,97,120,95,99,111,109, - 109,101,110,116,95,115,116,97,114,116,218,4,100,97,116,97, - 90,3,112,111,115,218,11,104,101,97,100,101,114,95,115,105, - 122,101,90,13,104,101,97,100,101,114,95,111,102,102,115,101, - 116,90,10,97,114,99,95,111,102,102,115,101,116,114,33,0, - 0,0,218,5,99,111,117,110,116,218,5,102,108,97,103,115, - 218,8,99,111,109,112,114,101,115,115,218,4,116,105,109,101, - 218,4,100,97,116,101,218,3,99,114,99,218,9,100,97,116, - 97,95,115,105,122,101,218,9,110,97,109,101,95,115,105,122, - 101,218,10,101,120,116,114,97,95,115,105,122,101,90,12,99, - 111,109,109,101,110,116,95,115,105,122,101,218,11,102,105,108, - 101,95,111,102,102,115,101,116,114,59,0,0,0,114,13,0, - 0,0,218,1,116,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,27,0,0,0,93,1,0,0,115,212,0, - 0,0,0,1,2,1,14,1,12,1,24,2,8,1,2,1, - 14,1,8,1,14,1,12,1,24,1,12,1,18,1,18,3, - 2,1,12,1,12,1,12,1,10,1,2,255,12,2,8,1, - 2,255,2,1,2,255,4,2,2,1,10,1,12,1,14,1, - 10,1,2,255,12,2,10,1,10,1,10,1,2,255,6,2, - 16,1,14,1,10,1,2,255,6,2,16,2,16,1,16,1, - 10,1,18,1,10,1,18,1,8,1,8,1,10,1,18,2, - 4,2,4,1,2,1,14,1,14,1,24,2,10,1,14,1, - 8,2,18,1,4,1,14,1,8,1,16,1,16,1,16,1, - 16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1, - 12,1,10,1,18,1,8,2,2,1,14,1,14,1,24,1, - 14,1,18,4,2,1,28,1,22,1,14,1,24,2,10,2, - 10,3,2,1,14,1,14,1,22,2,12,1,12,1,20,1, - 8,1,44,1,14,1,114,27,0,0,0,117,190,1,0,0, - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, - 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, - 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, - 195,135,195,188,195,169,195,162,195,164,195,160,195,165,195,167, - 195,170,195,171,195,168,195,175,195,174,195,172,195,132,195,133, - 195,137,195,166,195,134,195,180,195,182,195,178,195,187,195,185, - 195,191,195,150,195,156,194,162,194,163,194,165,226,130,167,198, - 146,195,161,195,173,195,179,195,186,195,177,195,145,194,170,194, - 186,194,191,226,140,144,194,172,194,189,194,188,194,161,194,171, - 194,187,226,150,145,226,150,146,226,150,147,226,148,130,226,148, - 164,226,149,161,226,149,162,226,149,150,226,149,149,226,149,163, - 226,149,145,226,149,151,226,149,157,226,149,156,226,149,155,226, - 148,144,226,148,148,226,148,180,226,148,172,226,148,156,226,148, - 128,226,148,188,226,149,158,226,149,159,226,149,154,226,149,148, - 226,149,169,226,149,166,226,149,160,226,149,144,226,149,172,226, - 149,167,226,149,168,226,149,164,226,149,165,226,149,153,226,149, - 152,226,149,146,226,149,147,226,149,171,226,149,170,226,148,152, - 226,148,140,226,150,136,226,150,132,226,150,140,226,150,144,226, - 150,128,206,177,195,159,206,147,207,128,206,163,207,131,194,181, - 207,132,206,166,206,152,206,169,206,180,226,136,158,207,134,206, - 181,226,136,169,226,137,161,194,177,226,137,165,226,137,164,226, - 140,160,226,140,161,195,183,226,137,136,194,176,226,136,153,194, - 183,226,136,154,226,129,191,194,178,226,150,160,194,160,99,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8, - 0,0,0,67,0,0,0,115,110,0,0,0,116,0,114,22, - 116,1,160,2,100,1,161,1,1,0,116,3,100,2,131,1, - 130,1,100,3,97,0,122,62,122,16,100,4,100,5,108,4, - 109,5,125,0,1,0,87,0,110,36,4,0,116,6,121,80, - 1,0,1,0,1,0,116,1,160,2,100,1,161,1,1,0, - 116,3,100,2,131,1,130,1,89,0,110,2,48,0,87,0, - 100,6,97,0,110,6,100,6,97,0,48,0,116,1,160,2, - 100,7,161,1,1,0,124,0,83,0,41,8,78,122,27,122, - 105,112,105,109,112,111,114,116,58,32,122,108,105,98,32,85, - 78,65,86,65,73,76,65,66,76,69,250,41,99,97,110,39, - 116,32,100,101,99,111,109,112,114,101,115,115,32,100,97,116, - 97,59,32,122,108,105,98,32,110,111,116,32,97,118,97,105, - 108,97,98,108,101,84,114,0,0,0,0,169,1,218,10,100, - 101,99,111,109,112,114,101,115,115,70,122,25,122,105,112,105, - 109,112,111,114,116,58,32,122,108,105,98,32,97,118,97,105, - 108,97,98,108,101,41,7,218,15,95,105,109,112,111,114,116, - 105,110,103,95,122,108,105,98,114,76,0,0,0,114,77,0, - 0,0,114,3,0,0,0,90,4,122,108,105,98,114,139,0, - 0,0,218,9,69,120,99,101,112,116,105,111,110,114,138,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,218,20,95,103,101,116,95,100,101,99,111,109,112,114,101, - 115,115,95,102,117,110,99,251,1,0,0,115,24,0,0,0, - 0,2,4,3,10,1,8,2,4,1,4,1,16,1,12,1, - 10,1,16,2,12,2,10,1,114,142,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,17,0,0,0,9,0, - 0,0,67,0,0,0,115,144,1,0,0,124,1,92,8,125, - 2,125,3,125,4,125,5,125,6,125,7,125,8,125,9,124, - 4,100,1,107,0,114,36,116,0,100,2,131,1,130,1,116, - 1,160,2,124,0,161,1,144,1,143,14,125,10,122,14,124, - 10,160,3,124,6,161,1,1,0,87,0,110,36,4,0,116, - 4,121,100,1,0,1,0,1,0,116,0,100,3,124,0,155, - 2,157,2,124,0,100,4,141,2,130,1,89,0,110,2,48, - 0,124,10,160,5,100,5,161,1,125,11,116,6,124,11,131, - 1,100,5,107,3,114,132,116,7,100,6,131,1,130,1,124, - 11,100,0,100,7,133,2,25,0,100,8,107,3,114,166,116, - 0,100,9,124,0,155,2,157,2,124,0,100,4,141,2,130, - 1,116,8,124,11,100,10,100,11,133,2,25,0,131,1,125, - 12,116,8,124,11,100,11,100,5,133,2,25,0,131,1,125, - 13,100,5,124,12,23,0,124,13,23,0,125,14,124,6,124, - 14,55,0,125,6,122,14,124,10,160,3,124,6,161,1,1, - 0,87,0,110,38,4,0,116,4,144,1,121,14,1,0,1, - 0,1,0,116,0,100,3,124,0,155,2,157,2,124,0,100, - 4,141,2,130,1,89,0,110,2,48,0,124,10,160,5,124, - 4,161,1,125,15,116,6,124,15,131,1,124,4,107,3,144, - 1,114,48,116,4,100,12,131,1,130,1,87,0,100,0,4, - 0,4,0,131,3,1,0,110,18,49,0,144,1,115,70,48, - 0,1,0,1,0,1,0,89,0,1,0,124,3,100,1,107, - 2,144,1,114,94,124,15,83,0,122,10,116,9,131,0,125, - 16,87,0,110,28,4,0,116,10,144,1,121,132,1,0,1, - 0,1,0,116,0,100,13,131,1,130,1,89,0,110,2,48, - 0,124,16,124,15,100,14,131,2,83,0,41,15,78,114,0, - 0,0,0,122,18,110,101,103,97,116,105,118,101,32,100,97, - 116,97,32,115,105,122,101,114,90,0,0,0,114,12,0,0, - 0,114,102,0,0,0,114,96,0,0,0,114,91,0,0,0, - 115,4,0,0,0,80,75,3,4,122,23,98,97,100,32,108, - 111,99,97,108,32,102,105,108,101,32,104,101,97,100,101,114, - 58,32,233,26,0,0,0,114,101,0,0,0,122,26,122,105, - 112,105,109,112,111,114,116,58,32,99,97,110,39,116,32,114, - 101,97,100,32,100,97,116,97,114,137,0,0,0,105,241,255, - 255,255,41,11,114,3,0,0,0,114,108,0,0,0,114,109, - 0,0,0,114,110,0,0,0,114,22,0,0,0,114,112,0, - 0,0,114,51,0,0,0,114,117,0,0,0,114,1,0,0, - 0,114,142,0,0,0,114,141,0,0,0,41,17,114,29,0, - 0,0,114,54,0,0,0,90,8,100,97,116,97,112,97,116, - 104,114,128,0,0,0,114,132,0,0,0,114,123,0,0,0, - 114,135,0,0,0,114,129,0,0,0,114,130,0,0,0,114, - 131,0,0,0,114,121,0,0,0,114,122,0,0,0,114,133, - 0,0,0,114,134,0,0,0,114,125,0,0,0,90,8,114, - 97,119,95,100,97,116,97,114,139,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,114,52,0,0,0, - 16,2,0,0,115,62,0,0,0,0,1,20,1,8,1,8, - 2,14,2,2,1,14,1,12,1,24,1,10,1,12,1,8, - 2,16,2,18,2,16,1,16,1,12,1,8,1,2,1,14, - 1,14,1,24,1,10,1,14,1,40,2,10,2,4,3,2, - 1,10,1,14,1,14,1,114,52,0,0,0,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,67,0,0,0,115,16,0,0,0,116,0,124,0,124,1, - 24,0,131,1,100,1,107,1,83,0,41,2,78,114,5,0, - 0,0,41,1,218,3,97,98,115,41,2,90,2,116,49,90, - 2,116,50,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,9,95,101,113,95,109,116,105,109,101,62,2,0, - 0,115,2,0,0,0,0,2,114,145,0,0,0,99,5,0, - 0,0,0,0,0,0,0,0,0,0,14,0,0,0,8,0, - 0,0,67,0,0,0,115,56,1,0,0,124,3,124,2,100, - 1,156,2,125,5,122,18,116,0,160,1,124,4,124,3,124, - 5,161,3,125,6,87,0,110,20,4,0,116,2,121,48,1, - 0,1,0,1,0,89,0,100,0,83,0,48,0,124,6,100, - 2,64,0,100,3,107,3,125,7,124,7,114,178,124,6,100, - 4,64,0,100,3,107,3,125,8,116,3,106,4,100,5,107, - 3,114,176,124,8,115,102,116,3,106,4,100,6,107,2,114, - 176,116,5,124,0,124,2,131,2,125,9,124,9,100,0,117, - 1,114,176,116,3,160,6,116,0,106,7,124,9,161,2,125, - 10,122,20,116,0,160,8,124,4,124,10,124,3,124,5,161, - 4,1,0,87,0,110,20,4,0,116,2,121,174,1,0,1, - 0,1,0,89,0,100,0,83,0,48,0,110,84,116,9,124, - 0,124,2,131,2,92,2,125,11,125,12,124,11,144,1,114, - 6,116,10,116,11,124,4,100,7,100,8,133,2,25,0,131, - 1,124,11,131,2,114,242,116,11,124,4,100,8,100,9,133, - 2,25,0,131,1,124,12,107,3,144,1,114,6,116,12,160, - 13,100,10,124,3,155,2,157,2,161,1,1,0,100,0,83, - 0,116,14,160,15,124,4,100,9,100,0,133,2,25,0,161, - 1,125,13,116,16,124,13,116,17,131,2,144,1,115,52,116, - 18,100,11,124,1,155,2,100,12,157,3,131,1,130,1,124, - 13,83,0,41,13,78,41,2,114,59,0,0,0,114,13,0, - 0,0,114,5,0,0,0,114,0,0,0,0,114,84,0,0, - 0,90,5,110,101,118,101,114,90,6,97,108,119,97,121,115, - 114,97,0,0,0,114,92,0,0,0,114,93,0,0,0,122, - 22,98,121,116,101,99,111,100,101,32,105,115,32,115,116,97, - 108,101,32,102,111,114,32,122,16,99,111,109,112,105,108,101, - 100,32,109,111,100,117,108,101,32,122,21,32,105,115,32,110, - 111,116,32,97,32,99,111,100,101,32,111,98,106,101,99,116, - 41,19,114,21,0,0,0,90,13,95,99,108,97,115,115,105, - 102,121,95,112,121,99,114,75,0,0,0,218,4,95,105,109, - 112,90,21,99,104,101,99,107,95,104,97,115,104,95,98,97, - 115,101,100,95,112,121,99,115,218,15,95,103,101,116,95,112, - 121,99,95,115,111,117,114,99,101,218,11,115,111,117,114,99, - 101,95,104,97,115,104,90,17,95,82,65,87,95,77,65,71, - 73,67,95,78,85,77,66,69,82,90,18,95,118,97,108,105, - 100,97,116,101,95,104,97,115,104,95,112,121,99,218,29,95, - 103,101,116,95,109,116,105,109,101,95,97,110,100,95,115,105, - 122,101,95,111,102,95,115,111,117,114,99,101,114,145,0,0, - 0,114,2,0,0,0,114,76,0,0,0,114,77,0,0,0, - 218,7,109,97,114,115,104,97,108,90,5,108,111,97,100,115, - 114,15,0,0,0,218,10,95,99,111,100,101,95,116,121,112, - 101,218,9,84,121,112,101,69,114,114,111,114,41,14,114,32, - 0,0,0,114,53,0,0,0,114,63,0,0,0,114,38,0, - 0,0,114,124,0,0,0,90,11,101,120,99,95,100,101,116, - 97,105,108,115,114,127,0,0,0,90,10,104,97,115,104,95, - 98,97,115,101,100,90,12,99,104,101,99,107,95,115,111,117, - 114,99,101,90,12,115,111,117,114,99,101,95,98,121,116,101, - 115,114,148,0,0,0,90,12,115,111,117,114,99,101,95,109, - 116,105,109,101,90,11,115,111,117,114,99,101,95,115,105,122, - 101,114,46,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,15,95,117,110,109,97,114,115,104,97, - 108,95,99,111,100,101,72,2,0,0,115,82,0,0,0,0, - 2,2,1,2,254,6,5,2,1,18,1,12,1,8,2,12, - 1,4,1,12,1,10,1,2,255,2,1,8,255,2,2,10, - 1,8,1,4,1,4,1,2,254,4,5,2,1,4,1,8, - 255,8,2,12,1,10,3,8,255,6,3,6,3,22,1,18, - 255,4,2,4,1,8,255,4,2,4,2,18,1,12,1,16, - 1,114,153,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115, - 28,0,0,0,124,0,160,0,100,1,100,2,161,2,125,0, - 124,0,160,0,100,3,100,2,161,2,125,0,124,0,83,0, - 41,4,78,115,2,0,0,0,13,10,243,1,0,0,0,10, - 243,1,0,0,0,13,41,1,114,19,0,0,0,41,1,218, - 6,115,111,117,114,99,101,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,23,95,110,111,114,109,97,108,105, - 122,101,95,108,105,110,101,95,101,110,100,105,110,103,115,123, - 2,0,0,115,6,0,0,0,0,1,12,1,12,1,114,157, - 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,6,0,0,0,67,0,0,0,115,24,0,0, - 0,116,0,124,1,131,1,125,1,116,1,124,1,124,0,100, - 1,100,2,100,3,141,4,83,0,41,4,78,114,74,0,0, - 0,84,41,1,90,12,100,111,110,116,95,105,110,104,101,114, - 105,116,41,2,114,157,0,0,0,218,7,99,111,109,112,105, - 108,101,41,2,114,53,0,0,0,114,156,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,15,95, - 99,111,109,112,105,108,101,95,115,111,117,114,99,101,130,2, - 0,0,115,4,0,0,0,0,1,8,1,114,159,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,11,0,0,0,67,0,0,0,115,68,0,0,0,116,0, - 160,1,124,0,100,1,63,0,100,2,23,0,124,0,100,3, - 63,0,100,4,64,0,124,0,100,5,64,0,124,1,100,6, - 63,0,124,1,100,3,63,0,100,7,64,0,124,1,100,5, - 64,0,100,8,20,0,100,9,100,9,100,9,102,9,161,1, - 83,0,41,10,78,233,9,0,0,0,105,188,7,0,0,233, - 5,0,0,0,233,15,0,0,0,233,31,0,0,0,233,11, - 0,0,0,233,63,0,0,0,114,84,0,0,0,114,14,0, - 0,0,41,2,114,129,0,0,0,90,6,109,107,116,105,109, - 101,41,2,218,1,100,114,136,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,14,95,112,97,114, - 115,101,95,100,111,115,116,105,109,101,136,2,0,0,115,18, - 0,0,0,0,1,4,1,10,1,10,1,6,1,6,1,10, - 1,10,1,6,249,114,167,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,6,0,0,0,10,0,0,0,67, - 0,0,0,115,114,0,0,0,122,82,124,1,100,1,100,0, - 133,2,25,0,100,2,118,0,115,22,74,0,130,1,124,1, - 100,0,100,1,133,2,25,0,125,1,124,0,106,0,124,1, - 25,0,125,2,124,2,100,3,25,0,125,3,124,2,100,4, - 25,0,125,4,124,2,100,5,25,0,125,5,116,1,124,4, - 124,3,131,2,124,5,102,2,87,0,83,0,4,0,116,2, - 116,3,116,4,102,3,121,108,1,0,1,0,1,0,89,0, - 100,6,83,0,48,0,100,0,83,0,41,7,78,114,14,0, - 0,0,169,2,218,1,99,218,1,111,114,161,0,0,0,233, - 6,0,0,0,233,3,0,0,0,41,2,114,0,0,0,0, - 114,0,0,0,0,41,5,114,28,0,0,0,114,167,0,0, - 0,114,26,0,0,0,218,10,73,110,100,101,120,69,114,114, - 111,114,114,152,0,0,0,41,6,114,32,0,0,0,114,13, - 0,0,0,114,54,0,0,0,114,129,0,0,0,114,130,0, - 0,0,90,17,117,110,99,111,109,112,114,101,115,115,101,100, - 95,115,105,122,101,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,149,0,0,0,149,2,0,0,115,20,0, - 0,0,0,1,2,2,20,1,12,1,10,3,8,1,8,1, - 8,1,16,1,18,1,114,149,0,0,0,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,8,0,0,0, - 67,0,0,0,115,84,0,0,0,124,1,100,1,100,0,133, - 2,25,0,100,2,118,0,115,20,74,0,130,1,124,1,100, - 0,100,1,133,2,25,0,125,1,122,14,124,0,106,0,124, - 1,25,0,125,2,87,0,110,20,4,0,116,1,121,66,1, - 0,1,0,1,0,89,0,100,0,83,0,48,0,116,2,124, - 0,106,3,124,2,131,2,83,0,100,0,83,0,41,3,78, - 114,14,0,0,0,114,168,0,0,0,41,4,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, - 41,3,114,32,0,0,0,114,13,0,0,0,114,54,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 114,147,0,0,0,168,2,0,0,115,14,0,0,0,0,2, - 20,1,12,2,2,1,14,1,12,1,8,2,114,147,0,0, - 0,99,2,0,0,0,0,0,0,0,0,0,0,0,11,0, - 0,0,9,0,0,0,67,0,0,0,115,196,0,0,0,116, - 0,124,0,124,1,131,2,125,2,116,1,68,0,93,158,92, - 3,125,3,125,4,125,5,124,2,124,3,23,0,125,6,116, - 2,106,3,100,1,124,0,106,4,116,5,124,6,100,2,100, - 3,141,5,1,0,122,14,124,0,106,6,124,6,25,0,125, - 7,87,0,110,18,4,0,116,7,121,86,1,0,1,0,1, - 0,89,0,113,14,48,0,124,7,100,4,25,0,125,8,116, - 8,124,0,106,4,124,7,131,2,125,9,124,4,114,130,116, - 9,124,0,124,8,124,6,124,1,124,9,131,5,125,10,110, - 10,116,10,124,8,124,9,131,2,125,10,124,10,100,0,117, - 0,114,150,113,14,124,7,100,4,25,0,125,8,124,10,124, - 5,124,8,102,3,2,0,1,0,83,0,113,14,116,11,100, - 5,124,1,155,2,157,2,124,1,100,6,141,2,130,1,100, - 0,83,0,41,7,78,122,13,116,114,121,105,110,103,32,123, - 125,123,125,123,125,114,84,0,0,0,41,1,90,9,118,101, - 114,98,111,115,105,116,121,114,0,0,0,0,114,57,0,0, - 0,114,58,0,0,0,41,12,114,36,0,0,0,114,87,0, - 0,0,114,76,0,0,0,114,77,0,0,0,114,29,0,0, - 0,114,20,0,0,0,114,28,0,0,0,114,26,0,0,0, - 114,52,0,0,0,114,153,0,0,0,114,159,0,0,0,114, - 3,0,0,0,41,11,114,32,0,0,0,114,38,0,0,0, - 114,13,0,0,0,114,88,0,0,0,114,89,0,0,0,114, - 47,0,0,0,114,63,0,0,0,114,54,0,0,0,114,40, - 0,0,0,114,124,0,0,0,114,46,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,44,0,0, - 0,183,2,0,0,115,36,0,0,0,0,1,10,1,14,1, - 8,1,22,1,2,1,14,1,12,1,6,2,8,1,12,1, - 4,1,18,2,10,1,8,3,2,1,8,1,16,2,114,44, - 0,0,0,41,44,114,82,0,0,0,90,26,95,102,114,111, - 122,101,110,95,105,109,112,111,114,116,108,105,98,95,101,120, - 116,101,114,110,97,108,114,21,0,0,0,114,1,0,0,0, - 114,2,0,0,0,90,17,95,102,114,111,122,101,110,95,105, - 109,112,111,114,116,108,105,98,114,76,0,0,0,114,146,0, - 0,0,114,108,0,0,0,114,150,0,0,0,114,67,0,0, - 0,114,129,0,0,0,90,7,95,95,97,108,108,95,95,114, - 20,0,0,0,90,15,112,97,116,104,95,115,101,112,97,114, - 97,116,111,114,115,114,18,0,0,0,114,75,0,0,0,114, - 3,0,0,0,114,25,0,0,0,218,4,116,121,112,101,114, - 70,0,0,0,114,111,0,0,0,114,113,0,0,0,114,115, - 0,0,0,114,4,0,0,0,114,87,0,0,0,114,36,0, - 0,0,114,37,0,0,0,114,35,0,0,0,114,27,0,0, - 0,114,120,0,0,0,114,140,0,0,0,114,142,0,0,0, - 114,52,0,0,0,114,145,0,0,0,114,153,0,0,0,218, - 8,95,95,99,111,100,101,95,95,114,151,0,0,0,114,157, - 0,0,0,114,159,0,0,0,114,167,0,0,0,114,149,0, - 0,0,114,147,0,0,0,114,44,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,84, - 0,0,0,4,16,8,1,16,1,8,1,8,1,8,1,8, - 1,8,1,8,2,8,3,6,1,14,3,16,4,4,2,8, - 2,4,1,4,1,4,2,14,127,0,125,12,1,12,1,2, - 1,2,252,4,9,8,4,8,9,8,31,8,126,2,254,2, - 29,4,5,8,21,8,46,8,10,8,46,10,5,8,7,8, - 6,8,13,8,19,8,15, + 2,48,0,116,8,124,23,131,1,124,19,107,3,144,3,114, + 238,116,3,100,4,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,122,50,116,8,124,1,160,7,124,8,124,19,24, + 0,161,1,131,1,124,8,124,19,24,0,107,3,144,4,114, + 30,116,3,100,4,124,0,155,2,157,2,124,0,100,2,141, + 2,130,1,87,0,110,38,4,0,116,2,144,4,121,70,1, + 0,1,0,1,0,116,3,100,4,124,0,155,2,157,2,124, + 0,100,2,141,2,130,1,89,0,110,2,48,0,124,13,100, + 28,64,0,144,4,114,92,124,23,160,16,161,0,125,23,110, + 52,122,14,124,23,160,16,100,29,161,1,125,23,87,0,110, + 36,4,0,116,17,144,4,121,142,1,0,1,0,1,0,124, + 23,160,16,100,30,161,1,160,18,116,19,161,1,125,23,89, + 0,110,2,48,0,124,23,160,20,100,31,116,21,161,2,125, + 23,116,22,160,23,124,0,124,23,161,2,125,24,124,24,124, + 14,124,18,124,4,124,22,124,15,124,16,124,17,102,8,125, + 25,124,25,124,11,124,23,60,0,124,12,100,32,55,0,125, + 12,144,2,113,108,87,0,100,0,4,0,4,0,131,3,1, + 0,110,18,49,0,144,4,115,230,48,0,1,0,1,0,1, + 0,89,0,1,0,116,24,160,25,100,33,124,12,124,0,161, + 3,1,0,124,11,83,0,41,34,78,122,21,99,97,110,39, + 116,32,111,112,101,110,32,90,105,112,32,102,105,108,101,58, + 32,114,12,0,0,0,114,84,0,0,0,250,21,99,97,110, + 39,116,32,114,101,97,100,32,90,105,112,32,102,105,108,101, + 58,32,233,4,0,0,0,114,0,0,0,0,122,16,110,111, + 116,32,97,32,90,105,112,32,102,105,108,101,58,32,122,18, + 99,111,114,114,117,112,116,32,90,105,112,32,102,105,108,101, + 58,32,233,12,0,0,0,233,16,0,0,0,233,20,0,0, + 0,122,28,98,97,100,32,99,101,110,116,114,97,108,32,100, + 105,114,101,99,116,111,114,121,32,115,105,122,101,58,32,122, + 30,98,97,100,32,99,101,110,116,114,97,108,32,100,105,114, + 101,99,116,111,114,121,32,111,102,102,115,101,116,58,32,122, + 38,98,97,100,32,99,101,110,116,114,97,108,32,100,105,114, + 101,99,116,111,114,121,32,115,105,122,101,32,111,114,32,111, + 102,102,115,101,116,58,32,233,46,0,0,0,250,27,69,79, + 70,32,114,101,97,100,32,119,104,101,114,101,32,110,111,116, + 32,101,120,112,101,99,116,101,100,115,4,0,0,0,80,75, + 1,2,233,8,0,0,0,233,10,0,0,0,233,14,0,0, + 0,233,24,0,0,0,233,28,0,0,0,233,30,0,0,0, + 233,32,0,0,0,233,34,0,0,0,233,42,0,0,0,122, + 25,98,97,100,32,108,111,99,97,108,32,104,101,97,100,101, + 114,32,111,102,102,115,101,116,58,32,105,0,8,0,0,218, + 5,97,115,99,105,105,90,6,108,97,116,105,110,49,250,1, + 47,114,5,0,0,0,122,33,122,105,112,105,109,112,111,114, + 116,58,32,102,111,117,110,100,32,123,125,32,110,97,109,101, + 115,32,105,110,32,123,33,114,125,41,26,218,3,95,105,111, + 218,9,111,112,101,110,95,99,111,100,101,114,22,0,0,0, + 114,3,0,0,0,218,4,115,101,101,107,218,20,69,78,68, + 95,67,69,78,84,82,65,76,95,68,73,82,95,83,73,90, + 69,90,4,116,101,108,108,218,4,114,101,97,100,114,51,0, + 0,0,218,18,83,84,82,73,78,71,95,69,78,68,95,65, + 82,67,72,73,86,69,218,3,109,97,120,218,15,77,65,88, + 95,67,79,77,77,69,78,84,95,76,69,78,218,5,114,102, + 105,110,100,114,2,0,0,0,218,8,69,79,70,69,114,114, + 111,114,114,1,0,0,0,114,62,0,0,0,218,18,85,110, + 105,99,111,100,101,68,101,99,111,100,101,69,114,114,111,114, + 218,9,116,114,97,110,115,108,97,116,101,218,11,99,112,52, + 51,55,95,116,97,98,108,101,114,19,0,0,0,114,20,0, + 0,0,114,21,0,0,0,114,30,0,0,0,114,76,0,0, + 0,114,77,0,0,0,41,26,114,29,0,0,0,218,2,102, + 112,90,15,104,101,97,100,101,114,95,112,111,115,105,116,105, + 111,110,218,6,98,117,102,102,101,114,218,9,102,105,108,101, + 95,115,105,122,101,90,17,109,97,120,95,99,111,109,109,101, + 110,116,95,115,116,97,114,116,218,4,100,97,116,97,90,3, + 112,111,115,218,11,104,101,97,100,101,114,95,115,105,122,101, + 90,13,104,101,97,100,101,114,95,111,102,102,115,101,116,90, + 10,97,114,99,95,111,102,102,115,101,116,114,33,0,0,0, + 218,5,99,111,117,110,116,218,5,102,108,97,103,115,218,8, + 99,111,109,112,114,101,115,115,218,4,116,105,109,101,218,4, + 100,97,116,101,218,3,99,114,99,218,9,100,97,116,97,95, + 115,105,122,101,218,9,110,97,109,101,95,115,105,122,101,218, + 10,101,120,116,114,97,95,115,105,122,101,90,12,99,111,109, + 109,101,110,116,95,115,105,122,101,218,11,102,105,108,101,95, + 111,102,102,115,101,116,114,59,0,0,0,114,13,0,0,0, + 218,1,116,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,114,27,0,0,0,93,1,0,0,115,212,0,0,0, + 0,1,2,1,14,1,12,1,24,2,8,1,2,1,14,1, + 8,1,14,1,12,1,24,1,12,1,18,1,18,3,2,1, + 12,1,12,1,12,1,10,1,2,255,12,2,8,1,2,255, + 2,1,2,255,4,2,2,1,10,1,12,1,14,1,10,1, + 2,255,12,2,10,1,10,1,10,1,2,255,6,2,16,1, + 14,1,10,1,2,255,6,2,16,2,16,1,16,1,10,1, + 18,1,10,1,18,1,8,1,8,1,10,1,18,2,4,2, + 4,1,2,1,14,1,14,1,24,2,10,1,14,1,8,2, + 18,1,4,1,14,1,8,1,16,1,16,1,16,1,16,1, + 16,1,16,1,16,1,16,1,16,1,16,1,16,1,12,1, + 10,1,18,1,8,2,2,1,14,1,14,1,24,1,14,1, + 18,4,2,1,28,1,22,1,14,1,24,2,10,2,10,3, + 2,1,14,1,14,1,22,2,12,1,12,1,20,1,8,1, + 44,1,14,1,114,27,0,0,0,117,190,1,0,0,0,1, + 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, + 18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33, + 34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49, + 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65, + 66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81, + 82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97, + 98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113, + 114,115,116,117,118,119,120,121,122,123,124,125,126,127,195,135, + 195,188,195,169,195,162,195,164,195,160,195,165,195,167,195,170, + 195,171,195,168,195,175,195,174,195,172,195,132,195,133,195,137, + 195,166,195,134,195,180,195,182,195,178,195,187,195,185,195,191, + 195,150,195,156,194,162,194,163,194,165,226,130,167,198,146,195, + 161,195,173,195,179,195,186,195,177,195,145,194,170,194,186,194, + 191,226,140,144,194,172,194,189,194,188,194,161,194,171,194,187, + 226,150,145,226,150,146,226,150,147,226,148,130,226,148,164,226, + 149,161,226,149,162,226,149,150,226,149,149,226,149,163,226,149, + 145,226,149,151,226,149,157,226,149,156,226,149,155,226,148,144, + 226,148,148,226,148,180,226,148,172,226,148,156,226,148,128,226, + 148,188,226,149,158,226,149,159,226,149,154,226,149,148,226,149, + 169,226,149,166,226,149,160,226,149,144,226,149,172,226,149,167, + 226,149,168,226,149,164,226,149,165,226,149,153,226,149,152,226, + 149,146,226,149,147,226,149,171,226,149,170,226,148,152,226,148, + 140,226,150,136,226,150,132,226,150,140,226,150,144,226,150,128, + 206,177,195,159,206,147,207,128,206,163,207,131,194,181,207,132, + 206,166,206,152,206,169,206,180,226,136,158,207,134,206,181,226, + 136,169,226,137,161,194,177,226,137,165,226,137,164,226,140,160, + 226,140,161,195,183,226,137,136,194,176,226,136,153,194,183,226, + 136,154,226,129,191,194,178,226,150,160,194,160,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, + 0,67,0,0,0,115,110,0,0,0,116,0,114,22,116,1, + 160,2,100,1,161,1,1,0,116,3,100,2,131,1,130,1, + 100,3,97,0,122,62,122,16,100,4,100,5,108,4,109,5, + 125,0,1,0,87,0,110,36,4,0,116,6,121,80,1,0, + 1,0,1,0,116,1,160,2,100,1,161,1,1,0,116,3, + 100,2,131,1,130,1,89,0,110,2,48,0,87,0,100,6, + 97,0,110,6,100,6,97,0,48,0,116,1,160,2,100,7, + 161,1,1,0,124,0,83,0,41,8,78,122,27,122,105,112, + 105,109,112,111,114,116,58,32,122,108,105,98,32,85,78,65, + 86,65,73,76,65,66,76,69,250,41,99,97,110,39,116,32, + 100,101,99,111,109,112,114,101,115,115,32,100,97,116,97,59, + 32,122,108,105,98,32,110,111,116,32,97,118,97,105,108,97, + 98,108,101,84,114,0,0,0,0,169,1,218,10,100,101,99, + 111,109,112,114,101,115,115,70,122,25,122,105,112,105,109,112, + 111,114,116,58,32,122,108,105,98,32,97,118,97,105,108,97, + 98,108,101,41,7,218,15,95,105,109,112,111,114,116,105,110, + 103,95,122,108,105,98,114,76,0,0,0,114,77,0,0,0, + 114,3,0,0,0,90,4,122,108,105,98,114,139,0,0,0, + 218,9,69,120,99,101,112,116,105,111,110,114,138,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, + 20,95,103,101,116,95,100,101,99,111,109,112,114,101,115,115, + 95,102,117,110,99,251,1,0,0,115,24,0,0,0,0,2, + 4,3,10,1,8,2,4,1,4,1,16,1,12,1,10,1, + 16,2,12,2,10,1,114,142,0,0,0,99,2,0,0,0, + 0,0,0,0,0,0,0,0,17,0,0,0,9,0,0,0, + 67,0,0,0,115,144,1,0,0,124,1,92,8,125,2,125, + 3,125,4,125,5,125,6,125,7,125,8,125,9,124,4,100, + 1,107,0,114,36,116,0,100,2,131,1,130,1,116,1,160, + 2,124,0,161,1,144,1,143,14,125,10,122,14,124,10,160, + 3,124,6,161,1,1,0,87,0,110,36,4,0,116,4,121, + 100,1,0,1,0,1,0,116,0,100,3,124,0,155,2,157, + 2,124,0,100,4,141,2,130,1,89,0,110,2,48,0,124, + 10,160,5,100,5,161,1,125,11,116,6,124,11,131,1,100, + 5,107,3,114,132,116,7,100,6,131,1,130,1,124,11,100, + 0,100,7,133,2,25,0,100,8,107,3,114,166,116,0,100, + 9,124,0,155,2,157,2,124,0,100,4,141,2,130,1,116, + 8,124,11,100,10,100,11,133,2,25,0,131,1,125,12,116, + 8,124,11,100,11,100,5,133,2,25,0,131,1,125,13,100, + 5,124,12,23,0,124,13,23,0,125,14,124,6,124,14,55, + 0,125,6,122,14,124,10,160,3,124,6,161,1,1,0,87, + 0,110,38,4,0,116,4,144,1,121,14,1,0,1,0,1, + 0,116,0,100,3,124,0,155,2,157,2,124,0,100,4,141, + 2,130,1,89,0,110,2,48,0,124,10,160,5,124,4,161, + 1,125,15,116,6,124,15,131,1,124,4,107,3,144,1,114, + 48,116,4,100,12,131,1,130,1,87,0,100,0,4,0,4, + 0,131,3,1,0,110,18,49,0,144,1,115,70,48,0,1, + 0,1,0,1,0,89,0,1,0,124,3,100,1,107,2,144, + 1,114,94,124,15,83,0,122,10,116,9,131,0,125,16,87, + 0,110,28,4,0,116,10,144,1,121,132,1,0,1,0,1, + 0,116,0,100,13,131,1,130,1,89,0,110,2,48,0,124, + 16,124,15,100,14,131,2,83,0,41,15,78,114,0,0,0, + 0,122,18,110,101,103,97,116,105,118,101,32,100,97,116,97, + 32,115,105,122,101,114,90,0,0,0,114,12,0,0,0,114, + 102,0,0,0,114,96,0,0,0,114,91,0,0,0,115,4, + 0,0,0,80,75,3,4,122,23,98,97,100,32,108,111,99, + 97,108,32,102,105,108,101,32,104,101,97,100,101,114,58,32, + 233,26,0,0,0,114,101,0,0,0,122,26,122,105,112,105, + 109,112,111,114,116,58,32,99,97,110,39,116,32,114,101,97, + 100,32,100,97,116,97,114,137,0,0,0,105,241,255,255,255, + 41,11,114,3,0,0,0,114,108,0,0,0,114,109,0,0, + 0,114,110,0,0,0,114,22,0,0,0,114,112,0,0,0, + 114,51,0,0,0,114,117,0,0,0,114,1,0,0,0,114, + 142,0,0,0,114,141,0,0,0,41,17,114,29,0,0,0, + 114,54,0,0,0,90,8,100,97,116,97,112,97,116,104,114, + 128,0,0,0,114,132,0,0,0,114,123,0,0,0,114,135, + 0,0,0,114,129,0,0,0,114,130,0,0,0,114,131,0, + 0,0,114,121,0,0,0,114,122,0,0,0,114,133,0,0, + 0,114,134,0,0,0,114,125,0,0,0,90,8,114,97,119, + 95,100,97,116,97,114,139,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,52,0,0,0,16,2, + 0,0,115,62,0,0,0,0,1,20,1,8,1,8,2,14, + 2,2,1,14,1,12,1,24,1,10,1,12,1,8,2,16, + 2,18,2,16,1,16,1,12,1,8,1,2,1,14,1,14, + 1,24,1,10,1,14,1,40,2,10,2,4,3,2,1,10, + 1,14,1,14,1,114,52,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,16,0,0,0,116,0,124,0,124,1,24,0, + 131,1,100,1,107,1,83,0,41,2,78,114,5,0,0,0, + 41,1,218,3,97,98,115,41,2,90,2,116,49,90,2,116, + 50,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,9,95,101,113,95,109,116,105,109,101,62,2,0,0,115, + 2,0,0,0,0,2,114,145,0,0,0,99,5,0,0,0, + 0,0,0,0,0,0,0,0,14,0,0,0,8,0,0,0, + 67,0,0,0,115,60,1,0,0,124,3,124,2,100,1,156, + 2,125,5,122,18,116,0,160,1,124,4,124,3,124,5,161, + 3,125,6,87,0,110,20,4,0,116,2,121,48,1,0,1, + 0,1,0,89,0,100,0,83,0,48,0,124,6,100,2,64, + 0,100,3,107,3,125,7,124,7,114,182,124,6,100,4,64, + 0,100,3,107,3,125,8,116,3,106,4,100,5,107,3,144, + 1,114,10,124,8,115,106,116,3,106,4,100,6,107,2,144, + 1,114,10,116,5,124,0,124,2,131,2,125,9,124,9,100, + 0,117,1,144,1,114,10,116,3,160,6,116,0,106,7,124, + 9,161,2,125,10,122,20,116,0,160,8,124,4,124,10,124, + 3,124,5,161,4,1,0,87,0,110,104,4,0,116,2,121, + 180,1,0,1,0,1,0,89,0,100,0,83,0,48,0,116, + 9,124,0,124,2,131,2,92,2,125,11,125,12,124,11,144, + 1,114,10,116,10,116,11,124,4,100,7,100,8,133,2,25, + 0,131,1,124,11,131,2,114,246,116,11,124,4,100,8,100, + 9,133,2,25,0,131,1,124,12,107,3,144,1,114,10,116, + 12,160,13,100,10,124,3,155,2,157,2,161,1,1,0,100, + 0,83,0,116,14,160,15,124,4,100,9,100,0,133,2,25, + 0,161,1,125,13,116,16,124,13,116,17,131,2,144,1,115, + 56,116,18,100,11,124,1,155,2,100,12,157,3,131,1,130, + 1,124,13,83,0,41,13,78,41,2,114,59,0,0,0,114, + 13,0,0,0,114,5,0,0,0,114,0,0,0,0,114,84, + 0,0,0,90,5,110,101,118,101,114,90,6,97,108,119,97, + 121,115,114,97,0,0,0,114,92,0,0,0,114,93,0,0, + 0,122,22,98,121,116,101,99,111,100,101,32,105,115,32,115, + 116,97,108,101,32,102,111,114,32,122,16,99,111,109,112,105, + 108,101,100,32,109,111,100,117,108,101,32,122,21,32,105,115, + 32,110,111,116,32,97,32,99,111,100,101,32,111,98,106,101, + 99,116,41,19,114,21,0,0,0,90,13,95,99,108,97,115, + 115,105,102,121,95,112,121,99,114,75,0,0,0,218,4,95, + 105,109,112,90,21,99,104,101,99,107,95,104,97,115,104,95, + 98,97,115,101,100,95,112,121,99,115,218,15,95,103,101,116, + 95,112,121,99,95,115,111,117,114,99,101,218,11,115,111,117, + 114,99,101,95,104,97,115,104,90,17,95,82,65,87,95,77, + 65,71,73,67,95,78,85,77,66,69,82,90,18,95,118,97, + 108,105,100,97,116,101,95,104,97,115,104,95,112,121,99,218, + 29,95,103,101,116,95,109,116,105,109,101,95,97,110,100,95, + 115,105,122,101,95,111,102,95,115,111,117,114,99,101,114,145, + 0,0,0,114,2,0,0,0,114,76,0,0,0,114,77,0, + 0,0,218,7,109,97,114,115,104,97,108,90,5,108,111,97, + 100,115,114,15,0,0,0,218,10,95,99,111,100,101,95,116, + 121,112,101,218,9,84,121,112,101,69,114,114,111,114,41,14, + 114,32,0,0,0,114,53,0,0,0,114,63,0,0,0,114, + 38,0,0,0,114,124,0,0,0,90,11,101,120,99,95,100, + 101,116,97,105,108,115,114,127,0,0,0,90,10,104,97,115, + 104,95,98,97,115,101,100,90,12,99,104,101,99,107,95,115, + 111,117,114,99,101,90,12,115,111,117,114,99,101,95,98,121, + 116,101,115,114,148,0,0,0,90,12,115,111,117,114,99,101, + 95,109,116,105,109,101,90,11,115,111,117,114,99,101,95,115, + 105,122,101,114,46,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,15,95,117,110,109,97,114,115, + 104,97,108,95,99,111,100,101,72,2,0,0,115,82,0,0, + 0,0,2,2,1,2,254,6,5,2,1,18,1,12,1,8, + 2,12,1,4,1,12,1,12,1,2,255,2,1,8,255,4, + 2,10,1,10,1,4,1,4,1,2,254,4,5,2,1,4, + 1,8,255,8,2,12,1,8,3,8,255,6,3,6,3,22, + 1,18,255,4,2,4,1,8,255,4,2,4,2,18,1,12, + 1,16,1,114,153,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, + 0,115,28,0,0,0,124,0,160,0,100,1,100,2,161,2, + 125,0,124,0,160,0,100,3,100,2,161,2,125,0,124,0, + 83,0,41,4,78,115,2,0,0,0,13,10,243,1,0,0, + 0,10,243,1,0,0,0,13,41,1,114,19,0,0,0,41, + 1,218,6,115,111,117,114,99,101,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,23,95,110,111,114,109,97, + 108,105,122,101,95,108,105,110,101,95,101,110,100,105,110,103, + 115,123,2,0,0,115,6,0,0,0,0,1,12,1,12,1, + 114,157,0,0,0,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,6,0,0,0,67,0,0,0,115,24, + 0,0,0,116,0,124,1,131,1,125,1,116,1,124,1,124, + 0,100,1,100,2,100,3,141,4,83,0,41,4,78,114,74, + 0,0,0,84,41,1,90,12,100,111,110,116,95,105,110,104, + 101,114,105,116,41,2,114,157,0,0,0,218,7,99,111,109, + 112,105,108,101,41,2,114,53,0,0,0,114,156,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, + 15,95,99,111,109,112,105,108,101,95,115,111,117,114,99,101, + 130,2,0,0,115,4,0,0,0,0,1,8,1,114,159,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,11,0,0,0,67,0,0,0,115,68,0,0,0, + 116,0,160,1,124,0,100,1,63,0,100,2,23,0,124,0, + 100,3,63,0,100,4,64,0,124,0,100,5,64,0,124,1, + 100,6,63,0,124,1,100,3,63,0,100,7,64,0,124,1, + 100,5,64,0,100,8,20,0,100,9,100,9,100,9,102,9, + 161,1,83,0,41,10,78,233,9,0,0,0,105,188,7,0, + 0,233,5,0,0,0,233,15,0,0,0,233,31,0,0,0, + 233,11,0,0,0,233,63,0,0,0,114,84,0,0,0,114, + 14,0,0,0,41,2,114,129,0,0,0,90,6,109,107,116, + 105,109,101,41,2,218,1,100,114,136,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,14,95,112, + 97,114,115,101,95,100,111,115,116,105,109,101,136,2,0,0, + 115,18,0,0,0,0,1,4,1,10,1,10,1,6,1,6, + 1,10,1,10,1,6,249,114,167,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,6,0,0,0,10,0,0, + 0,67,0,0,0,115,110,0,0,0,122,82,124,1,100,1, + 100,0,133,2,25,0,100,2,118,0,115,22,74,0,130,1, + 124,1,100,0,100,1,133,2,25,0,125,1,124,0,106,0, + 124,1,25,0,125,2,124,2,100,3,25,0,125,3,124,2, + 100,4,25,0,125,4,124,2,100,5,25,0,125,5,116,1, + 124,4,124,3,131,2,124,5,102,2,87,0,83,0,4,0, + 116,2,116,3,116,4,102,3,121,108,1,0,1,0,1,0, + 89,0,100,6,83,0,48,0,41,7,78,114,14,0,0,0, + 169,2,218,1,99,218,1,111,114,161,0,0,0,233,6,0, + 0,0,233,3,0,0,0,41,2,114,0,0,0,0,114,0, + 0,0,0,41,5,114,28,0,0,0,114,167,0,0,0,114, + 26,0,0,0,218,10,73,110,100,101,120,69,114,114,111,114, + 114,152,0,0,0,41,6,114,32,0,0,0,114,13,0,0, + 0,114,54,0,0,0,114,129,0,0,0,114,130,0,0,0, + 90,17,117,110,99,111,109,112,114,101,115,115,101,100,95,115, + 105,122,101,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,114,149,0,0,0,149,2,0,0,115,20,0,0,0, + 0,1,2,2,20,1,12,1,10,3,8,1,8,1,8,1, + 16,1,18,1,114,149,0,0,0,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,8,0,0,0,67,0, + 0,0,115,80,0,0,0,124,1,100,1,100,0,133,2,25, + 0,100,2,118,0,115,20,74,0,130,1,124,1,100,0,100, + 1,133,2,25,0,125,1,122,14,124,0,106,0,124,1,25, + 0,125,2,87,0,110,20,4,0,116,1,121,66,1,0,1, + 0,1,0,89,0,100,0,83,0,48,0,116,2,124,0,106, + 3,124,2,131,2,83,0,41,3,78,114,14,0,0,0,114, + 168,0,0,0,41,4,114,28,0,0,0,114,26,0,0,0, + 114,52,0,0,0,114,29,0,0,0,41,3,114,32,0,0, + 0,114,13,0,0,0,114,54,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,114,147,0,0,0,168, + 2,0,0,115,14,0,0,0,0,2,20,1,12,2,2,1, + 14,1,12,1,8,2,114,147,0,0,0,99,2,0,0,0, + 0,0,0,0,0,0,0,0,11,0,0,0,9,0,0,0, + 67,0,0,0,115,194,0,0,0,116,0,124,0,124,1,131, + 2,125,2,116,1,68,0,93,156,92,3,125,3,125,4,125, + 5,124,2,124,3,23,0,125,6,116,2,106,3,100,1,124, + 0,106,4,116,5,124,6,100,2,100,3,141,5,1,0,122, + 14,124,0,106,6,124,6,25,0,125,7,87,0,110,18,4, + 0,116,7,121,86,1,0,1,0,1,0,89,0,113,14,48, + 0,124,7,100,4,25,0,125,8,116,8,124,0,106,4,124, + 7,131,2,125,9,124,4,114,130,116,9,124,0,124,8,124, + 6,124,1,124,9,131,5,125,10,110,10,116,10,124,8,124, + 9,131,2,125,10,124,10,100,0,117,0,114,150,113,14,124, + 7,100,4,25,0,125,8,124,10,124,5,124,8,102,3,2, + 0,1,0,83,0,116,11,100,5,124,1,155,2,157,2,124, + 1,100,6,141,2,130,1,100,0,83,0,41,7,78,122,13, + 116,114,121,105,110,103,32,123,125,123,125,123,125,114,84,0, + 0,0,41,1,90,9,118,101,114,98,111,115,105,116,121,114, + 0,0,0,0,114,57,0,0,0,114,58,0,0,0,41,12, + 114,36,0,0,0,114,87,0,0,0,114,76,0,0,0,114, + 77,0,0,0,114,29,0,0,0,114,20,0,0,0,114,28, + 0,0,0,114,26,0,0,0,114,52,0,0,0,114,153,0, + 0,0,114,159,0,0,0,114,3,0,0,0,41,11,114,32, + 0,0,0,114,38,0,0,0,114,13,0,0,0,114,88,0, + 0,0,114,89,0,0,0,114,47,0,0,0,114,63,0,0, + 0,114,54,0,0,0,114,40,0,0,0,114,124,0,0,0, + 114,46,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,44,0,0,0,183,2,0,0,115,36,0, + 0,0,0,1,10,1,14,1,8,1,22,1,2,1,14,1, + 12,1,6,2,8,1,12,1,4,1,18,2,10,1,8,3, + 2,1,8,1,14,2,114,44,0,0,0,41,44,114,82,0, + 0,0,90,26,95,102,114,111,122,101,110,95,105,109,112,111, + 114,116,108,105,98,95,101,120,116,101,114,110,97,108,114,21, + 0,0,0,114,1,0,0,0,114,2,0,0,0,90,17,95, + 102,114,111,122,101,110,95,105,109,112,111,114,116,108,105,98, + 114,76,0,0,0,114,146,0,0,0,114,108,0,0,0,114, + 150,0,0,0,114,67,0,0,0,114,129,0,0,0,90,7, + 95,95,97,108,108,95,95,114,20,0,0,0,90,15,112,97, + 116,104,95,115,101,112,97,114,97,116,111,114,115,114,18,0, + 0,0,114,75,0,0,0,114,3,0,0,0,114,25,0,0, + 0,218,4,116,121,112,101,114,70,0,0,0,114,111,0,0, + 0,114,113,0,0,0,114,115,0,0,0,114,4,0,0,0, + 114,87,0,0,0,114,36,0,0,0,114,37,0,0,0,114, + 35,0,0,0,114,27,0,0,0,114,120,0,0,0,114,140, + 0,0,0,114,142,0,0,0,114,52,0,0,0,114,145,0, + 0,0,114,153,0,0,0,218,8,95,95,99,111,100,101,95, + 95,114,151,0,0,0,114,157,0,0,0,114,159,0,0,0, + 114,167,0,0,0,114,149,0,0,0,114,147,0,0,0,114, + 44,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,8,60,109,111,100,117,108, + 101,62,1,0,0,0,115,84,0,0,0,4,16,8,1,16, + 1,8,1,8,1,8,1,8,1,8,1,8,2,8,3,6, + 1,14,3,16,4,4,2,8,2,4,1,4,1,4,2,14, + 127,0,125,12,1,12,1,2,1,2,252,4,9,8,4,8, + 9,8,31,8,126,2,254,2,29,4,5,8,21,8,46,8, + 10,8,46,10,5,8,7,8,6,8,13,8,19,8,15, }; diff --git a/Python/peephole.c b/Python/peephole.c deleted file mode 100644 index fe67de42227b5bd..000000000000000 --- a/Python/peephole.c +++ /dev/null @@ -1,537 +0,0 @@ -/* Peephole optimizations for bytecode compiler. */ - -#include "Python.h" - -#include "Python-ast.h" -#include "ast.h" -#include "code.h" -#include "symtable.h" -#include "opcode.h" -#include "wordcode_helpers.h" - -#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) -#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ - || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP || op==JUMP_IF_NOT_EXC_MATCH) -#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE \ - || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ - || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP || op==JUMP_IF_NOT_EXC_MATCH) -#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP) -#define GETJUMPTGT(arr, i) (get_arg(arr, i) / sizeof(_Py_CODEUNIT) + \ - (ABSOLUTE_JUMP(_Py_OPCODE(arr[i])) ? 0 : i+1)) -#define ISBASICBLOCK(blocks, start, end) \ - (blocks[start]==blocks[end]) - - -/* Scans back N consecutive LOAD_CONST instructions, skipping NOPs, - returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix. - Callers are responsible to check CONST_STACK_LEN beforehand. -*/ -static Py_ssize_t -lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n) -{ - assert(n > 0); - for (;;) { - i--; - assert(i >= 0); - if (_Py_OPCODE(codestr[i]) == LOAD_CONST) { - if (!--n) { - while (i > 0 && _Py_OPCODE(codestr[i-1]) == EXTENDED_ARG) { - i--; - } - return i; - } - } - else { - assert(_Py_OPCODE(codestr[i]) == EXTENDED_ARG); - } - } -} - -/* Scans through EXTENDED ARGs, seeking the index of the effective opcode */ -static Py_ssize_t -find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i) -{ - while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) { - i++; - } - return i; -} - -/* Given the index of the effective opcode, - scan back to construct the oparg with EXTENDED_ARG */ -static unsigned int -get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) -{ - _Py_CODEUNIT word; - unsigned int oparg = _Py_OPARG(codestr[i]); - if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 8; - if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 16; - if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 24; - } - } - } - return oparg; -} - -/* Fill the region with NOPs. */ -static void -fill_nops(_Py_CODEUNIT *codestr, Py_ssize_t start, Py_ssize_t end) -{ - memset(codestr + start, NOP, (end - start) * sizeof(_Py_CODEUNIT)); -} - -/* Given the index of the effective opcode, - attempt to replace the argument, taking into account EXTENDED_ARG. - Returns -1 on failure, or the new op index on success */ -static Py_ssize_t -set_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned int oparg) -{ - unsigned int curarg = get_arg(codestr, i); - int curilen, newilen; - if (curarg == oparg) - return i; - curilen = instrsize(curarg); - newilen = instrsize(oparg); - if (curilen < newilen) { - return -1; - } - - write_op_arg(codestr + i + 1 - curilen, _Py_OPCODE(codestr[i]), oparg, newilen); - fill_nops(codestr, i + 1 - curilen + newilen, i + 1); - return i-curilen+newilen; -} - -/* Attempt to write op/arg at end of specified region of memory. - Preceding memory in the region is overwritten with NOPs. - Returns -1 on failure, op index on success */ -static Py_ssize_t -copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op, - unsigned int oparg, Py_ssize_t maxi) -{ - int ilen = instrsize(oparg); - if (i + ilen > maxi) { - return -1; - } - write_op_arg(codestr + maxi - ilen, op, oparg, ilen); - fill_nops(codestr, i, maxi - ilen); - return maxi - 1; -} - -/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n - with LOAD_CONST (c1, c2, ... cn). - The consts table must still be in list form so that the - new constant (c1, c2, ... cn) can be appended. - Called with codestr pointing to the first LOAD_CONST. -*/ -static Py_ssize_t -fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, - Py_ssize_t c_start, Py_ssize_t opcode_end, - PyObject *consts, int n) -{ - /* Pre-conditions */ - assert(PyList_CheckExact(consts)); - - /* Buildup new tuple of constants */ - PyObject *newconst = PyTuple_New(n); - if (newconst == NULL) { - return -1; - } - - for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) { - assert(pos < opcode_end); - pos = find_op(codestr, codelen, pos); - assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST); - - unsigned int arg = get_arg(codestr, pos); - PyObject *constant = PyList_GET_ITEM(consts, arg); - Py_INCREF(constant); - PyTuple_SET_ITEM(newconst, i, constant); - } - - Py_ssize_t index = PyList_GET_SIZE(consts); -#if SIZEOF_SIZE_T > SIZEOF_INT - if ((size_t)index >= UINT_MAX - 1) { - Py_DECREF(newconst); - PyErr_SetString(PyExc_OverflowError, "too many constants"); - return -1; - } -#endif - - /* Append folded constant onto consts */ - if (PyList_Append(consts, newconst)) { - Py_DECREF(newconst); - return -1; - } - Py_DECREF(newconst); - - return copy_op_arg(codestr, c_start, LOAD_CONST, - (unsigned int)index, opcode_end); -} - -static unsigned int * -markblocks(_Py_CODEUNIT *code, Py_ssize_t len) -{ - unsigned int *blocks = PyMem_New(unsigned int, len); - int i, j, opcode, blockcnt = 0; - - if (blocks == NULL) { - PyErr_NoMemory(); - return NULL; - } - memset(blocks, 0, len*sizeof(int)); - - /* Mark labels in the first pass */ - for (i = 0; i < len; i++) { - opcode = _Py_OPCODE(code[i]); - switch (opcode) { - case FOR_ITER: - case JUMP_FORWARD: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_NOT_EXC_MATCH: - case JUMP_ABSOLUTE: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - j = GETJUMPTGT(code, i); - assert(j < len); - blocks[j] = 1; - break; - } - } - /* Build block numbers in the second pass */ - for (i = 0; i < len; i++) { - blockcnt += blocks[i]; /* increment blockcnt over labels */ - blocks[i] = blockcnt; - } - return blocks; -} - -/* Perform basic peephole optimizations to components of a code object. - The consts object should still be in list form to allow new constants - to be appended. - - To keep the optimizer simple, it bails when the lineno table has complex - encoding for gaps >= 255. - - Optimizations are restricted to simple transformations occurring within a - single basic block. All transformations keep the code size the same or - smaller. For those that reduce size, the gaps are initially filled with - NOPs. Later those NOPs are removed and the jump addresses retargeted in - a single pass. */ - -PyObject * -PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, - PyObject *lnotab_obj) -{ - Py_ssize_t h, i, nexti, op_start, tgt; - unsigned int j, nops; - unsigned char opcode, nextop; - _Py_CODEUNIT *codestr = NULL; - unsigned char *lnotab; - unsigned int cum_orig_offset, last_offset; - Py_ssize_t tabsiz; - // Count runs of consecutive LOAD_CONSTs - unsigned int cumlc = 0, lastlc = 0; - unsigned int *blocks = NULL; - - /* Bail out if an exception is set */ - if (PyErr_Occurred()) - goto exitError; - - /* Bypass optimization when the lnotab table is too complex */ - assert(PyBytes_Check(lnotab_obj)); - lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj); - tabsiz = PyBytes_GET_SIZE(lnotab_obj); - assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1); - - /* Don't optimize if lnotab contains instruction pointer delta larger - than +255 (encoded as multiple bytes), just to keep the peephole optimizer - simple. The optimizer leaves line number deltas unchanged. */ - - for (i = 0; i < tabsiz; i += 2) { - if (lnotab[i] == 255) { - goto exitUnchanged; - } - } - - assert(PyBytes_Check(code)); - Py_ssize_t codesize = PyBytes_GET_SIZE(code); - assert(codesize % sizeof(_Py_CODEUNIT) == 0); - Py_ssize_t codelen = codesize / sizeof(_Py_CODEUNIT); - if (codelen > INT_MAX) { - /* Python assembler is limited to INT_MAX: see assembler.a_offset in - compile.c. */ - goto exitUnchanged; - } - - /* Make a modifiable copy of the code string */ - codestr = (_Py_CODEUNIT *)PyMem_Malloc(codesize); - if (codestr == NULL) { - PyErr_NoMemory(); - goto exitError; - } - memcpy(codestr, PyBytes_AS_STRING(code), codesize); - - blocks = markblocks(codestr, codelen); - if (blocks == NULL) - goto exitError; - assert(PyList_Check(consts)); - - for (i=find_op(codestr, codelen, 0) ; i= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) { - op_start--; - } - - nexti = i + 1; - while (nexti < codelen && _Py_OPCODE(codestr[nexti]) == EXTENDED_ARG) - nexti++; - nextop = nexti < codelen ? _Py_OPCODE(codestr[nexti]) : 0; - - lastlc = cumlc; - cumlc = 0; - - switch (opcode) { - /* Skip over LOAD_CONST trueconst - POP_JUMP_IF_FALSE xx. This improves - "while 1" performance. */ - case LOAD_CONST: - cumlc = lastlc + 1; - if (nextop != POP_JUMP_IF_FALSE || - !ISBASICBLOCK(blocks, op_start, i + 1)) { - break; - } - PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); - int is_true = PyObject_IsTrue(cnt); - if (is_true == -1) { - goto exitError; - } - if (is_true == 1) { - fill_nops(codestr, op_start, nexti + 1); - cumlc = 0; - } - break; - - /* Try to fold tuples of constants. - Skip over BUILD_SEQN 1 UNPACK_SEQN 1. - Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. - Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ - case BUILD_TUPLE: - j = get_arg(codestr, i); - if (j > 0 && lastlc >= j) { - h = lastn_const_start(codestr, op_start, j); - if (ISBASICBLOCK(blocks, h, op_start)) { - h = fold_tuple_on_constants(codestr, codelen, - h, i+1, consts, j); - break; - } - } - if (nextop != UNPACK_SEQUENCE || - !ISBASICBLOCK(blocks, op_start, i + 1) || - j != get_arg(codestr, nexti)) - break; - if (j < 2) { - fill_nops(codestr, op_start, nexti + 1); - } else if (j == 2) { - codestr[op_start] = PACKOPARG(ROT_TWO, 0); - fill_nops(codestr, op_start + 1, nexti + 1); - } else if (j == 3) { - codestr[op_start] = PACKOPARG(ROT_THREE, 0); - codestr[op_start + 1] = PACKOPARG(ROT_TWO, 0); - fill_nops(codestr, op_start + 2, nexti + 1); - } - break; - - /* Simplify conditional jump to conditional jump where the - result of the first test implies the success of a similar - test or the failure of the opposite test. - Arises in code like: - "a and b or c" - "(a and b) and c" - "(a or b) or c" - "(a or b) and c" - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z - --> x:JUMP_IF_FALSE_OR_POP z - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z - --> x:POP_JUMP_IF_FALSE y+1 - where y+1 is the instruction following the second test. - */ - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT); - tgt = find_op(codestr, codelen, h); - - j = _Py_OPCODE(codestr[tgt]); - if (CONDITIONAL_JUMP(j)) { - /* NOTE: all possible jumps here are absolute. */ - if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) { - /* The second jump will be taken iff the first is. - The current opcode inherits its target's - stack effect */ - h = set_arg(codestr, i, get_arg(codestr, tgt)); - } else { - /* The second jump is not taken if the first is (so - jump past it), and all conditional jumps pop their - argument when they're not taken (so change the - first jump to pop its argument when it's taken). */ - Py_ssize_t arg = (tgt + 1); - /* cannot overflow: codelen <= INT_MAX */ - assert((size_t)arg <= UINT_MAX / sizeof(_Py_CODEUNIT)); - arg *= sizeof(_Py_CODEUNIT); - h = set_arg(codestr, i, (unsigned int)arg); - j = opcode == JUMP_IF_TRUE_OR_POP ? - POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE; - } - - if (h >= 0) { - nexti = h; - codestr[nexti] = PACKOPARG(j, _Py_OPARG(codestr[nexti])); - break; - } - } - /* Intentional fallthrough */ - - /* Replace jumps to unconditional jumps */ - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_FORWARD: - case JUMP_ABSOLUTE: - h = GETJUMPTGT(codestr, i); - tgt = find_op(codestr, codelen, h); - /* Replace JUMP_* to a RETURN into just a RETURN */ - if (UNCONDITIONAL_JUMP(opcode) && - _Py_OPCODE(codestr[tgt]) == RETURN_VALUE) { - codestr[op_start] = PACKOPARG(RETURN_VALUE, 0); - fill_nops(codestr, op_start + 1, i + 1); - } else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) { - size_t arg = GETJUMPTGT(codestr, tgt); - if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */ - opcode = JUMP_ABSOLUTE; - } else if (!ABSOLUTE_JUMP(opcode)) { - if (arg < (size_t)(i + 1)) { - break; /* No backward relative jumps */ - } - arg -= i + 1; /* Calc relative jump addr */ - } - /* cannot overflow: codelen <= INT_MAX */ - assert(arg <= (UINT_MAX / sizeof(_Py_CODEUNIT))); - arg *= sizeof(_Py_CODEUNIT); - copy_op_arg(codestr, op_start, opcode, - (unsigned int)arg, i + 1); - } - break; - - /* Remove unreachable ops after RETURN */ - case RETURN_VALUE: - h = i + 1; - while (h < codelen && ISBASICBLOCK(blocks, i, h)) - { - /* Leave SETUP_FINALLY and RERAISE in place to help find block limits. */ - if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY || _Py_OPCODE(codestr[h]) == RERAISE) { - while (h > i + 1 && - _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG) - { - h--; - } - break; - } - h++; - } - if (h > i + 1) { - fill_nops(codestr, i + 1, h); - nexti = find_op(codestr, codelen, h); - } - break; - } - } - - /* Fixup lnotab */ - for (i = 0, nops = 0; i < codelen; i++) { - size_t block = (size_t)i - nops; - /* cannot overflow: codelen <= INT_MAX */ - assert(block <= UINT_MAX); - /* original code offset => new code offset */ - blocks[i] = (unsigned int)block; - if (_Py_OPCODE(codestr[i]) == NOP) { - nops++; - } - } - cum_orig_offset = 0; - last_offset = 0; - for (i=0 ; i < tabsiz ; i+=2) { - unsigned int offset_delta, new_offset; - cum_orig_offset += lnotab[i]; - assert(cum_orig_offset % sizeof(_Py_CODEUNIT) == 0); - new_offset = blocks[cum_orig_offset / sizeof(_Py_CODEUNIT)] * - sizeof(_Py_CODEUNIT); - offset_delta = new_offset - last_offset; - assert(offset_delta <= 255); - lnotab[i] = (unsigned char)offset_delta; - last_offset = new_offset; - } - - /* Remove NOPs and fixup jump targets */ - for (op_start = i = h = 0; i < codelen; i++, op_start = i) { - j = _Py_OPARG(codestr[i]); - while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) { - i++; - j = j<<8 | _Py_OPARG(codestr[i]); - } - opcode = _Py_OPCODE(codestr[i]); - switch (opcode) { - case NOP:continue; - - case JUMP_ABSOLUTE: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case JUMP_IF_NOT_EXC_MATCH: - j = blocks[j / sizeof(_Py_CODEUNIT)] * sizeof(_Py_CODEUNIT); - break; - - case FOR_ITER: - case JUMP_FORWARD: - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1; - j *= sizeof(_Py_CODEUNIT); - break; - } - Py_ssize_t ilen = i - op_start + 1; - if (instrsize(j) > ilen) { - goto exitUnchanged; - } - /* If instrsize(j) < ilen, we'll emit EXTENDED_ARG 0 */ - if (ilen > 4) { - /* Can only happen when PyCode_Optimize() is called with - malformed bytecode. */ - goto exitUnchanged; - } - write_op_arg(codestr + h, opcode, j, (int)ilen); - h += ilen; - } - assert(h + (Py_ssize_t)nops == codelen); - - PyMem_Free(blocks); - code = PyBytes_FromStringAndSize((char *)codestr, h * sizeof(_Py_CODEUNIT)); - PyMem_Free(codestr); - return code; - - exitError: - code = NULL; - - exitUnchanged: - Py_XINCREF(code); - PyMem_Free(blocks); - PyMem_Free(codestr); - return code; -} From e6f78532dabe9e37c8ae2018de9d7b08d26517fa Mon Sep 17 00:00:00 2001 From: Karthikeyan Singaravelan Date: Fri, 31 Jul 2020 16:20:48 +0530 Subject: [PATCH 092/486] bpo-40360: Handle PendingDeprecationWarning in test_lib2to3. (GH-21694) --- Lib/test/test_lib2to3.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_lib2to3.py b/Lib/test/test_lib2to3.py index 5eaa5164d490a7b..159a8387e4e97d4 100644 --- a/Lib/test/test_lib2to3.py +++ b/Lib/test/test_lib2to3.py @@ -1,5 +1,8 @@ -from lib2to3.tests import load_tests import unittest +from test.support.warnings_helper import check_warnings + +with check_warnings(("", PendingDeprecationWarning)): + from lib2to3.tests import load_tests if __name__ == '__main__': unittest.main() From b1d7a9daa48345eac93c27116ef5cd7c2210acdd Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 1 Aug 2020 01:18:26 -0700 Subject: [PATCH 093/486] bpo-41421: Algebraic simplification for random.paretovariate() (GH-21695) --- Lib/random.py | 2 +- .../next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst diff --git a/Lib/random.py b/Lib/random.py index a6454f520df0a32..37f71110403ad8b 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -749,7 +749,7 @@ def paretovariate(self, alpha): # Jain, pg. 495 u = 1.0 - self.random() - return 1.0 / u ** (1.0 / alpha) + return u ** (-1.0 / alpha) def weibullvariate(self, alpha, beta): """Weibull distribution. diff --git a/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst b/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst new file mode 100644 index 000000000000000..cf291c60d8ad575 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst @@ -0,0 +1,3 @@ +Make an algebraic simplification to random.paretovariate(). It now is +slightly less subject to round-off error and is slightly faster. Inputs that +used to cause ZeroDivisionError now cause an OverflowError instead. From d5cb840622c5f1856f3b138102c877ba71f632f1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 2 Aug 2020 12:03:32 -0700 Subject: [PATCH 094/486] random module: Convert a "while 1" to "while True (GH-21700) --- Lib/random.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/random.py b/Lib/random.py index 37f71110403ad8b..3ea369b81b3e50f 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -682,7 +682,7 @@ def gammavariate(self, alpha, beta): bbb = alpha - LOG4 ccc = alpha + ainv - while 1: + while True: u1 = random() if not 1e-7 < u1 < 0.9999999: continue From 8ac5c899ef7261023e72c714bea40e64591bffd8 Mon Sep 17 00:00:00 2001 From: Luciano Ramalho Date: Sun, 2 Aug 2020 19:32:36 -0300 Subject: [PATCH 095/486] bpo-40979: refactored typing.rst; (mostly) same content, new sub-sections and ordering (#21574) Also added PEP 585 deprecation notes. --- Doc/library/typing.rst | 1547 ++++++++++------- .../2020-07-21-15-23-30.bpo-40979.pLA8rO.rst | 1 + 2 files changed, 879 insertions(+), 669 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index e5143c5f8d9e4a4..44b537f1669e1ae 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1,3 +1,4 @@ +======================================== :mod:`typing` --- Support for type hints ======================================== @@ -34,7 +35,7 @@ In the function ``greeting``, the argument ``name`` is expected to be of type arguments. Type aliases ------------- +============ A type alias is defined by assigning the type to the alias. In this example, ``Vector`` and ``List[float]`` will be treated as interchangeable synonyms:: @@ -72,7 +73,7 @@ Note that ``None`` as a type hint is a special case and is replaced by .. _distinct: NewType -------- +======= Use the :func:`NewType` helper function to create distinct types:: @@ -149,7 +150,7 @@ See :pep:`484` for more details. .. versionadded:: 3.5.2 Callable --------- +======== Frameworks expecting callback functions of specific signatures might be type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``. @@ -172,7 +173,7 @@ for the list of arguments in the type hint: ``Callable[..., ReturnType]``. .. _generics: Generics --------- +======== Since type information about objects kept in containers cannot be statically inferred in a generic way, abstract base classes have been extended to support @@ -199,7 +200,7 @@ called :class:`TypeVar`. User-defined generic types --------------------------- +========================== A user-defined class can be defined as a generic class. @@ -317,7 +318,7 @@ comparable for equality. The :data:`Any` type --------------------- +==================== A special kind of type is :data:`Any`. A static type checker will treat every type as being compatible with :data:`Any` and :data:`Any` as being @@ -395,7 +396,7 @@ manner. Use :data:`Any` to indicate that a value is dynamically typed. Nominal vs structural subtyping -------------------------------- +=============================== Initially :pep:`484` defined Python static type system as using *nominal subtyping*. This means that a class ``A`` is allowed where @@ -434,106 +435,152 @@ Moreover, by subclassing a special class :class:`Protocol`, a user can define new custom protocols to fully enjoy structural subtyping (see examples below). +Module contents +=============== -Classes, functions, and decorators ----------------------------------- +The module defines the following classes, functions and decorators. -The module defines the following classes, functions and decorators: +.. note:: -.. class:: TypeVar + This module defines several types that are subclasses of pre-existing + standard library classes which also extend :class:`Generic` + to support type variables inside ``[]``. + These types became redundant in Python 3.9 when the + corresponding pre-existing classes were enhanced to support ``[]``. - Type variable. + The redundant types are deprecated as of Python 3.9 but no + deprecation warnings will be issued by the interpreter. + It is expected that type checkers will flag the deprecated types + when the checked program targets Python 3.9 or newer. - Usage:: + The deprecated types will be removed from the :mod:`typing` module + in the first Python version released 5 years after the release of Python 3.9.0. + See details in :pep:`585`—*Type Hinting Generics In Standard Collections*. - T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more - information on generic types. Generic functions work as follows:: +Special typing primitives +------------------------- - def repeat(x: T, n: int) -> Sequence[T]: - """Return a list containing n references to x.""" - return [x]*n +Special types +""""""""""""" - def longest(x: A, y: A) -> A: - """Return the longest of two strings.""" - return x if len(x) >= len(y) else y +These can be used as types in annotations and do not support ``[]``. - The latter example's signature is essentially the overloading - of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note - that if the arguments are instances of some subclass of :class:`str`, - the return type is still plain :class:`str`. +.. data:: Any - At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, - :func:`isinstance` and :func:`issubclass` should not be used with types. + Special type indicating an unconstrained type. - Type variables may be marked covariant or contravariant by passing - ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default type variables are invariant. Alternatively, - a type variable may specify an upper bound using ``bound=``. - This means that an actual type substituted (explicitly or implicitly) - for the type variable must be a subclass of the boundary type, - see :pep:`484`. + * Every type is compatible with :data:`Any`. + * :data:`Any` is compatible with every type. -.. class:: Generic +.. data:: NoReturn - Abstract base class for generic types. + Special type indicating that a function never returns. + For example:: - A generic type is typically declared by inheriting from an - instantiation of this class with one or more type variables. - For example, a generic mapping type might be defined as:: + from typing import NoReturn - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. + def stop() -> NoReturn: + raise RuntimeError('no way') - This class can then be used as follows:: + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.2 - X = TypeVar('X') - Y = TypeVar('Y') +Special forms +""""""""""""" - def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: - try: - return mapping[key] - except KeyError: - return default +These can be used as types in annotations using ``[]``, each having a unique syntax. -.. class:: Protocol(Generic) +.. data:: Tuple - Base class for protocol classes. Protocol classes are defined like this:: + Tuple type; ``Tuple[X, Y]`` is the type of a tuple of two items + with the first item of type X and the second of type Y. The type of + the empty tuple can be written as ``Tuple[()]``. - class Proto(Protocol): - def meth(self) -> int: - ... + Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding + to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple + of an int, a float and a string. - Such classes are primarily used with static type checkers that recognize - structural subtyping (static duck-typing), for example:: + To specify a variable-length tuple of homogeneous type, + use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain :data:`Tuple` + is equivalent to ``Tuple[Any, ...]``, and in turn to :class:`tuple`. - class C: - def meth(self) -> int: - return 0 + .. deprecated:: 3.9 + :class:`builtins.tuple ` now supports ``[]``. See :pep:`585`. - def func(x: Proto) -> int: - return x.meth() +.. data:: Union - func(C()) # Passes static type check + Union type; ``Union[X, Y]`` means either X or Y. - See :pep:`544` for details. Protocol classes decorated with - :func:`runtime_checkable` (described later) act as simple-minded runtime - protocols that check only the presence of given attributes, ignoring their - type signatures. + To define a union, use e.g. ``Union[int, str]``. Details: - Protocol classes can be generic, for example:: + * The arguments must be types and there must be at least one. - class GenProto(Protocol[T]): - def meth(self) -> T: - ... + * Unions of unions are flattened, e.g.:: - .. versionadded:: 3.8 + Union[Union[int, str], float] == Union[int, str, float] + + * Unions of a single argument vanish, e.g.:: + + Union[int] == int # The constructor actually returns int + + * Redundant arguments are skipped, e.g.:: + + Union[int, str, int] == Union[int, str] + + * When comparing unions, the argument order is ignored, e.g.:: + + Union[int, str] == Union[str, int] + + * You cannot subclass or instantiate a union. + + * You cannot write ``Union[X][Y]``. + + * You can use ``Optional[X]`` as a shorthand for ``Union[X, None]``. + + .. versionchanged:: 3.7 + Don't remove explicit subclasses from unions at runtime. + +.. data:: Optional + + Optional type. + + ``Optional[X]`` is equivalent to ``Union[X, None]``. + + Note that this is not the same concept as an optional argument, + which is one that has a default. An optional argument with a + default does not require the ``Optional`` qualifier on its type + annotation just because it is optional. For example:: + + def foo(arg: int = 0) -> None: + ... + + On the other hand, if an explicit value of ``None`` is allowed, the + use of ``Optional`` is appropriate, whether the argument is optional + or not. For example:: + + def foo(arg: Optional[int] = None) -> None: + ... + +.. data:: Callable + + Callable type; ``Callable[[int], str]`` is a function of (int) -> str. + + The subscription syntax must always be used with exactly two + values: the argument list and the return type. The argument list + must be a list of types or an ellipsis; the return type must be + a single type. + + There is no syntax to indicate optional or keyword arguments; + such function types are rarely used as callback types. + ``Callable[..., ReturnType]`` (literal ellipsis) can be used to + type hint a callable taking any number of arguments and returning + ``ReturnType``. A plain :data:`Callable` is equivalent to + ``Callable[..., Any]``, and in turn to + :class:`collections.abc.Callable`. + + .. deprecated:: 3.9 + :class:`collections.abc.Callable` now supports ``[]``. See :pep:`585`. .. class:: Type(Generic[CT_co]) @@ -577,374 +624,342 @@ The module defines the following classes, functions and decorators: .. versionadded:: 3.5.2 -.. class:: Iterable(Generic[T_co]) + .. deprecated:: 3.9 + :class:`builtins.type ` now supports ``[]``. See :pep:`585`. - A generic version of :class:`collections.abc.Iterable`. +.. data:: Literal -.. class:: Iterator(Iterable[T_co]) + A type that can be used to indicate to type checkers that the + corresponding variable or function parameter has a value equivalent to + the provided literal (or one of several literals). For example:: - A generic version of :class:`collections.abc.Iterator`. + def validate_simple(data: Any) -> Literal[True]: # always returns True + ... -.. class:: Reversible(Iterable[T_co]) + MODE = Literal['r', 'rb', 'w', 'wb'] + def open_helper(file: str, mode: MODE) -> str: + ... - A generic version of :class:`collections.abc.Reversible`. + open_helper('/some/path', 'r') # Passes type check + open_helper('/other/path', 'typo') # Error in type checker -.. class:: SupportsInt + ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value + is allowed as type argument to ``Literal[...]``, but type checkers may + impose restrictions. See :pep:`586` for more details about literal types. - An ABC with one abstract method ``__int__``. + .. versionadded:: 3.8 -.. class:: SupportsFloat +.. data:: ClassVar - An ABC with one abstract method ``__float__``. + Special type construct to mark class variables. -.. class:: SupportsComplex + As introduced in :pep:`526`, a variable annotation wrapped in ClassVar + indicates that a given attribute is intended to be used as a class variable + and should not be set on instances of that class. Usage:: - An ABC with one abstract method ``__complex__``. + class Starship: + stats: ClassVar[Dict[str, int]] = {} # class variable + damage: int = 10 # instance variable -.. class:: SupportsBytes + :data:`ClassVar` accepts only types and cannot be further subscribed. - An ABC with one abstract method ``__bytes__``. + :data:`ClassVar` is not a class itself, and should not + be used with :func:`isinstance` or :func:`issubclass`. + :data:`ClassVar` does not change Python runtime behavior, but + it can be used by third-party type checkers. For example, a type checker + might flag the following code as an error:: -.. class:: SupportsIndex + enterprise_d = Starship(3000) + enterprise_d.stats = {} # Error, setting class variable on instance + Starship.stats = {} # This is OK - An ABC with one abstract method ``__index__``. + .. versionadded:: 3.5.3 - .. versionadded:: 3.8 +.. data:: Final -.. class:: SupportsAbs + A special typing construct to indicate to type checkers that a name + cannot be re-assigned or overridden in a subclass. For example:: - An ABC with one abstract method ``__abs__`` that is covariant - in its return type. + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker -.. class:: SupportsRound + class Connection: + TIMEOUT: Final[int] = 10 - An ABC with one abstract method ``__round__`` - that is covariant in its return type. + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker -.. class:: Container(Generic[T_co]) + There is no runtime checking of these properties. See :pep:`591` for + more details. - A generic version of :class:`collections.abc.Container`. + .. versionadded:: 3.8 -.. class:: Hashable +.. data:: Annotated - An alias to :class:`collections.abc.Hashable` + A type, introduced in :pep:`593` (``Flexible function and variable + annotations``), to decorate existing types with context-specific metadata + (possibly multiple pieces of it, as ``Annotated`` is variadic). + Specifically, a type ``T`` can be annotated with metadata ``x`` via the + typehint ``Annotated[T, x]``. This metadata can be used for either static + analysis or at runtime. If a library (or tool) encounters a typehint + ``Annotated[T, x]`` and has no special logic for metadata ``x``, it + should ignore it and simply treat the type as ``T``. Unlike the + ``no_type_check`` functionality that currently exists in the ``typing`` + module which completely disables typechecking annotations on a function + or a class, the ``Annotated`` type allows for both static typechecking + of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) + together with runtime access to ``x`` within a specific application. -.. class:: Sized + Ultimately, the responsibility of how to interpret the annotations (if + at all) is the responsibility of the tool or library encountering the + ``Annotated`` type. A tool or library encountering an ``Annotated`` type + can scan through the annotations to determine if they are of interest + (e.g., using ``isinstance()``). - An alias to :class:`collections.abc.Sized` + When a tool or a library does not support annotations or encounters an + unknown annotation it should just ignore it and treat annotated type as + the underlying type. -.. class:: Collection(Sized, Iterable[T_co], Container[T_co]) + It's up to the tool consuming the annotations to decide whether the + client is allowed to have several annotations on one type and how to + merge those annotations. - A generic version of :class:`collections.abc.Collection` + Since the ``Annotated`` type allows you to put several annotations of + the same (or different) type(s) on any node, the tools or libraries + consuming those annotations are in charge of dealing with potential + duplicates. For example, if you are doing value range analysis you might + allow this:: - .. versionadded:: 3.6.0 + T1 = Annotated[int, ValueRange(-10, 5)] + T2 = Annotated[T1, ValueRange(-20, 3)] -.. class:: AbstractSet(Sized, Collection[T_co]) + Passing ``include_extras=True`` to :func:`get_type_hints` lets one + access the extra annotations at runtime. - A generic version of :class:`collections.abc.Set`. + The details of the syntax: -.. class:: MutableSet(AbstractSet[T]) + * The first argument to ``Annotated`` must be a valid type - A generic version of :class:`collections.abc.MutableSet`. + * Multiple type annotations are supported (``Annotated`` supports variadic + arguments):: -.. class:: Mapping(Sized, Collection[KT], Generic[VT_co]) + Annotated[int, ValueRange(3, 10), ctype("char")] - A generic version of :class:`collections.abc.Mapping`. - This type can be used as follows:: + * ``Annotated`` must be called with at least two arguments ( + ``Annotated[int]`` is not valid) - def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: - return word_list[word] + * The order of the annotations is preserved and matters for equality + checks:: -.. class:: MutableMapping(Mapping[KT, VT]) + Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ + int, ctype("char"), ValueRange(3, 10) + ] - A generic version of :class:`collections.abc.MutableMapping`. + * Nested ``Annotated`` types are flattened, with metadata ordered + starting with the innermost annotation:: -.. class:: Sequence(Reversible[T_co], Collection[T_co]) + Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ + int, ValueRange(3, 10), ctype("char") + ] - A generic version of :class:`collections.abc.Sequence`. + * Duplicated annotations are not removed:: -.. class:: MutableSequence(Sequence[T]) + Annotated[int, ValueRange(3, 10)] != Annotated[ + int, ValueRange(3, 10), ValueRange(3, 10) + ] - A generic version of :class:`collections.abc.MutableSequence`. + * ``Annotated`` can be used with nested and generic aliases:: -.. class:: ByteString(Sequence[int]) + T = TypeVar('T') + Vec = Annotated[List[Tuple[T, T]], MaxLen(10)] + V = Vec[int] - A generic version of :class:`collections.abc.ByteString`. + V == Annotated[List[Tuple[int, int]], MaxLen(10)] - This type represents the types :class:`bytes`, :class:`bytearray`, - and :class:`memoryview` of byte sequences. + .. versionadded:: 3.9 - As a shorthand for this type, :class:`bytes` can be used to - annotate arguments of any of the types mentioned above. +Building generic types +"""""""""""""""""""""" -.. class:: Deque(deque, MutableSequence[T]) +These are not used in annotations. They are building blocks for creating generic types. - A generic version of :class:`collections.deque`. +.. class:: Generic - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 + Abstract base class for generic types. -.. class:: List(list, MutableSequence[T]) + A generic type is typically declared by inheriting from an + instantiation of this class with one or more type variables. + For example, a generic mapping type might be defined as:: - Generic version of :class:`list`. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`Sequence` or - :class:`Iterable`. + class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc. - This type may be used as follows:: + This class can then be used as follows:: - T = TypeVar('T', int, float) + X = TypeVar('X') + Y = TypeVar('Y') - def vec2(x: T, y: T) -> List[T]: - return [x, y] + def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: + try: + return mapping[key] + except KeyError: + return default - def keep_positives(vector: Sequence[T]) -> List[T]: - return [item for item in vector if item > 0] +.. class:: TypeVar -.. class:: Set(set, MutableSet[T]) + Type variable. - A generic version of :class:`builtins.set `. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`AbstractSet`. + Usage:: -.. class:: FrozenSet(frozenset, AbstractSet[T_co]) + T = TypeVar('T') # Can be anything + A = TypeVar('A', str, bytes) # Must be str or bytes - A generic version of :class:`builtins.frozenset `. + Type variables exist primarily for the benefit of static type + checkers. They serve as the parameters for generic types as well + as for generic function definitions. See class Generic for more + information on generic types. Generic functions work as follows:: -.. class:: MappingView(Sized, Iterable[T_co]) + def repeat(x: T, n: int) -> Sequence[T]: + """Return a list containing n references to x.""" + return [x]*n - A generic version of :class:`collections.abc.MappingView`. + def longest(x: A, y: A) -> A: + """Return the longest of two strings.""" + return x if len(x) >= len(y) else y -.. class:: KeysView(MappingView[KT_co], AbstractSet[KT_co]) + The latter example's signature is essentially the overloading + of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note + that if the arguments are instances of some subclass of :class:`str`, + the return type is still plain :class:`str`. - A generic version of :class:`collections.abc.KeysView`. + At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, + :func:`isinstance` and :func:`issubclass` should not be used with types. -.. class:: ItemsView(MappingView, Generic[KT_co, VT_co]) + Type variables may be marked covariant or contravariant by passing + ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more + details. By default type variables are invariant. Alternatively, + a type variable may specify an upper bound using ``bound=``. + This means that an actual type substituted (explicitly or implicitly) + for the type variable must be a subclass of the boundary type, + see :pep:`484`. - A generic version of :class:`collections.abc.ItemsView`. +.. data:: AnyStr -.. class:: ValuesView(MappingView[VT_co]) + ``AnyStr`` is a type variable defined as + ``AnyStr = TypeVar('AnyStr', str, bytes)``. - A generic version of :class:`collections.abc.ValuesView`. + It is meant to be used for functions that may accept any kind of string + without allowing different kinds of strings to mix. For example:: -.. class:: Awaitable(Generic[T_co]) + def concat(a: AnyStr, b: AnyStr) -> AnyStr: + return a + b - A generic version of :class:`collections.abc.Awaitable`. + concat(u"foo", u"bar") # Ok, output has type 'unicode' + concat(b"foo", b"bar") # Ok, output has type 'bytes' + concat(u"foo", b"bar") # Error, cannot mix unicode and bytes - .. versionadded:: 3.5.2 +.. class:: Protocol(Generic) -.. class:: Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co]) + Base class for protocol classes. Protocol classes are defined like this:: - A generic version of :class:`collections.abc.Coroutine`. - The variance and order of type variables - correspond to those of :class:`Generator`, for example:: + class Proto(Protocol): + def meth(self) -> int: + ... - from typing import List, Coroutine - c = None # type: Coroutine[List[str], str, int] - ... - x = c.send('hi') # type: List[str] - async def bar() -> None: - x = await c # type: int + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: - .. versionadded:: 3.5.3 + class C: + def meth(self) -> int: + return 0 -.. class:: AsyncIterable(Generic[T_co]) + def func(x: Proto) -> int: + return x.meth() - A generic version of :class:`collections.abc.AsyncIterable`. + func(C()) # Passes static type check - .. versionadded:: 3.5.2 + See :pep:`544` for details. Protocol classes decorated with + :func:`runtime_checkable` (described later) act as simple-minded runtime + protocols that check only the presence of given attributes, ignoring their + type signatures. -.. class:: AsyncIterator(AsyncIterable[T_co]) + Protocol classes can be generic, for example:: - A generic version of :class:`collections.abc.AsyncIterator`. + class GenProto(Protocol[T]): + def meth(self) -> T: + ... - .. versionadded:: 3.5.2 + .. versionadded:: 3.8 -.. class:: ContextManager(Generic[T_co]) +.. decorator:: runtime_checkable - A generic version of :class:`contextlib.AbstractContextManager`. + Mark a protocol class as a runtime protocol. - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.0 + Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. + This raises :exc:`TypeError` when applied to a non-protocol class. This + allows a simple-minded structural check, very similar to "one trick ponies" + in :mod:`collections.abc` such as :class:`Iterable`. For example:: -.. class:: AsyncContextManager(Generic[T_co]) + @runtime_checkable + class Closable(Protocol): + def close(self): ... - A generic version of :class:`contextlib.AbstractAsyncContextManager`. + assert isinstance(open('/some/file'), Closable) - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.2 + .. note:: -.. class:: Dict(dict, MutableMapping[KT, VT]) + :func:`runtime_checkable` will check only the presence of the required methods, + not their type signatures! For example, :class:`builtins.complex ` + implements :func:`__float__`, therefore it passes an :func:`issubclass` check + against :class:`SupportsFloat`. However, the ``complex.__float__`` method + exists only to raise a :class:`TypeError` with a more informative message. - A generic version of :class:`dict`. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`Mapping`. + .. versionadded:: 3.8 - This type can be used as follows:: +Other special directives +"""""""""""""""""""""""" - def count_words(text: str) -> Dict[str, int]: - ... +These are not used in annotations. They are building blocks for declaring types. -.. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT]) +.. class:: NamedTuple - A generic version of :class:`collections.defaultdict`. + Typed version of :func:`collections.namedtuple`. - .. versionadded:: 3.5.2 + Usage:: -.. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) + class Employee(NamedTuple): + name: str + id: int - A generic version of :class:`collections.OrderedDict`. + This is equivalent to:: - .. versionadded:: 3.7.2 + Employee = collections.namedtuple('Employee', ['name', 'id']) -.. class:: Counter(collections.Counter, Dict[T, int]) + To give a field a default value, you can assign to it in the class body:: - A generic version of :class:`collections.Counter`. + class Employee(NamedTuple): + name: str + id: int = 3 - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 + employee = Employee('Guido') + assert employee.id == 3 -.. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) + Fields with a default value must come after any fields without a default. - A generic version of :class:`collections.ChainMap`. + The resulting class has an extra attribute ``__annotations__`` giving a + dict that maps the field names to the field types. (The field names are in + the ``_fields`` attribute and the default values are in the + ``_field_defaults`` attribute both of which are part of the namedtuple + API.) - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 + ``NamedTuple`` subclasses can also have docstrings and methods:: -.. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) - - A generator can be annotated by the generic type - ``Generator[YieldType, SendType, ReturnType]``. For example:: - - def echo_round() -> Generator[int, float, str]: - sent = yield 0 - while sent >= 0: - sent = yield round(sent) - return 'Done' - - Note that unlike many other generics in the typing module, the ``SendType`` - of :class:`Generator` behaves contravariantly, not covariantly or - invariantly. - - If your generator will only yield values, set the ``SendType`` and - ``ReturnType`` to ``None``:: - - def infinite_stream(start: int) -> Generator[int, None, None]: - while True: - yield start - start += 1 - - Alternatively, annotate your generator as having a return type of - either ``Iterable[YieldType]`` or ``Iterator[YieldType]``:: - - def infinite_stream(start: int) -> Iterator[int]: - while True: - yield start - start += 1 - -.. class:: AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra]) - - An async generator can be annotated by the generic type - ``AsyncGenerator[YieldType, SendType]``. For example:: - - async def echo_round() -> AsyncGenerator[int, float]: - sent = yield 0 - while sent >= 0.0: - rounded = await round(sent) - sent = yield rounded - - Unlike normal generators, async generators cannot return a value, so there - is no ``ReturnType`` type parameter. As with :class:`Generator`, the - ``SendType`` behaves contravariantly. - - If your generator will only yield values, set the ``SendType`` to - ``None``:: - - async def infinite_stream(start: int) -> AsyncGenerator[int, None]: - while True: - yield start - start = await increment(start) - - Alternatively, annotate your generator as having a return type of - either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``:: - - async def infinite_stream(start: int) -> AsyncIterator[int]: - while True: - yield start - start = await increment(start) - - .. versionadded:: 3.6.1 - -.. class:: Text - - ``Text`` is an alias for ``str``. It is provided to supply a forward - compatible path for Python 2 code: in Python 2, ``Text`` is an alias for - ``unicode``. - - Use ``Text`` to indicate that a value must contain a unicode string in - a manner that is compatible with both Python 2 and Python 3:: - - def add_unicode_checkmark(text: Text) -> Text: - return text + u' \u2713' - - .. versionadded:: 3.5.2 - -.. class:: IO - TextIO - BinaryIO - - Generic type ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])`` - and ``BinaryIO(IO[bytes])`` - represent the types of I/O streams such as returned by - :func:`open`. - -.. class:: Pattern - Match - - These type aliases - correspond to the return types from :func:`re.compile` and - :func:`re.match`. These types (and the corresponding functions) - are generic in ``AnyStr`` and can be made specific by writing - ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or - ``Match[bytes]``. - -.. class:: NamedTuple - - Typed version of :func:`collections.namedtuple`. - - Usage:: - - class Employee(NamedTuple): - name: str - id: int - - This is equivalent to:: - - Employee = collections.namedtuple('Employee', ['name', 'id']) - - To give a field a default value, you can assign to it in the class body:: - - class Employee(NamedTuple): - name: str - id: int = 3 - - employee = Employee('Guido') - assert employee.id == 3 - - Fields with a default value must come after any fields without a default. - - The resulting class has an extra attribute ``__annotations__`` giving a - dict that maps the field names to the field types. (The field names are in - the ``_fields`` attribute and the default values are in the - ``_field_defaults`` attribute both of which are part of the namedtuple - API.) - - ``NamedTuple`` subclasses can also have docstrings and methods:: - - class Employee(NamedTuple): - """Represents an employee.""" - name: str - id: int = 3 + class Employee(NamedTuple): + """Represents an employee.""" + name: str + id: int = 3 def __repr__(self) -> str: return f'' @@ -967,13 +982,23 @@ The module defines the following classes, functions and decorators: Removed the ``_field_types`` attribute in favor of the more standard ``__annotations__`` attribute which has the same information. +.. function:: NewType(name, tp) + + A helper function to indicate a distinct type to a typechecker, + see :ref:`distinct`. At runtime it returns a function that returns + its argument. Usage:: + + UserId = NewType('UserId', int) + first_user = UserId(1) + + .. versionadded:: 3.5.2 .. class:: TypedDict(dict) - A simple typed namespace. At runtime it is equivalent to - a plain :class:`dict`. + Special construct to add type hints to a dictionary. + At runtime it is a plain :class:`dict`. - ``TypedDict`` creates a dictionary type that expects all of its + ``TypedDict`` declares a dictionary type that expects all of its instances to have a certain set of keys, where each key is associated with a value of a consistent type. This expectation is not checked at runtime but is only enforced by type checkers. @@ -1014,474 +1039,658 @@ The module defines the following classes, functions and decorators: .. versionadded:: 3.8 -.. class:: ForwardRef +Generic concrete collections +---------------------------- - A class used for internal typing representation of string forward references. - For example, ``List["SomeClass"]`` is implicitly transformed into - ``List[ForwardRef("SomeClass")]``. This class should not be instantiated by - a user, but may be used by introspection tools. +Corresponding to built-in types +""""""""""""""""""""""""""""""" -.. function:: NewType(name, tp) +.. class:: Dict(dict, MutableMapping[KT, VT]) - A helper function to indicate a distinct type to a typechecker, - see :ref:`distinct`. At runtime it returns a function that returns - its argument. Usage:: + A generic version of :class:`dict`. + Useful for annotating return types. To annotate arguments it is preferred + to use an abstract collection type such as :class:`Mapping`. - UserId = NewType('UserId', int) - first_user = UserId(1) + This type can be used as follows:: - .. versionadded:: 3.5.2 + def count_words(text: str) -> Dict[str, int]: + ... -.. function:: cast(typ, val) + .. deprecated:: 3.9 + :class:`builtins.dict ` now supports ``[]``. See :pep:`585`. - Cast a value to a type. +.. class:: List(list, MutableSequence[T]) - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). + Generic version of :class:`list`. + Useful for annotating return types. To annotate arguments it is preferred + to use an abstract collection type such as :class:`Sequence` or + :class:`Iterable`. -.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) + This type may be used as follows:: - Return a dictionary containing type hints for a function, method, module - or class object. + T = TypeVar('T', int, float) - This is often the same as ``obj.__annotations__``. In addition, - forward references encoded as string literals are handled by evaluating - them in ``globals`` and ``locals`` namespaces. If necessary, - ``Optional[t]`` is added for function and method annotations if a default - value equal to ``None`` is set. For a class ``C``, return - a dictionary constructed by merging all the ``__annotations__`` along - ``C.__mro__`` in reverse order. + def vec2(x: T, y: T) -> List[T]: + return [x, y] - The function recursively replaces all ``Annotated[T, ...]`` with ``T``, - unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for - more information). For example:: + def keep_positives(vector: Sequence[T]) -> List[T]: + return [item for item in vector if item > 0] - class Student(NamedTuple): - name: Annotated[str, 'some marker'] + .. deprecated:: 3.9 + :class:`builtins.list ` now supports ``[]``. See :pep:`585`. - get_type_hints(Student) == {'name': str} - get_type_hints(Student, include_extras=False) == {'name': str} - get_type_hints(Student, include_extras=True) == { - 'name': Annotated[str, 'some marker'] - } +.. class:: Set(set, MutableSet[T]) - .. versionchanged:: 3.9 - Added ``include_extras`` parameter as part of :pep:`593`. + A generic version of :class:`builtins.set `. + Useful for annotating return types. To annotate arguments it is preferred + to use an abstract collection type such as :class:`AbstractSet`. -.. function:: get_origin(tp) -.. function:: get_args(tp) + .. deprecated:: 3.9 + :class:`builtins.set ` now supports ``[]``. See :pep:`585`. - Provide basic introspection for generic types and special typing forms. +.. class:: FrozenSet(frozenset, AbstractSet[T_co]) - For a typing object of the form ``X[Y, Z, ...]`` these functions return - ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or - :mod:`collections` class, it gets normalized to the original class. - For unsupported objects return ``None`` and ``()`` correspondingly. - Examples:: + A generic version of :class:`builtins.frozenset `. - assert get_origin(Dict[str, int]) is dict - assert get_args(Dict[int, str]) == (int, str) + .. deprecated:: 3.9 + :class:`builtins.frozenset ` now supports ``[]``. See :pep:`585`. - assert get_origin(Union[int, str]) is Union - assert get_args(Union[int, str]) == (int, str) +.. note:: :data:`Tuple` is a special form. - .. versionadded:: 3.8 +Corresponding to types in :mod:`collections` +"""""""""""""""""""""""""""""""""""""""""""" -.. decorator:: overload +.. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT]) - The ``@overload`` decorator allows describing functions and methods - that support multiple different combinations of argument types. A series - of ``@overload``-decorated definitions must be followed by exactly one - non-``@overload``-decorated definition (for the same function/method). - The ``@overload``-decorated definitions are for the benefit of the - type checker only, since they will be overwritten by the - non-``@overload``-decorated definition, while the latter is used at - runtime but should be ignored by a type checker. At runtime, calling - a ``@overload``-decorated function directly will raise - :exc:`NotImplementedError`. An example of overload that gives a more - precise type than can be expressed using a union or a type variable:: + A generic version of :class:`collections.defaultdict`. - @overload - def process(response: None) -> None: - ... - @overload - def process(response: int) -> Tuple[int, str]: - ... - @overload - def process(response: bytes) -> str: - ... - def process(response): - + .. versionadded:: 3.5.2 - See :pep:`484` for details and comparison with other typing semantics. + .. deprecated:: 3.9 + :class:`collections.defaultdict` now supports ``[]``. See :pep:`585`. -.. decorator:: final +.. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) - A decorator to indicate to type checkers that the decorated method - cannot be overridden, and the decorated class cannot be subclassed. - For example:: + A generic version of :class:`collections.OrderedDict`. - class Base: - @final - def done(self) -> None: - ... - class Sub(Base): - def done(self) -> None: # Error reported by type checker - ... + .. versionadded:: 3.7.2 - @final - class Leaf: - ... - class Other(Leaf): # Error reported by type checker - ... + .. deprecated:: 3.9 + :class:`collections.OrderedDict` now supports ``[]``. See :pep:`585`. - There is no runtime checking of these properties. See :pep:`591` for - more details. +.. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) - .. versionadded:: 3.8 + A generic version of :class:`collections.ChainMap`. -.. decorator:: no_type_check + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 - Decorator to indicate that annotations are not type hints. + .. deprecated:: 3.9 + :class:`collections.ChainMap` now supports ``[]``. See :pep:`585`. - This works as class or function :term:`decorator`. With a class, it - applies recursively to all methods defined in that class (but not - to methods defined in its superclasses or subclasses). +.. class:: Counter(collections.Counter, Dict[T, int]) - This mutates the function(s) in place. + A generic version of :class:`collections.Counter`. -.. decorator:: no_type_check_decorator + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 - Decorator to give another decorator the :func:`no_type_check` effect. + .. deprecated:: 3.9 + :class:`collections.Counter` now supports ``[]``. See :pep:`585`. - This wraps the decorator with something that wraps the decorated - function in :func:`no_type_check`. +.. class:: Deque(deque, MutableSequence[T]) -.. decorator:: type_check_only + A generic version of :class:`collections.deque`. - Decorator to mark a class or function to be unavailable at runtime. + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 - This decorator is itself not available at runtime. It is mainly - intended to mark classes that are defined in type stub files if - an implementation returns an instance of a private class:: + .. deprecated:: 3.9 + :class:`collections.deque` now supports ``[]``. See :pep:`585`. - @type_check_only - class Response: # private or not available at runtime - code: int - def get_header(self, name: str) -> str: ... +Other concrete types +"""""""""""""""""""" - def fetch_response() -> Response: ... +.. class:: IO + TextIO + BinaryIO - Note that returning instances of private classes is not recommended. - It is usually preferable to make such classes public. + Generic type ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])`` + and ``BinaryIO(IO[bytes])`` + represent the types of I/O streams such as returned by + :func:`open`. These types are also in the ``typing.io`` namespace. -.. decorator:: runtime_checkable +.. class:: Pattern + Match - Mark a protocol class as a runtime protocol. + These type aliases + correspond to the return types from :func:`re.compile` and + :func:`re.match`. These types (and the corresponding functions) + are generic in ``AnyStr`` and can be made specific by writing + ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or + ``Match[bytes]``. These types are also in the ``typing.re`` namespace. - Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. - This raises :exc:`TypeError` when applied to a non-protocol class. This - allows a simple-minded structural check, very similar to "one trick ponies" - in :mod:`collections.abc` such as :class:`Iterable`. For example:: + .. deprecated:: 3.9 + Classes ``Pattern`` and ``Match`` from :mod:`re` now support ``[]``. See :pep:`585`. - @runtime_checkable - class Closable(Protocol): - def close(self): ... +.. class:: Text - assert isinstance(open('/some/file'), Closable) + ``Text`` is an alias for ``str``. It is provided to supply a forward + compatible path for Python 2 code: in Python 2, ``Text`` is an alias for + ``unicode``. - **Warning:** this will check only the presence of the required methods, - not their type signatures! + Use ``Text`` to indicate that a value must contain a unicode string in + a manner that is compatible with both Python 2 and Python 3:: - .. versionadded:: 3.8 + def add_unicode_checkmark(text: Text) -> Text: + return text + u' \u2713' -.. data:: Any + .. versionadded:: 3.5.2 - Special type indicating an unconstrained type. +Abstract Base Classes +--------------------- - * Every type is compatible with :data:`Any`. - * :data:`Any` is compatible with every type. +Corresponding to collections in :mod:`collections.abc` +"""""""""""""""""""""""""""""""""""""""""""""""""""""" -.. data:: NoReturn +.. class:: AbstractSet(Sized, Collection[T_co]) - Special type indicating that a function never returns. - For example:: + A generic version of :class:`collections.abc.Set`. - from typing import NoReturn + .. deprecated:: 3.9 + :class:`collections.abc.Set` now supports ``[]``. See :pep:`585`. - def stop() -> NoReturn: - raise RuntimeError('no way') +.. class:: ByteString(Sequence[int]) - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.2 + A generic version of :class:`collections.abc.ByteString`. -.. data:: Union + This type represents the types :class:`bytes`, :class:`bytearray`, + and :class:`memoryview` of byte sequences. - Union type; ``Union[X, Y]`` means either X or Y. + As a shorthand for this type, :class:`bytes` can be used to + annotate arguments of any of the types mentioned above. - To define a union, use e.g. ``Union[int, str]``. Details: + .. deprecated:: 3.9 + :class:`collections.abc.ByteString` now supports ``[]``. See :pep:`585`. - * The arguments must be types and there must be at least one. +.. class:: Collection(Sized, Iterable[T_co], Container[T_co]) - * Unions of unions are flattened, e.g.:: + A generic version of :class:`collections.abc.Collection` - Union[Union[int, str], float] == Union[int, str, float] + .. versionadded:: 3.6.0 - * Unions of a single argument vanish, e.g.:: + .. deprecated:: 3.9 + :class:`collections.abc.Collection` now supports ``[]``. See :pep:`585`. - Union[int] == int # The constructor actually returns int +.. class:: Container(Generic[T_co]) - * Redundant arguments are skipped, e.g.:: + A generic version of :class:`collections.abc.Container`. - Union[int, str, int] == Union[int, str] + .. deprecated:: 3.9 + :class:`collections.abc.Container` now supports ``[]``. See :pep:`585`. - * When comparing unions, the argument order is ignored, e.g.:: +.. class:: ItemsView(MappingView, Generic[KT_co, VT_co]) - Union[int, str] == Union[str, int] + A generic version of :class:`collections.abc.ItemsView`. - * You cannot subclass or instantiate a union. + .. deprecated:: 3.9 + :class:`collections.abc.ItemsView` now supports ``[]``. See :pep:`585`. - * You cannot write ``Union[X][Y]``. +.. class:: KeysView(MappingView[KT_co], AbstractSet[KT_co]) - * You can use ``Optional[X]`` as a shorthand for ``Union[X, None]``. + A generic version of :class:`collections.abc.KeysView`. - .. versionchanged:: 3.7 - Don't remove explicit subclasses from unions at runtime. + .. deprecated:: 3.9 + :class:`collections.abc.KeysView` now supports ``[]``. See :pep:`585`. -.. data:: Optional +.. class:: Mapping(Sized, Collection[KT], Generic[VT_co]) - Optional type. + A generic version of :class:`collections.abc.Mapping`. + This type can be used as follows:: - ``Optional[X]`` is equivalent to ``Union[X, None]``. + def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: + return word_list[word] - Note that this is not the same concept as an optional argument, - which is one that has a default. An optional argument with a - default does not require the ``Optional`` qualifier on its type - annotation just because it is optional. For example:: + .. deprecated:: 3.9 + :class:`collections.abc.Mapping` now supports ``[]``. See :pep:`585`. - def foo(arg: int = 0) -> None: - ... +.. class:: MappingView(Sized, Iterable[T_co]) - On the other hand, if an explicit value of ``None`` is allowed, the - use of ``Optional`` is appropriate, whether the argument is optional - or not. For example:: + A generic version of :class:`collections.abc.MappingView`. - def foo(arg: Optional[int] = None) -> None: - ... + .. deprecated:: 3.9 + :class:`collections.abc.MappingView` now supports ``[]``. See :pep:`585`. -.. data:: Tuple +.. class:: MutableMapping(Mapping[KT, VT]) - Tuple type; ``Tuple[X, Y]`` is the type of a tuple of two items - with the first item of type X and the second of type Y. The type of - the empty tuple can be written as ``Tuple[()]``. + A generic version of :class:`collections.abc.MutableMapping`. - Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding - to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple - of an int, a float and a string. + .. deprecated:: 3.9 + :class:`collections.abc.MutableMapping` now supports ``[]``. See :pep:`585`. - To specify a variable-length tuple of homogeneous type, - use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain :data:`Tuple` - is equivalent to ``Tuple[Any, ...]``, and in turn to :class:`tuple`. +.. class:: MutableSequence(Sequence[T]) -.. data:: Callable + A generic version of :class:`collections.abc.MutableSequence`. - Callable type; ``Callable[[int], str]`` is a function of (int) -> str. + .. deprecated:: 3.9 + :class:`collections.abc.MutableSequence` now supports ``[]``. See :pep:`585`. - The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or an ellipsis; the return type must be - a single type. +.. class:: MutableSet(AbstractSet[T]) - There is no syntax to indicate optional or keyword arguments; - such function types are rarely used as callback types. - ``Callable[..., ReturnType]`` (literal ellipsis) can be used to - type hint a callable taking any number of arguments and returning - ``ReturnType``. A plain :data:`Callable` is equivalent to - ``Callable[..., Any]``, and in turn to - :class:`collections.abc.Callable`. + A generic version of :class:`collections.abc.MutableSet`. -.. data:: Literal + .. deprecated:: 3.9 + :class:`collections.abc.MutableSet` now supports ``[]``. See :pep:`585`. - A type that can be used to indicate to type checkers that the - corresponding variable or function parameter has a value equivalent to - the provided literal (or one of several literals). For example:: +.. class:: Sequence(Reversible[T_co], Collection[T_co]) - def validate_simple(data: Any) -> Literal[True]: # always returns True - ... + A generic version of :class:`collections.abc.Sequence`. - MODE = Literal['r', 'rb', 'w', 'wb'] - def open_helper(file: str, mode: MODE) -> str: - ... + .. deprecated:: 3.9 + :class:`collections.abc.Sequence` now supports ``[]``. See :pep:`585`. - open_helper('/some/path', 'r') # Passes type check - open_helper('/other/path', 'typo') # Error in type checker +.. class:: ValuesView(MappingView[VT_co]) - ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value - is allowed as type argument to ``Literal[...]``, but type checkers may - impose restrictions. See :pep:`586` for more details about literal types. + A generic version of :class:`collections.abc.ValuesView`. - .. versionadded:: 3.8 + .. deprecated:: 3.9 + :class:`collections.abc.ValuesView` now supports ``[]``. See :pep:`585`. -.. data:: ClassVar +Corresponding to other types in :mod:`collections.abc` +"""""""""""""""""""""""""""""""""""""""""""""""""""""" - Special type construct to mark class variables. +.. class:: Iterable(Generic[T_co]) - As introduced in :pep:`526`, a variable annotation wrapped in ClassVar - indicates that a given attribute is intended to be used as a class variable - and should not be set on instances of that class. Usage:: + A generic version of :class:`collections.abc.Iterable`. - class Starship: - stats: ClassVar[Dict[str, int]] = {} # class variable - damage: int = 10 # instance variable + .. deprecated:: 3.9 + :class:`collections.abc.Iterable` now supports ``[]``. See :pep:`585`. - :data:`ClassVar` accepts only types and cannot be further subscribed. +.. class:: Iterator(Iterable[T_co]) - :data:`ClassVar` is not a class itself, and should not - be used with :func:`isinstance` or :func:`issubclass`. - :data:`ClassVar` does not change Python runtime behavior, but - it can be used by third-party type checkers. For example, a type checker - might flag the following code as an error:: + A generic version of :class:`collections.abc.Iterator`. - enterprise_d = Starship(3000) - enterprise_d.stats = {} # Error, setting class variable on instance - Starship.stats = {} # This is OK + .. deprecated:: 3.9 + :class:`collections.abc.Iterator` now supports ``[]``. See :pep:`585`. - .. versionadded:: 3.5.3 +.. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) -.. data:: Final + A generator can be annotated by the generic type + ``Generator[YieldType, SendType, ReturnType]``. For example:: - A special typing construct to indicate to type checkers that a name - cannot be re-assigned or overridden in a subclass. For example:: + def echo_round() -> Generator[int, float, str]: + sent = yield 0 + while sent >= 0: + sent = yield round(sent) + return 'Done' - MAX_SIZE: Final = 9000 - MAX_SIZE += 1 # Error reported by type checker + Note that unlike many other generics in the typing module, the ``SendType`` + of :class:`Generator` behaves contravariantly, not covariantly or + invariantly. - class Connection: - TIMEOUT: Final[int] = 10 + If your generator will only yield values, set the ``SendType`` and + ``ReturnType`` to ``None``:: - class FastConnector(Connection): - TIMEOUT = 1 # Error reported by type checker + def infinite_stream(start: int) -> Generator[int, None, None]: + while True: + yield start + start += 1 - There is no runtime checking of these properties. See :pep:`591` for - more details. + Alternatively, annotate your generator as having a return type of + either ``Iterable[YieldType]`` or ``Iterator[YieldType]``:: - .. versionadded:: 3.8 + def infinite_stream(start: int) -> Iterator[int]: + while True: + yield start + start += 1 -.. data:: AnyStr + .. deprecated:: 3.9 + :class:`collections.abc.Generator` now supports ``[]``. See :pep:`585`. - ``AnyStr`` is a type variable defined as - ``AnyStr = TypeVar('AnyStr', str, bytes)``. +.. class:: Hashable - It is meant to be used for functions that may accept any kind of string - without allowing different kinds of strings to mix. For example:: + An alias to :class:`collections.abc.Hashable` - def concat(a: AnyStr, b: AnyStr) -> AnyStr: - return a + b +.. class:: Reversible(Iterable[T_co]) - concat(u"foo", u"bar") # Ok, output has type 'unicode' - concat(b"foo", b"bar") # Ok, output has type 'bytes' - concat(u"foo", b"bar") # Error, cannot mix unicode and bytes + A generic version of :class:`collections.abc.Reversible`. -.. data:: TYPE_CHECKING + .. deprecated:: 3.9 + :class:`collections.abc.Reversible` now supports ``[]``. See :pep:`585`. - A special constant that is assumed to be ``True`` by 3rd party static - type checkers. It is ``False`` at runtime. Usage:: +.. class:: Sized - if TYPE_CHECKING: - import expensive_mod + An alias to :class:`collections.abc.Sized` - def fun(arg: 'expensive_mod.SomeType') -> None: - local_var: expensive_mod.AnotherType = other_fun() +Asynchronous programming +"""""""""""""""""""""""" - Note that the first type annotation must be enclosed in quotes, making it a - "forward reference", to hide the ``expensive_mod`` reference from the - interpreter runtime. Type annotations for local variables are not - evaluated, so the second annotation does not need to be enclosed in quotes. +.. class:: Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co]) + + A generic version of :class:`collections.abc.Coroutine`. + The variance and order of type variables + correspond to those of :class:`Generator`, for example:: + + from typing import List, Coroutine + c = None # type: Coroutine[List[str], str, int] + ... + x = c.send('hi') # type: List[str] + async def bar() -> None: + x = await c # type: int + + .. versionadded:: 3.5.3 + + .. deprecated:: 3.9 + :class:`collections.abc.Coroutine` now supports ``[]``. See :pep:`585`. + +.. class:: AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra]) + + An async generator can be annotated by the generic type + ``AsyncGenerator[YieldType, SendType]``. For example:: + + async def echo_round() -> AsyncGenerator[int, float]: + sent = yield 0 + while sent >= 0.0: + rounded = await round(sent) + sent = yield rounded + + Unlike normal generators, async generators cannot return a value, so there + is no ``ReturnType`` type parameter. As with :class:`Generator`, the + ``SendType`` behaves contravariantly. + + If your generator will only yield values, set the ``SendType`` to + ``None``:: + + async def infinite_stream(start: int) -> AsyncGenerator[int, None]: + while True: + yield start + start = await increment(start) + + Alternatively, annotate your generator as having a return type of + either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``:: + + async def infinite_stream(start: int) -> AsyncIterator[int]: + while True: + yield start + start = await increment(start) + + .. versionadded:: 3.6.1 + + .. deprecated:: 3.9 + :class:`collections.abc.AsyncGenerator` now supports ``[]``. See :pep:`585`. + +.. class:: AsyncIterable(Generic[T_co]) + + A generic version of :class:`collections.abc.AsyncIterable`. .. versionadded:: 3.5.2 -.. data:: Annotated + .. deprecated:: 3.9 + :class:`collections.abc.AsyncIterable` now supports ``[]``. See :pep:`585`. - A type, introduced in :pep:`593` (``Flexible function and variable - annotations``), to decorate existing types with context-specific metadata - (possibly multiple pieces of it, as ``Annotated`` is variadic). - Specifically, a type ``T`` can be annotated with metadata ``x`` via the - typehint ``Annotated[T, x]``. This metadata can be used for either static - analysis or at runtime. If a library (or tool) encounters a typehint - ``Annotated[T, x]`` and has no special logic for metadata ``x``, it - should ignore it and simply treat the type as ``T``. Unlike the - ``no_type_check`` functionality that currently exists in the ``typing`` - module which completely disables typechecking annotations on a function - or a class, the ``Annotated`` type allows for both static typechecking - of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) - together with runtime access to ``x`` within a specific application. +.. class:: AsyncIterator(AsyncIterable[T_co]) - Ultimately, the responsibility of how to interpret the annotations (if - at all) is the responsibility of the tool or library encountering the - ``Annotated`` type. A tool or library encountering an ``Annotated`` type - can scan through the annotations to determine if they are of interest - (e.g., using ``isinstance()``). + A generic version of :class:`collections.abc.AsyncIterator`. - When a tool or a library does not support annotations or encounters an - unknown annotation it should just ignore it and treat annotated type as - the underlying type. + .. versionadded:: 3.5.2 - It's up to the tool consuming the annotations to decide whether the - client is allowed to have several annotations on one type and how to - merge those annotations. + .. deprecated:: 3.9 + :class:`collections.abc.AsyncIterator` now supports ``[]``. See :pep:`585`. - Since the ``Annotated`` type allows you to put several annotations of - the same (or different) type(s) on any node, the tools or libraries - consuming those annotations are in charge of dealing with potential - duplicates. For example, if you are doing value range analysis you might - allow this:: +.. class:: Awaitable(Generic[T_co]) - T1 = Annotated[int, ValueRange(-10, 5)] - T2 = Annotated[T1, ValueRange(-20, 3)] + A generic version of :class:`collections.abc.Awaitable`. - Passing ``include_extras=True`` to :func:`get_type_hints` lets one - access the extra annotations at runtime. + .. versionadded:: 3.5.2 - The details of the syntax: + .. deprecated:: 3.9 + :class:`collections.abc.Awaitable` now supports ``[]``. See :pep:`585`. - * The first argument to ``Annotated`` must be a valid type - * Multiple type annotations are supported (``Annotated`` supports variadic - arguments):: +Context manager types +""""""""""""""""""""" - Annotated[int, ValueRange(3, 10), ctype("char")] +.. class:: ContextManager(Generic[T_co]) - * ``Annotated`` must be called with at least two arguments ( - ``Annotated[int]`` is not valid) + A generic version of :class:`contextlib.AbstractContextManager`. - * The order of the annotations is preserved and matters for equality - checks:: + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.0 - Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ - int, ctype("char"), ValueRange(3, 10) - ] + .. deprecated:: 3.9 + :class:`collections.contextlib.AbstractContextManager` now supports ``[]``. See :pep:`585`. - * Nested ``Annotated`` types are flattened, with metadata ordered - starting with the innermost annotation:: +.. class:: AsyncContextManager(Generic[T_co]) - Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ - int, ValueRange(3, 10), ctype("char") - ] + A generic version of :class:`contextlib.AbstractAsyncContextManager`. - * Duplicated annotations are not removed:: + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.2 - Annotated[int, ValueRange(3, 10)] != Annotated[ - int, ValueRange(3, 10), ValueRange(3, 10) - ] + .. deprecated:: 3.9 + :class:`collections.contextlib.AbstractAsyncContextManager` now supports ``[]``. See :pep:`585`. - * ``Annotated`` can be used with nested and generic aliases:: +Protocols +--------- - T = TypeVar('T') - Vec = Annotated[List[Tuple[T, T]], MaxLen(10)] - V = Vec[int] +These protocols are decorated with :func:`runtime_checkable`. - V == Annotated[List[Tuple[int, int]], MaxLen(10)] +.. class:: SupportsAbs + + An ABC with one abstract method ``__abs__`` that is covariant + in its return type. + +.. class:: SupportsBytes + + An ABC with one abstract method ``__bytes__``. + +.. class:: SupportsComplex + + An ABC with one abstract method ``__complex__``. + +.. class:: SupportsFloat + + An ABC with one abstract method ``__float__``. + +.. class:: SupportsIndex + + An ABC with one abstract method ``__index__``. + + .. versionadded:: 3.8 + +.. class:: SupportsInt + + An ABC with one abstract method ``__int__``. + +.. class:: SupportsRound + + An ABC with one abstract method ``__round__`` + that is covariant in its return type. + +Functions and decorators +------------------------ + +.. function:: cast(typ, val) + + Cast a value to a type. + + This returns the value unchanged. To the type checker this + signals that the return value has the designated type, but at + runtime we intentionally don't check anything (we want this + to be as fast as possible). + +.. decorator:: overload + + The ``@overload`` decorator allows describing functions and methods + that support multiple different combinations of argument types. A series + of ``@overload``-decorated definitions must be followed by exactly one + non-``@overload``-decorated definition (for the same function/method). + The ``@overload``-decorated definitions are for the benefit of the + type checker only, since they will be overwritten by the + non-``@overload``-decorated definition, while the latter is used at + runtime but should be ignored by a type checker. At runtime, calling + a ``@overload``-decorated function directly will raise + :exc:`NotImplementedError`. An example of overload that gives a more + precise type than can be expressed using a union or a type variable:: + + @overload + def process(response: None) -> None: + ... + @overload + def process(response: int) -> Tuple[int, str]: + ... + @overload + def process(response: bytes) -> str: + ... + def process(response): + + + See :pep:`484` for details and comparison with other typing semantics. + +.. decorator:: final + + A decorator to indicate to type checkers that the decorated method + cannot be overridden, and the decorated class cannot be subclassed. + For example:: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. See :pep:`591` for + more details. + + .. versionadded:: 3.8 + +.. decorator:: no_type_check + + Decorator to indicate that annotations are not type hints. + + This works as class or function :term:`decorator`. With a class, it + applies recursively to all methods defined in that class (but not + to methods defined in its superclasses or subclasses). + + This mutates the function(s) in place. + +.. decorator:: no_type_check_decorator + + Decorator to give another decorator the :func:`no_type_check` effect. + + This wraps the decorator with something that wraps the decorated + function in :func:`no_type_check`. + +.. decorator:: type_check_only + + Decorator to mark a class or function to be unavailable at runtime. + + This decorator is itself not available at runtime. It is mainly + intended to mark classes that are defined in type stub files if + an implementation returns an instance of a private class:: + + @type_check_only + class Response: # private or not available at runtime + code: int + def get_header(self, name: str) -> str: ... + + def fetch_response() -> Response: ... + + Note that returning instances of private classes is not recommended. + It is usually preferable to make such classes public. + +Introspection helpers +--------------------- + +.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) + + Return a dictionary containing type hints for a function, method, module + or class object. + + This is often the same as ``obj.__annotations__``. In addition, + forward references encoded as string literals are handled by evaluating + them in ``globals`` and ``locals`` namespaces. If necessary, + ``Optional[t]`` is added for function and method annotations if a default + value equal to ``None`` is set. For a class ``C``, return + a dictionary constructed by merging all the ``__annotations__`` along + ``C.__mro__`` in reverse order. + + The function recursively replaces all ``Annotated[T, ...]`` with ``T``, + unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for + more information). For example:: + + class Student(NamedTuple): + name: Annotated[str, 'some marker'] + + get_type_hints(Student) == {'name': str} + get_type_hints(Student, include_extras=False) == {'name': str} + get_type_hints(Student, include_extras=True) == { + 'name': Annotated[str, 'some marker'] + } + + .. versionchanged:: 3.9 + Added ``include_extras`` parameter as part of :pep:`593`. + +.. function:: get_args(tp) +.. function:: get_origin(tp) + + Provide basic introspection for generic types and special typing forms. + + For a typing object of the form ``X[Y, Z, ...]`` these functions return + ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or + :mod:`collections` class, it gets normalized to the original class. + For unsupported objects return ``None`` and ``()`` correspondingly. + Examples:: + + assert get_origin(Dict[str, int]) is dict + assert get_args(Dict[int, str]) == (int, str) + + assert get_origin(Union[int, str]) is Union + assert get_args(Union[int, str]) == (int, str) + + .. versionadded:: 3.8 + +.. class:: ForwardRef + + A class used for internal typing representation of string forward references. + For example, ``List["SomeClass"]`` is implicitly transformed into + ``List[ForwardRef("SomeClass")]``. This class should not be instantiated by + a user, but may be used by introspection tools. + +Constant +-------- + +.. data:: TYPE_CHECKING + + A special constant that is assumed to be ``True`` by 3rd party static + type checkers. It is ``False`` at runtime. Usage:: + + if TYPE_CHECKING: + import expensive_mod + + def fun(arg: 'expensive_mod.SomeType') -> None: + local_var: expensive_mod.AnotherType = other_fun() + + The first type annotation must be enclosed in quotes, making it a + "forward reference", to hide the ``expensive_mod`` reference from the + interpreter runtime. Type annotations for local variables are not + evaluated, so the second annotation does not need to be enclosed in quotes. + + .. note:: + + If ``from __future__ import annotations`` is used in Python 3.7 or later, + annotations are not evaluated at function definition time. + Instead, the are stored as strings in ``__annotations__``, + This makes it unnecessary to use quotes around the annotation. + (see :pep:`563`). + + .. versionadded:: 3.5.2 - .. versionadded:: 3.9 diff --git a/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst b/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst new file mode 100644 index 000000000000000..b0ca4327ad61a42 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst @@ -0,0 +1 @@ +Refactored typing.rst, arranging more than 70 classes, functions, and decorators into new sub-sections. \ No newline at end of file From b6dfc1770e48db1496c8aeac023e0d53cf2e444d Mon Sep 17 00:00:00 2001 From: Nathan M Date: Sun, 2 Aug 2020 22:13:03 -0400 Subject: [PATCH 096/486] bpo-41424: Remove extra words in Tkinter-Packer documentation (GH-21707) --- Doc/library/tkinter.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 2dc44ad36a7f736..3d90b4be17c979e 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -464,12 +464,11 @@ The Packer .. index:: single: packing (widgets) The packer is one of Tk's geometry-management mechanisms. Geometry managers -are used to specify the relative positioning of the positioning of widgets -within their container - their mutual *master*. In contrast to the more -cumbersome *placer* (which is used less commonly, and we do not cover here), the -packer takes qualitative relationship specification - *above*, *to the left of*, -*filling*, etc - and works everything out to determine the exact placement -coordinates for you. +are used to specify the relative positioning of widgets within their container - +their mutual *master*. In contrast to the more cumbersome *placer* (which is +used less commonly, and we do not cover here), the packer takes qualitative +relationship specification - *above*, *to the left of*, *filling*, etc - and +works everything out to determine the exact placement coordinates for you. The size of any *master* widget is determined by the size of the "slave widgets" inside. The packer is used to control where slave widgets appear inside the From 6b38745a2761e2d300c4cc62b7595b3d2be71326 Mon Sep 17 00:00:00 2001 From: Ankit Chandawala Date: Mon, 3 Aug 2020 05:03:48 +0100 Subject: [PATCH 097/486] bpo-41425: Make tkinter doc example runnable (GH-21706) Co-authored-by: Ankit Chandawala Co-authored-by: Terry Jan Reedy --- Doc/library/tkinter.rst | 30 +++++++++++-------- .../2020-08-03-01-59-48.bpo-41425.KJo6zF.rst | 1 + 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 3d90b4be17c979e..9f954255c8b300f 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -541,31 +541,35 @@ the variable, with no further intervention on your part. For example:: - class App(Frame): - def __init__(self, master=None): + import tkinter as tk + + class App(tk.Frame): + def __init__(self, master): super().__init__(master) self.pack() - self.entrythingy = Entry() + self.entrythingy = tk.Entry() self.entrythingy.pack() - # here is the application variable - self.contents = StringVar() - # set it to some value + # Create the application variable. + self.contents = tk.StringVar() + # Set it to some value. self.contents.set("this is a variable") - # tell the entry widget to watch this variable + # Tell the entry widget to watch this variable. self.entrythingy["textvariable"] = self.contents - # and here we get a callback when the user hits return. - # we will have the program print out the value of the - # application variable when the user hits return + # Define a callback for when the user hits return. + # It prints the current value of the variable. self.entrythingy.bind('', - self.print_contents) + self.print_contents) def print_contents(self, event): - print("hi. contents of entry is now ---->", + print("Hi. The current entry content is:", self.contents.get()) + root = tk.Tk() + myapp = App(root) + myapp.mainloop() The Window Manager ^^^^^^^^^^^^^^^^^^ @@ -860,4 +864,4 @@ use raw reads or ``os.read(file.fileno(), maxbytecount)``. WRITABLE EXCEPTION - Constants used in the *mask* arguments. \ No newline at end of file + Constants used in the *mask* arguments. diff --git a/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst b/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst new file mode 100644 index 000000000000000..617df72faeb37f1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst @@ -0,0 +1 @@ +Make tkinter doc example runnable. From db89dd80ab2959f2d7ef4dd3dc8a84c830ff1232 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 3 Aug 2020 09:04:13 -0700 Subject: [PATCH 098/486] A (very) slight speed improvement for iterating over bytes (#21705) My mentee @xvxvxvxvxv noticed that iterating over array.array is slightly faster than iterating over bytes. Looking at the source I observed that arrayiter_next() calls `getitem(ao, it->index++)` wheras striter_next() uses the idiom (paraphrased) item = PyLong_FromLong(seq->ob_sval[it->it_index]); if (item != NULL) ++it->it_next; return item; I'm not 100% sure but I think that the second version has fewer opportunity for the CPU to overlap the `index++` operation with the rest of the code (which in both cases involves a call). So here I am optimistically incrementing the index -- if the PyLong_FromLong() call fails, this will leave the iterator pointing at the next byte, but honestly I doubt that anyone would seriously consider resuming use of the iterator after that kind of failure (it would have to be a MemoryError). And the author of arrayiter_next() made the same consideration (or never ever gave it a thought :-). With this, a loop like for _ in b: pass is now slightly *faster* than the same thing over an equivalent array, rather than slightly *slower* (in both cases a few percent). --- Objects/bytesobject.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 3a922d32b16e4ad..836a736037ba438 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3139,7 +3139,6 @@ static PyObject * striter_next(striterobject *it) { PyBytesObject *seq; - PyObject *item; assert(it != NULL); seq = it->it_seq; @@ -3148,11 +3147,8 @@ striter_next(striterobject *it) assert(PyBytes_Check(seq)); if (it->it_index < PyBytes_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)seq->ob_sval[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; + return PyLong_FromLong( + (unsigned char)seq->ob_sval[it->it_index++]); } it->it_seq = NULL; From 841d11e34d82bf83dc3472470ffc0f3a3e19db9d Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 4 Aug 2020 00:41:24 +0800 Subject: [PATCH 099/486] bpo-40275: Use new test.support helper submodules in tests (GH-21449) --- Lib/test/test__opcode.py | 2 +- Lib/test/test_asyncore.py | 26 +++---- Lib/test/test_binascii.py | 15 ++-- Lib/test/test_bisect.py | 7 +- Lib/test/test_builtin.py | 6 +- Lib/test/test_concurrent_futures.py | 3 +- Lib/test/test_configparser.py | 7 +- Lib/test/test_coroutines.py | 13 ++-- Lib/test/test_curses.py | 3 +- Lib/test/test_datetime.py | 4 +- Lib/test/test_mmap.py | 5 +- Lib/test/test_signal.py | 3 +- Lib/test/test_ssl.py | 53 +++++++------- Lib/test/test_tarfile.py | 107 ++++++++++++++-------------- Lib/test/test_threading.py | 3 +- Lib/test/test_trace.py | 3 +- Lib/test/test_tracemalloc.py | 13 ++-- Lib/test/test_xml_etree_c.py | 2 +- Lib/unittest/test/test_discovery.py | 5 +- Lib/unittest/test/test_result.py | 6 +- 20 files changed, 154 insertions(+), 132 deletions(-) diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 0fb39eed6064251..3bb64a798b3e386 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -1,5 +1,5 @@ import dis -from test.support import import_module +from test.support.import_helper import import_module import unittest _opcode = import_module("_opcode") diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 2cee6fb2e996a98..06c6bc2e99dc02a 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -10,8 +10,10 @@ import threading from test import support +from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +from test.support import warnings_helper from io import BytesIO if support.PGO: @@ -92,7 +94,7 @@ def bind_af_aware(sock, addr): """Helper function to bind a socket according to its family.""" if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: # Make sure the path doesn't exist. - support.unlink(addr) + os_helper.unlink(addr) socket_helper.bind_unix_socket(sock, addr) else: sock.bind(addr) @@ -369,14 +371,14 @@ def test_send(self): class FileWrapperTest(unittest.TestCase): def setUp(self): self.d = b"It's not dead, it's sleeping!" - with open(support.TESTFN, 'wb') as file: + with open(os_helper.TESTFN, 'wb') as file: file.write(self.d) def tearDown(self): - support.unlink(support.TESTFN) + os_helper.unlink(os_helper.TESTFN) def test_recv(self): - fd = os.open(support.TESTFN, os.O_RDONLY) + fd = os.open(os_helper.TESTFN, os.O_RDONLY) w = asyncore.file_wrapper(fd) os.close(fd) @@ -390,20 +392,20 @@ def test_recv(self): def test_send(self): d1 = b"Come again?" d2 = b"I want to buy some cheese." - fd = os.open(support.TESTFN, os.O_WRONLY | os.O_APPEND) + fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_APPEND) w = asyncore.file_wrapper(fd) os.close(fd) w.write(d1) w.send(d2) w.close() - with open(support.TESTFN, 'rb') as file: + with open(os_helper.TESTFN, 'rb') as file: self.assertEqual(file.read(), self.d + d1 + d2) @unittest.skipUnless(hasattr(asyncore, 'file_dispatcher'), 'asyncore.file_dispatcher required') def test_dispatcher(self): - fd = os.open(support.TESTFN, os.O_RDONLY) + fd = os.open(os_helper.TESTFN, os.O_RDONLY) data = [] class FileDispatcher(asyncore.file_dispatcher): def handle_read(self): @@ -415,16 +417,16 @@ def handle_read(self): def test_resource_warning(self): # Issue #11453 - fd = os.open(support.TESTFN, os.O_RDONLY) + fd = os.open(os_helper.TESTFN, os.O_RDONLY) f = asyncore.file_wrapper(fd) os.close(fd) - with support.check_warnings(('', ResourceWarning)): + with warnings_helper.check_warnings(('', ResourceWarning)): f = None support.gc_collect() def test_close_twice(self): - fd = os.open(support.TESTFN, os.O_RDONLY) + fd = os.open(os_helper.TESTFN, os.O_RDONLY) f = asyncore.file_wrapper(fd) os.close(fd) @@ -804,10 +806,10 @@ class TestAPI_UseIPv6Sockets(BaseTestAPI): class TestAPI_UseUnixSockets(BaseTestAPI): if HAS_UNIX_SOCKETS: family = socket.AF_UNIX - addr = support.TESTFN + addr = os_helper.TESTFN def tearDown(self): - support.unlink(self.addr) + os_helper.unlink(self.addr) BaseTestAPI.tearDown(self) class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets, unittest.TestCase): diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 45327953a7701ad..4d1bf2cce1f1e32 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -4,7 +4,8 @@ import binascii import array import re -from test import support +from test.support import warnings_helper + # Note: "*_hex" functions are aliases for "(un)hexlify" b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_hqx', 'b2a_qp', 'b2a_uu', @@ -37,7 +38,7 @@ def test_functions(self): self.assertTrue(hasattr(getattr(binascii, name), '__call__')) self.assertRaises(TypeError, getattr(binascii, name)) - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_returned_value(self): # Limit to the minimum of all limits (b2a_uu) MAX_ALL = 45 @@ -181,7 +182,7 @@ def test_uu(self): with self.assertRaises(TypeError): binascii.b2a_uu(b"", True) - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_crc_hqx(self): crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0) crc = binascii.crc_hqx(self.type2test(b" this string."), crc) @@ -201,7 +202,7 @@ def test_crc32(self): self.assertRaises(TypeError, binascii.crc32) - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_hqx(self): # Perform binhex4 style RLE-compression # Then calculate the hexbin4 binary-to-ASCII translation @@ -212,7 +213,7 @@ def test_hqx(self): res = binascii.rledecode_hqx(b) self.assertEqual(res, self.rawdata) - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_rle(self): # test repetition with a repetition longer than the limit of 255 data = (b'a' * 100 + b'b' + b'c' * 300) @@ -359,7 +360,7 @@ def test_qp(self): self.assertEqual(b2a_qp(type2test(b'a.\n')), b'a.\n') self.assertEqual(b2a_qp(type2test(b'.a')[:-1]), b'=2E') - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_empty_string(self): # A test for SF bug #1022953. Make sure SystemError is not raised. empty = self.type2test(b'') @@ -384,7 +385,7 @@ def test_unicode_b2a(self): # crc_hqx needs 2 arguments self.assertRaises(TypeError, binascii.crc_hqx, "test", 0) - @support.ignore_warnings(category=DeprecationWarning) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_unicode_a2b(self): # Unicode strings are accepted by a2b_* functions. MAX_ALL = 45 diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 580a963f627a34d..fc7990d765e53b0 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -1,10 +1,11 @@ import sys import unittest -from test import support +from test.support import import_helper from collections import UserList -py_bisect = support.import_fresh_module('bisect', blocked=['_bisect']) -c_bisect = support.import_fresh_module('bisect', fresh=['_bisect']) + +py_bisect = import_helper.import_fresh_module('bisect', blocked=['_bisect']) +c_bisect = import_helper.import_fresh_module('bisect', fresh=['_bisect']) class Range(object): """A trivial range()-like object that has an insert() method.""" diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 3bc1a3e246fdf84..edb4ec092e3586c 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -26,10 +26,10 @@ from types import AsyncGeneratorType, FunctionType from operator import neg from test import support -from test.support import ( - EnvironmentVarGuard, TESTFN, check_warnings, swap_attr, unlink, - maybe_get_event_loop_policy) +from test.support import (swap_attr, maybe_get_event_loop_policy) +from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink) from test.support.script_helper import assert_python_ok +from test.support.warnings_helper import check_warnings from unittest.mock import MagicMock, patch try: import pty, signal diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 7da967ea6ced576..a182b14fb9bc056 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -1,8 +1,9 @@ from test import support +from test.support import import_helper from test.support import threading_helper # Skip tests if _multiprocessing wasn't built. -support.import_module('_multiprocessing') +import_helper.import_module('_multiprocessing') # Skip tests if sem_open implementation is broken. support.skip_if_broken_multiprocessing_synchronize() diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index f16da116a745f3a..230ffc1ccf81a79 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -8,6 +8,7 @@ import warnings from test import support +from test.support import os_helper class SortedDict(collections.UserDict): @@ -1063,17 +1064,17 @@ def setUp(self): cf.add_section(s) for j in range(10): cf.set(s, 'lovely_spam{}'.format(j), self.wonderful_spam) - with open(support.TESTFN, 'w') as f: + with open(os_helper.TESTFN, 'w') as f: cf.write(f) def tearDown(self): - os.unlink(support.TESTFN) + os.unlink(os_helper.TESTFN) def test_dominating_multiline_values(self): # We're reading from file because this is where the code changed # during performance updates in Python 3.2 cf_from_file = self.newconfig() - with open(support.TESTFN) as f: + with open(os_helper.TESTFN) as f: cf_from_file.read_file(f) self.assertEqual(cf_from_file.get('section8', 'lovely_spam4'), self.wonderful_spam.replace('\t\n', '\n')) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 8d1e0692a24221b..145adb677817011 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -7,6 +7,8 @@ import unittest import warnings from test import support +from test.support import import_helper +from test.support import warnings_helper from test.support.script_helper import assert_python_ok @@ -2117,7 +2119,7 @@ class CoroAsyncIOCompatTest(unittest.TestCase): def test_asyncio_1(self): # asyncio cannot be imported when Python is compiled without thread # support - asyncio = support.import_module('asyncio') + asyncio = import_helper.import_module('asyncio') class MyException(Exception): pass @@ -2258,8 +2260,9 @@ async def corofn(): try: warnings._warn_unawaited_coroutine = lambda coro: 1/0 with support.catch_unraisable_exception() as cm, \ - support.check_warnings((r'coroutine .* was never awaited', - RuntimeWarning)): + warnings_helper.check_warnings( + (r'coroutine .* was never awaited', + RuntimeWarning)): # only store repr() to avoid keeping the coroutine alive coro = corofn() coro_repr = repr(coro) @@ -2272,8 +2275,8 @@ async def corofn(): self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) del warnings._warn_unawaited_coroutine - with support.check_warnings((r'coroutine .* was never awaited', - RuntimeWarning)): + with warnings_helper.check_warnings( + (r'coroutine .* was never awaited', RuntimeWarning)): corofn() support.gc_collect() diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 5e619d13836d260..2c6d14c3f79ddac 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -15,7 +15,8 @@ import tempfile import unittest -from test.support import requires, import_module, verbose, SaveSignals +from test.support import requires, verbose, SaveSignals +from test.support.import_helper import import_module # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index d659f369d54e46f..bdb9f02e5756a27 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1,7 +1,9 @@ import unittest import sys -from test.support import import_fresh_module, run_unittest +from test.support import run_unittest +from test.support.import_helper import import_fresh_module + TESTS = 'test.datetimetester' diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 5400f25f50800b6..8f34c182f82eaff 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,5 +1,6 @@ -from test.support import (TESTFN, import_module, unlink, - requires, _2G, _4G, gc_collect, cpython_only) +from test.support import (requires, _2G, _4G, gc_collect, cpython_only) +from test.support.import_helper import import_module +from test.support.os_helper import TESTFN, unlink import unittest import os import re diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 45553a6a42de792..c6567906321fe17 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -9,6 +9,7 @@ import time import unittest from test import support +from test.support import os_helper from test.support.script_helper import assert_python_ok, spawn_python try: import _testcapi @@ -154,7 +155,7 @@ def test_invalid_call(self): signal.set_wakeup_fd(signal.SIGINT, False) def test_invalid_fd(self): - fd = support.make_bad_fd() + fd = os_helper.make_bad_fd() self.assertRaises((ValueError, OSError), signal.set_wakeup_fd, fd) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index de778d34658b7a0..26eec969a82e0d7 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4,8 +4,11 @@ import unittest import unittest.mock from test import support +from test.support import import_helper +from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +from test.support import warnings_helper import socket import select import time @@ -27,7 +30,7 @@ except ImportError: ctypes = None -ssl = support.import_module("ssl") +ssl = import_helper.import_module("ssl") from ssl import TLSVersion, _TLSContentType, _TLSMessageType @@ -571,7 +574,7 @@ def test_refcycle(self): s = socket.socket(socket.AF_INET) ss = test_wrap_socket(s) wr = weakref.ref(ss) - with support.check_warnings(("", ResourceWarning)): + with warnings_helper.check_warnings(("", ResourceWarning)): del ss self.assertEqual(wr(), None) @@ -893,7 +896,7 @@ def test_get_default_verify_paths(self): self.assertEqual(len(paths), 6) self.assertIsInstance(paths, ssl.DefaultVerifyPaths) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["SSL_CERT_DIR"] = CAPATH env["SSL_CERT_FILE"] = CERTFILE paths = ssl.get_default_verify_paths() @@ -1605,7 +1608,7 @@ def test_load_default_certs(self): @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars") def test_load_default_certs_env(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["SSL_CERT_DIR"] = CAPATH env["SSL_CERT_FILE"] = CERTFILE ctx.load_default_certs() @@ -1619,7 +1622,7 @@ def test_load_default_certs_env_windows(self): stats = ctx.cert_store_stats() ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["SSL_CERT_DIR"] = CAPATH env["SSL_CERT_FILE"] = CERTFILE ctx.load_default_certs() @@ -4266,9 +4269,9 @@ def test_read_write_after_close_raises_valuerror(self): def test_sendfile(self): TEST_DATA = b"x" * 512 - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: f.write(TEST_DATA) - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) context = ssl.SSLContext(ssl.PROTOCOL_TLS) context.verify_mode = ssl.CERT_REQUIRED context.load_verify_locations(SIGNING_CA) @@ -4277,7 +4280,7 @@ def test_sendfile(self): with server: with context.wrap_socket(socket.socket()) as s: s.connect((HOST, server.port)) - with open(support.TESTFN, 'rb') as file: + with open(os_helper.TESTFN, 'rb') as file: s.sendfile(file) self.assertEqual(s.recv(1024), TEST_DATA) @@ -4603,21 +4606,21 @@ def test_bpo37428_pha_cert_none(self): class TestSSLDebug(unittest.TestCase): - def keylog_lines(self, fname=support.TESTFN): + def keylog_lines(self, fname=os_helper.TESTFN): with open(fname) as f: return len(list(f)) @requires_keylog @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_keylog_defaults(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ctx.keylog_filename, None) - self.assertFalse(os.path.isfile(support.TESTFN)) - ctx.keylog_filename = support.TESTFN - self.assertEqual(ctx.keylog_filename, support.TESTFN) - self.assertTrue(os.path.isfile(support.TESTFN)) + self.assertFalse(os.path.isfile(os_helper.TESTFN)) + ctx.keylog_filename = os_helper.TESTFN + self.assertEqual(ctx.keylog_filename, os_helper.TESTFN) + self.assertTrue(os.path.isfile(os_helper.TESTFN)) self.assertEqual(self.keylog_lines(), 1) ctx.keylog_filename = None @@ -4626,7 +4629,7 @@ def test_keylog_defaults(self): with self.assertRaises((IsADirectoryError, PermissionError)): # Windows raises PermissionError ctx.keylog_filename = os.path.dirname( - os.path.abspath(support.TESTFN)) + os.path.abspath(os_helper.TESTFN)) with self.assertRaises(TypeError): ctx.keylog_filename = 1 @@ -4634,10 +4637,10 @@ def test_keylog_defaults(self): @requires_keylog @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_keylog_filename(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) client_context, server_context, hostname = testing_context() - client_context.keylog_filename = support.TESTFN + client_context.keylog_filename = os_helper.TESTFN server = ThreadedEchoServer(context=server_context, chatty=False) with server: with client_context.wrap_socket(socket.socket(), @@ -4647,7 +4650,7 @@ def test_keylog_filename(self): self.assertEqual(self.keylog_lines(), 6) client_context.keylog_filename = None - server_context.keylog_filename = support.TESTFN + server_context.keylog_filename = os_helper.TESTFN server = ThreadedEchoServer(context=server_context, chatty=False) with server: with client_context.wrap_socket(socket.socket(), @@ -4655,8 +4658,8 @@ def test_keylog_filename(self): s.connect((HOST, server.port)) self.assertGreaterEqual(self.keylog_lines(), 11) - client_context.keylog_filename = support.TESTFN - server_context.keylog_filename = support.TESTFN + client_context.keylog_filename = os_helper.TESTFN + server_context.keylog_filename = os_helper.TESTFN server = ThreadedEchoServer(context=server_context, chatty=False) with server: with client_context.wrap_socket(socket.socket(), @@ -4672,19 +4675,19 @@ def test_keylog_filename(self): "test is not compatible with ignore_environment") @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_keylog_env(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) with unittest.mock.patch.dict(os.environ): - os.environ['SSLKEYLOGFILE'] = support.TESTFN - self.assertEqual(os.environ['SSLKEYLOGFILE'], support.TESTFN) + os.environ['SSLKEYLOGFILE'] = os_helper.TESTFN + self.assertEqual(os.environ['SSLKEYLOGFILE'], os_helper.TESTFN) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ctx.keylog_filename, None) ctx = ssl.create_default_context() - self.assertEqual(ctx.keylog_filename, support.TESTFN) + self.assertEqual(ctx.keylog_filename, os_helper.TESTFN) ctx = ssl._create_stdlib_context() - self.assertEqual(ctx.keylog_filename, support.TESTFN) + self.assertEqual(ctx.keylog_filename, os_helper.TESTFN) def test_msg_callback(self): client_context, server_context, hostname = testing_context() diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 3ddeb97f5268fe8..4bf7248767c4b90 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -11,6 +11,7 @@ import tarfile from test import support +from test.support import os_helper from test.support import script_helper # Check for our compression modules. @@ -30,7 +31,7 @@ def sha256sum(data): return sha256(data).hexdigest() -TEMPDIR = os.path.abspath(support.TESTFN) + "-tardir" +TEMPDIR = os.path.abspath(os_helper.TESTFN) + "-tardir" tarextdir = TEMPDIR + '-extract-test' tarname = support.findfile("testtar.tar") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") @@ -575,21 +576,21 @@ def test_find_members(self): @unittest.skipUnless(hasattr(os, "link"), "Missing hardlink implementation") - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: tar.extract("ustar/regtype", TEMPDIR) - self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/regtype")) + self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/regtype")) tar.extract("ustar/lnktype", TEMPDIR) - self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/lnktype")) + self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/lnktype")) with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f: data = f.read() self.assertEqual(sha256sum(data), sha256_regtype) tar.extract("ustar/symtype", TEMPDIR) - self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/symtype")) + self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() self.assertEqual(sha256sum(data), sha256_regtype) @@ -622,7 +623,7 @@ def format_mtime(mtime): self.assertEqual(tarinfo.mtime, file_mtime, errmsg) finally: tar.close() - support.rmtree(DIR) + os_helper.rmtree(DIR) def test_extract_directory(self): dirtype = "ustar/dirtype" @@ -637,11 +638,11 @@ def test_extract_directory(self): if sys.platform != "win32": self.assertEqual(os.stat(extracted).st_mode & 0o777, 0o755) finally: - support.rmtree(DIR) + os_helper.rmtree(DIR) def test_extractall_pathlike_name(self): DIR = pathlib.Path(TEMPDIR) / "extractall" - with support.temp_dir(DIR), \ + with os_helper.temp_dir(DIR), \ tarfile.open(tarname, encoding="iso8859-1") as tar: directories = [t for t in tar if t.isdir()] tar.extractall(DIR, directories) @@ -652,7 +653,7 @@ def test_extractall_pathlike_name(self): def test_extract_pathlike_name(self): dirtype = "ustar/dirtype" DIR = pathlib.Path(TEMPDIR) / "extractall" - with support.temp_dir(DIR), \ + with os_helper.temp_dir(DIR), \ tarfile.open(tarname, encoding="iso8859-1") as tar: tarinfo = tar.getmember(dirtype) tar.extract(tarinfo, path=DIR) @@ -676,7 +677,7 @@ def test_init_close_fobj(self): else: self.fail("ReadError not raised") finally: - support.unlink(empty) + os_helper.unlink(empty) def test_parallel_iteration(self): # Issue #16601: Restarting iteration over tarfile continued @@ -1026,7 +1027,7 @@ def _fs_supports_holes(): fobj.write(b'x' * 4096) fobj.truncate() s = os.stat(name) - support.unlink(name) + os_helper.unlink(name) return (s.st_blocks * 512 < s.st_size) else: return False @@ -1171,7 +1172,7 @@ def test_directory_size(self): finally: tar.close() finally: - support.rmdir(path) + os_helper.rmdir(path) # mock the following: # os.listdir: so we know that files are in the wrong order @@ -1193,9 +1194,9 @@ def test_ordered_recursion(self): finally: tar.close() finally: - support.unlink(os.path.join(path, "1")) - support.unlink(os.path.join(path, "2")) - support.rmdir(path) + os_helper.unlink(os.path.join(path, "1")) + os_helper.unlink(os.path.join(path, "2")) + os_helper.rmdir(path) def test_gettarinfo_pathlike_name(self): with tarfile.open(tmpname, self.mode) as tar: @@ -1229,10 +1230,10 @@ def test_link_size(self): finally: tar.close() finally: - support.unlink(target) - support.unlink(link) + os_helper.unlink(target) + os_helper.unlink(link) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_symlink_size(self): path = os.path.join(TEMPDIR, "symlink") os.symlink("link_target", path) @@ -1244,7 +1245,7 @@ def test_symlink_size(self): finally: tar.close() finally: - support.unlink(path) + os_helper.unlink(path) def test_add_self(self): # Test for #1257255. @@ -1257,7 +1258,7 @@ def test_add_self(self): self.assertEqual(tar.getnames(), [], "added the archive to itself") - with support.change_cwd(TEMPDIR): + with os_helper.change_cwd(TEMPDIR): tar.add(dstname) self.assertEqual(tar.getnames(), [], "added the archive to itself") @@ -1270,7 +1271,7 @@ def test_filter(self): try: for name in ("foo", "bar", "baz"): name = os.path.join(tempdir, name) - support.create_empty_file(name) + os_helper.create_empty_file(name) def filter(tarinfo): if os.path.basename(tarinfo.name) == "bar": @@ -1298,7 +1299,7 @@ def filter(tarinfo): finally: tar.close() finally: - support.rmtree(tempdir) + os_helper.rmtree(tempdir) # Guarantee that stored pathnames are not modified. Don't # remove ./ or ../ or double slashes. Still make absolute @@ -1309,7 +1310,7 @@ def _test_pathname(self, path, cmp_path=None, dir=False): # and compare the stored name with the original. foo = os.path.join(TEMPDIR, "foo") if not dir: - support.create_empty_file(foo) + os_helper.create_empty_file(foo) else: os.mkdir(foo) @@ -1326,14 +1327,14 @@ def _test_pathname(self, path, cmp_path=None, dir=False): tar.close() if not dir: - support.unlink(foo) + os_helper.unlink(foo) else: - support.rmdir(foo) + os_helper.rmdir(foo) self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/")) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_extractall_symlinks(self): # Test if extractall works properly when tarfile contains symlinks tempdir = os.path.join(TEMPDIR, "testsymlinks") @@ -1356,8 +1357,8 @@ def test_extractall_symlinks(self): except OSError: self.fail("extractall failed with symlinked files") finally: - support.unlink(temparchive) - support.rmtree(tempdir) + os_helper.unlink(temparchive) + os_helper.rmtree(tempdir) def test_pathnames(self): self._test_pathname("foo") @@ -1385,7 +1386,7 @@ def test_abs_pathnames(self): def test_cwd(self): # Test adding the current working directory. - with support.change_cwd(TEMPDIR): + with os_helper.change_cwd(TEMPDIR): tar = tarfile.open(tmpname, self.mode) try: tar.add(".") @@ -1453,7 +1454,7 @@ def test_file_mode(self): # Test for issue #8464: Create files with correct # permissions. if os.path.exists(tmpname): - support.unlink(tmpname) + os_helper.unlink(tmpname) original_umask = os.umask(0o022) try: @@ -1599,7 +1600,7 @@ def test_headers_written_only_for_device_files(self): self.assertEqual(buf_blk[device_headers], b"0000000\0" * 2) self.assertEqual(buf_reg[device_headers], b"\0" * 16) finally: - support.rmtree(tempdir) + os_helper.rmtree(tempdir) class CreateTest(WriteTestBase, unittest.TestCase): @@ -1609,7 +1610,7 @@ class CreateTest(WriteTestBase, unittest.TestCase): file_path = os.path.join(TEMPDIR, "spameggs42") def setUp(self): - support.unlink(tmpname) + os_helper.unlink(tmpname) @classmethod def setUpClass(cls): @@ -1618,7 +1619,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - support.unlink(cls.file_path) + os_helper.unlink(cls.file_path) def test_create(self): with tarfile.open(tmpname, self.mode) as tobj: @@ -1733,8 +1734,8 @@ def setUp(self): def tearDown(self): self.tar.close() - support.unlink(self.foo) - support.unlink(self.bar) + os_helper.unlink(self.foo) + os_helper.unlink(self.bar) def test_add_twice(self): # The same name will be added as a REGTYPE every @@ -2043,7 +2044,7 @@ class AppendTestBase: def setUp(self): self.tarname = tmpname if os.path.exists(self.tarname): - support.unlink(self.tarname) + os_helper.unlink(self.tarname) def _create_testtar(self, mode="w:"): with tarfile.open(tarname, encoding="iso8859-1") as src: @@ -2288,7 +2289,7 @@ def make_simple_tarfile(self, tar_name): files = [support.findfile('tokenize_tests.txt'), support.findfile('tokenize_tests-no-coding-cookie-' 'and-utf8-bom-sig-only.txt')] - self.addCleanup(support.unlink, tar_name) + self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: for tardata in files: tf.add(tardata, arcname=os.path.basename(tardata)) @@ -2334,7 +2335,7 @@ def test_test_command_invalid_file(self): self.assertEqual(out, b'') self.assertEqual(rc, 1) finally: - support.unlink(tmpname) + os_helper.unlink(tmpname) def test_list_command(self): for tar_name in testtarnames: @@ -2376,7 +2377,7 @@ def test_create_command(self): with tarfile.open(tmpname) as tar: tar.getmembers() finally: - support.unlink(tmpname) + os_helper.unlink(tmpname) def test_create_command_verbose(self): files = [support.findfile('tokenize_tests.txt'), @@ -2390,7 +2391,7 @@ def test_create_command_verbose(self): with tarfile.open(tmpname) as tar: tar.getmembers() finally: - support.unlink(tmpname) + os_helper.unlink(tmpname) def test_create_command_dotless_filename(self): files = [support.findfile('tokenize_tests.txt')] @@ -2400,7 +2401,7 @@ def test_create_command_dotless_filename(self): with tarfile.open(dotlessname) as tar: tar.getmembers() finally: - support.unlink(dotlessname) + os_helper.unlink(dotlessname) def test_create_command_dot_started_filename(self): tar_name = os.path.join(TEMPDIR, ".testtar") @@ -2411,7 +2412,7 @@ def test_create_command_dot_started_filename(self): with tarfile.open(tar_name) as tar: tar.getmembers() finally: - support.unlink(tar_name) + os_helper.unlink(tar_name) def test_create_command_compressed(self): files = [support.findfile('tokenize_tests.txt'), @@ -2426,41 +2427,41 @@ def test_create_command_compressed(self): with filetype.taropen(tar_name) as tar: tar.getmembers() finally: - support.unlink(tar_name) + os_helper.unlink(tar_name) def test_extract_command(self): self.make_simple_tarfile(tmpname) for opt in '-e', '--extract': try: - with support.temp_cwd(tarextdir): + with os_helper.temp_cwd(tarextdir): out = self.tarfilecmd(opt, tmpname) self.assertEqual(out, b'') finally: - support.rmtree(tarextdir) + os_helper.rmtree(tarextdir) def test_extract_command_verbose(self): self.make_simple_tarfile(tmpname) for opt in '-v', '--verbose': try: - with support.temp_cwd(tarextdir): + with os_helper.temp_cwd(tarextdir): out = self.tarfilecmd(opt, '-e', tmpname, PYTHONIOENCODING='utf-8') self.assertIn(b' file is extracted.', out) finally: - support.rmtree(tarextdir) + os_helper.rmtree(tarextdir) def test_extract_command_different_directory(self): self.make_simple_tarfile(tmpname) try: - with support.temp_cwd(tarextdir): + with os_helper.temp_cwd(tarextdir): out = self.tarfilecmd('-e', tmpname, 'spamdir') self.assertEqual(out, b'') finally: - support.rmtree(tarextdir) + os_helper.rmtree(tarextdir) def test_extract_command_invalid_file(self): zipname = support.findfile('zipdir.zip') - with support.temp_cwd(tarextdir): + with os_helper.temp_cwd(tarextdir): rc, out, err = self.tarfilecmd_failure('-e', zipname) self.assertIn(b' is not a tar archive.', err) self.assertEqual(out, b'') @@ -2723,7 +2724,7 @@ def test_keyword_only(self, mock_geteuid): def setUpModule(): - support.unlink(TEMPDIR) + os_helper.unlink(TEMPDIR) os.makedirs(TEMPDIR) global testtarnames @@ -2734,14 +2735,14 @@ def setUpModule(): # Create compressed tarfiles. for c in GzipTest, Bz2Test, LzmaTest: if c.open: - support.unlink(c.tarname) + os_helper.unlink(c.tarname) testtarnames.append(c.tarname) with c.open(c.tarname, "wb") as tar: tar.write(data) def tearDownModule(): if os.path.exists(TEMPDIR): - support.rmtree(TEMPDIR) + os_helper.rmtree(TEMPDIR) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index ad82e304e32f3db..47e131ae27a148f 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -4,7 +4,8 @@ import test.support from test.support import threading_helper -from test.support import verbose, import_module, cpython_only +from test.support import verbose, cpython_only +from test.support.import_helper import import_module from test.support.script_helper import assert_python_ok, assert_python_failure import random diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index c03982ba72b3f1f..75478557e787196 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -1,6 +1,7 @@ import os import sys -from test.support import TESTFN, TESTFN_UNICODE, FS_NONASCII, rmtree, unlink, captured_stdout +from test.support import captured_stdout +from test.support.os_helper import (TESTFN, rmtree, unlink) from test.support.script_helper import assert_python_ok, assert_python_failure import textwrap import unittest diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index c5ae4e6d653bf74..a0037f81b88f277 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -7,6 +7,7 @@ from test.support.script_helper import (assert_python_ok, assert_python_failure, interpreter_requires_environment) from test import support +from test.support import os_helper try: import _testcapi @@ -287,11 +288,11 @@ def test_snapshot(self): self.assertGreater(snapshot.traces[1].traceback.total_nframe, 10) # write on disk - snapshot.dump(support.TESTFN) - self.addCleanup(support.unlink, support.TESTFN) + snapshot.dump(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) # load from disk - snapshot2 = tracemalloc.Snapshot.load(support.TESTFN) + snapshot2 = tracemalloc.Snapshot.load(os_helper.TESTFN) self.assertEqual(snapshot2.traces, snapshot.traces) # tracemalloc must be tracing memory allocations to take a snapshot @@ -306,11 +307,11 @@ def test_snapshot_save_attr(self): # take a snapshot with a new attribute snapshot = tracemalloc.take_snapshot() snapshot.test_attr = "new" - snapshot.dump(support.TESTFN) - self.addCleanup(support.unlink, support.TESTFN) + snapshot.dump(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) # load() should recreate the attribute - snapshot2 = tracemalloc.Snapshot.load(support.TESTFN) + snapshot2 = tracemalloc.Snapshot.load(os_helper.TESTFN) self.assertEqual(snapshot2.test_attr, "new") def fork_child(self): diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index e26e1714a540bdb..e68613bb910dd41 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -2,7 +2,7 @@ import io import struct from test import support -from test.support import import_fresh_module +from test.support.import_helper import import_fresh_module import types import unittest diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 16e081e1fb76ec1..9d502c51fb36ab9 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -5,6 +5,7 @@ import types import pickle from test import support +from test.support import import_helper import test.test_importlib.util import unittest @@ -848,7 +849,7 @@ def _find_tests(start_dir, pattern, namespace=None): with unittest.mock.patch('builtins.__import__', _import): # Since loader.discover() can modify sys.path, restore it when done. - with support.DirsOnSysPath(): + with import_helper.DirsOnSysPath(): # Make sure to remove 'package' from sys.modules when done. with test.test_importlib.util.uncache('package'): suite = loader.discover('package') @@ -865,7 +866,7 @@ def _import(packagename, *args, **kwargs): with unittest.mock.patch('builtins.__import__', _import): # Since loader.discover() can modify sys.path, restore it when done. - with support.DirsOnSysPath(): + with import_helper.DirsOnSysPath(): # Make sure to remove 'package' from sys.modules when done. with test.test_importlib.util.uncache('package'): with self.assertRaises(TypeError) as cm: diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py index 0ffb87b40256cff..a4af67bd8d56de2 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/unittest/test/test_result.py @@ -2,7 +2,7 @@ import sys import textwrap -from test import support +from test.support import warnings_helper import traceback import unittest @@ -458,8 +458,8 @@ def __init__(self, stream=None, descriptions=None, verbosity=None): class Test_OldTestResult(unittest.TestCase): def assertOldResultWarning(self, test, failures): - with support.check_warnings(("TestResult has no add.+ method,", - RuntimeWarning)): + with warnings_helper.check_warnings( + ("TestResult has no add.+ method,", RuntimeWarning)): result = OldResult() test.run(result) self.assertEqual(len(result.failures), failures) From 2a72b6cbc45d2a4df5f887bd8de2ecf8d9baa839 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 4 Aug 2020 00:47:42 +0800 Subject: [PATCH 100/486] bpo-40275: Use new test.support helper submodules in tests (GH-21451) --- Lib/test/test_bdb.py | 7 +- Lib/test/test_code_module.py | 5 +- Lib/test/test_embed.py | 10 +- Lib/test/test_gzip.py | 24 +- Lib/test/test_largefile.py | 3 +- Lib/test/test_lltrace.py | 8 +- Lib/test/test_ordered_dict.py | 7 +- Lib/test/test_pathlib.py | 72 ++--- Lib/test/test_pipes.py | 4 +- Lib/test/test_posix.py | 358 +++++++++++++----------- Lib/test/test_pydoc.py | 15 +- Lib/test/test_resource.py | 8 +- Lib/test/test_runpy.py | 6 +- Lib/test/test_sax.py | 30 +- Lib/test/test_sys.py | 7 +- Lib/test/test_syslog.py | 5 +- Lib/test/test_ttk_textonly.py | 4 +- Lib/test/test_unicode_file_functions.py | 20 +- Lib/test/test_urllib2.py | 6 +- Lib/test/test_venv.py | 3 +- 20 files changed, 324 insertions(+), 278 deletions(-) diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index ae1688056788294..9bce780e0d041cf 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -58,6 +58,9 @@ from contextlib import contextmanager from itertools import islice, repeat import test.support +from test.support import import_helper +from test.support import os_helper + class BdbException(Exception): pass class BdbError(BdbException): """Error raised by the Bdb instance.""" @@ -531,7 +534,7 @@ def gen(a, b): @contextmanager def create_modules(modules): - with test.support.temp_cwd(): + with os_helper.temp_cwd(): sys.path.append(os.getcwd()) try: for m in modules: @@ -543,7 +546,7 @@ def create_modules(modules): yield finally: for m in modules: - test.support.forget(m) + import_helper.forget(m) sys.path.pop() def break_in_func(funcname, fname=__file__, temporary=False, cond=None): diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 24db0ace80122e7..226bc3a853b7b94 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -4,9 +4,10 @@ from textwrap import dedent from contextlib import ExitStack from unittest import mock -from test import support +from test.support import import_helper -code = support.import_module('code') + +code = import_helper.import_module('code') class TestInteractiveConsole(unittest.TestCase): diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 2b740521e723cac..31dc39fd9e8efe1 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1,5 +1,7 @@ # Run the tests in Programs/_testembed.c (tests for the CPython embedding APIs) from test import support +from test.support import import_helper +from test.support import os_helper import unittest from collections import namedtuple @@ -1339,8 +1341,8 @@ def test_global_pathconfig(self): # # The global path configuration (_Py_path_config) must be a copy # of the path configuration of PyInterpreter.config (PyConfig). - ctypes = support.import_module('ctypes') - _testinternalcapi = support.import_module('_testinternalcapi') + ctypes = import_helper.import_module('ctypes') + _testinternalcapi = import_helper.import_module('_testinternalcapi') def get_func(name): func = getattr(ctypes.pythonapi, name) @@ -1418,7 +1420,7 @@ def test_audit_run_file(self): returncode=1) def test_audit_run_interactivehook(self): - startup = os.path.join(self.oldcwd, support.TESTFN) + ".py" + startup = os.path.join(self.oldcwd, os_helper.TESTFN) + ".py" with open(startup, "w", encoding="utf-8") as f: print("import sys", file=f) print("sys.__interactivehook__ = lambda: None", file=f) @@ -1431,7 +1433,7 @@ def test_audit_run_interactivehook(self): os.unlink(startup) def test_audit_run_startup(self): - startup = os.path.join(self.oldcwd, support.TESTFN) + ".py" + startup = os.path.join(self.oldcwd, os_helper.TESTFN) + ".py" with open(startup, "w", encoding="utf-8") as f: print("pass", file=f) try: diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 0f235d1805e0d3a..c3fa9b097f8aaaf 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -11,10 +11,12 @@ import unittest from subprocess import PIPE, Popen from test import support +from test.support import import_helper +from test.support import os_helper from test.support import _4G, bigmemtest from test.support.script_helper import assert_python_ok, assert_python_failure -gzip = support.import_module('gzip') +gzip = import_helper.import_module('gzip') data1 = b""" int length=DEFAULTALLOC, err = Z_OK; PyObject *RetVal; @@ -29,7 +31,7 @@ """ -TEMPDIR = os.path.abspath(support.TESTFN) + '-gzdir' +TEMPDIR = os.path.abspath(os_helper.TESTFN) + '-gzdir' class UnseekableIO(io.BytesIO): @@ -44,13 +46,13 @@ def seek(self, *args): class BaseTest(unittest.TestCase): - filename = support.TESTFN + filename = os_helper.TESTFN def setUp(self): - support.unlink(self.filename) + os_helper.unlink(self.filename) def tearDown(self): - support.unlink(self.filename) + os_helper.unlink(self.filename) class TestGzip(BaseTest): @@ -286,7 +288,7 @@ def test_mode(self): self.test_write() with gzip.GzipFile(self.filename, 'r') as f: self.assertEqual(f.myfileobj.mode, 'rb') - support.unlink(self.filename) + os_helper.unlink(self.filename) with gzip.GzipFile(self.filename, 'x') as f: self.assertEqual(f.myfileobj.mode, 'xb') @@ -365,7 +367,7 @@ def test_metadata(self): self.assertEqual(isizeBytes, struct.pack(' Date: Tue, 4 Aug 2020 00:49:18 +0800 Subject: [PATCH 101/486] bpo-40275: Use new test.support helper submodules in tests (GH-21448) --- Lib/test/test_argparse.py | 5 +- Lib/test/test_asyncgen.py | 2 +- Lib/test/test_clinic.py | 3 +- Lib/test/test_codecs.py | 28 ++--- Lib/test/test_doctest.py | 16 +-- Lib/test/test_exceptions.py | 9 +- Lib/test/test_ftplib.py | 3 +- Lib/test/test_gc.py | 5 +- Lib/test/test_genericpath.py | 103 ++++++++++--------- Lib/test/test_imghdr.py | 4 +- Lib/test/test_mimetypes.py | 5 +- Lib/test/test_ntpath.py | 78 +++++++------- Lib/test/test_operator.py | 8 +- Lib/test/test_optparse.py | 29 +++--- Lib/test/test_peg_generator/test_c_parser.py | 3 +- Lib/test/test_queue.py | 7 +- Lib/test/test_spwd.py | 5 +- Lib/test/test_stat.py | 4 +- Lib/test/test_tokenize.py | 5 +- Lib/test/test_webbrowser.py | 17 +-- 20 files changed, 185 insertions(+), 154 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 22cae626ccc2973..e98c15b11afb318 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -13,6 +13,7 @@ from io import StringIO from test import support +from test.support import os_helper from unittest import mock class StdIOBuffer(StringIO): pass @@ -23,7 +24,7 @@ def setUp(self): # The tests assume that line wrapping occurs at 80 columns, but this # behaviour can be overridden by setting the COLUMNS environment # variable. To ensure that this width is used, set COLUMNS to 80. - env = support.EnvironmentVarGuard() + env = os_helper.EnvironmentVarGuard() env['COLUMNS'] = '80' self.addCleanup(env.__exit__) @@ -3244,7 +3245,7 @@ class TestShortColumns(HelpTestCase): but we don't want any exceptions thrown in such cases. Only ugly representation. ''' def setUp(self): - env = support.EnvironmentVarGuard() + env = os_helper.EnvironmentVarGuard() env.set("COLUMNS", '15') self.addCleanup(env.__exit__) diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 62bf8774166529a..1f7e05b42be99c2 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -2,7 +2,7 @@ import types import unittest -from test.support import import_module +from test.support.import_helper import import_module asyncio = import_module("asyncio") diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 3d5dc4759d5018f..80b9aec7c2f5bc8 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -3,6 +3,7 @@ # Licensed to the PSF under a contributor agreement. from test import support, test_tools +from test.support import os_helper from unittest import TestCase import collections import inspect @@ -797,7 +798,7 @@ def test_external(self): source = support.findfile('clinic.test') with open(source, 'r', encoding='utf-8') as f: original = f.read() - with support.temp_dir() as testdir: + with os_helper.temp_dir() as testdir: testfile = os.path.join(testdir, 'clinic.test.c') with open(testfile, 'w', encoding='utf-8') as f: f.write(original) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 54a3520802a4f31..f0da35c039e11e6 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -8,6 +8,8 @@ from unittest import mock from test import support +from test.support import os_helper +from test.support import warnings_helper try: import _testcapi @@ -709,11 +711,11 @@ def test_bug691291(self): s1 = 'Hello\r\nworld\r\n' s = s1.encode(self.encoding) - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, 'wb') as fp: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, 'wb') as fp: fp.write(s) - with support.check_warnings(('', DeprecationWarning)): - reader = codecs.open(support.TESTFN, 'U', encoding=self.encoding) + with warnings_helper.check_warnings(('', DeprecationWarning)): + reader = codecs.open(os_helper.TESTFN, 'U', encoding=self.encoding) with reader: self.assertEqual(reader.read(), s1) @@ -1697,10 +1699,10 @@ def test_all(self): getattr(codecs, api) def test_open(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) for mode in ('w', 'r', 'r+', 'w+', 'a', 'a+'): with self.subTest(mode), \ - codecs.open(support.TESTFN, mode, 'ascii') as file: + codecs.open(os_helper.TESTFN, mode, 'ascii') as file: self.assertIsInstance(file, codecs.StreamReaderWriter) def test_undefined(self): @@ -1718,7 +1720,7 @@ def test_file_closes_if_lookup_error_raised(self): mock_open = mock.mock_open() with mock.patch('builtins.open', mock_open) as file: with self.assertRaises(LookupError): - codecs.open(support.TESTFN, 'wt', 'invalid-encoding') + codecs.open(os_helper.TESTFN, 'wt', 'invalid-encoding') file().close.assert_called() @@ -2516,10 +2518,10 @@ def test_seek0(self): "utf-32", "utf-32-le", "utf-32-be") - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) for encoding in tests: # Check if the BOM is written only once - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f: f.write(data) f.write(data) f.seek(0) @@ -2528,7 +2530,7 @@ def test_seek0(self): self.assertEqual(f.read(), data * 2) # Check that the BOM is written after a seek(0) - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f: f.write(data[0]) self.assertNotEqual(f.tell(), 0) f.seek(0) @@ -2537,7 +2539,7 @@ def test_seek0(self): self.assertEqual(f.read(), data) # (StreamWriter) Check that the BOM is written after a seek(0) - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f: f.writer.write(data[0]) self.assertNotEqual(f.writer.tell(), 0) f.writer.seek(0) @@ -2547,7 +2549,7 @@ def test_seek0(self): # Check that the BOM is not written after a seek() at a position # different than the start - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f: f.write(data) f.seek(f.tell()) f.write(data) @@ -2556,7 +2558,7 @@ def test_seek0(self): # (StreamWriter) Check that the BOM is not written after a seek() # at a position different than the start - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + with codecs.open(os_helper.TESTFN, 'w+', encoding=encoding) as f: f.writer.write(data) f.writer.seek(f.writer.tell()) f.writer.write(data) diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 8d9f8729687754d..bff20f9cac9c989 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -3,6 +3,8 @@ """ from test import support +from test.support import import_helper +from test.support import os_helper import doctest import functools import os @@ -441,7 +443,7 @@ def basics(): r""" >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [] + [] The exact name depends on how test_doctest was invoked, so allow for leading path components. @@ -705,7 +707,7 @@ def test_empty_namespace_package(self): try: mod = importlib.import_module(pkg_name) finally: - support.forget(pkg_name) + import_helper.forget(pkg_name) sys.path.pop() include_empty_finder = doctest.DocTestFinder(exclude_empty=False) @@ -2758,7 +2760,7 @@ def test_lineendings(): r""" >>> dn = tempfile.mkdtemp() >>> pkg = os.path.join(dn, "doctest_testpkg") >>> os.mkdir(pkg) - >>> support.create_empty_file(os.path.join(pkg, "__init__.py")) + >>> os_helper.create_empty_file(os.path.join(pkg, "__init__.py")) >>> fn = os.path.join(pkg, "doctest_testfile.txt") >>> with open(fn, 'wb') as f: ... f.write( @@ -2840,7 +2842,8 @@ def test_CLI(): r""" simple tests and no errors. We'll run both the unadorned doctest command, and the verbose version, and then check the output: - >>> from test.support import script_helper, temp_dir + >>> from test.support import script_helper + >>> from test.support.os_helper import temp_dir >>> with temp_dir() as tmpdir: ... fn = os.path.join(tmpdir, 'myfile.doc') ... with open(fn, 'w') as f: @@ -2891,7 +2894,8 @@ def test_CLI(): r""" file ends in '.py', its handling of python module files (as opposed to straight text files). - >>> from test.support import script_helper, temp_dir + >>> from test.support import script_helper + >>> from test.support.os_helper import temp_dir >>> with temp_dir() as tmpdir: ... fn = os.path.join(tmpdir, 'myfile.doc') ... with open(fn, 'w') as f: @@ -3109,7 +3113,7 @@ def test_main(): def test_coverage(coverdir): - trace = support.import_module('trace') + trace = import_helper.import_module('trace') tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], trace=0, count=1) tracer.run('test_main()') diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index a67e69bfff72811..2ffe8caa03f8121 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -8,10 +8,13 @@ import weakref import errno -from test.support import (TESTFN, captured_stderr, check_impl_detail, - check_warnings, cpython_only, gc_collect, - no_tracing, unlink, import_module, script_helper, +from test.support import (captured_stderr, check_impl_detail, + cpython_only, gc_collect, + no_tracing, script_helper, SuppressCrashReport) +from test.support.import_helper import import_module +from test.support.os_helper import TESTFN, unlink +from test.support.warnings_helper import check_warnings from test import support diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index cb43573318b6a99..65feb3aadedd672 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -21,6 +21,7 @@ from test import support from test.support import threading_helper from test.support import socket_helper +from test.support import warnings_helper from test.support.socket_helper import HOST, HOSTv6 TIMEOUT = support.LOOPBACK_TIMEOUT @@ -623,7 +624,7 @@ def test_storlines(self): f = io.StringIO(RETR_DATA.replace('\r\n', '\n')) # storlines() expects a binary file, not a text file - with support.check_warnings(('', BytesWarning), quiet=True): + with warnings_helper.check_warnings(('', BytesWarning), quiet=True): self.assertRaises(TypeError, self.client.storlines, 'stor foo', f) def test_nlst(self): diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index c82970827c6728c..1b096efdbcf5fb7 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1,8 +1,9 @@ import unittest import unittest.mock from test.support import (verbose, refcount_test, run_unittest, - cpython_only, temp_dir, TESTFN, unlink, - import_module) + cpython_only) +from test.support.import_helper import import_module +from test.support.os_helper import temp_dir, TESTFN, unlink from test.support.script_helper import assert_python_ok, make_script from test.support import threading_helper diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index e7acbcd29088b39..1ff7f75ad3e6147 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -7,9 +7,10 @@ import sys import unittest import warnings -from test import support +from test.support import os_helper +from test.support import warnings_helper from test.support.script_helper import assert_python_ok -from test.support import FakePath +from test.support.os_helper import FakePath def create_file(filename, data=b'foo'): @@ -97,8 +98,8 @@ def test_commonprefix(self): self.assertNotEqual(s1[n:n+1], s2[n:n+1]) def test_getsize(self): - filename = support.TESTFN - self.addCleanup(support.unlink, filename) + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) create_file(filename, b'Hello') self.assertEqual(self.pathmodule.getsize(filename), 5) @@ -108,8 +109,8 @@ def test_getsize(self): self.assertEqual(self.pathmodule.getsize(filename), 12) def test_filetime(self): - filename = support.TESTFN - self.addCleanup(support.unlink, filename) + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) create_file(filename, b'foo') @@ -126,9 +127,9 @@ def test_filetime(self): ) def test_exists(self): - filename = support.TESTFN + filename = os_helper.TESTFN bfilename = os.fsencode(filename) - self.addCleanup(support.unlink, filename) + self.addCleanup(os_helper.unlink, filename) self.assertIs(self.pathmodule.exists(filename), False) self.assertIs(self.pathmodule.exists(bfilename), False) @@ -163,7 +164,7 @@ def test_exists_fd(self): self.assertFalse(self.pathmodule.exists(r)) def test_isdir(self): - filename = support.TESTFN + filename = os_helper.TESTFN bfilename = os.fsencode(filename) self.assertIs(self.pathmodule.isdir(filename), False) self.assertIs(self.pathmodule.isdir(bfilename), False) @@ -178,17 +179,17 @@ def test_isdir(self): self.assertIs(self.pathmodule.isdir(filename), False) self.assertIs(self.pathmodule.isdir(bfilename), False) finally: - support.unlink(filename) + os_helper.unlink(filename) try: os.mkdir(filename) self.assertIs(self.pathmodule.isdir(filename), True) self.assertIs(self.pathmodule.isdir(bfilename), True) finally: - support.rmdir(filename) + os_helper.rmdir(filename) def test_isfile(self): - filename = support.TESTFN + filename = os_helper.TESTFN bfilename = os.fsencode(filename) self.assertIs(self.pathmodule.isfile(filename), False) self.assertIs(self.pathmodule.isfile(bfilename), False) @@ -203,20 +204,20 @@ def test_isfile(self): self.assertIs(self.pathmodule.isfile(filename), True) self.assertIs(self.pathmodule.isfile(bfilename), True) finally: - support.unlink(filename) + os_helper.unlink(filename) try: os.mkdir(filename) self.assertIs(self.pathmodule.isfile(filename), False) self.assertIs(self.pathmodule.isfile(bfilename), False) finally: - support.rmdir(filename) + os_helper.rmdir(filename) def test_samefile(self): - file1 = support.TESTFN - file2 = support.TESTFN + "2" - self.addCleanup(support.unlink, file1) - self.addCleanup(support.unlink, file2) + file1 = os_helper.TESTFN + file2 = os_helper.TESTFN + "2" + self.addCleanup(os_helper.unlink, file1) + self.addCleanup(os_helper.unlink, file2) create_file(file1) self.assertTrue(self.pathmodule.samefile(file1, file1)) @@ -227,10 +228,10 @@ def test_samefile(self): self.assertRaises(TypeError, self.pathmodule.samefile) def _test_samefile_on_link_func(self, func): - test_fn1 = support.TESTFN - test_fn2 = support.TESTFN + "2" - self.addCleanup(support.unlink, test_fn1) - self.addCleanup(support.unlink, test_fn2) + test_fn1 = os_helper.TESTFN + test_fn2 = os_helper.TESTFN + "2" + self.addCleanup(os_helper.unlink, test_fn1) + self.addCleanup(os_helper.unlink, test_fn2) create_file(test_fn1) @@ -241,7 +242,7 @@ def _test_samefile_on_link_func(self, func): create_file(test_fn2) self.assertFalse(self.pathmodule.samefile(test_fn1, test_fn2)) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_samefile_on_symlink(self): self._test_samefile_on_link_func(os.symlink) @@ -252,10 +253,10 @@ def test_samefile_on_link(self): self.skipTest('os.link(): %s' % e) def test_samestat(self): - test_fn1 = support.TESTFN - test_fn2 = support.TESTFN + "2" - self.addCleanup(support.unlink, test_fn1) - self.addCleanup(support.unlink, test_fn2) + test_fn1 = os_helper.TESTFN + test_fn2 = os_helper.TESTFN + "2" + self.addCleanup(os_helper.unlink, test_fn1) + self.addCleanup(os_helper.unlink, test_fn2) create_file(test_fn1) stat1 = os.stat(test_fn1) @@ -268,10 +269,10 @@ def test_samestat(self): self.assertRaises(TypeError, self.pathmodule.samestat) def _test_samestat_on_link_func(self, func): - test_fn1 = support.TESTFN + "1" - test_fn2 = support.TESTFN + "2" - self.addCleanup(support.unlink, test_fn1) - self.addCleanup(support.unlink, test_fn2) + test_fn1 = os_helper.TESTFN + "1" + test_fn2 = os_helper.TESTFN + "2" + self.addCleanup(os_helper.unlink, test_fn1) + self.addCleanup(os_helper.unlink, test_fn2) create_file(test_fn1) func(test_fn1, test_fn2) @@ -283,7 +284,7 @@ def _test_samestat_on_link_func(self, func): self.assertFalse(self.pathmodule.samestat(os.stat(test_fn1), os.stat(test_fn2))) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_samestat_on_symlink(self): self._test_samestat_on_link_func(os.symlink) @@ -294,8 +295,8 @@ def test_samestat_on_link(self): self.skipTest('os.link(): %s' % e) def test_sameopenfile(self): - filename = support.TESTFN - self.addCleanup(support.unlink, filename) + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) create_file(filename) with open(filename, "rb", 0) as fp1: @@ -374,7 +375,7 @@ def test_splitdrive(self): def test_expandvars(self): expandvars = self.pathmodule.expandvars - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.clear() env["foo"] = "bar" env["{foo"] = "baz1" @@ -403,14 +404,14 @@ def test_expandvars(self): self.assertEqual(expandvars(b"$foo$foo"), b"barbar") self.assertEqual(expandvars(b"$bar$bar"), b"$bar$bar") - @unittest.skipUnless(support.FS_NONASCII, 'need support.FS_NONASCII') + @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII') def test_expandvars_nonascii(self): expandvars = self.pathmodule.expandvars def check(value, expected): self.assertEqual(expandvars(value), expected) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.clear() - nonascii = support.FS_NONASCII + nonascii = os_helper.FS_NONASCII env['spam'] = nonascii env[nonascii] = 'ham' + nonascii check(nonascii, nonascii) @@ -469,31 +470,31 @@ def test_abspath_issue3426(self): # FS encoding is probably ASCII pass else: - with support.temp_cwd(unicwd): + with os_helper.temp_cwd(unicwd): for path in ('', 'fuu', 'f\xf9\xf9', '/fuu', 'U:\\'): self.assertIsInstance(abspath(path), str) def test_nonascii_abspath(self): - if (support.TESTFN_UNDECODABLE + if (os_helper.TESTFN_UNDECODABLE # Mac OS X denies the creation of a directory with an invalid # UTF-8 name. Windows allows creating a directory with an # arbitrary bytes name, but fails to enter this directory # (when the bytes name is used). and sys.platform not in ('win32', 'darwin')): - name = support.TESTFN_UNDECODABLE - elif support.TESTFN_NONASCII: - name = support.TESTFN_NONASCII + name = os_helper.TESTFN_UNDECODABLE + elif os_helper.TESTFN_NONASCII: + name = os_helper.TESTFN_NONASCII else: - self.skipTest("need support.TESTFN_NONASCII") + self.skipTest("need os_helper.TESTFN_NONASCII") with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - with support.temp_cwd(name): + with os_helper.temp_cwd(name): self.test_abspath() def test_join_errors(self): # Check join() raises friendly TypeErrors. - with support.check_warnings(('', BytesWarning), quiet=True): + with warnings_helper.check_warnings(('', BytesWarning), quiet=True): errmsg = "Can't mix strings and bytes in path components" with self.assertRaisesRegex(TypeError, errmsg): self.pathmodule.join(b'bytes', 'str') @@ -513,8 +514,8 @@ def test_join_errors(self): def test_relpath_errors(self): # Check relpath() raises friendly TypeErrors. - with support.check_warnings(('', (BytesWarning, DeprecationWarning)), - quiet=True): + with warnings_helper.check_warnings( + ('', (BytesWarning, DeprecationWarning)), quiet=True): errmsg = "Can't mix strings and bytes in path components" with self.assertRaisesRegex(TypeError, errmsg): self.pathmodule.relpath(b'bytes', 'str') @@ -534,9 +535,9 @@ def test_import(self): class PathLikeTests(unittest.TestCase): def setUp(self): - self.file_name = support.TESTFN - self.file_path = FakePath(support.TESTFN) - self.addCleanup(support.unlink, self.file_name) + self.file_name = os_helper.TESTFN + self.file_path = FakePath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, self.file_name) create_file(self.file_name, b"test_genericpath.PathLikeTests") def assertPathEqual(self, func): diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py index 476ba95f173c1cd..b2d1fc8322a038c 100644 --- a/Lib/test/test_imghdr.py +++ b/Lib/test/test_imghdr.py @@ -4,7 +4,9 @@ import pathlib import unittest import warnings -from test.support import findfile, TESTFN, unlink +from test.support import findfile +from test.support.os_helper import TESTFN, unlink + TEST_FILES = ( ('python.png', 'png'), diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 683d393fdb49139..ddeae38e1372f54 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -6,6 +6,7 @@ import unittest from test import support +from test.support import os_helper from platform import win32_edition @@ -60,7 +61,7 @@ def test_read_mime_types(self): # Unreadable file returns None self.assertIsNone(mimetypes.read_mime_types("non-existent")) - with support.temp_dir() as directory: + with os_helper.temp_dir() as directory: data = "x-application/x-unittest pyunit\n" file = pathlib.Path(directory, "sample.mimetype") file.write_text(data) @@ -70,7 +71,7 @@ def test_read_mime_types(self): # bpo-41048: read_mime_types should read the rule file with 'utf-8' encoding. # Not with locale encoding. _bootlocale has been imported because io.open(...) # uses it. - with support.temp_dir() as directory: + with os_helper.temp_dir() as directory: data = "application/no-mans-land Fran\u00E7ais" file = pathlib.Path(directory, "sample.mimetype") file.write_text(data, encoding='utf-8') diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 6f881f197c4f54d..69c44710f0b5ada 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -3,7 +3,9 @@ import sys import unittest import warnings -from test.support import TestFailed, FakePath +from test.support import os_helper +from test.support import TestFailed +from test.support.os_helper import FakePath from test import support, test_genericpath from tempfile import TemporaryFile @@ -254,34 +256,34 @@ def test_realpath_pardir(self): tester("ntpath.realpath('\\'.join(['..'] * 50))", ntpath.splitdrive(expected)[0] + '\\') - @support.skip_unless_symlink + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_basic(self): - ABSTFN = ntpath.abspath(support.TESTFN) + ABSTFN = ntpath.abspath(os_helper.TESTFN) open(ABSTFN, "wb").close() - self.addCleanup(support.unlink, ABSTFN) - self.addCleanup(support.unlink, ABSTFN + "1") + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") os.symlink(ABSTFN, ABSTFN + "1") self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")), os.fsencode(ABSTFN)) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_relative(self): - ABSTFN = ntpath.abspath(support.TESTFN) + ABSTFN = ntpath.abspath(os_helper.TESTFN) open(ABSTFN, "wb").close() - self.addCleanup(support.unlink, ABSTFN) - self.addCleanup(support.unlink, ABSTFN + "1") + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1")) self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_broken_symlinks(self): - ABSTFN = ntpath.abspath(support.TESTFN) + ABSTFN = ntpath.abspath(os_helper.TESTFN) os.mkdir(ABSTFN) self.addCleanup(support.rmtree, ABSTFN) @@ -335,18 +337,18 @@ def test_realpath_broken_symlinks(self): self.assertPathEqual(ntpath.realpath(b"broken5"), os.fsencode(ABSTFN + r"\missing")) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_loops(self): # Symlink loops are non-deterministic as to which path is returned, but # it will always be the fully resolved path of one member of the cycle - ABSTFN = ntpath.abspath(support.TESTFN) - self.addCleanup(support.unlink, ABSTFN) - self.addCleanup(support.unlink, ABSTFN + "1") - self.addCleanup(support.unlink, ABSTFN + "2") - self.addCleanup(support.unlink, ABSTFN + "y") - self.addCleanup(support.unlink, ABSTFN + "c") - self.addCleanup(support.unlink, ABSTFN + "a") + ABSTFN = ntpath.abspath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") + self.addCleanup(os_helper.unlink, ABSTFN + "2") + self.addCleanup(os_helper.unlink, ABSTFN + "y") + self.addCleanup(os_helper.unlink, ABSTFN + "c") + self.addCleanup(os_helper.unlink, ABSTFN + "a") os.symlink(ABSTFN, ABSTFN) self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN) @@ -381,14 +383,14 @@ def test_realpath_symlink_loops(self): # Test using relative path as well. self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN) - @support.skip_unless_symlink + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_prefix(self): - ABSTFN = ntpath.abspath(support.TESTFN) - self.addCleanup(support.unlink, ABSTFN + "3") - self.addCleanup(support.unlink, "\\\\?\\" + ABSTFN + "3.") - self.addCleanup(support.unlink, ABSTFN + "3link") - self.addCleanup(support.unlink, ABSTFN + "3.link") + ABSTFN = ntpath.abspath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "3") + self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.") + self.addCleanup(os_helper.unlink, ABSTFN + "3link") + self.addCleanup(os_helper.unlink, ABSTFN + "3.link") with open(ABSTFN + "3", "wb") as f: f.write(b'0') @@ -422,9 +424,9 @@ def test_realpath_nul(self): @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') def test_realpath_cwd(self): - ABSTFN = ntpath.abspath(support.TESTFN) + ABSTFN = ntpath.abspath(os_helper.TESTFN) - support.unlink(ABSTFN) + os_helper.unlink(ABSTFN) support.rmtree(ABSTFN) os.mkdir(ABSTFN) self.addCleanup(support.rmtree, ABSTFN) @@ -449,7 +451,7 @@ def test_realpath_cwd(self): self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) def test_expandvars(self): - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.clear() env["foo"] = "bar" env["{foo"] = "baz1" @@ -474,13 +476,13 @@ def test_expandvars(self): tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar") tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%") - @unittest.skipUnless(support.FS_NONASCII, 'need support.FS_NONASCII') + @unittest.skipUnless(os_helper.FS_NONASCII, 'need os_helper.FS_NONASCII') def test_expandvars_nonascii(self): def check(value, expected): tester('ntpath.expandvars(%r)' % value, expected) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.clear() - nonascii = support.FS_NONASCII + nonascii = os_helper.FS_NONASCII env['spam'] = nonascii env[nonascii] = 'ham' + nonascii check('$spam bar', '%s bar' % nonascii) @@ -497,7 +499,7 @@ def check(value, expected): def test_expanduser(self): tester('ntpath.expanduser("test")', 'test') - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.clear() tester('ntpath.expanduser("~test")', '~test') @@ -533,7 +535,7 @@ def test_expanduser(self): @unittest.skipUnless(nt, "abspath requires 'nt' module") def test_abspath(self): tester('ntpath.abspath("C:\\")', "C:\\") - with support.temp_cwd(support.TESTFN) as cwd_dir: # bpo-31047 + with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047 tester('ntpath.abspath("")', cwd_dir) tester('ntpath.abspath(" ")', cwd_dir + "\\ ") tester('ntpath.abspath("?")', cwd_dir + "\\?") @@ -545,7 +547,7 @@ def test_relpath(self): tester('ntpath.relpath(ntpath.abspath("a"))', 'a') tester('ntpath.relpath("a/b")', 'a\\b') tester('ntpath.relpath("../a/b")', '..\\a\\b') - with support.temp_cwd(support.TESTFN) as cwd_dir: + with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: currentdir = ntpath.basename(cwd_dir) tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a') tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') @@ -661,7 +663,7 @@ def test_ismount(self): self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\")) self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\")) - with support.temp_dir() as d: + with os_helper.temp_dir() as d: self.assertFalse(ntpath.ismount(d)) if sys.platform == "win32": @@ -725,9 +727,9 @@ class PathLikeTests(NtpathTestCase): path = ntpath def setUp(self): - self.file_name = support.TESTFN - self.file_path = FakePath(support.TESTFN) - self.addCleanup(support.unlink, self.file_name) + self.file_name = os_helper.TESTFN + self.file_path = FakePath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, self.file_name) with open(self.file_name, 'xb', 0) as file: file.write(b"test_ntpath.PathLikeTests") diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py index 29f5e4275c55eb0..1ecae85f62f2c9a 100644 --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -3,9 +3,13 @@ import sys from test import support +from test.support import import_helper -py_operator = support.import_fresh_module('operator', blocked=['_operator']) -c_operator = support.import_fresh_module('operator', fresh=['_operator']) + +py_operator = import_helper.import_fresh_module('operator', + blocked=['_operator']) +c_operator = import_helper.import_fresh_module('operator', + fresh=['_operator']) class Seq1: def __init__(self, lst): diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index 437fdd2be8d85ac..ed65b7798e3d2ab 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -14,6 +14,7 @@ from io import StringIO from test import support +from test.support import os_helper import optparse @@ -1021,10 +1022,10 @@ def setUp(self): self.parser.add_option("-f", "--file", type="file", dest="file") def tearDown(self): - if os.path.isdir(support.TESTFN): - os.rmdir(support.TESTFN) - elif os.path.isfile(support.TESTFN): - os.unlink(support.TESTFN) + if os.path.isdir(os_helper.TESTFN): + os.rmdir(os_helper.TESTFN) + elif os.path.isfile(os_helper.TESTFN): + os.unlink(os_helper.TESTFN) class MyOption (Option): def check_file(option, opt, value): @@ -1039,21 +1040,21 @@ def check_file(option, opt, value): TYPE_CHECKER["file"] = check_file def test_filetype_ok(self): - support.create_empty_file(support.TESTFN) - self.assertParseOK(["--file", support.TESTFN, "-afoo"], - {'file': support.TESTFN, 'a': 'foo'}, + os_helper.create_empty_file(os_helper.TESTFN) + self.assertParseOK(["--file", os_helper.TESTFN, "-afoo"], + {'file': os_helper.TESTFN, 'a': 'foo'}, []) def test_filetype_noexist(self): - self.assertParseFail(["--file", support.TESTFN, "-afoo"], + self.assertParseFail(["--file", os_helper.TESTFN, "-afoo"], "%s: file does not exist" % - support.TESTFN) + os_helper.TESTFN) def test_filetype_notfile(self): - os.mkdir(support.TESTFN) - self.assertParseFail(["--file", support.TESTFN, "-afoo"], + os.mkdir(os_helper.TESTFN) + self.assertParseFail(["--file", os_helper.TESTFN, "-afoo"], "%s: not a regular file" % - support.TESTFN) + os_helper.TESTFN) class TestExtendAddActions(BaseTest): @@ -1497,7 +1498,7 @@ def make_parser(self, columns): # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env['COLUMNS'] = str(columns) return InterceptingOptionParser(option_list=options) @@ -1522,7 +1523,7 @@ def test_help_long_opts_first(self): self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["COLUMNS"] = "80" self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index f9935258c861e0d..2c13635d37dea34 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -5,6 +5,7 @@ from test import test_tools from test import support +from test.support import os_helper from test.support.script_helper import assert_python_ok test_tools.skip_if_missing("peg_generator") @@ -68,7 +69,7 @@ def setUp(self): self.skipTest("The %r command is not found" % cmd) super(TestCParser, self).setUp() self.tmp_path = self.mkdtemp() - change_cwd = support.change_cwd(self.tmp_path) + change_cwd = os_helper.change_cwd(self.tmp_path) change_cwd.__enter__() self.addCleanup(change_cwd.__exit__, None, None, None) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 7b23699a00f1d0d..508b739019593d6 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -6,11 +6,12 @@ import time import unittest import weakref -from test import support +from test.support import import_helper from test.support import threading_helper -py_queue = support.import_fresh_module('queue', blocked=['_queue']) -c_queue = support.import_fresh_module('queue', fresh=['_queue']) + +py_queue = import_helper.import_fresh_module('queue', blocked=['_queue']) +c_queue = import_helper.import_fresh_module('queue', fresh=['_queue']) need_c_queue = unittest.skipUnless(c_queue, "No _queue module found") QUEUE_SIZE = 5 diff --git a/Lib/test/test_spwd.py b/Lib/test/test_spwd.py index 07793c84c8e912c..a143acc659ef6a5 100644 --- a/Lib/test/test_spwd.py +++ b/Lib/test/test_spwd.py @@ -1,8 +1,9 @@ import os import unittest -from test import support +from test.support import import_helper -spwd = support.import_module('spwd') + +spwd = import_helper.import_module('spwd') @unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0, diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index d9e4ffde658dbd0..83d09e17f93c563 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -3,7 +3,9 @@ import socket import sys from test.support import socket_helper -from test.support import TESTFN, import_fresh_module +from test.support.import_helper import import_fresh_module +from test.support.os_helper import TESTFN + c_stat = import_fresh_module('stat', fresh=['_stat']) py_stat = import_fresh_module('stat', blocked=['_stat']) diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 6de7aa87bb2f9e3..681f2c72f9c3785 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -1,4 +1,5 @@ from test import support +from test.support import os_helper from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP, STRING, ENDMARKER, ENCODING, tok_name, detect_encoding, open as tokenize_open, Untokenizer, generate_tokens, @@ -1265,8 +1266,8 @@ def test_false_encoding(self): self.assertEqual(consumed_lines, [b'print("#coding=fake")']) def test_open(self): - filename = support.TESTFN + '.py' - self.addCleanup(support.unlink, filename) + filename = os_helper.TESTFN + '.py' + self.addCleanup(os_helper.unlink, filename) # test coding cookie for encoding in ('iso-8859-15', 'utf-8'): diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 519a9432abe012d..6ceb49069f65649 100644 --- a/Lib/test/test_webbrowser.py +++ b/Lib/test/test_webbrowser.py @@ -5,6 +5,7 @@ import subprocess from unittest import mock from test import support +from test.support import import_helper URL = 'http://www.example.com' @@ -270,7 +271,7 @@ def test_register_preferred(self): class ImportTest(unittest.TestCase): def test_register(self): - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') self.assertIsNone(webbrowser._tryorder) self.assertFalse(webbrowser._browsers) @@ -284,7 +285,7 @@ class ExampleBrowser: self.assertEqual(webbrowser._browsers['example1'], [ExampleBrowser, None]) def test_get(self): - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') self.assertIsNone(webbrowser._tryorder) self.assertFalse(webbrowser._browsers) @@ -293,24 +294,24 @@ def test_get(self): self.assertIsNotNone(webbrowser._tryorder) def test_synthesize(self): - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') name = os.path.basename(sys.executable).lower() webbrowser.register(name, None, webbrowser.GenericBrowser(name)) webbrowser.get(sys.executable) def test_environment(self): - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') try: browser = webbrowser.get().name except (webbrowser.Error, AttributeError) as err: self.skipTest(str(err)) with support.EnvironmentVarGuard() as env: env["BROWSER"] = browser - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') webbrowser.get() def test_environment_preferred(self): - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') try: webbrowser.get() least_preferred_browser = webbrowser.get(webbrowser._tryorder[-1]).name @@ -319,12 +320,12 @@ def test_environment_preferred(self): with support.EnvironmentVarGuard() as env: env["BROWSER"] = least_preferred_browser - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') self.assertEqual(webbrowser.get().name, least_preferred_browser) with support.EnvironmentVarGuard() as env: env["BROWSER"] = sys.executable - webbrowser = support.import_fresh_module('webbrowser') + webbrowser = import_helper.import_fresh_module('webbrowser') self.assertEqual(webbrowser.get().name, sys.executable) From 16479f730a78a5b0cabbf8178c6db37bc1dc7ed2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Aug 2020 22:51:23 +0200 Subject: [PATCH 102/486] bpo-38912: regrtest logs unraisable exception into sys.__stderr__ (GH-21718) regrtest_unraisable_hook() temporarily replaces sys.stderr with sys.__stderr__ to help to display errors when a test captures stderr. --- Lib/test/libregrtest/utils.py | 7 ++++++- Lib/test/test_regrtest.py | 13 +++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 0368694b2adcb7d..71f538f0c453385 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -72,7 +72,12 @@ def regrtest_unraisable_hook(unraisable): global orig_unraisablehook support.environment_altered = True print_warning("Unraisable exception") - orig_unraisablehook(unraisable) + old_stderr = sys.stderr + try: + sys.stderr = sys.__stderr__ + orig_unraisablehook(unraisable) + finally: + sys.stderr = old_stderr def setup_unraisable_hook(): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 39af0d96d1e54d0..38321e04b54a9e3 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -1235,10 +1235,12 @@ def test_sleep(self): re.compile('%s timed out' % testname, re.MULTILINE)) def test_unraisable_exc(self): - # --fail-env-changed must catch unraisable exception + # --fail-env-changed must catch unraisable exception. + # The exceptioin must be displayed even if sys.stderr is redirected. code = textwrap.dedent(r""" import unittest import weakref + from test.support import captured_stderr class MyObject: pass @@ -1250,9 +1252,11 @@ class Tests(unittest.TestCase): def test_unraisable_exc(self): obj = MyObject() ref = weakref.ref(obj, weakref_callback) - # call weakref_callback() which logs - # an unraisable exception - obj = None + with captured_stderr() as stderr: + # call weakref_callback() which logs + # an unraisable exception + obj = None + self.assertEqual(stderr.getvalue(), '') """) testname = self.create_test(code=code) @@ -1261,6 +1265,7 @@ def test_unraisable_exc(self): env_changed=[testname], fail_env_changed=True) self.assertIn("Warning -- Unraisable exception", output) + self.assertIn("Exception: weakref callback bug", output) def test_cleanup(self): dirname = os.path.join(self.tmptestdir, "test_python_123") From 7c602cc295104a7e0b8d285f186dcf893089d6fc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Aug 2020 02:38:16 +0200 Subject: [PATCH 103/486] bpo-38156: Fix compiler warning in PyOS_StdioReadline() (GH-21721) incr cannot be larger than INT_MAX: downcast to int explicitly. --- Parser/myreadline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Parser/myreadline.c b/Parser/myreadline.c index a49c9d892dda9e3..143b41f1eab95eb 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -317,7 +317,7 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) return NULL; } p = pr; - int err = my_fgets(tstate, p + n, incr, sys_stdin); + int err = my_fgets(tstate, p + n, (int)incr, sys_stdin); if (err == 1) { // Interrupt PyMem_RawFree(p); From e05270ef0aeb9ca7b9ebd2fb3b5bb86f03e2e75f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Aug 2020 02:40:10 +0200 Subject: [PATCH 104/486] bpo-41467: Fix asyncio recv_into() on Windows (GH-21720) On Windows, fix asyncio recv_into() return value when the socket/pipe is closed (BrokenPipeError): return 0 rather than an empty byte string (b''). --- Lib/asyncio/windows_events.py | 2 +- .../next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index c07fe3241c569af..a6759b78bd801fa 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -469,7 +469,7 @@ def recv_into(self, conn, buf, flags=0): else: ov.ReadFileInto(conn.fileno(), buf) except BrokenPipeError: - return self._result(b'') + return self._result(0) def finish_recv(trans, key, ov): try: diff --git a/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst b/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst new file mode 100644 index 000000000000000..f12693e117631a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst @@ -0,0 +1,3 @@ +On Windows, fix asyncio ``recv_into()`` return value when the socket/pipe is +closed (:exc:`BrokenPipeError`): return ``0`` rather than an empty byte +string (``b''``). From 440a55b253661df9826549e09589d93e63410481 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 4 Aug 2020 11:08:06 +0900 Subject: [PATCH 105/486] bpo-41431: Optimize dict_merge for copy (GH-21674) --- Lib/test/test_ordered_dict.py | 11 ++- .../2020-08-02-15-53-12.bpo-41431.TblUBT.rst | 2 + Objects/dictobject.c | 96 +++++++++++++------ 3 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index 1f27c0e0b57eb23..31759f20d28349d 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -740,20 +740,21 @@ def test_sizeof_exact(self): size = support.calcobjsize check = self.check_sizeof - basicsize = size('nQ2P' + '3PnPn2P') + calcsize('2nP2n') + basicsize = size('nQ2P' + '3PnPn2P') + keysize = calcsize('2nP2n') entrysize = calcsize('n2P') p = calcsize('P') nodesize = calcsize('Pn2P') od = OrderedDict() - check(od, basicsize + 8 + 5*entrysize) # 8byte indices + 8*2//3 * entry table + check(od, basicsize) # 8byte indices + 8*2//3 * entry table od.x = 1 - check(od, basicsize + 8 + 5*entrysize) + check(od, basicsize) od.update([(i, i) for i in range(3)]) - check(od, basicsize + 8*p + 8 + 5*entrysize + 3*nodesize) + check(od, basicsize + keysize + 8*p + 8 + 5*entrysize + 3*nodesize) od.update([(i, i) for i in range(3, 10)]) - check(od, basicsize + 16*p + 16 + 10*entrysize + 10*nodesize) + check(od, basicsize + keysize + 16*p + 16 + 10*entrysize + 10*nodesize) check(od.keys(), size('P')) check(od.items(), size('P')) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst new file mode 100644 index 000000000000000..fa9d047edc39459 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst @@ -0,0 +1,2 @@ +Optimize ``dict_merge()`` for copying dict (e.g. ``dict(d)`` and +``{}.update(d)``). diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ba22489539ae7df..1b7ae06d8227102 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -674,10 +674,11 @@ new_dict_with_shared_keys(PyDictKeysObject *keys) } -static PyObject * -clone_combined_dict(PyDictObject *orig) +static PyDictKeysObject * +clone_combined_dict_keys(PyDictObject *orig) { - assert(PyDict_CheckExact(orig)); + assert(PyDict_Check(orig)); + assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter); assert(orig->ma_values == NULL); assert(orig->ma_keys->dk_refcnt == 1); @@ -704,19 +705,6 @@ clone_combined_dict(PyDictObject *orig) } } - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); - if (new == NULL) { - /* In case of an error, `new_dict()` takes care of - cleaning up `keys`. */ - return NULL; - } - new->ma_used = orig->ma_used; - ASSERT_CONSISTENT(new); - if (_PyObject_GC_IS_TRACKED(orig)) { - /* Maintain tracking. */ - _PyObject_GC_TRACK(new); - } - /* Since we copied the keys table we now have an extra reference in the system. Manually call increment _Py_RefTotal to signal that we have it now; calling dictkeys_incref would be an error as @@ -724,8 +712,7 @@ clone_combined_dict(PyDictObject *orig) #ifdef Py_REF_DEBUG _Py_RefTotal++; #endif - - return (PyObject *)new; + return keys; } PyObject * @@ -2527,12 +2514,45 @@ dict_merge(PyObject *a, PyObject *b, int override) if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ return 0; - if (mp->ma_used == 0) + if (mp->ma_used == 0) { /* Since the target dict is empty, PyDict_GetItem() * always returns NULL. Setting override to 1 * skips the unnecessary test. */ override = 1; + PyDictKeysObject *okeys = other->ma_keys; + + // If other is clean, combined, and just allocated, just clone it. + if (other->ma_values == NULL && + other->ma_used == okeys->dk_nentries && + (okeys->dk_size == PyDict_MINSIZE || + USABLE_FRACTION(okeys->dk_size/2) < other->ma_used)) { + PyDictKeysObject *keys = clone_combined_dict_keys(other); + if (keys == NULL) { + return -1; + } + + dictkeys_decref(mp->ma_keys); + mp->ma_keys = keys; + if (mp->ma_values != NULL) { + if (mp->ma_values != empty_values) { + free_values(mp->ma_values); + } + mp->ma_values = NULL; + } + + mp->ma_used = other->ma_used; + mp->ma_version_tag = DICT_NEXT_VERSION(); + ASSERT_CONSISTENT(mp); + + if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) { + /* Maintain tracking. */ + _PyObject_GC_TRACK(mp); + } + + return 0; + } + } /* Do one big resize at the start, rather than * incrementally resizing as we insert new items. Expect * that there will be no (or few) overlapping keys. @@ -2718,12 +2738,13 @@ PyDict_Copy(PyObject *o) return (PyObject *)split_copy; } - if (PyDict_CheckExact(mp) && mp->ma_values == NULL && + if (Py_TYPE(mp)->tp_iter == (getiterfunc)dict_iter && + mp->ma_values == NULL && (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) { /* Use fast-copy if: - (1) 'mp' is an instance of a subclassed dict; and + (1) type(mp) doesn't override tp_iter; and (2) 'mp' is not a split-dict; and @@ -2735,13 +2756,31 @@ PyDict_Copy(PyObject *o) operations and copied after that. In cases like this, we defer to PyDict_Merge, which produces a compacted copy. */ - return clone_combined_dict(mp); + PyDictKeysObject *keys = clone_combined_dict_keys(mp); + if (keys == NULL) { + return NULL; + } + PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); + if (new == NULL) { + /* In case of an error, `new_dict()` takes care of + cleaning up `keys`. */ + return NULL; + } + + new->ma_used = mp->ma_used; + ASSERT_CONSISTENT(new); + if (_PyObject_GC_IS_TRACKED(mp)) { + /* Maintain tracking. */ + _PyObject_GC_TRACK(new); + } + + return (PyObject *)new; } copy = PyDict_New(); if (copy == NULL) return NULL; - if (PyDict_Merge(copy, o, 1) == 0) + if (dict_merge(copy, o, 1) == 0) return copy; Py_DECREF(copy); return NULL; @@ -3359,16 +3398,15 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d = (PyDictObject *)self; /* The object has been implicitly tracked by tp_alloc */ - if (type == &PyDict_Type) + if (type == &PyDict_Type) { _PyObject_GC_UNTRACK(d); + } d->ma_used = 0; d->ma_version_tag = DICT_NEXT_VERSION(); - d->ma_keys = new_keys_object(PyDict_MINSIZE); - if (d->ma_keys == NULL) { - Py_DECREF(self); - return NULL; - } + dictkeys_incref(Py_EMPTY_KEYS); + d->ma_keys = Py_EMPTY_KEYS; + d->ma_values = empty_values; ASSERT_CONSISTENT(d); return self; } From 0493c0aec2b8811d5c27512d57cc85dbfc33fb69 Mon Sep 17 00:00:00 2001 From: Hans Petter Jansson Date: Mon, 3 Aug 2020 22:51:33 -0500 Subject: [PATCH 106/486] bpo-36982: Add support for extended color functions in ncurses 6.1 (GH-17536) Co-authored-by: Jeffrey Kintscher --- Doc/library/curses.rst | 9 + Doc/whatsnew/3.10.rst | 10 + Lib/test/test_curses.py | 16 +- Misc/ACKS | 2 + .../2019-05-25-05-27-39.bpo-36982.0UHgfB.rst | 1 + Modules/_cursesmodule.c | 194 ++++++++++++-- Modules/clinic/_cursesmodule.c.h | 250 ++++-------------- 7 files changed, 258 insertions(+), 224 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index c86ca5d9bc5541e..0b687db1bd2c4db 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -242,6 +242,15 @@ The module :mod:`curses` defines the following functions: Return ``True`` if the terminal can display colors; otherwise, return ``False``. +.. function:: has_extended_color_support() + + Return ``True`` if the module supports extended colors; otherwise, return + ``False``. Extended color support allows more than 256 color pairs for + terminals that support more than 16 colors (e.g. xterm-256color). + + Extended color support requires ncurses version 6.1 or later. + + .. versionadded:: 3.10 .. function:: has_ic() diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 1865fa227534a53..ec0343f2ce71e8e 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -103,6 +103,16 @@ New Modules Improved Modules ================ +curses +------ + +The extended color functions added in ncurses 6.1 will be used transparently +by :func:`curses.color_content`, :func:`curses.init_color`, +:func:`curses.init_pair`, and :func:`curses.pair_content`. A new function, +:func:`curses.has_extended_color_support`, indicates whether extended color +support is provided by the underlying ncurses library. +(Contributed by Jeffrey Kintscher and Hans Petter Jansson in :issue:`36982`.) + glob ---- diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 2c6d14c3f79ddac..cabc10da8365c3f 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -232,7 +232,8 @@ def test_module_funcs(self): curses.nocbreak, curses.noecho, curses.nonl, curses.noqiflush, curses.noraw, curses.reset_prog_mode, curses.termattrs, - curses.termname, curses.erasechar]: + curses.termname, curses.erasechar, + curses.has_extended_color_support]: with self.subTest(func=func.__qualname__): func() if hasattr(curses, 'filter'): @@ -293,6 +294,19 @@ def test_colors_funcs(self): if hasattr(curses, 'use_default_colors'): curses.use_default_colors() + self.assertRaises(ValueError, curses.color_content, -1) + self.assertRaises(ValueError, curses.color_content, curses.COLORS + 1) + self.assertRaises(ValueError, curses.color_content, -2**31 - 1) + self.assertRaises(ValueError, curses.color_content, 2**31) + self.assertRaises(ValueError, curses.color_content, -2**63 - 1) + self.assertRaises(ValueError, curses.color_content, 2**63 - 1) + self.assertRaises(ValueError, curses.pair_content, -1) + self.assertRaises(ValueError, curses.pair_content, curses.COLOR_PAIRS) + self.assertRaises(ValueError, curses.pair_content, -2**31 - 1) + self.assertRaises(ValueError, curses.pair_content, 2**31) + self.assertRaises(ValueError, curses.pair_content, -2**63 - 1) + self.assertRaises(ValueError, curses.pair_content, 2**63 - 1) + @requires_curses_func('keyname') def test_keyname(self): curses.keyname(13) diff --git a/Misc/ACKS b/Misc/ACKS index f5e9459276c86ce..1599b09c692b756 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -798,6 +798,7 @@ Geert Jansen Jack Jansen Hans-Peter Jansen Bill Janssen +Hans Petter Jansson Jon Janzen Thomas Jarosch Juhana Jauhiainen @@ -882,6 +883,7 @@ Sam Kimbrel Tomohiko Kinebuchi James King W. Trevor King +Jeffrey Kintscher Paul Kippes Steve Kirsch Sebastian Kirsche diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst new file mode 100644 index 000000000000000..f105f1857d487f2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst @@ -0,0 +1 @@ +Use ncurses extended color functions when available to support terminals with 256 colors, and add the new function :func:`curses.has_extended_color_support` to indicate whether extended color support is provided by the underlying ncurses library. \ No newline at end of file diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index c70b0e2a19fadc4..34331017f85c7b9 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -134,6 +134,31 @@ typedef chtype attr_t; /* No attr_t type is available */ #define STRICT_SYSV_CURSES #endif +#if defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS) +#define _NCURSES_EXTENDED_COLOR_FUNCS 1 +#else +#define _NCURSES_EXTENDED_COLOR_FUNCS 0 +#endif /* defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS) */ + +#if _NCURSES_EXTENDED_COLOR_FUNCS +#define _NCURSES_COLOR_VAL_TYPE int +#define _CURSES_INIT_COLOR_FUNC init_extended_color +#define _CURSES_INIT_PAIR_FUNC init_extended_pair +#define _COLOR_CONTENT_FUNC extended_color_content +#define _CURSES_PAIR_NUMBER_FUNC extended_pair_content +#else +#define _NCURSES_COLOR_VAL_TYPE short +#define _CURSES_INIT_COLOR_FUNC init_color +#define _CURSES_INIT_PAIR_FUNC init_pair +#define _COLOR_CONTENT_FUNC color_content +#define _CURSES_PAIR_NUMBER_FUNC pair_content +#endif /* _NCURSES_EXTENDED_COLOR_FUNCS */ + +#define _CURSES_FUNC_NAME_STR(s) #s + +#define _CURSES_INIT_COLOR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_COLOR_FUNC) +#define _CURSES_INIT_PAIR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_PAIR_FUNC) + /*[clinic input] module _curses class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" @@ -387,6 +412,104 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, return 0; } +static int +color_converter(PyObject *arg, void *ptr) +{ + long color_number; + int overflow; + + color_number = PyLong_AsLongAndOverflow(arg, &overflow); + if (color_number == -1 && PyErr_Occurred()) + return 0; + + if (overflow > 0 || color_number > COLORS) { + PyErr_Format(PyExc_ValueError, + "Color number is greater than COLORS (%d).", + COLORS); + return 0; + } + else if (overflow < 0 || color_number < 0) { + PyErr_SetString(PyExc_ValueError, + "Color number is less than 0."); + return 0; + } + + *(int *)ptr = (int)color_number; + return 1; +} + +/*[python input] +class color_converter(CConverter): + type = 'int' + converter = 'color_converter' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/ + +static int +pair_converter(PyObject *arg, void *ptr) +{ + long pair_number; + int overflow; + + pair_number = PyLong_AsLongAndOverflow(arg, &overflow); + if (pair_number == -1 && PyErr_Occurred()) + return 0; + + if (overflow > 0 || pair_number > COLOR_PAIRS - 1) { + PyErr_Format(PyExc_ValueError, + "Color pair is greater than COLOR_PAIRS-1 (%d).", + COLOR_PAIRS - 1); + return 0; + } + else if (overflow < 0 || pair_number < 1) { + PyErr_SetString(PyExc_ValueError, + "Color pair is less than 1."); + return 0; + } + + *(int *)ptr = (int)pair_number; + return 1; +} + +/*[python input] +class pair_converter(CConverter): + type = 'int' + converter = 'pair_converter' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=1a918ae6a1b32af7]*/ + +static int +component_converter(PyObject *arg, void *ptr) +{ + long component; + int overflow; + + component = PyLong_AsLongAndOverflow(arg, &overflow); + if (component == -1 && PyErr_Occurred()) + return 0; + + if (overflow > 0 || component > 1000) { + PyErr_SetString(PyExc_ValueError, + "Color component is greater than 1000"); + return 0; + } + else if (overflow < 0 || component < 0) { + PyErr_SetString(PyExc_ValueError, + "Color component is less than 0"); + return 0; + } + + *(short *)ptr = (short)component; + return 1; +} + +/*[python input] +class component_converter(CConverter): + type = 'short' + converter = 'component_converter' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=38e9be01d33927fb]*/ + /* Function versions of the 3 functions for testing whether curses has been initialised or not. */ @@ -2585,7 +2708,7 @@ NoArgOrFlagNoReturnFunctionBody(cbreak, flag) /*[clinic input] _curses.color_content - color_number: short + color_number: color The number of the color (0 - COLORS). / @@ -2596,15 +2719,15 @@ which will be between 0 (no component) and 1000 (maximum amount of component). [clinic start generated code]*/ static PyObject * -_curses_color_content_impl(PyObject *module, short color_number) -/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/ +_curses_color_content_impl(PyObject *module, int color_number) +/*[clinic end generated code: output=17b466df7054e0de input=c10ef58f694b13ee]*/ { - short r,g,b; + _NCURSES_COLOR_VAL_TYPE r,g,b; PyCursesInitialised; PyCursesInitialisedColor; - if (color_content(color_number, &r, &g, &b) != ERR) + if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) != ERR) return Py_BuildValue("(iii)", r, g, b); else { PyErr_SetString(PyCursesError, @@ -2616,7 +2739,7 @@ _curses_color_content_impl(PyObject *module, short color_number) /*[clinic input] _curses.color_pair - color_number: short + color_number: color The number of the color (0 - COLORS). / @@ -2627,8 +2750,8 @@ other A_* attributes. pair_number() is the counterpart to this function. [clinic start generated code]*/ static PyObject * -_curses_color_pair_impl(PyObject *module, short color_number) -/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/ +_curses_color_pair_impl(PyObject *module, int color_number) +/*[clinic end generated code: output=3fd752e8e24c93fb input=b049033819ab4ef5]*/ { PyCursesInitialised; PyCursesInitialisedColor; @@ -3027,13 +3150,13 @@ _curses_has_key_impl(PyObject *module, int key) /*[clinic input] _curses.init_color - color_number: short + color_number: color The number of the color to be changed (0 - COLORS). - r: short + r: component Red component (0 - 1000). - g: short + g: component Green component (0 - 1000). - b: short + b: component Blue component (0 - 1000). / @@ -3045,24 +3168,24 @@ most terminals; it is active only if can_change_color() returns 1. [clinic start generated code]*/ static PyObject * -_curses_init_color_impl(PyObject *module, short color_number, short r, - short g, short b) -/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/ +_curses_init_color_impl(PyObject *module, int color_number, short r, short g, + short b) +/*[clinic end generated code: output=d7ed71b2d818cdf2 input=8a2fe94ca9204aa5]*/ { PyCursesInitialised; PyCursesInitialisedColor; - return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color"); + return PyCursesCheckERR(_CURSES_INIT_COLOR_FUNC(color_number, r, g, b), _CURSES_INIT_COLOR_FUNC_NAME); } /*[clinic input] _curses.init_pair - pair_number: short + pair_number: pair The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)). - fg: short + fg: color Foreground color number (0 - COLORS). - bg: short + bg: color Background color number (0 - COLORS). / @@ -3073,14 +3196,13 @@ all occurrences of that color-pair are changed to the new definition. [clinic start generated code]*/ static PyObject * -_curses_init_pair_impl(PyObject *module, short pair_number, short fg, - short bg) -/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/ +_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg) +/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=b865583a18061c1f]*/ { PyCursesInitialised; PyCursesInitialisedColor; - return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair"); + return PyCursesCheckERR(_CURSES_INIT_PAIR_FUNC(pair_number, fg, bg), _CURSES_INIT_PAIR_FUNC_NAME); } static PyObject *ModDict; @@ -3697,7 +3819,7 @@ NoArgNoReturnFunctionBody(noraw) /*[clinic input] _curses.pair_content - pair_number: short + pair_number: pair The number of the color pair (1 - (COLOR_PAIRS-1)). / @@ -3705,15 +3827,15 @@ Return a tuple (fg, bg) containing the colors for the requested color pair. [clinic start generated code]*/ static PyObject * -_curses_pair_content_impl(PyObject *module, short pair_number) -/*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/ +_curses_pair_content_impl(PyObject *module, int pair_number) +/*[clinic end generated code: output=4a726dd0e6885f3f input=b42eacf8a4103852]*/ { - short f, b; + _NCURSES_COLOR_VAL_TYPE f, b; PyCursesInitialised; PyCursesInitialisedColor; - if (pair_content(pair_number, &f, &b)==ERR) { + if (_CURSES_PAIR_NUMBER_FUNC(pair_number, &f, &b)==ERR) { PyErr_SetString(PyCursesError, "Argument 1 was out of range. (1..COLOR_PAIRS-1)"); return NULL; @@ -4450,6 +4572,21 @@ make_ncurses_version(void) #endif /* NCURSES_VERSION */ +/*[clinic input] +_curses.has_extended_color_support + +Return True if the module supports extended colors; otherwise, return False. + +Extended color support allows more than 256 color-pairs for terminals +that support more than 16 colors (e.g. xterm-256color). +[clinic start generated code]*/ + +static PyObject * +_curses_has_extended_color_support_impl(PyObject *module) +/*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/ +{ + return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS); +} /* List of functions defined in the module */ @@ -4476,6 +4613,7 @@ static PyMethodDef PyCurses_methods[] = { _CURSES_GETSYX_METHODDEF _CURSES_GETWIN_METHODDEF _CURSES_HAS_COLORS_METHODDEF + _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF _CURSES_HAS_IC_METHODDEF _CURSES_HAS_IL_METHODDEF _CURSES_HAS_KEY_METHODDEF diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index f686ded51976c65..c4c2b71e4cc223c 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -1967,32 +1967,16 @@ PyDoc_STRVAR(_curses_color_content__doc__, {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__}, static PyObject * -_curses_color_content_impl(PyObject *module, short color_number); +_curses_color_content_impl(PyObject *module, int color_number); static PyObject * _curses_color_content(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short color_number; + int color_number; - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - color_number = (short) ival; - } + if (!color_converter(arg, &color_number)) { + goto exit; } return_value = _curses_color_content_impl(module, color_number); @@ -2016,32 +2000,16 @@ PyDoc_STRVAR(_curses_color_pair__doc__, {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__}, static PyObject * -_curses_color_pair_impl(PyObject *module, short color_number); +_curses_color_pair_impl(PyObject *module, int color_number); static PyObject * _curses_color_pair(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short color_number; + int color_number; - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - color_number = (short) ival; - } + if (!color_converter(arg, &color_number)) { + goto exit; } return_value = _curses_color_pair_impl(module, color_number); @@ -2590,14 +2558,14 @@ PyDoc_STRVAR(_curses_init_color__doc__, {"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, static PyObject * -_curses_init_color_impl(PyObject *module, short color_number, short r, - short g, short b); +_curses_init_color_impl(PyObject *module, int color_number, short r, short g, + short b); static PyObject * _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - short color_number; + int color_number; short r; short g; short b; @@ -2605,81 +2573,17 @@ _curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("init_color", nargs, 4, 4)) { goto exit; } - { - long ival = PyLong_AsLong(args[0]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - color_number = (short) ival; - } + if (!color_converter(args[0], &color_number)) { + goto exit; } - { - long ival = PyLong_AsLong(args[1]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - r = (short) ival; - } + if (!component_converter(args[1], &r)) { + goto exit; } - { - long ival = PyLong_AsLong(args[2]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - g = (short) ival; - } + if (!component_converter(args[2], &g)) { + goto exit; } - { - long ival = PyLong_AsLong(args[3]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - b = (short) ival; - } + if (!component_converter(args[3], &b)) { + goto exit; } return_value = _curses_init_color_impl(module, color_number, r, g, b); @@ -2707,76 +2611,27 @@ PyDoc_STRVAR(_curses_init_pair__doc__, {"init_pair", (PyCFunction)(void(*)(void))_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, static PyObject * -_curses_init_pair_impl(PyObject *module, short pair_number, short fg, - short bg); +_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg); static PyObject * _curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - short pair_number; - short fg; - short bg; + int pair_number; + int fg; + int bg; if (!_PyArg_CheckPositional("init_pair", nargs, 3, 3)) { goto exit; } - { - long ival = PyLong_AsLong(args[0]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - pair_number = (short) ival; - } + if (!pair_converter(args[0], &pair_number)) { + goto exit; } - { - long ival = PyLong_AsLong(args[1]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - fg = (short) ival; - } + if (!color_converter(args[1], &fg)) { + goto exit; } - { - long ival = PyLong_AsLong(args[2]); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - bg = (short) ival; - } + if (!color_converter(args[2], &bg)) { + goto exit; } return_value = _curses_init_pair_impl(module, pair_number, fg, bg); @@ -3554,32 +3409,16 @@ PyDoc_STRVAR(_curses_pair_content__doc__, {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__}, static PyObject * -_curses_pair_content_impl(PyObject *module, short pair_number); +_curses_pair_content_impl(PyObject *module, int pair_number); static PyObject * _curses_pair_content(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - short pair_number; + int pair_number; - { - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - goto exit; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - goto exit; - } - else { - pair_number = (short) ival; - } + if (!pair_converter(arg, &pair_number)) { + goto exit; } return_value = _curses_pair_content_impl(module, pair_number); @@ -4337,6 +4176,27 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* !defined(STRICT_SYSV_CURSES) */ +PyDoc_STRVAR(_curses_has_extended_color_support__doc__, +"has_extended_color_support($module, /)\n" +"--\n" +"\n" +"Return True if the module supports extended colors; otherwise, return False.\n" +"\n" +"Extended color support allows more than 256 color-pairs for terminals\n" +"that support more than 16 colors (e.g. xterm-256color)."); + +#define _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF \ + {"has_extended_color_support", (PyCFunction)_curses_has_extended_color_support, METH_NOARGS, _curses_has_extended_color_support__doc__}, + +static PyObject * +_curses_has_extended_color_support_impl(PyObject *module); + +static PyObject * +_curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_extended_color_support_impl(module); +} + #ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF #define _CURSES_WINDOW_ENCLOSE_METHODDEF #endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */ @@ -4428,4 +4288,4 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=478d93f7692385eb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=38b2531d17f119e1 input=a9049054013a1b77]*/ From d04cd163c60d7aa3613f1333c618c74bd2d1d765 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 4 Aug 2020 23:51:43 +0800 Subject: [PATCH 107/486] bpo-40275: Use new test.support helper submodules in tests (GH-21452) --- Lib/test/eintrdata/eintr_tester.py | 13 ++++---- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_multibytecodec.py | 7 +++-- Lib/test/test_pdb.py | 48 +++++++++++++++--------------- Lib/test/test_urllib2_localnet.py | 6 ++-- Lib/test/test_warnings/__init__.py | 40 ++++++++++++++----------- 6 files changed, 62 insertions(+), 54 deletions(-) diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py index 606f31b09109618..e43b59d064f55a8 100644 --- a/Lib/test/eintrdata/eintr_tester.py +++ b/Lib/test/eintrdata/eintr_tester.py @@ -22,6 +22,7 @@ import unittest from test import support +from test.support import os_helper from test.support import socket_helper @contextlib.contextmanager @@ -314,16 +315,16 @@ def test_accept(self): @support.requires_freebsd_version(10, 3) @unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()') def _test_open(self, do_open_close_reader, do_open_close_writer): - filename = support.TESTFN + filename = os_helper.TESTFN # Use a fifo: until the child opens it for reading, the parent will # block when trying to open it for writing. - support.unlink(filename) + os_helper.unlink(filename) try: os.mkfifo(filename) except PermissionError as e: self.skipTest('os.mkfifo(): %s' % e) - self.addCleanup(support.unlink, filename) + self.addCleanup(os_helper.unlink, filename) code = '\n'.join(( 'import os, time', @@ -486,16 +487,16 @@ def test_devpoll(self): class FNTLEINTRTest(EINTRBaseTest): def _lock(self, lock_func, lock_name): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) code = '\n'.join(( "import fcntl, time", - "with open('%s', 'wb') as f:" % support.TESTFN, + "with open('%s', 'wb') as f:" % os_helper.TESTFN, " fcntl.%s(f, fcntl.LOCK_EX)" % lock_name, " time.sleep(%s)" % self.sleep_time)) start_time = time.monotonic() proc = self.subprocess(code) with kill_on_error(proc): - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: while True: # synchronize the subprocess dt = time.monotonic() - start_time if dt > 60.0: diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 1d28e26dec6813f..ba4ed69cc9b34b1 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -38,7 +38,7 @@ from email import quoprimime from test.support import threading_helper -from test.support import unlink +from test.support.os_helper import unlink from test.test_email import openfile, TestEmailBase # These imports are documented to work, but we are testing them using a diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py index 3cf5d7beb144b3d..7c3b67f3cbf6ea8 100644 --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -4,7 +4,8 @@ # from test import support -from test.support import TESTFN +from test.support import os_helper +from test.support.os_helper import TESTFN import unittest, io, codecs, sys import _multibytecodec @@ -57,7 +58,7 @@ def test_codingspec(self): code = '# coding: {}\n'.format(enc) exec(code) finally: - support.unlink(TESTFN) + os_helper.unlink(TESTFN) def test_init_segfault(self): # bug #3305: this used to segfault @@ -296,7 +297,7 @@ def test_bug1728403(self): finally: f.close() finally: - support.unlink(TESTFN) + os_helper.unlink(TESTFN) class Test_StreamWriter(unittest.TestCase): def test_gb18030(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 65bca291d961873..1a2bbb382e86426 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -12,7 +12,7 @@ from contextlib import ExitStack from io import StringIO -from test import support +from test.support import os_helper # This little helper class is essential for testing pdb under doctest. from test.test_doctest import _FakeInput from unittest.mock import patch @@ -1188,10 +1188,10 @@ def test_pdb_issue_20766(): class PdbTestCase(unittest.TestCase): def tearDown(self): - support.unlink(support.TESTFN) + os_helper.unlink(os_helper.TESTFN) def _run_pdb(self, pdb_args, commands): - self.addCleanup(support.rmtree, '__pycache__') + self.addCleanup(os_helper.rmtree, '__pycache__') cmd = [sys.executable, '-m', 'pdb'] + pdb_args with subprocess.Popen( cmd, @@ -1210,13 +1210,13 @@ def run_pdb_script(self, script, commands): filename = 'main.py' with open(filename, 'w') as f: f.write(textwrap.dedent(script)) - self.addCleanup(support.unlink, filename) + self.addCleanup(os_helper.unlink, filename) return self._run_pdb([filename], commands) def run_pdb_module(self, script, commands): """Runs the script code as part of a module""" self.module_name = 't_main' - support.rmtree(self.module_name) + os_helper.rmtree(self.module_name) main_file = self.module_name + '/__main__.py' init_file = self.module_name + '/__init__.py' os.mkdir(self.module_name) @@ -1224,17 +1224,17 @@ def run_pdb_module(self, script, commands): pass with open(main_file, 'w') as f: f.write(textwrap.dedent(script)) - self.addCleanup(support.rmtree, self.module_name) + self.addCleanup(os_helper.rmtree, self.module_name) return self._run_pdb(['-m', self.module_name], commands) def _assert_find_function(self, file_content, func_name, expected): - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: f.write(file_content) expected = None if not expected else ( - expected[0], support.TESTFN, expected[1]) + expected[0], os_helper.TESTFN, expected[1]) self.assertEqual( - expected, pdb.find_function(func_name, support.TESTFN)) + expected, pdb.find_function(func_name, os_helper.TESTFN)) def test_find_function_empty_file(self): self._assert_find_function(b'', 'foo', None) @@ -1284,9 +1284,9 @@ def bœr(): def test_issue7964(self): # open the file as binary so we can force \r\n newline - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: f.write(b'print("testing my pdb")\r\n') - cmd = [sys.executable, '-m', 'pdb', support.TESTFN] + cmd = [sys.executable, '-m', 'pdb', os_helper.TESTFN] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, @@ -1327,7 +1327,7 @@ def bar(): """ with open('bar.py', 'w') as f: f.write(textwrap.dedent(bar)) - self.addCleanup(support.unlink, 'bar.py') + self.addCleanup(os_helper.unlink, 'bar.py') stdout, stderr = self.run_pdb_script(script, commands) self.assertTrue( any('main.py(5)foo()->None' in l for l in stdout.splitlines()), @@ -1337,7 +1337,7 @@ def test_issue13120(self): # Invoking "continue" on a non-main thread triggered an exception # inside signal.signal. - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: f.write(textwrap.dedent(""" import threading import pdb @@ -1349,7 +1349,7 @@ def start_pdb(): t = threading.Thread(target=start_pdb) t.start()""").encode('ascii')) - cmd = [sys.executable, '-u', support.TESTFN] + cmd = [sys.executable, '-u', os_helper.TESTFN] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, @@ -1363,7 +1363,7 @@ def start_pdb(): def test_issue36250(self): - with open(support.TESTFN, 'wb') as f: + with open(os_helper.TESTFN, 'wb') as f: f.write(textwrap.dedent(""" import threading import pdb @@ -1379,7 +1379,7 @@ def start_pdb(): pdb.Pdb(readrc=False).set_trace() evt.set() t.join()""").encode('ascii')) - cmd = [sys.executable, '-u', support.TESTFN] + cmd = [sys.executable, '-u', os_helper.TESTFN] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, @@ -1412,7 +1412,7 @@ def test_readrc_kwarg(self): save_home = os.environ.pop('HOME', None) try: - with support.temp_cwd(): + with os_helper.temp_cwd(): with open('.pdbrc', 'w') as f: f.write("invalid\n") @@ -1437,7 +1437,7 @@ def test_readrc_kwarg(self): def test_readrc_homedir(self): save_home = os.environ.pop("HOME", None) - with support.temp_dir() as temp_dir, patch("os.path.expanduser"): + with os_helper.temp_dir() as temp_dir, patch("os.path.expanduser"): rc_path = os.path.join(temp_dir, ".pdbrc") os.path.expanduser.return_value = rc_path try: @@ -1506,12 +1506,12 @@ def test_run_pdb_with_pdb(self): def test_module_without_a_main(self): module_name = 't_main' - support.rmtree(module_name) + os_helper.rmtree(module_name) init_file = module_name + '/__init__.py' os.mkdir(module_name) with open(init_file, 'w') as f: pass - self.addCleanup(support.rmtree, module_name) + self.addCleanup(os_helper.rmtree, module_name) stdout, stderr = self._run_pdb(['-m', module_name], "") self.assertIn("ImportError: No module named t_main.__main__", stdout.splitlines()) @@ -1531,11 +1531,11 @@ def test_blocks_at_first_code_line(self): def test_relative_imports(self): self.module_name = 't_main' - support.rmtree(self.module_name) + os_helper.rmtree(self.module_name) main_file = self.module_name + '/__main__.py' init_file = self.module_name + '/__init__.py' module_file = self.module_name + '/module.py' - self.addCleanup(support.rmtree, self.module_name) + self.addCleanup(os_helper.rmtree, self.module_name) os.mkdir(self.module_name) with open(init_file, 'w') as f: f.write(textwrap.dedent(""" @@ -1569,11 +1569,11 @@ def test_relative_imports(self): def test_relative_imports_on_plain_module(self): # Validates running a plain module. See bpo32691 self.module_name = 't_main' - support.rmtree(self.module_name) + os_helper.rmtree(self.module_name) main_file = self.module_name + '/runme.py' init_file = self.module_name + '/__init__.py' module_file = self.module_name + '/module.py' - self.addCleanup(support.rmtree, self.module_name) + self.addCleanup(os_helper.rmtree, self.module_name) os.mkdir(self.module_name) with open(init_file, 'w') as f: f.write(textwrap.dedent(""" diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index e568cc457554957..ebb43c30b4d5052 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -8,9 +8,9 @@ import unittest import hashlib -from test import support from test.support import hashlib_helper from test.support import threading_helper +from test.support import warnings_helper try: import ssl @@ -567,7 +567,7 @@ def test_https(self): def test_https_with_cafile(self): handler = self.start_https_server(certfile=CERT_localhost) - with support.check_warnings(('', DeprecationWarning)): + with warnings_helper.check_warnings(('', DeprecationWarning)): # Good cert data = self.urlopen("https://localhost:%s/bizarre" % handler.port, cafile=CERT_localhost) @@ -585,7 +585,7 @@ def test_https_with_cafile(self): def test_https_with_cadefault(self): handler = self.start_https_server(certfile=CERT_localhost) # Self-signed cert should fail verification with system certificate store - with support.check_warnings(('', DeprecationWarning)): + with warnings_helper.check_warnings(('', DeprecationWarning)): with self.assertRaises(urllib.error.URLError) as cm: self.urlopen("https://localhost:%s/bizarre" % handler.port, cadefault=True) diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index dcc0ea89b5a85cd..04f7560ecc09c17 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -7,14 +7,20 @@ import textwrap import unittest from test import support +from test.support import import_helper +from test.support import os_helper +from test.support import warnings_helper from test.support.script_helper import assert_python_ok, assert_python_failure from test.test_warnings.data import stacklevel as warning_tests import warnings as original_warnings -py_warnings = support.import_fresh_module('warnings', blocked=['_warnings']) -c_warnings = support.import_fresh_module('warnings', fresh=['_warnings']) + +py_warnings = import_helper.import_fresh_module('warnings', + blocked=['_warnings']) +c_warnings = import_helper.import_fresh_module('warnings', + fresh=['_warnings']) Py_DEBUG = hasattr(sys, 'gettotalrefcount') @@ -440,7 +446,7 @@ def test_stacklevel(self): def test_stacklevel_import(self): # Issue #24305: With stacklevel=2, module-level warnings should work. - support.unload('test.test_warnings.data.import_warning') + import_helper.unload('test.test_warnings.data.import_warning') with warnings_state(self.module): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -543,7 +549,7 @@ class CWarnTests(WarnTests, unittest.TestCase): module = c_warnings # As an early adopter, we sanity check the - # test.support.import_fresh_module utility function + # test.import_helper.import_fresh_module utility function def test_accelerated(self): self.assertIsNot(original_warnings, self.module) self.assertFalse(hasattr(self.module.warn, '__code__')) @@ -552,7 +558,7 @@ class PyWarnTests(WarnTests, unittest.TestCase): module = py_warnings # As an early adopter, we sanity check the - # test.support.import_fresh_module utility function + # test.import_helper.import_fresh_module utility function def test_pure_python(self): self.assertIsNot(original_warnings, self.module) self.assertTrue(hasattr(self.module.warn, '__code__')) @@ -927,9 +933,9 @@ class PyWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase): module = py_warnings def test_tracemalloc(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) - with open(support.TESTFN, 'w') as fp: + with open(os_helper.TESTFN, 'w') as fp: fp.write(textwrap.dedent(""" def func(): f = open(__file__) @@ -949,8 +955,8 @@ def run(*args): return stderr # tracemalloc disabled - filename = os.path.abspath(support.TESTFN) - stderr = run('-Wd', support.TESTFN) + filename = os.path.abspath(os_helper.TESTFN) + stderr = run('-Wd', os_helper.TESTFN) expected = textwrap.dedent(f''' {filename}:5: ResourceWarning: unclosed file <...> f = None @@ -959,7 +965,7 @@ def run(*args): self.assertEqual(stderr, expected) # tracemalloc enabled - stderr = run('-Wd', '-X', 'tracemalloc=2', support.TESTFN) + stderr = run('-Wd', '-X', 'tracemalloc=2', os_helper.TESTFN) expected = textwrap.dedent(f''' {filename}:5: ResourceWarning: unclosed file <...> f = None @@ -1093,7 +1099,7 @@ def test_check_warnings(self): wmod = self.module if wmod is not sys.modules['warnings']: self.skipTest('module to test is not loaded warnings module') - with support.check_warnings(quiet=False) as w: + with warnings_helper.check_warnings(quiet=False) as w: self.assertEqual(w.warnings, []) wmod.simplefilter("always") wmod.warn("foo") @@ -1105,18 +1111,18 @@ def test_check_warnings(self): w.reset() self.assertEqual(w.warnings, []) - with support.check_warnings(): + with warnings_helper.check_warnings(): # defaults to quiet=True without argument pass - with support.check_warnings(('foo', UserWarning)): + with warnings_helper.check_warnings(('foo', UserWarning)): wmod.warn("foo") with self.assertRaises(AssertionError): - with support.check_warnings(('', RuntimeWarning)): + with warnings_helper.check_warnings(('', RuntimeWarning)): # defaults to quiet=False with argument pass with self.assertRaises(AssertionError): - with support.check_warnings(('foo', RuntimeWarning)): + with warnings_helper.check_warnings(('foo', RuntimeWarning)): wmod.warn("foo") class CCatchWarningTests(CatchWarningTests, unittest.TestCase): @@ -1198,7 +1204,7 @@ def test_default_filter_configuration(self): @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii', 'requires non-ascii filesystemencoding') def test_nonascii(self): - PYTHONWARNINGS="ignore:DeprecationWarning" + support.FS_NONASCII + PYTHONWARNINGS="ignore:DeprecationWarning" + os_helper.FS_NONASCII rc, stdout, stderr = assert_python_ok("-c", "import sys; sys.stdout.write(str(sys.warnoptions))", PYTHONIOENCODING="utf-8", @@ -1218,7 +1224,7 @@ def test_issue_8766(self): # "import encodings" emits a warning whereas the warnings is not loaded # or not completely loaded (warnings imports indirectly encodings by # importing linecache) yet - with support.temp_cwd() as cwd, support.temp_cwd('encodings'): + with os_helper.temp_cwd() as cwd, os_helper.temp_cwd('encodings'): # encodings loaded by initfsencoding() assert_python_ok('-c', 'pass', PYTHONPATH=cwd) From 39fbc13ab08211de17551df3d046a1682de4bc70 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 4 Aug 2020 23:53:12 +0800 Subject: [PATCH 108/486] bpo-40275: Use new test.support helper submodules in tests (GH-21727) --- Lib/test/test_importlib/fixtures.py | 4 ++-- .../test_importlib/import_/test_packages.py | 3 ++- .../test_importlib/source/test_file_loader.py | 2 +- Lib/test/test_importlib/source/test_finder.py | 2 +- Lib/test/test_importlib/test_abc.py | 5 +++-- Lib/test/test_importlib/test_api.py | 18 ++++++++++-------- Lib/test/test_importlib/test_pkg_import.py | 2 +- Lib/test/test_importlib/test_spec.py | 2 +- .../test_importlib/test_threaded_import.py | 6 +++--- Lib/test/test_importlib/test_windows.py | 3 ++- Lib/test/test_importlib/util.py | 11 ++++++----- Lib/test/test_inspect.py | 4 +++- Lib/test/test_site.py | 4 ++-- Lib/test/test_tools/test_fixcid.py | 15 ++++++++------- Lib/test/test_tools/test_i18n.py | 2 +- Lib/test/test_tools/test_lll.py | 3 ++- Lib/test/test_tools/test_pathfix.py | 9 +++++---- Lib/test/test_tools/test_pindent.py | 3 ++- Lib/test/test_tools/test_sundry.py | 6 +++--- 19 files changed, 58 insertions(+), 46 deletions(-) diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index 2e55d14b9aab971..985277f64615fec 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -213,11 +213,11 @@ def build_files(file_defs, prefix=pathlib.Path()): class FileBuilder: def unicode_filename(self): try: - import test.support + from test.support import os_helper except ImportError: # outside CPython, hard-code a unicode snowman return '☃' - return test.support.FS_NONASCII or \ + return os_helper.FS_NONASCII or \ self.skip("File system does not support non-ascii.") diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py index 24396044a5bcf16..c73ac63f6eef3df 100644 --- a/Lib/test/test_importlib/import_/test_packages.py +++ b/Lib/test/test_importlib/import_/test_packages.py @@ -2,6 +2,7 @@ import sys import unittest from test import support +from test.support import import_helper class ParentModuleTests: @@ -98,7 +99,7 @@ def module_injection(): try: submodule = self.__import__(subname) finally: - support.unload(subname) + import_helper.unload(subname) (Frozen_ParentTests, diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index ab44722146e37ad..cbd1533b6766442 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -17,7 +17,7 @@ import unittest import warnings -from test.support import make_legacy_pyc, unload +from test.support.import_helper import make_legacy_pyc, unload from test.test_py_compile import without_source_date_epoch from test.test_py_compile import SourceDateEpochTestMeta diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index f372b850dc7c159..e9207deedc75c88 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -9,7 +9,7 @@ import stat import sys import tempfile -from test.support import make_legacy_pyc +from test.support.import_helper import make_legacy_pyc import unittest import warnings diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 9816b35ef829a72..605738fae2e3787 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -3,6 +3,7 @@ import os import sys from test import support +from test.support import import_helper import types import unittest from unittest import mock @@ -579,8 +580,8 @@ class InspectLoaderLoadModuleTests: module_name = 'blah' def setUp(self): - support.unload(self.module_name) - self.addCleanup(support.unload, self.module_name) + import_helper.unload(self.module_name) + self.addCleanup(import_helper.unload, self.module_name) def load(self, loader): spec = self.util.spec_from_loader(self.module_name, loader) diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 0fb1346f9eec8f5..fd60634e0933398 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -7,6 +7,8 @@ import os.path import sys from test import support +from test.support import import_helper +from test.support import os_helper import types import unittest import warnings @@ -200,7 +202,7 @@ class ReloadTests: def test_reload_modules(self): for mod in ('tokenize', 'time', 'marshal'): with self.subTest(module=mod): - with support.CleanImport(mod): + with import_helper.CleanImport(mod): module = self.init.import_module(mod) self.init.reload(module) @@ -221,7 +223,7 @@ def code(): self.assertEqual(reloaded.spam, 3) def test_reload_missing_loader(self): - with support.CleanImport('types'): + with import_helper.CleanImport('types'): import types loader = types.__loader__ del types.__loader__ @@ -232,7 +234,7 @@ def test_reload_missing_loader(self): self.assertEqual(reloaded.__loader__.path, loader.path) def test_reload_loader_replaced(self): - with support.CleanImport('types'): + with import_helper.CleanImport('types'): import types types.__loader__ = None self.init.invalidate_caches() @@ -244,9 +246,9 @@ def test_reload_loader_replaced(self): def test_reload_location_changed(self): name = 'spam' - with support.temp_cwd(None) as cwd: + with os_helper.temp_cwd(None) as cwd: with test_util.uncache('spam'): - with support.DirsOnSysPath(cwd): + with import_helper.DirsOnSysPath(cwd): # Start as a plain module. self.init.invalidate_caches() path = os.path.join(cwd, name + '.py') @@ -257,7 +259,7 @@ def test_reload_location_changed(self): '__cached__': cached, '__doc__': None, } - support.create_empty_file(path) + os_helper.create_empty_file(path) module = self.init.import_module(name) ns = vars(module).copy() loader = ns.pop('__loader__') @@ -295,9 +297,9 @@ def test_reload_location_changed(self): def test_reload_namespace_changed(self): name = 'spam' - with support.temp_cwd(None) as cwd: + with os_helper.temp_cwd(None) as cwd: with test_util.uncache('spam'): - with support.DirsOnSysPath(cwd): + with import_helper.DirsOnSysPath(cwd): # Start as a namespace package. self.init.invalidate_caches() bad_path = os.path.join(cwd, name, '__init.py') diff --git a/Lib/test/test_importlib/test_pkg_import.py b/Lib/test/test_importlib/test_pkg_import.py index 6181dcfab280cf5..36e78afa10bfc43 100644 --- a/Lib/test/test_importlib/test_pkg_import.py +++ b/Lib/test/test_importlib/test_pkg_import.py @@ -7,7 +7,7 @@ import unittest from importlib.util import cache_from_source -from test.support import create_empty_file +from test.support.os_helper import create_empty_file class TestImport(unittest.TestCase): diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py index 20dacec8664e1de..eed90f29f9286c9 100644 --- a/Lib/test/test_importlib/test_spec.py +++ b/Lib/test/test_importlib/test_spec.py @@ -6,7 +6,7 @@ import os.path import pathlib -from test.support import CleanImport +from test.support.import_helper import CleanImport import unittest import sys import warnings diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index 06da18ed396d983..c6a6e1715abadea 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -14,9 +14,9 @@ import threading import unittest from unittest import mock -from test.support import ( - verbose, run_unittest, TESTFN, - forget, unlink, rmtree) +from test.support import (verbose, run_unittest) +from test.support.import_helper import forget +from test.support.os_helper import (TESTFN, unlink, rmtree) from test.support import threading_helper def task(N, done, done_tasks, errors): diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py index 005b685cc03cd92..8b3f2009a850da9 100644 --- a/Lib/test/test_importlib/test_windows.py +++ b/Lib/test/test_importlib/test_windows.py @@ -6,11 +6,12 @@ import sys import unittest from test import support +from test.support import import_helper from distutils.util import get_platform from contextlib import contextmanager from .util import temp_module -support.import_module('winreg', required_on=['win']) +import_helper.import_module('winreg', required_on=['win']) from winreg import ( CreateKey, HKEY_CURRENT_USER, SetValue, REG_SZ, KEY_ALL_ACCESS, diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index 2745c9b7e3c3bf4..5c0375e04a6ffb5 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -13,6 +13,7 @@ from pathlib import Path, PurePath from test import support from test.support import import_helper +from test.support import os_helper import unittest import sys import tempfile @@ -159,9 +160,9 @@ def uncache(*names): @contextlib.contextmanager def temp_module(name, content='', *, pkg=False): conflicts = [n for n in sys.modules if n.partition('.')[0] == name] - with support.temp_cwd(None) as cwd: + with os_helper.temp_cwd(None) as cwd: with uncache(name, *conflicts): - with support.DirsOnSysPath(cwd): + with import_helper.DirsOnSysPath(cwd): invalidate_caches() location = os.path.join(cwd, name) @@ -397,7 +398,7 @@ def create_modules(*names): state_manager.__exit__(None, None, None) if uncache_manager is not None: uncache_manager.__exit__(None, None, None) - support.rmtree(temp_dir) + os_helper.rmtree(temp_dir) def mock_path_hook(*entries, importer): @@ -573,8 +574,8 @@ def tearDownClass(cls): pass def setUp(self): - modules = support.modules_setup() - self.addCleanup(support.modules_cleanup, *modules) + modules = import_helper.modules_setup() + self.addCleanup(import_helper.modules_cleanup, *modules) class ZipSetup(ZipSetupBase): diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index e3e2be52076c6aa..6667dc91edbcec6 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -24,8 +24,10 @@ except ImportError: ThreadPoolExecutor = None -from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only +from test.support import run_unittest, cpython_only from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ +from test.support.import_helper import DirsOnSysPath +from test.support.os_helper import TESTFN from test.support.script_helper import assert_python_ok, assert_python_failure from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index ec86c645981b36e..5901939725e1853 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -8,8 +8,8 @@ import test.support from test import support from test.support import socket_helper -from test.support import (captured_stderr, TESTFN, EnvironmentVarGuard, - change_cwd) +from test.support import captured_stderr +from test.support.os_helper import TESTFN, EnvironmentVarGuard, change_cwd import builtins import encodings import glob diff --git a/Lib/test/test_tools/test_fixcid.py b/Lib/test/test_tools/test_fixcid.py index bce029b1aac83ae..3df13680437194f 100644 --- a/Lib/test/test_tools/test_fixcid.py +++ b/Lib/test/test_tools/test_fixcid.py @@ -5,6 +5,7 @@ import runpy import sys from test import support +from test.support import os_helper from test.test_tools import skip_if_missing, scriptsdir import unittest @@ -57,15 +58,15 @@ def test_alter_comments(self): ) def test_directory(self): - os.mkdir(support.TESTFN) - self.addCleanup(support.rmtree, support.TESTFN) - c_filename = os.path.join(support.TESTFN, "file.c") + os.mkdir(os_helper.TESTFN) + self.addCleanup(os_helper.rmtree, os_helper.TESTFN) + c_filename = os.path.join(os_helper.TESTFN, "file.c") with open(c_filename, "w") as file: file.write("int xx;\n") - with open(os.path.join(support.TESTFN, "file.py"), "w") as file: + with open(os.path.join(os_helper.TESTFN, "file.py"), "w") as file: file.write("xx = 'unaltered'\n") script = os.path.join(scriptsdir, "fixcid.py") - output = self.run_script(args=(support.TESTFN,)) + output = self.run_script(args=(os_helper.TESTFN,)) self.assertMultiLineEqual(output, "{}:\n" "1\n" @@ -74,10 +75,10 @@ def test_directory(self): ) def run_script(self, input="", *, args=("-",), substfile="xx yy\n"): - substfilename = support.TESTFN + ".subst" + substfilename = os_helper.TESTFN + ".subst" with open(substfilename, "w") as file: file.write(substfile) - self.addCleanup(support.unlink, substfilename) + self.addCleanup(os_helper.unlink, substfilename) argv = ["fixcid.py", "-s", substfilename] + list(args) script = os.path.join(scriptsdir, "fixcid.py") diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 42e20f8f7716dbe..8da657907eab872 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -7,7 +7,7 @@ from test.support.script_helper import assert_python_ok from test.test_tools import skip_if_missing, toolsdir -from test.support import temp_cwd, temp_dir +from test.support.os_helper import temp_cwd, temp_dir skip_if_missing() diff --git a/Lib/test/test_tools/test_lll.py b/Lib/test/test_tools/test_lll.py index 568cbfb5e474608..ec0c97334fdebdd 100644 --- a/Lib/test/test_tools/test_lll.py +++ b/Lib/test/test_tools/test_lll.py @@ -3,6 +3,7 @@ import os import tempfile from test import support +from test.support import os_helper from test.test_tools import skip_if_missing, import_tool import unittest @@ -14,7 +15,7 @@ class lllTests(unittest.TestCase): def setUp(self): self.lll = import_tool('lll') - @support.skip_unless_symlink + @os_helper.skip_unless_symlink def test_lll_multiple_dirs(self): with tempfile.TemporaryDirectory() as dir1, \ tempfile.TemporaryDirectory() as dir2: diff --git a/Lib/test/test_tools/test_pathfix.py b/Lib/test/test_tools/test_pathfix.py index 03ed29d3f974f23..ff61935298b920b 100644 --- a/Lib/test/test_tools/test_pathfix.py +++ b/Lib/test/test_tools/test_pathfix.py @@ -3,6 +3,7 @@ import sys import unittest from test import support +from test.support import os_helper from test.test_tools import scriptsdir, skip_if_missing @@ -14,7 +15,7 @@ class TestPathfixFunctional(unittest.TestCase): script = os.path.join(scriptsdir, 'pathfix.py') def setUp(self): - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', directory=''): @@ -24,7 +25,7 @@ def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', filename = os.path.join(directory, 'script-A_1.py') pathfix_arg = directory else: - filename = support.TESTFN + filename = os_helper.TESTFN pathfix_arg = filename with open(filename, 'w', encoding='utf8') as f: @@ -56,8 +57,8 @@ def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', return new_shebang def test_recursive(self): - tmpdir = support.TESTFN + '.d' - self.addCleanup(support.rmtree, tmpdir) + tmpdir = os_helper.TESTFN + '.d' + self.addCleanup(os_helper.rmtree, tmpdir) os.mkdir(tmpdir) expected_stderr = f"recursedown('{os.path.basename(tmpdir)}')\n" self.assertEqual( diff --git a/Lib/test/test_tools/test_pindent.py b/Lib/test/test_tools/test_pindent.py index e293bc872ce51e6..e7a547ad7d61277 100644 --- a/Lib/test/test_tools/test_pindent.py +++ b/Lib/test/test_tools/test_pindent.py @@ -6,6 +6,7 @@ import subprocess import textwrap from test import support +from test.support import os_helper from test.support.script_helper import assert_python_ok from test.test_tools import scriptsdir, skip_if_missing @@ -34,7 +35,7 @@ def lstriplines(self, data): def test_selftest(self): self.maxDiff = None - with support.temp_dir() as directory: + with os_helper.temp_dir() as directory: data_path = os.path.join(directory, '_test.py') with open(self.script) as f: closed = f.read() diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py index 10eb6941b3be6f8..8b5a963e25bd151 100644 --- a/Lib/test/test_tools/test_sundry.py +++ b/Lib/test/test_tools/test_sundry.py @@ -8,7 +8,7 @@ import os import sys import unittest -from test import support +from test.support import import_helper from test.test_tools import scriptsdir, import_tool, skip_if_missing @@ -30,7 +30,7 @@ class TestSundryScripts(unittest.TestCase): skiplist = blacklist + whitelist + windows_only + other def test_sundry(self): - old_modules = support.modules_setup() + old_modules = import_helper.modules_setup() try: for fn in os.listdir(scriptsdir): if not fn.endswith('.py'): @@ -43,7 +43,7 @@ def test_sundry(self): import_tool(name) finally: # Unload all modules loaded in this test - support.modules_cleanup(*old_modules) + import_helper.modules_cleanup(*old_modules) @unittest.skipIf(sys.platform != "win32", "Windows-only test") def test_sundry_windows(self): From b47b85baf46bd7818aa99f32342d8cba725a403e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 4 Aug 2020 17:30:11 +0100 Subject: [PATCH 109/486] bpo-41463: Generate information about jumps from 'opcode.py' rather than duplicating it in 'compile.c' (GH-21714) Generate information about jumps from 'opcode.py' rather than duplicate it in 'compile.c' --- Include/opcode.h | 22 +++++ Python/compile.c | 132 ++++++++++++++++------------- Tools/scripts/generate_opcode_h.py | 19 +++++ 3 files changed, 114 insertions(+), 59 deletions(-) diff --git a/Include/opcode.h b/Include/opcode.h index 19944fac0b9f2b3..420c87aa0f24f3e 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -127,6 +127,28 @@ extern "C" { #define SET_UPDATE 163 #define DICT_MERGE 164 #define DICT_UPDATE 165 +#ifdef NEED_OPCODE_JUMP_TABLES +static uint32_t _PyOpcode_RelativeJump[8] = { + 0U, + 0U, + 536870912U, + 67125248U, + 67141632U, + 0U, + 0U, + 0U, +}; +static uint32_t _PyOpcode_Jump[8] = { + 0U, + 0U, + 536870912U, + 101695488U, + 67141632U, + 0U, + 0U, + 0U, +}; +#endif /* OPCODE_TABLES */ /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here diff --git a/Python/compile.c b/Python/compile.c index 42b09fd96dfbb96..5dbd9f221fdf143 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -27,6 +27,7 @@ #include "ast.h" #include "code.h" #include "symtable.h" +#define NEED_OPCODE_JUMP_TABLES #include "opcode.h" #include "wordcode_helpers.h" @@ -45,14 +46,38 @@ && (c->u->u_ste->ste_type == ModuleBlock)) struct instr { - unsigned i_jabs : 1; - unsigned i_jrel : 1; unsigned char i_opcode; int i_oparg; struct basicblock_ *i_target; /* target block (if jump instruction) */ int i_lineno; }; +#define LOG_BITS_PER_INT 5 +#define MASK_LOW_LOG_BITS 31 + +static inline int +is_bit_set_in_table(uint32_t *table, int bitindex) { + /* Is the relevant bit set in the relevant word? */ + /* 256 bits fit into 8 32-bits words. + * Word is indexed by (bitindex>>ln(size of int in bits)). + * Bit within word is the low bits of bitindex. + */ + uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; + return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; +} + +static inline int +is_relative_jump(struct instr *i) +{ + return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode); +} + +static inline int +is_jump(struct instr *i) +{ + return is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); +} + typedef struct basicblock_ { /* Each basicblock in a compilation unit is linked via b_list in the reverse order that the block are allocated. b_list points to the next @@ -182,7 +207,7 @@ static basicblock *compiler_new_block(struct compiler *); static int compiler_next_instr(basicblock *); static int compiler_addop(struct compiler *, int); static int compiler_addop_i(struct compiler *, int, Py_ssize_t); -static int compiler_addop_j(struct compiler *, int, basicblock *, int); +static int compiler_addop_j(struct compiler *, int, basicblock *); static int compiler_error(struct compiler *, const char *); static int compiler_warn(struct compiler *, const char *, ...); static int compiler_nameop(struct compiler *, identifier, expr_context_ty); @@ -1381,7 +1406,7 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) } static int -compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) +compiler_addop_j(struct compiler *c, int opcode, basicblock *b) { struct instr *i; int off; @@ -1398,10 +1423,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_target = b; - if (absolute) - i->i_jabs = 1; - else - i->i_jrel = 1; i->i_lineno = c->u->u_lineno; return 1; } @@ -1471,17 +1492,11 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 0; \ } -#define ADDOP_JABS(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O), 1)) \ +#define ADDOP_JUMP(C, OP, O) { \ + if (!compiler_addop_j((C), (OP), (O))) \ return 0; \ } -#define ADDOP_JREL(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O), 0)) \ - return 0; \ -} - - #define ADDOP_COMPARE(C, CMP) { \ if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ return 0; \ @@ -2545,7 +2560,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) return 0; if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); compiler_use_next_block(c, next2); if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) return 0; @@ -2568,20 +2583,20 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JABS(c, POP_JUMP_IF_FALSE, cleanup); + ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup); NEXT_BLOCK(c); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); compiler_use_next_block(c, cleanup); ADDOP(c, POP_TOP); if (!cond) { - ADDOP_JREL(c, JUMP_FORWARD, next); + ADDOP_JUMP(c, JUMP_FORWARD, next); } compiler_use_next_block(c, end); return 1; @@ -2596,7 +2611,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* general implementation */ VISIT(c, expr, e); - ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); return 1; } @@ -2615,7 +2630,7 @@ compiler_ifexp(struct compiler *c, expr_ty e) if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) return 0; VISIT(c, expr, e->v.IfExp.body); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); compiler_use_next_block(c, next); VISIT(c, expr, e->v.IfExp.orelse); compiler_use_next_block(c, end); @@ -2721,7 +2736,7 @@ compiler_if(struct compiler *c, stmt_ty s) } VISIT_SEQ(c, stmt, s->v.If.body); if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); compiler_use_next_block(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } @@ -2747,10 +2762,10 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); compiler_use_next_block(c, start); - ADDOP_JREL(c, FOR_ITER, cleanup); + ADDOP_JUMP(c, FOR_ITER, cleanup); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, cleanup); compiler_pop_fblock(c, FOR_LOOP, start); @@ -2786,7 +2801,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) return 0; } /* SETUP_FINALLY to guard the __anext__ call */ - ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); @@ -2795,7 +2810,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_pop_fblock(c, FOR_LOOP, start); @@ -2859,7 +2874,7 @@ compiler_while(struct compiler *c, stmt_ty s) return 0; } VISIT_SEQ(c, stmt, s->v.While.body); - ADDOP_JABS(c, JUMP_ABSOLUTE, loop); + ADDOP_JUMP(c, JUMP_ABSOLUTE, loop); /* XXX should the two POP instructions be in a separate block if there is no else clause ? @@ -2918,7 +2933,7 @@ compiler_break(struct compiler *c) if (!compiler_unwind_fblock(c, loop, 0)) { return 0; } - ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_exit); + ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_exit); return 1; } @@ -2932,7 +2947,7 @@ compiler_continue(struct compiler *c) if (loop == NULL) { return compiler_error(c, "'continue' not properly in loop"); } - ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_block); + ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_block); return 1; } @@ -2978,7 +2993,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) return 0; /* `try` block */ - ADDOP_JREL(c, SETUP_FINALLY, end); + ADDOP_JUMP(c, SETUP_FINALLY, end); compiler_use_next_block(c, body); if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) return 0; @@ -2992,7 +3007,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JREL(c, JUMP_FORWARD, exit); + ADDOP_JUMP(c, JUMP_FORWARD, exit); /* `finally` block */ compiler_use_next_block(c, end); if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) @@ -3046,14 +3061,14 @@ compiler_try_except(struct compiler *c, stmt_ty s) end = compiler_new_block(c); if (body == NULL || except == NULL || orelse == NULL || end == NULL) return 0; - ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, EXCEPT, body); - ADDOP_JREL(c, JUMP_FORWARD, orelse); + ADDOP_JUMP(c, JUMP_FORWARD, orelse); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); for (i = 0; i < n; i++) { @@ -3068,7 +3083,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) if (handler->v.ExceptHandler.type) { ADDOP(c, DUP_TOP); VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP_JABS(c, JUMP_IF_NOT_EXC_MATCH, except); + ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except); } ADDOP(c, POP_TOP); if (handler->v.ExceptHandler.name) { @@ -3095,7 +3110,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) */ /* second try: */ - ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); + ADDOP_JUMP(c, SETUP_FINALLY, cleanup_end); compiler_use_next_block(c, cleanup_body); if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) return 0; @@ -3109,7 +3124,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); /* except: */ compiler_use_next_block(c, cleanup_end); @@ -3136,7 +3151,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); ADDOP(c, POP_EXCEPT); - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); } compiler_use_next_block(c, except); } @@ -3645,7 +3660,7 @@ compiler_boolop(struct compiler *c, expr_ty e) assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); - ADDOP_JABS(c, jumpi, end); + ADDOP_JUMP(c, jumpi, end); basicblock *next = compiler_new_block(c); if (next == NULL) { return 0; @@ -3933,7 +3948,7 @@ compiler_compare(struct compiler *c, expr_ty e) ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup); + ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup); NEXT_BLOCK(c); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); @@ -3941,7 +3956,7 @@ compiler_compare(struct compiler *c, expr_ty e) basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JREL(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP_FORWARD, end); compiler_use_next_block(c, cleanup); ADDOP(c, ROT_TWO); ADDOP(c, POP_TOP); @@ -4435,7 +4450,7 @@ compiler_sync_comprehension_generator(struct compiler *c, if (start) { depth++; compiler_use_next_block(c, start); - ADDOP_JREL(c, FOR_ITER, anchor); + ADDOP_JUMP(c, FOR_ITER, anchor); NEXT_BLOCK(c); } VISIT(c, expr, gen->target); @@ -4487,7 +4502,7 @@ compiler_sync_comprehension_generator(struct compiler *c, } compiler_use_next_block(c, if_cleanup); if (start) { - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, anchor); } @@ -4526,7 +4541,7 @@ compiler_async_comprehension_generator(struct compiler *c, compiler_use_next_block(c, start); - ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP_JUMP(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); @@ -4577,7 +4592,7 @@ compiler_async_comprehension_generator(struct compiler *c, } } compiler_use_next_block(c, if_cleanup); - ADDOP_JABS(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, except); ADDOP(c, END_ASYNC_FOR); @@ -4773,7 +4788,7 @@ compiler_with_except_finish(struct compiler *c) { exit = compiler_new_block(c); if (exit == NULL) return 0; - ADDOP_JABS(c, POP_JUMP_IF_TRUE, exit); + ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit); ADDOP(c, RERAISE); compiler_use_next_block(c, exit); ADDOP(c, POP_TOP); @@ -4835,7 +4850,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); - ADDOP_JREL(c, SETUP_ASYNC_WITH, final); + ADDOP_JUMP(c, SETUP_ASYNC_WITH, final); /* SETUP_ASYNC_WITH pushes a finally block. */ compiler_use_next_block(c, block); @@ -4873,7 +4888,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP(c, POP_TOP); - ADDOP_JABS(c, JUMP_ABSOLUTE, exit); + ADDOP_JUMP(c, JUMP_ABSOLUTE, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); @@ -4927,7 +4942,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); /* Will push bound __exit__ */ - ADDOP_JREL(c, SETUP_WITH, final); + ADDOP_JUMP(c, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ compiler_use_next_block(c, block); @@ -4961,7 +4976,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) if (!compiler_call_exit_with_nones(c)) return 0; ADDOP(c, POP_TOP); - ADDOP_JREL(c, JUMP_FORWARD, exit); + ADDOP_JUMP(c, JUMP_FORWARD, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); @@ -5492,7 +5507,7 @@ stackdepth(struct compiler *c) maxdepth = new_depth; } assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (instr->i_jrel || instr->i_jabs) { + if (is_jump(instr)) { effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); assert(effect != PY_INVALID_STACK_EFFECT); int target_depth = depth + effect; @@ -5730,9 +5745,9 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) the jump instruction. */ bsize += isize; - if (instr->i_jabs || instr->i_jrel) { + if (is_jump(instr)) { instr->i_oparg = instr->i_target->b_offset; - if (instr->i_jrel) { + if (is_relative_jump(instr)) { instr->i_oparg -= bsize; } instr->i_oparg *= sizeof(_Py_CODEUNIT); @@ -5946,8 +5961,8 @@ makecode(struct compiler *c, struct assembler *a, PyObject *consts) static void dump_instr(const struct instr *i) { - const char *jrel = i->i_jrel ? "jrel " : ""; - const char *jabs = i->i_jabs ? "jabs " : ""; + const char *jrel = (is_relative_jump(instr)) ? "jrel " : ""; + const char *jabs = (is_jump(instr) && !is_relative_jump(instr))? "jabs " : ""; char arg[128]; *arg = '\0'; @@ -6122,7 +6137,7 @@ optimize_basic_block(basicblock *bb, PyObject *consts) struct instr *inst = &bb->b_instr[i]; int oparg = inst->i_oparg; int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; - if (inst->i_jabs || inst->i_jrel) { + if (is_jump(inst)) { /* Skip over empty basic blocks. */ while (inst->i_target->b_iused == 0) { inst->i_target = inst->i_target->b_next; @@ -6148,7 +6163,6 @@ optimize_basic_block(basicblock *bb, PyObject *consts) if (is_true == 1) { inst->i_opcode = NOP; bb->b_instr[i+1].i_opcode = NOP; - bb->b_instr[i+1].i_jabs = 0; } break; @@ -6318,7 +6332,7 @@ mark_reachable(struct assembler *a) { } for (int i = 0; i < b->b_iused; i++) { basicblock *target; - if (b->b_instr[i].i_jrel || b->b_instr[i].i_jabs) { + if (is_jump(&b->b_instr[i])) { target = b->b_instr[i].i_target; if (target->b_reachable == 0) { target->b_reachable = 1; diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py index 873f82156e217bf..cba13b24213906f 100644 --- a/Tools/scripts/generate_opcode_h.py +++ b/Tools/scripts/generate_opcode_h.py @@ -30,6 +30,18 @@ #endif /* !Py_OPCODE_H */ """ +UINT32_MASK = (1<<32)-1 + +def write_int_array_from_ops(name, ops, out): + bits = 0 + for op in ops: + bits |= 1<>= 32 + assert bits == 0 + out.write(f"}};\n") def main(opcode_py, outfile='Include/opcode.h'): opcode = {} @@ -41,6 +53,8 @@ def main(opcode_py, outfile='Include/opcode.h'): code = fp.read() exec(code, opcode) opmap = opcode['opmap'] + hasjrel = opcode['hasjrel'] + hasjabs = opcode['hasjabs'] with open(outfile, 'w') as fobj: fobj.write(header) for name in opcode['opname']: @@ -49,8 +63,13 @@ def main(opcode_py, outfile='Include/opcode.h'): if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT fobj.write("#define %-23s %3d\n" % ('HAVE_ARGUMENT', opcode['HAVE_ARGUMENT'])) + fobj.write("#ifdef NEED_OPCODE_JUMP_TABLES\n") + write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj) + write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj) + fobj.write("#endif /* OPCODE_TABLES */\n") fobj.write(footer) + print("%s regenerated from %s" % (outfile, opcode_py)) From e94fee12714a5a5321133b3fc27523d214113228 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Wed, 5 Aug 2020 10:48:51 +0900 Subject: [PATCH 110/486] bpo-36346: Doc: Update removal schedule of legacy Unicode (GH-21479) See PEP 623 for detail. --- Doc/c-api/unicode.rst | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 0748a1e319489d1..f3f0c4c6c2b9b84 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -34,6 +34,11 @@ can internally be in two states depending on how they were created: :c:type:`Py_UNICODE*` representation; you will have to call :c:func:`PyUnicode_READY` on them before calling any other API. +.. note:: + The "legacy" Unicode object will be removed in Python 3.12 with deprecated + APIs. All Unicode objects will be "canonical" since then. See :pep:`623` + for more information. + Unicode Type """""""""""" @@ -107,6 +112,9 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 + .. deprecated-removed:: 3.10 3.12 + This API will be removed with :c:func:`PyUnicode_FromUnicode`. + .. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *o) @@ -138,6 +146,9 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 + .. deprecated-removed:: 3.10 3.12 + ``PyUnicode_WCHAR_KIND`` is deprecated. + .. c:function:: int PyUnicode_KIND(PyObject *o) @@ -203,7 +214,7 @@ access internal read-only data of Unicode objects: code units (this includes surrogate pairs as 2 units). *o* has to be a Unicode object (not checked). - .. deprecated-removed:: 3.3 4.0 + .. deprecated-removed:: 3.3 3.12 Part of the old-style Unicode API, please migrate to using :c:func:`PyUnicode_GET_LENGTH`. @@ -213,7 +224,7 @@ access internal read-only data of Unicode objects: Return the size of the deprecated :c:type:`Py_UNICODE` representation in bytes. *o* has to be a Unicode object (not checked). - .. deprecated-removed:: 3.3 4.0 + .. deprecated-removed:: 3.3 3.12 Part of the old-style Unicode API, please migrate to using :c:func:`PyUnicode_GET_LENGTH`. @@ -235,7 +246,7 @@ access internal read-only data of Unicode objects: code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use :c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`. - .. deprecated-removed:: 3.3 4.0 + .. deprecated-removed:: 3.3 3.12 Part of the old-style Unicode API, please migrate to using the :c:func:`PyUnicode_nBYTE_DATA` family of macros. @@ -687,8 +698,10 @@ Extension modules can continue using them, as they will not be removed in Python string content has been filled before using any of the access macros such as :c:func:`PyUnicode_KIND`. - Please migrate to using :c:func:`PyUnicode_FromKindAndData`, - :c:func:`PyUnicode_FromWideChar` or :c:func:`PyUnicode_New`. + .. deprecated-removed:: 3.3 3.12 + Part of the old-style Unicode API, please migrate to using + :c:func:`PyUnicode_FromKindAndData`, :c:func:`PyUnicode_FromWideChar`, or + :c:func:`PyUnicode_New`. .. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) @@ -701,9 +714,10 @@ Extension modules can continue using them, as they will not be removed in Python embedded null code points, which would cause the string to be truncated when used in most C functions. - Please migrate to using :c:func:`PyUnicode_AsUCS4`, - :c:func:`PyUnicode_AsWideChar`, :c:func:`PyUnicode_ReadChar` or similar new - APIs. + .. deprecated-removed:: 3.3 3.12 + Part of the old-style Unicode API, please migrate to using + :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, + :c:func:`PyUnicode_ReadChar` or similar new APIs. .. c:function:: PyObject* PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, Py_ssize_t size) @@ -723,13 +737,20 @@ Extension modules can continue using them, as they will not be removed in Python .. versionadded:: 3.3 + .. deprecated-removed:: 3.3 3.12 + Part of the old-style Unicode API, please migrate to using + :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, + :c:func:`PyUnicode_ReadChar` or similar new APIs. + .. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) Return the size of the deprecated :c:type:`Py_UNICODE` representation, in code units (this includes surrogate pairs as 2 units). - Please migrate to using :c:func:`PyUnicode_GetLength`. + .. deprecated-removed:: 3.3 3.12 + Part of the old-style Unicode API, please migrate to using + :c:func:`PyUnicode_GET_LENGTH`. .. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj) From 2e0f5edeeb351488ef228f5152253b69f5aca710 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 5 Aug 2020 16:32:32 +0300 Subject: [PATCH 111/486] bpo-40726: handle uninitalized end_lineno on ast.increment_lineno (GH-20312) --- Lib/ast.py | 13 ++++++++++--- Lib/test/test_ast.py | 11 +++++++++++ .../2020-05-22-12-45-58.bpo-40726.7oBdMw.rst | 2 ++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst diff --git a/Lib/ast.py b/Lib/ast.py index 6a5b39e270b9b52..65ebd0100de0074 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -180,7 +180,11 @@ def copy_location(new_node, old_node): for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset': if attr in old_node._attributes and attr in new_node._attributes: value = getattr(old_node, attr, None) - if value is not None: + # end_lineno and end_col_offset are optional attributes, and they + # should be copied whether the value is None or not. + if value is not None or ( + hasattr(old_node, attr) and attr.startswith("end_") + ): setattr(new_node, attr, value) return new_node @@ -229,8 +233,11 @@ def increment_lineno(node, n=1): for child in walk(node): if 'lineno' in child._attributes: child.lineno = getattr(child, 'lineno', 0) + n - if 'end_lineno' in child._attributes: - child.end_lineno = getattr(child, 'end_lineno', 0) + n + if ( + "end_lineno" in child._attributes + and (end_lineno := getattr(child, "end_lineno", 0)) is not None + ): + child.end_lineno = end_lineno + n return node diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 78e4a5653d4efdf..f5aef61ec6f7c03 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -812,6 +812,12 @@ def test_copy_location(self): 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, ' 'col_offset=0, end_lineno=1, end_col_offset=5))' ) + src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1) + new = ast.copy_location(src, ast.Call(col_offset=None, lineno=None)) + self.assertIsNone(new.end_lineno) + self.assertIsNone(new.end_col_offset) + self.assertEqual(new.lineno, 1) + self.assertEqual(new.col_offset, 1) def test_fix_missing_locations(self): src = ast.parse('write("spam")') @@ -851,6 +857,11 @@ def test_increment_lineno(self): 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, ' 'col_offset=0, end_lineno=4, end_col_offset=5))' ) + src = ast.Call( + func=ast.Name("test", ast.Load()), args=[], keywords=[], lineno=1 + ) + self.assertEqual(ast.increment_lineno(src).lineno, 2) + self.assertIsNone(ast.increment_lineno(src).end_lineno) def test_iter_fields(self): node = ast.parse('foo()', mode='eval') diff --git a/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst b/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst new file mode 100644 index 000000000000000..7409eb3d80df644 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst @@ -0,0 +1,2 @@ +Handle cases where the ``end_lineno`` is ``None`` on +:func:`ast.increment_lineno`. From 20fef0d5232796022eaf588dac8263f8613046af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Aug 2020 16:23:10 +0200 Subject: [PATCH 112/486] bpo-40989: Fix compiler warning in winreg.c (GH-21722) Explicitly cast PyHKEYObject* to PyObject* to call _PyObject_Init(). --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index a24d784c773c027..78c08693a8ace35 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -463,7 +463,7 @@ PyHKEY_FromHKEY(HKEY h) if (op == NULL) { return PyErr_NoMemory(); } - _PyObject_Init(op, &PyHKEY_Type); + _PyObject_Init((PyObject*)op, &PyHKEY_Type); op->hkey = h; return (PyObject *)op; } From 39bc6912c7603c57556469bfab47b0493b0edb0f Mon Sep 17 00:00:00 2001 From: "Eric L. Frederich" Date: Wed, 5 Aug 2020 14:44:53 -0400 Subject: [PATCH 113/486] bpo-41482: Fix error in ipaddress.IPv4Network docstring (GH-21736) --- Lib/ipaddress.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 75b4c352c1d257a..bc662c415b2a49f 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1466,7 +1466,7 @@ def __init__(self, address, strict=True): address: A string or integer representing the IP [& network]. '192.0.2.0/24' '192.0.2.0/255.255.255.0' - '192.0.0.2/0.0.0.255' + '192.0.2.0/0.0.0.255' are all functionally the same in IPv4. Similarly, '192.0.2.1' '192.0.2.1/255.255.255.255' From 7424e5de810f6386046f9df7da199bddefc1363f Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Thu, 6 Aug 2020 19:51:29 +0800 Subject: [PATCH 114/486] bpo-40275: Use new test.support helper submodules in tests (GH-21743) --- Lib/test/test_dbm_gnu.py | 2 +- Lib/test/test_faulthandler.py | 3 ++- Lib/test/test_grp.py | 5 +++-- Lib/test/test_http_cookiejar.py | 18 ++++++++++-------- Lib/test/test_httpservers.py | 4 ++-- Lib/test/test_import/__init__.py | 3 +-- Lib/test/test_ntpath.py | 6 +++--- Lib/test/test_site.py | 3 ++- Lib/test/test_socketserver.py | 9 +++++---- Lib/test/test_statistics.py | 8 +++++--- Lib/test/test_tabnanny.py | 3 ++- Lib/test/test_tcl.py | 15 ++++++++------- Lib/test/test_tools/test_md5sum.py | 8 ++++---- Lib/test/test_turtle.py | 7 ++++--- Lib/test/test_urllib2net.py | 3 ++- Lib/test/test_urllibnet.py | 7 ++++--- Lib/test/test_webbrowser.py | 7 ++++--- Lib/test/test_winsound.py | 4 +++- Lib/tkinter/test/test_tkinter/test_images.py | 11 ++++++----- Lib/tkinter/test/test_tkinter/test_loadtk.py | 3 ++- 20 files changed, 73 insertions(+), 56 deletions(-) diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 078bf0e9b927016..017d0ffa658bd62 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -3,7 +3,7 @@ gdbm = import_helper.import_module("dbm.gnu") #skip if not supported import unittest import os -from test.support import TESTFN, TESTFN_NONASCII, unlink +from test.support.os_helper import TESTFN, TESTFN_NONASCII, unlink filename = TESTFN diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index c64afe88c25d6c0..80c1f7d90adf0fd 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -7,6 +7,7 @@ import sys import sysconfig from test import support +from test.support import os_helper from test.support import script_helper, is_android import tempfile import unittest @@ -51,7 +52,7 @@ def temporary_filename(): try: yield filename finally: - support.unlink(filename) + os_helper.unlink(filename) class FaultHandlerTests(unittest.TestCase): def get_output(self, code, filename=None, fd=None): diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index 0993f091f59560d..c7ec03ec0e43884 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -1,9 +1,10 @@ """Test script for the grp module.""" import unittest -from test import support +from test.support import import_helper -grp = support.import_module('grp') + +grp = import_helper.import_module('grp') class GroupDatabaseTestCase(unittest.TestCase): diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 2d7077af6da39e5..99d038fa15c1e35 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -3,6 +3,8 @@ import os import re import test.support +from test.support import os_helper +from test.support import warnings_helper import time import unittest import urllib.request @@ -328,12 +330,12 @@ def _interact(cookiejar, url, set_cookie_hdrs, hdr_name): class FileCookieJarTests(unittest.TestCase): def test_constructor_with_str(self): - filename = test.support.TESTFN + filename = os_helper.TESTFN c = LWPCookieJar(filename) self.assertEqual(c.filename, filename) def test_constructor_with_path_like(self): - filename = pathlib.Path(test.support.TESTFN) + filename = pathlib.Path(os_helper.TESTFN) c = LWPCookieJar(filename) self.assertEqual(c.filename, os.fspath(filename)) @@ -353,7 +355,7 @@ class A: def test_lwp_valueless_cookie(self): # cookies with no value should be saved and loaded consistently - filename = test.support.TESTFN + filename = os_helper.TESTFN c = LWPCookieJar() interact_netscape(c, "http://www.acme.com/", 'boo') self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None) @@ -368,7 +370,7 @@ def test_lwp_valueless_cookie(self): def test_bad_magic(self): # OSErrors (eg. file doesn't exist) are allowed to propagate - filename = test.support.TESTFN + filename = os_helper.TESTFN for cookiejar_class in LWPCookieJar, MozillaCookieJar: c = cookiejar_class() try: @@ -475,7 +477,7 @@ def test_domain_return_ok(self): def test_missing_value(self): # missing = sign in Cookie: header is regarded by Mozilla as a missing # name, and by http.cookiejar as a missing value - filename = test.support.TESTFN + filename = os_helper.TESTFN c = MozillaCookieJar(filename) interact_netscape(c, "http://www.acme.com/", 'eggs') interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/') @@ -599,7 +601,7 @@ def test_expires(self): c = CookieJar() future = time2netscape(time.time()+3600) - with test.support.check_no_warnings(self): + with warnings_helper.check_no_warnings(self): headers = [f"Set-Cookie: FOO=BAR; path=/; expires={future}"] req = urllib.request.Request("http://www.coyote.com/") res = FakeResponse(headers, "http://www.coyote.com/") @@ -1713,7 +1715,7 @@ def test_rejection(self): self.assertEqual(len(c), 6) # save and restore - filename = test.support.TESTFN + filename = os_helper.TESTFN try: c.save(filename, ignore_discard=True) @@ -1753,7 +1755,7 @@ def test_mozilla(self): # Save / load Mozilla/Netscape cookie file format. year_plus_one = time.localtime()[0] + 1 - filename = test.support.TESTFN + filename = os_helper.TESTFN c = MozillaCookieJar(filename, policy=DefaultCookiePolicy(rfc2965=True)) diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 0c871afca37bdc0..a7e1719ab60ee75 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -67,7 +67,7 @@ def stop(self): class BaseTestCase(unittest.TestCase): def setUp(self): self._threads = threading_helper.threading_setup() - os.environ = support.EnvironmentVarGuard() + os.environ = os_helper.EnvironmentVarGuard() self.server_started = threading.Event() self.thread = TestServerThread(self, self.request_handler) self.thread.start() @@ -621,7 +621,7 @@ def setUp(self): # The shebang line should be pure ASCII: use symlink if possible. # See issue #7668. self._pythonexe_symlink = None - if support.can_symlink(): + if os_helper.can_symlink(): self.pythonexe = os.path.join(self.parent_dir, 'python') self._pythonexe_symlink = support.PythonSymlink(self.pythonexe).__enter__() else: diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index f4a83d2e7a13a17..6fd3983a20f68e7 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -18,7 +18,6 @@ import unittest from unittest import mock -import test.support from test.support import os_helper from test.support import (is_jython, swap_attr, swap_item, cpython_only) from test.support.import_helper import ( @@ -480,7 +479,7 @@ def test_dll_dependency_import(self): os.path.dirname(pydname), "sqlite3{}.dll".format("_d" if "_d" in pydname else "")) - with test.support.temp_dir() as tmp: + with os_helper.temp_dir() as tmp: tmp2 = os.path.join(tmp, "DLLs") os.mkdir(tmp2) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 69c44710f0b5ada..0d84ff8bce2c07a 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -285,7 +285,7 @@ def test_realpath_relative(self): def test_realpath_broken_symlinks(self): ABSTFN = ntpath.abspath(os_helper.TESTFN) os.mkdir(ABSTFN) - self.addCleanup(support.rmtree, ABSTFN) + self.addCleanup(os_helper.rmtree, ABSTFN) with support.change_cwd(ABSTFN): os.mkdir("subdir") @@ -427,9 +427,9 @@ def test_realpath_cwd(self): ABSTFN = ntpath.abspath(os_helper.TESTFN) os_helper.unlink(ABSTFN) - support.rmtree(ABSTFN) + os_helper.rmtree(ABSTFN) os.mkdir(ABSTFN) - self.addCleanup(support.rmtree, ABSTFN) + self.addCleanup(os_helper.rmtree, ABSTFN) test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") os.mkdir(test_dir_long) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 5901939725e1853..97b5c5de95bbc24 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -7,6 +7,7 @@ import unittest import test.support from test import support +from test.support import os_helper from test.support import socket_helper from test.support import captured_stderr from test.support.os_helper import TESTFN, EnvironmentVarGuard, change_cwd @@ -601,7 +602,7 @@ class _pthFileTests(unittest.TestCase): def _create_underpth_exe(self, lines, exe_pth=True): import _winapi temp_dir = tempfile.mkdtemp() - self.addCleanup(test.support.rmtree, temp_dir) + self.addCleanup(os_helper.rmtree, temp_dir) exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) dll_src_file = _winapi.GetModuleFileName(sys.dllhandle) dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1]) diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 5db8cec567afb58..7cdd115a9515399 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -15,6 +15,7 @@ import test.support from test.support import reap_children, verbose +from test.support import os_helper from test.support import socket_helper from test.support import threading_helper @@ -299,7 +300,7 @@ class ErrorHandlerTest(unittest.TestCase): KeyboardInterrupt are not passed.""" def tearDown(self): - test.support.unlink(test.support.TESTFN) + os_helper.unlink(os_helper.TESTFN) def test_sync_handled(self): BaseErrorTestServer(ValueError) @@ -329,7 +330,7 @@ def test_forking_not_handled(self): self.check_result(handled=False) def check_result(self, handled): - with open(test.support.TESTFN) as log: + with open(os_helper.TESTFN) as log: expected = 'Handler called\n' + 'Error handled\n' * handled self.assertEqual(log.read(), expected) @@ -347,7 +348,7 @@ def __init__(self, exception): self.wait_done() def handle_error(self, request, client_address): - with open(test.support.TESTFN, 'a') as log: + with open(os_helper.TESTFN, 'a') as log: log.write('Error handled\n') def wait_done(self): @@ -356,7 +357,7 @@ def wait_done(self): class BadHandler(socketserver.BaseRequestHandler): def handle(self): - with open(test.support.TESTFN, 'a') as log: + with open(os_helper.TESTFN, 'a') as log: log.write('Handler called\n') raise self.server.exception('Test error') diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index bf415dda557e60c..997110732a17657 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -15,10 +15,10 @@ import sys import unittest from test import support +from test.support import import_helper from decimal import Decimal from fractions import Fraction -from test import support # Module to be tested. @@ -179,8 +179,10 @@ class _DoNothing: # We prefer this for testing numeric values that may not be exactly equal, # and avoid using TestCase.assertAlmostEqual, because it sucks :-) -py_statistics = support.import_fresh_module('statistics', blocked=['_statistics']) -c_statistics = support.import_fresh_module('statistics', fresh=['_statistics']) +py_statistics = import_helper.import_fresh_module('statistics', + blocked=['_statistics']) +c_statistics = import_helper.import_fresh_module('statistics', + fresh=['_statistics']) class TestModules(unittest.TestCase): diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 95840d6ac0c5f4c..4dfbd2985d5b5a8 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -12,7 +12,8 @@ import tempfile import textwrap from test.support import (captured_stderr, captured_stdout, script_helper, - findfile, unlink) + findfile) +from test.support.os_helper import unlink SOURCE_CODES = { diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index db982dac8d6533f..cd2a30e533ae032 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -6,6 +6,7 @@ import warnings from test import support from test.support import import_helper +from test.support import os_helper # Skip this test if the _tkinter module wasn't built. _tkinter = import_helper.import_module('_tkinter') @@ -192,26 +193,26 @@ def test_getboolean(self): def testEvalFile(self): tcl = self.interp - with open(support.TESTFN, 'w') as f: - self.addCleanup(support.unlink, support.TESTFN) + with open(os_helper.TESTFN, 'w') as f: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) f.write("""set a 1 set b 2 set c [ expr $a + $b ] """) - tcl.evalfile(support.TESTFN) + tcl.evalfile(os_helper.TESTFN) self.assertEqual(tcl.eval('set a'),'1') self.assertEqual(tcl.eval('set b'),'2') self.assertEqual(tcl.eval('set c'),'3') def test_evalfile_null_in_result(self): tcl = self.interp - with open(support.TESTFN, 'w') as f: - self.addCleanup(support.unlink, support.TESTFN) + with open(os_helper.TESTFN, 'w') as f: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) f.write(""" set a "a\0b" set b "a\\0b" """) - tcl.evalfile(support.TESTFN) + tcl.evalfile(os_helper.TESTFN) self.assertEqual(tcl.eval('set a'), 'a\x00b') self.assertEqual(tcl.eval('set b'), 'a\x00b') @@ -243,7 +244,7 @@ def testLoadWithUNC(self): if not os.path.exists(unc_name): raise unittest.SkipTest('Cannot connect to UNC Path') - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.unset("TCL_LIBRARY") stdout = subprocess.check_output( [unc_name, '-c', 'import tkinter; print(tkinter)']) diff --git a/Lib/test/test_tools/test_md5sum.py b/Lib/test/test_tools/test_md5sum.py index 321bc4bb3628261..bfc1f287fff6e12 100644 --- a/Lib/test/test_tools/test_md5sum.py +++ b/Lib/test/test_tools/test_md5sum.py @@ -2,7 +2,7 @@ import os import unittest -from test import support +from test.support import os_helper from test.support import hashlib_helper from test.support.script_helper import assert_python_ok, assert_python_failure @@ -15,8 +15,8 @@ class MD5SumTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.script = os.path.join(scriptsdir, 'md5sum.py') - os.mkdir(support.TESTFN) - cls.fodder = os.path.join(support.TESTFN, 'md5sum.fodder') + os.mkdir(os_helper.TESTFN) + cls.fodder = os.path.join(os_helper.TESTFN, 'md5sum.fodder') with open(cls.fodder, 'wb') as f: f.write(b'md5sum\r\ntest file\r\n') cls.fodder_md5 = b'd38dae2eb1ab346a292ef6850f9e1a0d' @@ -24,7 +24,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - support.rmtree(support.TESTFN) + os_helper.rmtree(os_helper.TESTFN) def test_noargs(self): rc, out, err = assert_python_ok(self.script) diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 39b3d96fb43bbb5..46ff4a3aac709a7 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -2,6 +2,7 @@ import unittest from test import support from test.support import import_helper +from test.support import os_helper turtle = import_helper.import_module('turtle') @@ -52,10 +53,10 @@ class TurtleConfigTest(unittest.TestCase): def get_cfg_file(self, cfg_str): - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, 'w') as f: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, 'w') as f: f.write(cfg_str) - return support.TESTFN + return os_helper.TESTFN def test_config_dict(self): diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index cb74685715d35b9..c1d55ee8b29b34f 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -1,6 +1,7 @@ import errno import unittest from test import support +from test.support import os_helper from test.support import socket_helper from test.test_urllib2 import sanepathname2url @@ -148,7 +149,7 @@ def test_ftp(self): self._test_urls(urls, self._extra_handlers()) def test_file(self): - TESTFN = support.TESTFN + TESTFN = os_helper.TESTFN f = open(TESTFN, 'w') try: f.write('hi there\n') diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 28680aa6b2405d7..773101ce41f6021 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -1,5 +1,6 @@ import unittest from test import support +from test.support import os_helper from test.support import socket_helper import contextlib @@ -162,7 +163,7 @@ def urlretrieve(self, *args, **kwargs): try: yield file_location, info finally: - support.unlink(file_location) + os_helper.unlink(file_location) def test_basic(self): # Test basic functionality. @@ -176,8 +177,8 @@ def test_basic(self): def test_specified_path(self): # Make sure that specifying the location of the file to write to works. with self.urlretrieve(self.logo, - support.TESTFN) as (file_location, info): - self.assertEqual(file_location, support.TESTFN) + os_helper.TESTFN) as (file_location, info): + self.assertEqual(file_location, os_helper.TESTFN) self.assertTrue(os.path.exists(file_location)) with open(file_location, 'rb') as f: self.assertTrue(f.read(), "reading from temporary file failed") diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 6ceb49069f65649..673cc995d3f5a40 100644 --- a/Lib/test/test_webbrowser.py +++ b/Lib/test/test_webbrowser.py @@ -6,6 +6,7 @@ from unittest import mock from test import support from test.support import import_helper +from test.support import os_helper URL = 'http://www.example.com' @@ -305,7 +306,7 @@ def test_environment(self): browser = webbrowser.get().name except (webbrowser.Error, AttributeError) as err: self.skipTest(str(err)) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["BROWSER"] = browser webbrowser = import_helper.import_fresh_module('webbrowser') webbrowser.get() @@ -318,12 +319,12 @@ def test_environment_preferred(self): except (webbrowser.Error, AttributeError, IndexError) as err: self.skipTest(str(err)) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["BROWSER"] = least_preferred_browser webbrowser = import_helper.import_fresh_module('webbrowser') self.assertEqual(webbrowser.get().name, least_preferred_browser) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env["BROWSER"] = sys.executable webbrowser = import_helper.import_fresh_module('webbrowser') self.assertEqual(webbrowser.get().name, sys.executable) diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index dca77cb45bfa915..3c3359b9004fd2f 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -5,9 +5,11 @@ import unittest from test import support +from test.support import import_helper + support.requires('audio') -winsound = support.import_module('winsound') +winsound = import_helper.import_module('winsound') # Unless we actually have an ear in the room, we have no idea whether a sound diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/tkinter/test/test_tkinter/test_images.py index 2805d35a1f5b1bf..6c6cb4e148573fe 100644 --- a/Lib/tkinter/test/test_tkinter/test_images.py +++ b/Lib/tkinter/test/test_tkinter/test_images.py @@ -1,6 +1,7 @@ import unittest import tkinter from test import support +from test.support import os_helper from tkinter.test.support import AbstractTkTest, requires_tcl support.requires('gui') @@ -296,12 +297,12 @@ def test_get(self): def test_write(self): image = self.create() - self.addCleanup(support.unlink, support.TESTFN) + self.addCleanup(os_helper.unlink, os_helper.TESTFN) - image.write(support.TESTFN) + image.write(os_helper.TESTFN) image2 = tkinter.PhotoImage('::img::test2', master=self.root, format='ppm', - file=support.TESTFN) + file=os_helper.TESTFN) self.assertEqual(str(image2), '::img::test2') self.assertEqual(image2.type(), 'photo') self.assertEqual(image2.width(), 16) @@ -309,10 +310,10 @@ def test_write(self): self.assertEqual(image2.get(0, 0), image.get(0, 0)) self.assertEqual(image2.get(15, 8), image.get(15, 8)) - image.write(support.TESTFN, format='gif', from_coords=(4, 6, 6, 9)) + image.write(os_helper.TESTFN, format='gif', from_coords=(4, 6, 6, 9)) image3 = tkinter.PhotoImage('::img::test3', master=self.root, format='gif', - file=support.TESTFN) + file=os_helper.TESTFN) self.assertEqual(str(image3), '::img::test3') self.assertEqual(image3.type(), 'photo') self.assertEqual(image3.width(), 2) diff --git a/Lib/tkinter/test/test_tkinter/test_loadtk.py b/Lib/tkinter/test/test_tkinter/test_loadtk.py index bab7bcd37ce3188..760ba721340829e 100644 --- a/Lib/tkinter/test/test_tkinter/test_loadtk.py +++ b/Lib/tkinter/test/test_tkinter/test_loadtk.py @@ -2,6 +2,7 @@ import sys import unittest import test.support as test_support +from test.support import os_helper from tkinter import Tcl, TclError test_support.requires('gui') @@ -24,7 +25,7 @@ def testLoadTkFailure(self): # XXX Maybe on tk older than 8.4.13 it would be possible, # see tkinter.h. return - with test_support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: if 'DISPLAY' in os.environ: del env['DISPLAY'] # on some platforms, deleting environment variables From e758ab4f34290fe0af80ec5154e511cd59bc6d6e Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 6 Aug 2020 17:36:22 +0100 Subject: [PATCH 115/486] bpo-41492: Fixes the description appearing in UAC prompts on Windows (GH-21754) --- .azure-pipelines/windows-release/msi-steps.yml | 6 ++++++ .azure-pipelines/windows-release/stage-pack-msix.yml | 8 +++++++- .azure-pipelines/windows-release/stage-sign.yml | 6 ++++++ .../next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst | 1 + 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index a460eb1bac8fe5d..307510a40dd4e50 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -1,6 +1,12 @@ steps: - template: ./checkout.yml + - powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)" + displayName: 'Update signing description' + condition: and(succeeded(), not(variables['SigningDescription'])) + - task: DownloadPipelineArtifact@1 displayName: 'Download artifact: doc' inputs: diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml index 07e343a0b4e0c78..26a5712e845ca9e 100644 --- a/.azure-pipelines/windows-release/stage-pack-msix.yml +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -105,9 +105,15 @@ jobs: clean: all steps: - - checkout: none + - template: ./checkout.yml - template: ./find-sdk.yml + - powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)" + displayName: 'Update signing description' + condition: and(succeeded(), not(variables['SigningDescription'])) + - task: DownloadBuildArtifacts@0 displayName: 'Download Artifact: unsigned_msix' inputs: diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml index 4d757ae8fca0325..584772af8b428e9 100644 --- a/.azure-pipelines/windows-release/stage-sign.yml +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -26,6 +26,12 @@ jobs: - template: ./checkout.yml - template: ./find-sdk.yml + - powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=SigningDescription]Python $($d.PythonVersion)" + displayName: 'Update signing description' + condition: and(succeeded(), not(variables['SigningDescription'])) + - powershell: | Write-Host "##vso[build.addbuildtag]signed" displayName: 'Add build tags' diff --git a/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst b/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst new file mode 100644 index 000000000000000..065803e2c207593 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst @@ -0,0 +1 @@ +Fixes the description that appears in UAC prompts. From e23dbe6311774f144b08aa9e7e6c51dd578133d1 Mon Sep 17 00:00:00 2001 From: Nathan M Date: Thu, 6 Aug 2020 18:09:40 -0400 Subject: [PATCH 116/486] bpo-41371: Handle lzma lib import error in test_zoneinfo.py (GH-21734) --- Lib/test/test_zoneinfo/test_zoneinfo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index 1f1fa60f1ffc1fe..d16e0d2c3310686 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -6,7 +6,6 @@ import importlib.metadata import io import json -import lzma import os import pathlib import pickle @@ -20,7 +19,9 @@ from . import _support as test_support from ._support import OS_ENV_LOCK, TZPATH_TEST_LOCK, ZoneInfoTestBase +from test.support.import_helper import import_module +lzma = import_module('lzma') py_zoneinfo, c_zoneinfo = test_support.get_modules() try: From 81586f4b63cbddd799c550f5f9b9f0be079e7edc Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Fri, 7 Aug 2020 14:08:55 +0900 Subject: [PATCH 117/486] bpo-41493: Refactoring dictresize (GH-21751) Split newsize calculation into new function. dictresize() now accepts exact newsize. --- Objects/dictobject.c | 67 +++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1b7ae06d8227102..6c3fc62d2ecc7ee 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -111,6 +111,7 @@ converting the dict to the combined table. #define PyDict_MINSIZE 8 #include "Python.h" +#include "pycore_bitutils.h" // _Py_bit_length #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_pyerrors.h" // _PyErr_Fetch() @@ -236,7 +237,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); -static int dictresize(PyDictObject *mp, Py_ssize_t minused); +static int dictresize(PyDictObject *mp, Py_ssize_t newsize); static PyObject* dict_iter(PyDictObject *dict); @@ -411,18 +412,40 @@ dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) */ #define USABLE_FRACTION(n) (((n) << 1)/3) -/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION. +/* Find the smallest dk_size >= minsize. */ +static inline Py_ssize_t +calculate_keysize(Py_ssize_t minsize) +{ +#if SIZEOF_LONG == SIZEOF_SIZE_T + minsize = (minsize | PyDict_MINSIZE) - 1; + return 1LL << _Py_bit_length(minsize | (PyDict_MINSIZE-1)); +#elif defined(_MSC_VER) + // On 64bit Windows, sizeof(long) == 4. + minsize = (minsize | PyDict_MINSIZE) - 1; + unsigned long msb; + _BitScanReverse64(&msb, (uint64_t)minsize); + return 1LL << (msb + 1); +#else + Py_ssize_t size; + for (size = PyDict_MINSIZE; + size < minsize && size > 0; + size <<= 1) + ; + return size; +#endif +} + +/* estimate_keysize is reverse function of USABLE_FRACTION. + * * This can be used to reserve enough size to insert n entries without * resizing. */ -#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1) +static inline Py_ssize_t +estimate_keysize(Py_ssize_t n) +{ + return calculate_keysize((n*3 + 1) / 2); +} -/* Alternative fraction that is otherwise close enough to 2n/3 to make - * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10. - * 32 * 2/3 = 21, 32 * 5/8 = 20. - * Its advantage is that it is faster to compute on machines with slow division. - * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3)) - */ /* GROWTH_RATE. Growth rate upon hitting maximum load. * Currently set to used*3. @@ -1036,7 +1059,7 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) static int insertion_resize(PyDictObject *mp) { - return dictresize(mp, GROWTH_RATE(mp)); + return dictresize(mp, calculate_keysize(GROWTH_RATE(mp))); } /* @@ -1194,22 +1217,19 @@ After resizing a table is always combined, but can be resplit by make_keys_shared(). */ static int -dictresize(PyDictObject *mp, Py_ssize_t minsize) +dictresize(PyDictObject *mp, Py_ssize_t newsize) { - Py_ssize_t newsize, numentries; + Py_ssize_t numentries; PyDictKeysObject *oldkeys; PyObject **oldvalues; PyDictKeyEntry *oldentries, *newentries; - /* Find the smallest table size > minused. */ - for (newsize = PyDict_MINSIZE; - newsize < minsize && newsize > 0; - newsize <<= 1) - ; if (newsize <= 0) { PyErr_NoMemory(); return -1; } + assert(IS_POWER_OF_2(newsize)); + assert(newsize >= PyDict_MINSIZE); oldkeys = mp->ma_keys; @@ -1355,13 +1375,8 @@ _PyDict_NewPresized(Py_ssize_t minused) newsize = max_presize; } else { - Py_ssize_t minsize = ESTIMATE_SIZE(minused); - newsize = PyDict_MINSIZE*2; - while (newsize < minsize) { - newsize <<= 1; - } + newsize = estimate_keysize(minused); } - assert(IS_POWER_OF_2(newsize)); new_keys = new_keys_object(newsize); if (new_keys == NULL) @@ -1930,7 +1945,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_keysize(PyDict_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } @@ -1949,7 +1964,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_keysize(PySet_GET_SIZE(iterable)))) { Py_DECREF(d); return NULL; } @@ -2558,7 +2573,7 @@ dict_merge(PyObject *a, PyObject *b, int override) * that there will be no (or few) overlapping keys. */ if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) { - if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) { + if (dictresize(mp, estimate_keysize(mp->ma_used + other->ma_used))) { return -1; } } From 3d5f96721dde450f6fa18ba5c9a0a568f301e529 Mon Sep 17 00:00:00 2001 From: pxinwr Date: Fri, 7 Aug 2020 13:21:52 +0800 Subject: [PATCH 118/486] bpo-41440: add os.cpu_count() support for VxWorks RTOS (GH-21685) --- Doc/whatsnew/3.10.rst | 6 ++++++ .../next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst | 1 + Modules/posixmodule.c | 5 +++++ 3 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index ec0343f2ce71e8e..62bb1438416e6ca 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -120,6 +120,12 @@ Added the *root_dir* and *dir_fd* parameters in :func:`~glob.glob` and :func:`~glob.iglob` which allow to specify the root directory for searching. (Contributed by Serhiy Storchaka in :issue:`38144`.) +os +-- + +Added :func:`os.cpu_count()` support for VxWorks RTOS. +(Contributed by Peixing Xin in :issue:`41440`.) + py_compile ---------- diff --git a/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst b/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst new file mode 100644 index 000000000000000..3ee1f656d1870c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst @@ -0,0 +1 @@ +Add :func:`os.cpu_count()` support for VxWorks RTOS. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index efd99544f5a9974..a6a4b9f012f009a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -32,6 +32,9 @@ # include #endif +#ifdef __VXWORKS__ +# include "pycore_bitutils.h" // _Py_popcount32() +#endif #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() @@ -12607,6 +12610,8 @@ os_cpu_count_impl(PyObject *module) ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(__VXWORKS__) + ncpu = _Py_popcount32(vxCpuEnabledGet()); #elif defined(__DragonFly__) || \ defined(__OpenBSD__) || \ defined(__FreeBSD__) || \ From 2bc48da025a27e3c4914488333e8042b0a017057 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 6 Aug 2020 23:38:48 -0600 Subject: [PATCH 119/486] bpo-39871: Fix an error in a news entry (GH-21749) --- Misc/NEWS.d/3.9.0a5.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/3.9.0a5.rst b/Misc/NEWS.d/3.9.0a5.rst index 39e017768c3ad0b..355a3fc22350cb8 100644 --- a/Misc/NEWS.d/3.9.0a5.rst +++ b/Misc/NEWS.d/3.9.0a5.rst @@ -232,7 +232,7 @@ exits before trying to take the GIL. Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()`` when the first argument cannot be converted to a :class:`float`. Patch by -Zachary Spytz. +Zackery Spytz. .. From 075b5825c406a910119ab83dee12dd91bb679988 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Fri, 7 Aug 2020 16:31:53 +0900 Subject: [PATCH 120/486] bpo-41098: Doc: Add missing deprecated directives (GH-21162) PyUnicodeEncodeError_Create has been deprecated with `Py_DEPRECATED` macro. But it was not documented. --- Doc/c-api/exceptions.rst | 10 ++++++++++ Include/cpython/pyerrors.h | 10 ++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index e7805ba143c5844..b4722ff81979f4a 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -637,11 +637,21 @@ The following functions are used to create and modify Unicode exceptions from C. *object*, *length*, *start*, *end* and *reason*. *encoding* and *reason* are UTF-8 encoded strings. + .. deprecated:: 3.3 3.11 + + ``Py_UNICODE`` is deprecated since Python 3.3. Please migrate to + ``PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns", ...)``. + .. c:function:: PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) Create a :class:`UnicodeTranslateError` object with the attributes *object*, *length*, *start*, *end* and *reason*. *reason* is a UTF-8 encoded string. + .. deprecated:: 3.3 3.11 + + ``Py_UNICODE`` is deprecated since Python 3.3. Please migrate to + ``PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", ...)``. + .. c:function:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc) PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc) diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 3f347dc2e2d62be..c2500d927bf7f07 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -145,7 +145,10 @@ PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( PyObject *filename, int lineno); -/* Create a UnicodeEncodeError object */ +/* Create a UnicodeEncodeError object. + * + * TODO: This API will be removed in Python 3.11. + */ Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( const char *encoding, /* UTF-8 encoded string */ const Py_UNICODE *object, @@ -155,7 +158,10 @@ Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( const char *reason /* UTF-8 encoded string */ ); -/* Create a UnicodeTranslateError object */ +/* Create a UnicodeTranslateError object. + * + * TODO: This API will be removed in Python 3.11. + */ Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( const Py_UNICODE *object, Py_ssize_t length, From 39c9801b067fd9a1fa4719702f03326cec87cb9c Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 7 Aug 2020 23:18:38 +0800 Subject: [PATCH 121/486] bpo-40275: Use new test.support helper submodules in tests (GH-21764) --- Lib/ctypes/test/test_loading.py | 3 +- Lib/sqlite3/test/hooks.py | 3 +- Lib/test/_test_multiprocessing.py | 32 ++++--- Lib/test/test___all__.py | 5 +- Lib/test/test_asyncio/test_proactor_events.py | 8 +- Lib/test/test_ntpath.py | 12 +-- Lib/test/test_ossaudiodev.py | 3 +- Lib/test/test_platform.py | 2 +- Lib/test/test_posixpath.py | 92 ++++++++++--------- Lib/test/test_py_compile.py | 2 +- Lib/test/test_source_encoding.py | 4 +- Lib/test/test_startfile.py | 3 +- Lib/test/test_sundry.py | 6 +- Lib/test/test_winconsoleio.py | 4 +- Lib/test/test_zoneinfo/_support.py | 2 +- 15 files changed, 97 insertions(+), 84 deletions(-) diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index ba655bceb8b215f..38b45f95fefae88 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -5,6 +5,7 @@ import sys import unittest import test.support +from test.support import import_helper from ctypes.util import find_library libc_name = None @@ -117,7 +118,7 @@ def test_1703286_B(self): @unittest.skipUnless(os.name == "nt", 'test specific to Windows') def test_load_dll_with_flags(self): - _sqlite3 = test.support.import_module("_sqlite3") + _sqlite3 = import_helper.import_module("_sqlite3") src = _sqlite3.__file__ if src.lower().endswith("_d.pyd"): ext = "_d.dll" diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index d74e74bf2722754..b08adf1d8097b39 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -24,7 +24,8 @@ import unittest import sqlite3 as sqlite -from test.support import TESTFN, unlink +from test.support.os_helper import TESTFN, unlink + class CollationTests(unittest.TestCase): def CheckCreateCollationNotString(self): diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index bde102ae2e0518d..58663c02002e94d 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -28,8 +28,10 @@ from test import support from test.support import hashlib_helper from test.support import import_helper +from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +from test.support import warnings_helper # Skip tests if _multiprocessing wasn't built. @@ -615,7 +617,7 @@ def test_lose_target_ref(self): @classmethod def _test_child_fd_inflation(self, evt, q): - q.put(test.support.fd_count()) + q.put(os_helper.fd_count()) evt.wait() def test_child_fd_inflation(self): @@ -819,8 +821,8 @@ def test_stderr_flush(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) - testfn = test.support.TESTFN - self.addCleanup(test.support.unlink, testfn) + testfn = os_helper.TESTFN + self.addCleanup(os_helper.unlink, testfn) proc = self.Process(target=self._test_stderr_flush, args=(testfn,)) proc.start() proc.join() @@ -849,8 +851,8 @@ def test_sys_exit(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) - testfn = test.support.TESTFN - self.addCleanup(test.support.unlink, testfn) + testfn = os_helper.TESTFN + self.addCleanup(os_helper.unlink, testfn) for reason in ( [1, 2, 3], @@ -1114,7 +1116,7 @@ def test_task_done(self): close_queue(queue) def test_no_import_lock_contention(self): - with test.support.temp_cwd(): + with os_helper.temp_cwd(): module_name = 'imported_by_an_imported_module' with open(module_name + '.py', 'w') as f: f.write("""if 1: @@ -1127,7 +1129,7 @@ def test_no_import_lock_contention(self): del q """) - with test.support.DirsOnSysPath(os.getcwd()): + with import_helper.DirsOnSysPath(os.getcwd()): try: __import__(module_name) except pyqueue.Empty: @@ -2688,8 +2690,8 @@ def test_resource_warning(self): # force state to RUN to emit ResourceWarning in __del__() pool._state = multiprocessing.pool.RUN - with support.check_warnings(('unclosed running multiprocessing pool', - ResourceWarning)): + with warnings_helper.check_warnings( + ('unclosed running multiprocessing pool', ResourceWarning)): pool = None support.gc_collect() @@ -3199,14 +3201,14 @@ def test_fd_transfer(self): p = self.Process(target=self._writefd, args=(child_conn, b"foo")) p.daemon = True p.start() - self.addCleanup(test.support.unlink, test.support.TESTFN) - with open(test.support.TESTFN, "wb") as f: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, "wb") as f: fd = f.fileno() if msvcrt: fd = msvcrt.get_osfhandle(fd) reduction.send_handle(conn, fd, p.pid) p.join() - with open(test.support.TESTFN, "rb") as f: + with open(os_helper.TESTFN, "rb") as f: self.assertEqual(f.read(), b"foo") @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @@ -3225,8 +3227,8 @@ def test_large_fd_transfer(self): p = self.Process(target=self._writefd, args=(child_conn, b"bar", True)) p.daemon = True p.start() - self.addCleanup(test.support.unlink, test.support.TESTFN) - with open(test.support.TESTFN, "wb") as f: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, "wb") as f: fd = f.fileno() for newfd in range(256, MAXFD): if not self._is_fd_assigned(newfd): @@ -3239,7 +3241,7 @@ def test_large_fd_transfer(self): finally: os.close(newfd) p.join() - with open(test.support.TESTFN, "rb") as f: + with open(os_helper.TESTFN, "rb") as f: self.assertEqual(f.read(), b"bar") @classmethod diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 0ba243ee4e74e45..0a03dd20065feba 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -1,5 +1,6 @@ import unittest from test import support +from test.support import warnings_helper import os import sys @@ -15,7 +16,7 @@ class AllTest(unittest.TestCase): def check_all(self, modname): names = {} - with support.check_warnings( + with warnings_helper.check_warnings( (".* (module|package)", DeprecationWarning), (".* (module|package)", PendingDeprecationWarning), ("", ResourceWarning), @@ -31,7 +32,7 @@ def check_all(self, modname): raise NoAll(modname) names = {} with self.subTest(module=modname): - with support.check_warnings( + with warnings_helper.check_warnings( ("", DeprecationWarning), ("", ResourceWarning), quiet=True): diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 50ba4c19d425cac..d0ab38743ecd1fd 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -12,7 +12,7 @@ from asyncio.proactor_events import _ProactorWritePipeTransport from asyncio.proactor_events import _ProactorDuplexPipeTransport from asyncio.proactor_events import _ProactorDatagramTransport -from test import support +from test.support import os_helper from test.support import socket_helper from test.test_asyncio import utils as test_utils @@ -935,20 +935,20 @@ async def wait_closed(self): @classmethod def setUpClass(cls): - with open(support.TESTFN, 'wb') as fp: + with open(os_helper.TESTFN, 'wb') as fp: fp.write(cls.DATA) super().setUpClass() @classmethod def tearDownClass(cls): - support.unlink(support.TESTFN) + os_helper.unlink(os_helper.TESTFN) super().tearDownClass() def setUp(self): self.loop = asyncio.ProactorEventLoop() self.set_event_loop(self.loop) self.addCleanup(self.loop.close) - self.file = open(support.TESTFN, 'rb') + self.file = open(os_helper.TESTFN, 'rb') self.addCleanup(self.file.close) super().setUp() diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 0d84ff8bce2c07a..a8f764f48ca00f5 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -6,7 +6,7 @@ from test.support import os_helper from test.support import TestFailed from test.support.os_helper import FakePath -from test import support, test_genericpath +from test import test_genericpath from tempfile import TemporaryFile @@ -287,7 +287,7 @@ def test_realpath_broken_symlinks(self): os.mkdir(ABSTFN) self.addCleanup(os_helper.rmtree, ABSTFN) - with support.change_cwd(ABSTFN): + with os_helper.change_cwd(ABSTFN): os.mkdir("subdir") os.chdir("subdir") os.symlink(".", "recursive") @@ -443,11 +443,11 @@ def test_realpath_cwd(self): self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) - with support.change_cwd(test_dir_long): + with os_helper.change_cwd(test_dir_long): self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) - with support.change_cwd(test_dir_long.lower()): + with os_helper.change_cwd(test_dir_long.lower()): self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) - with support.change_cwd(test_dir_short): + with os_helper.change_cwd(test_dir_short): self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) def test_expandvars(self): @@ -673,7 +673,7 @@ def test_ismount(self): # locations below cannot then refer to mount points # drive, path = ntpath.splitdrive(sys.executable) - with support.change_cwd(ntpath.dirname(sys.executable)): + with os_helper.change_cwd(ntpath.dirname(sys.executable)): self.assertFalse(ntpath.ismount(drive.lower())) self.assertFalse(ntpath.ismount(drive.upper())) diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py index 624fbf21ba7d88f..d3766e580b98439 100644 --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -1,9 +1,10 @@ from test import support +from test.support import import_helper support.requires('audio') from test.support import findfile -ossaudiodev = support.import_module('ossaudiodev') +ossaudiodev = import_helper.import_module('ossaudiodev') import errno import sys diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 5ad306e0ed5795d..b5d21e54610e3dd 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -196,7 +196,7 @@ def test_uname_win32_ARCHITEW6432(self): # using it, per # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx try: - with support.EnvironmentVarGuard() as environ: + with os_helper.EnvironmentVarGuard() as environ: if 'PROCESSOR_ARCHITEW6432' in environ: del environ['PROCESSOR_ARCHITEW6432'] environ['PROCESSOR_ARCHITECTURE'] = 'foo' diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 18819a5dc1cfee2..f37e82505796dbb 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -2,7 +2,9 @@ import posixpath import unittest from posixpath import realpath, abspath, dirname, basename -from test import support, test_genericpath +from test import test_genericpath +from test.support import import_helper +from test.support import os_helper from test.support import FakePath from unittest import mock @@ -15,7 +17,7 @@ # An absolute path to a temporary filename for testing. We can't rely on TESTFN # being an absolute path, so we need this. -ABSTFN = abspath(support.TESTFN) +ABSTFN = abspath(os_helper.TESTFN) def skip_if_ABSTFN_contains_backslash(test): """ @@ -40,8 +42,8 @@ def setUp(self): def tearDown(self): for suffix in ["", "1", "2"]: - support.unlink(support.TESTFN + suffix) - safe_rmdir(support.TESTFN + suffix) + os_helper.unlink(os_helper.TESTFN + suffix) + safe_rmdir(os_helper.TESTFN + suffix) def test_join(self): self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), @@ -152,25 +154,25 @@ def test_dirname(self): self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo") def test_islink(self): - self.assertIs(posixpath.islink(support.TESTFN + "1"), False) - self.assertIs(posixpath.lexists(support.TESTFN + "2"), False) + self.assertIs(posixpath.islink(os_helper.TESTFN + "1"), False) + self.assertIs(posixpath.lexists(os_helper.TESTFN + "2"), False) - with open(support.TESTFN + "1", "wb") as f: + with open(os_helper.TESTFN + "1", "wb") as f: f.write(b"foo") - self.assertIs(posixpath.islink(support.TESTFN + "1"), False) + self.assertIs(posixpath.islink(os_helper.TESTFN + "1"), False) - if support.can_symlink(): - os.symlink(support.TESTFN + "1", support.TESTFN + "2") - self.assertIs(posixpath.islink(support.TESTFN + "2"), True) - os.remove(support.TESTFN + "1") - self.assertIs(posixpath.islink(support.TESTFN + "2"), True) - self.assertIs(posixpath.exists(support.TESTFN + "2"), False) - self.assertIs(posixpath.lexists(support.TESTFN + "2"), True) + if os_helper.can_symlink(): + os.symlink(os_helper.TESTFN + "1", os_helper.TESTFN + "2") + self.assertIs(posixpath.islink(os_helper.TESTFN + "2"), True) + os.remove(os_helper.TESTFN + "1") + self.assertIs(posixpath.islink(os_helper.TESTFN + "2"), True) + self.assertIs(posixpath.exists(os_helper.TESTFN + "2"), False) + self.assertIs(posixpath.lexists(os_helper.TESTFN + "2"), True) - self.assertIs(posixpath.islink(support.TESTFN + "\udfff"), False) - self.assertIs(posixpath.islink(os.fsencode(support.TESTFN) + b"\xff"), False) - self.assertIs(posixpath.islink(support.TESTFN + "\x00"), False) - self.assertIs(posixpath.islink(os.fsencode(support.TESTFN) + b"\x00"), False) + self.assertIs(posixpath.islink(os_helper.TESTFN + "\udfff"), False) + self.assertIs(posixpath.islink(os.fsencode(os_helper.TESTFN) + b"\xff"), False) + self.assertIs(posixpath.islink(os_helper.TESTFN + "\x00"), False) + self.assertIs(posixpath.islink(os.fsencode(os_helper.TESTFN) + b"\x00"), False) def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) @@ -190,7 +192,7 @@ def test_ismount_non_existent(self): self.assertIs(posixpath.ismount('/\x00'), False) self.assertIs(posixpath.ismount(b'/\x00'), False) - @unittest.skipUnless(support.can_symlink(), + @unittest.skipUnless(os_helper.can_symlink(), "Test requires symlink support") def test_ismount_symlinks(self): # Symlinks are never mountpoints. @@ -245,7 +247,7 @@ def test_expanduser(self): self.assertEqual(posixpath.expanduser(b"foo"), b"foo") def test_expanduser_home_envvar(self): - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env['HOME'] = '/home/victor' self.assertEqual(posixpath.expanduser("~"), "/home/victor") @@ -261,7 +263,7 @@ def test_expanduser_home_envvar(self): self.assertEqual(posixpath.expanduser("~/foo"), "/foo") def test_expanduser_pwd(self): - pwd = support.import_module('pwd') + pwd = import_helper.import_module('pwd') self.assertIsInstance(posixpath.expanduser("~/"), str) self.assertIsInstance(posixpath.expanduser(b"~/"), bytes) @@ -281,7 +283,7 @@ def test_expanduser_pwd(self): self.assertIsInstance(posixpath.expanduser(b"~root/"), bytes) self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes) - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: # expanduser should fall back to using the password database del env['HOME'] @@ -348,7 +350,7 @@ def test_realpath_basic(self): os.symlink(ABSTFN+"1", ABSTFN) self.assertEqual(realpath(ABSTFN), ABSTFN+"1") finally: - support.unlink(ABSTFN) + os_helper.unlink(ABSTFN) @unittest.skipUnless(hasattr(os, "symlink"), "Missing symlink implementation") @@ -358,7 +360,7 @@ def test_realpath_relative(self): os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN) self.assertEqual(realpath(ABSTFN), ABSTFN+"1") finally: - support.unlink(ABSTFN) + os_helper.unlink(ABSTFN) @unittest.skipUnless(hasattr(os, "symlink"), "Missing symlink implementation") @@ -392,15 +394,15 @@ def test_realpath_symlink_loops(self): self.assertEqual(realpath(ABSTFN+"c"), ABSTFN+"c") # Test using relative path as well. - with support.change_cwd(dirname(ABSTFN)): + with os_helper.change_cwd(dirname(ABSTFN)): self.assertEqual(realpath(basename(ABSTFN)), ABSTFN) finally: - support.unlink(ABSTFN) - support.unlink(ABSTFN+"1") - support.unlink(ABSTFN+"2") - support.unlink(ABSTFN+"y") - support.unlink(ABSTFN+"c") - support.unlink(ABSTFN+"a") + os_helper.unlink(ABSTFN) + os_helper.unlink(ABSTFN+"1") + os_helper.unlink(ABSTFN+"2") + os_helper.unlink(ABSTFN+"y") + os_helper.unlink(ABSTFN+"c") + os_helper.unlink(ABSTFN+"a") @unittest.skipUnless(hasattr(os, "symlink"), "Missing symlink implementation") @@ -413,8 +415,8 @@ def test_realpath_repeated_indirect_symlinks(self): os.symlink('self/self/self', ABSTFN + '/link') self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN) finally: - support.unlink(ABSTFN + '/self') - support.unlink(ABSTFN + '/link') + os_helper.unlink(ABSTFN + '/self') + os_helper.unlink(ABSTFN + '/link') safe_rmdir(ABSTFN) @unittest.skipUnless(hasattr(os, "symlink"), @@ -430,11 +432,11 @@ def test_realpath_deep_recursion(self): self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN) # Test using relative path as well. - with support.change_cwd(ABSTFN): + with os_helper.change_cwd(ABSTFN): self.assertEqual(realpath('%d' % depth), ABSTFN) finally: for i in range(depth + 1): - support.unlink(ABSTFN + '/%d' % i) + os_helper.unlink(ABSTFN + '/%d' % i) safe_rmdir(ABSTFN) @unittest.skipUnless(hasattr(os, "symlink"), @@ -450,10 +452,10 @@ def test_realpath_resolve_parents(self): os.mkdir(ABSTFN + "/y") os.symlink(ABSTFN + "/y", ABSTFN + "/k") - with support.change_cwd(ABSTFN + "/k"): + with os_helper.change_cwd(ABSTFN + "/k"): self.assertEqual(realpath("a"), ABSTFN + "/y/a") finally: - support.unlink(ABSTFN + "/k") + os_helper.unlink(ABSTFN + "/k") safe_rmdir(ABSTFN + "/y") safe_rmdir(ABSTFN) @@ -477,11 +479,11 @@ def test_realpath_resolve_before_normalizing(self): # Absolute path. self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k") # Relative path. - with support.change_cwd(dirname(ABSTFN)): + with os_helper.change_cwd(dirname(ABSTFN)): self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."), ABSTFN + "/k") finally: - support.unlink(ABSTFN + "/link-y") + os_helper.unlink(ABSTFN + "/link-y") safe_rmdir(ABSTFN + "/k/y") safe_rmdir(ABSTFN + "/k") safe_rmdir(ABSTFN) @@ -497,12 +499,12 @@ def test_realpath_resolve_first(self): os.mkdir(ABSTFN) os.mkdir(ABSTFN + "/k") os.symlink(ABSTFN, ABSTFN + "link") - with support.change_cwd(dirname(ABSTFN)): + with os_helper.change_cwd(dirname(ABSTFN)): base = basename(ABSTFN) self.assertEqual(realpath(base + "link"), ABSTFN) self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k") finally: - support.unlink(ABSTFN + "link") + os_helper.unlink(ABSTFN + "link") safe_rmdir(ABSTFN + "/k") safe_rmdir(ABSTFN) @@ -627,9 +629,9 @@ class PathLikeTests(unittest.TestCase): path = posixpath def setUp(self): - self.file_name = support.TESTFN - self.file_path = FakePath(support.TESTFN) - self.addCleanup(support.unlink, self.file_name) + self.file_name = os_helper.TESTFN + self.file_path = FakePath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, self.file_name) with open(self.file_name, 'xb', 0) as file: file.write(b"test_posixpath.PathLikeTests") diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 009645689f42377..b58f28a4bc88855 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -228,7 +228,7 @@ def setUp(self): file.write('x = 123\n') def tearDown(self): - support.rmtree(self.directory) + os_helper.rmtree(self.directory) def pycompilecmd(self, *args, **kwargs): # assert_python_* helpers don't return proc object. We'll just use diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index 5ca43461d9940da..b410c03221bf323 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,7 +1,9 @@ # -*- coding: koi8-r -*- import unittest -from test.support import TESTFN, unlink, unload, rmtree, script_helper, captured_stdout +from test.support import script_helper, captured_stdout +from test.support.os_helper import TESTFN, unlink, rmtree +from test.support.import_helper import unload import importlib import os import sys diff --git a/Lib/test/test_startfile.py b/Lib/test/test_startfile.py index 1a26a8025e6243e..589ffa25244da99 100644 --- a/Lib/test/test_startfile.py +++ b/Lib/test/test_startfile.py @@ -9,6 +9,7 @@ import unittest from test import support +from test.support import os_helper import os import platform import sys @@ -27,7 +28,7 @@ def test_empty(self): # we're not about to delete. If we're running under -j, that # means the test harness provided directory isn't a safe option. # See http://bugs.python.org/issue15526 for more details - with support.change_cwd(path.dirname(sys.executable)): + with os_helper.change_cwd(path.dirname(sys.executable)): empty = path.join(path.dirname(__file__), "empty.vbs") startfile(empty) startfile(empty, "open") diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 2accad1aeebd4f9..04e572c00a19690 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -3,15 +3,17 @@ import platform import sys from test import support +from test.support import import_helper +from test.support import warnings_helper import unittest class TestUntestedModules(unittest.TestCase): def test_untested_modules_can_be_imported(self): untested = ('encodings', 'formatter') - with support.check_warnings(quiet=True): + with warnings_helper.check_warnings(quiet=True): for name in untested: try: - support.import_module('test.test_{}'.format(name)) + import_helper.import_module('test.test_{}'.format(name)) except unittest.SkipTest: importlib.import_module(name) else: diff --git a/Lib/test/test_winconsoleio.py b/Lib/test/test_winconsoleio.py index a44f7bbd27b7009..1807e47c66c387a 100644 --- a/Lib/test/test_winconsoleio.py +++ b/Lib/test/test_winconsoleio.py @@ -6,7 +6,7 @@ import sys import tempfile import unittest -from test import support +from test.support import os_helper if sys.platform != 'win32': raise unittest.SkipTest("test only relevant on win32") @@ -109,7 +109,7 @@ def test_conin_conout_names(self): def test_conout_path(self): temp_path = tempfile.mkdtemp() - self.addCleanup(support.rmtree, temp_path) + self.addCleanup(os_helper.rmtree, temp_path) conout_path = os.path.join(temp_path, 'CONOUT$') diff --git a/Lib/test/test_zoneinfo/_support.py b/Lib/test/test_zoneinfo/_support.py index 0fe162c25836876..5a76c163fb75bda 100644 --- a/Lib/test/test_zoneinfo/_support.py +++ b/Lib/test/test_zoneinfo/_support.py @@ -3,7 +3,7 @@ import sys import threading import unittest -from test.support import import_fresh_module +from test.support.import_helper import import_fresh_module OS_ENV_LOCK = threading.Lock() TZPATH_LOCK = threading.Lock() From ff4eefb5d2d04a99c4f5aaf32c1ec82060b556d1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 Aug 2020 17:56:42 +0200 Subject: [PATCH 122/486] bpo-41477: Make ctypes optional in test_genericalias (GH-21766) --- Lib/test/test_genericalias.py | 80 ++++++++++--------- .../2020-08-07-17-28-49.bpo-41477.GrFexU.rst | 1 + 2 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 4f3798e8f87d8ff..1f24469471428af 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -13,7 +13,10 @@ from dataclasses import Field from functools import partial, partialmethod, cached_property from mailbox import Mailbox, _PartialFile -from ctypes import Array, LibraryLoader +try: + import ctypes +except ImportError: + ctypes = None from difflib import SequenceMatcher from filecmp import dircmp from fileinput import FileInput @@ -46,43 +49,44 @@ class BaseTest(unittest.TestCase): """Test basics.""" def test_subscriptable(self): - for t in (type, tuple, list, dict, set, frozenset, enumerate, - defaultdict, deque, - SequenceMatcher, - dircmp, - FileInput, - OrderedDict, Counter, UserDict, UserList, - Pattern, Match, - partial, partialmethod, cached_property, - AbstractContextManager, AbstractAsyncContextManager, - Awaitable, Coroutine, - AsyncIterable, AsyncIterator, - AsyncGenerator, Generator, - Iterable, Iterator, - Reversible, - Container, Collection, - Callable, - Mailbox, _PartialFile, - ContextVar, Token, - Field, - Set, MutableSet, - Mapping, MutableMapping, MappingView, - KeysView, ItemsView, ValuesView, - Sequence, MutableSequence, - MappingProxyType, AsyncGeneratorType, - DirEntry, - chain, - TemporaryDirectory, SpooledTemporaryFile, - Queue, SimpleQueue, - _AssertRaisesContext, - Array, LibraryLoader, - SplitResult, ParseResult, - ValueProxy, ApplyResult, - WeakSet, ReferenceType, ref, - ShareableList, SimpleQueue, - Future, _WorkItem, - Morsel, - ): + types = [type, tuple, list, dict, set, frozenset, enumerate, + defaultdict, deque, + SequenceMatcher, + dircmp, + FileInput, + OrderedDict, Counter, UserDict, UserList, + Pattern, Match, + partial, partialmethod, cached_property, + AbstractContextManager, AbstractAsyncContextManager, + Awaitable, Coroutine, + AsyncIterable, AsyncIterator, + AsyncGenerator, Generator, + Iterable, Iterator, + Reversible, + Container, Collection, + Callable, + Mailbox, _PartialFile, + ContextVar, Token, + Field, + Set, MutableSet, + Mapping, MutableMapping, MappingView, + KeysView, ItemsView, ValuesView, + Sequence, MutableSequence, + MappingProxyType, AsyncGeneratorType, + DirEntry, + chain, + TemporaryDirectory, SpooledTemporaryFile, + Queue, SimpleQueue, + _AssertRaisesContext, + SplitResult, ParseResult, + ValueProxy, ApplyResult, + WeakSet, ReferenceType, ref, + ShareableList, SimpleQueue, + Future, _WorkItem, + Morsel] + if ctypes is not None: + types.extend((ctypes.Array, ctypes.LibraryLoader)) + for t in types: if t is None: continue tname = t.__name__ diff --git a/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst b/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst new file mode 100644 index 000000000000000..bf0f54abecd85d6 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst @@ -0,0 +1 @@ +Make ctypes optional in test_genericalias. From 975489bf72dc0ebd4fe3de40b6b95bcb148da999 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 Aug 2020 17:57:56 +0200 Subject: [PATCH 123/486] bpo-41473: Skip test_gdb with gdb 9.2 to work around gdb bug (GH-21768) gdb 9.2 on Fedora Rawhide is not reliable, see: * https://bugs.python.org/issue41473 * https://bugzilla.redhat.com/show_bug.cgi?id=1866884 --- Lib/test/test_gdb.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 22c75bae987219d..44cb9a0f07b75dc 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -51,6 +51,11 @@ def get_gdb_version(): "embedding. Saw %s.%s:\n%s" % (gdb_major_version, gdb_minor_version, gdb_version)) +if (gdb_major_version, gdb_minor_version) >= (9, 2): + # gdb 9.2 on Fedora Rawhide is not reliable, see: + # * https://bugs.python.org/issue41473 + # * https://bugzilla.redhat.com/show_bug.cgi?id=1866884 + raise unittest.SkipTest("https://bugzilla.redhat.com/show_bug.cgi?id=1866884") if not sysconfig.is_python_build(): raise unittest.SkipTest("test_gdb only works on source builds at the moment.") From 3ea9092d2b501ae59b1da51c89719b571b94ff07 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sat, 8 Aug 2020 05:55:35 +0800 Subject: [PATCH 124/486] bpo-40275: Use new test.support helper submodules in tests (GH-21772) --- Lib/sqlite3/test/dbapi.py | 2 +- Lib/test/libregrtest/refleak.py | 6 ++++-- Lib/test/libregrtest/win_utils.py | 6 ++++-- Lib/test/test_audit.py | 11 +++++++---- Lib/test/test_bytes.py | 5 +++-- Lib/test/test_dbm_ndbm.py | 7 ++++--- Lib/test/test_descr.py | 6 +++--- Lib/test/test_xml_etree.py | 2 +- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index be11337154bdd23..119da12170331fd 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -25,7 +25,7 @@ import unittest import sqlite3 as sqlite -from test.support import TESTFN, unlink +from test.support.os_helper import TESTFN, unlink class ModuleTests(unittest.TestCase): diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 8d221232eb6ce7d..77298d318898dbd 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -4,6 +4,8 @@ import warnings from inspect import isabstract from test import support +from test.support import os_helper + try: from _abc import _get_dump except ImportError: @@ -61,7 +63,7 @@ def get_pooled_int(value): return int_pool.setdefault(value, value) nwarmup, ntracked, fname = ns.huntrleaks - fname = os.path.join(support.SAVEDCWD, fname) + fname = os.path.join(os_helper.SAVEDCWD, fname) repcount = nwarmup + ntracked # Pre-allocate to ensure that the loop doesn't allocate anything new @@ -71,7 +73,7 @@ def get_pooled_int(value): fd_deltas = [0] * repcount getallocatedblocks = sys.getallocatedblocks gettotalrefcount = sys.gettotalrefcount - fd_count = support.fd_count + fd_count = os_helper.fd_count # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = 0 diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index 028c01106dee08e..a1cc2201147dbc7 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -5,7 +5,7 @@ import subprocess import uuid import winreg -from test import support +from test.support import os_helper from test.libregrtest.utils import print_warning @@ -69,7 +69,9 @@ def start(self): # Spawn off the load monitor counter_name = self._get_counter_name() command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self._popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD) + self._popen = subprocess.Popen(' '.join(command), + stdout=command_stdout, + cwd=os_helper.SAVEDCWD) # Close our copy of the write end of the pipe os.close(command_stdout) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index f79edbc4bd0d9fc..4f8d06a3ebcbeeb 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -5,6 +5,9 @@ import sys import unittest from test import support +from test.support import import_helper +from test.support import os_helper + if not hasattr(sys, "addaudithook") or not hasattr(sys, "audit"): raise unittest.SkipTest("test only relevant when sys.audit is available") @@ -52,7 +55,7 @@ def test_block_add_hook_baseexception(self): self.do_test("test_block_add_hook_baseexception") def test_pickle(self): - support.import_module("pickle") + import_helper.import_module("pickle") self.do_test("test_pickle") @@ -60,7 +63,7 @@ def test_monkeypatch(self): self.do_test("test_monkeypatch") def test_open(self): - self.do_test("test_open", support.TESTFN) + self.do_test("test_open", os_helper.TESTFN) def test_cantrace(self): self.do_test("test_cantrace") @@ -89,7 +92,7 @@ def test_unraisablehook(self): ) def test_winreg(self): - support.import_module("winreg") + import_helper.import_module("winreg") returncode, events, stderr = self.run_python("test_winreg") if returncode: self.fail(stderr) @@ -103,7 +106,7 @@ def test_winreg(self): self.assertSequenceEqual(["winreg.PyHKEY.Detach", " ", expected], events[4]) def test_socket(self): - support.import_module("socket") + import_helper.import_module("socket") returncode, events, stderr = self.run_python("test_socket") if returncode: self.fail(stderr) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 61b4b9162ccc54a..e61228d1a266f94 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -17,6 +17,7 @@ import test.support from test.support import import_helper +from test.support import warnings_helper import test.string_tests import test.list_tests from test.support import bigaddrspacetest, MAX_Py_ssize_t @@ -27,7 +28,7 @@ def check_bytes_warnings(func): @functools.wraps(func) def wrapper(*args, **kw): - with test.support.check_warnings(('', BytesWarning)): + with warnings_helper.check_warnings(('', BytesWarning)): return func(*args, **kw) return wrapper else: @@ -1769,7 +1770,7 @@ def test_return_self(self): "BytesWarning is needed for this test: use -bb option") def test_compare(self): def bytes_warning(): - return test.support.check_warnings(('', BytesWarning)) + return warnings_helper.check_warnings(('', BytesWarning)) with bytes_warning(): b'' == '' with bytes_warning(): diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index 278fca2cf231529..e17a1d9eca93169 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -1,5 +1,6 @@ from test import support from test.support import import_helper +from test.support import os_helper import_helper.import_module("dbm.ndbm") #skip if not supported import os import unittest @@ -9,7 +10,7 @@ class DbmTestCase(unittest.TestCase): def setUp(self): - self.filename = support.TESTFN + self.filename = os_helper.TESTFN self.d = dbm.ndbm.open(self.filename, 'c') self.d.close() @@ -102,10 +103,10 @@ def test_write_readonly_file(self): with self.assertRaises(error): db[b'not exist key'] = b'not exist value' - @unittest.skipUnless(support.TESTFN_NONASCII, + @unittest.skipUnless(os_helper.TESTFN_NONASCII, 'requires OS support of non-ASCII encodings') def test_nonascii_filename(self): - filename = support.TESTFN_NONASCII + filename = os_helper.TESTFN_NONASCII for suffix in ['', '.pag', '.dir', '.db']: self.addCleanup(support.unlink, filename + suffix) with dbm.ndbm.open(filename, 'c') as db: diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 9738fb52a04bf2b..307416c3300ae30 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -2975,12 +2975,12 @@ class sublist(list): ## self.ateof = 1 ## return s ## - ## f = file(name=support.TESTFN, mode='w') + ## f = file(name=os_helper.TESTFN, mode='w') ## lines = ['a\n', 'b\n', 'c\n'] ## try: ## f.writelines(lines) ## f.close() - ## f = CountedInput(support.TESTFN) + ## f = CountedInput(os_helper.TESTFN) ## for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]): ## got = f.readline() ## self.assertEqual(expected, got) @@ -2992,7 +2992,7 @@ class sublist(list): ## f.close() ## except: ## pass - ## support.unlink(support.TESTFN) + ## os_helper.unlink(os_helper.TESTFN) def test_keywords(self): # Testing keyword args to basic type constructors ... diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 63f9b92a83de24e..c7d446185cfe4e7 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -111,7 +111,7 @@ def checkwarnings(*filters, quiet=False): def decorator(test): def newtest(*args, **kwargs): - with support.check_warnings(*filters, quiet=quiet): + with warnings_helper.check_warnings(*filters, quiet=quiet): test(*args, **kwargs) functools.update_wrapper(newtest, test) return newtest From ebc1520df44b7a619a603d7ca1deff235372bd45 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 7 Aug 2020 23:22:02 +0100 Subject: [PATCH 125/486] Update Azure Pipelines build to use Ubuntu 18.04 and move triggers into YAML files (GH-21776) --- .azure-pipelines/ci.yml | 45 +++++------------------------------------ .azure-pipelines/pr.yml | 45 +++++------------------------------------ 2 files changed, 10 insertions(+), 80 deletions(-) diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 50dc50a65493402..531ed060fd38661 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -1,18 +1,14 @@ variables: - manylinux: false coverage: false -resources: - containers: - - container: manylinux1 - image: pyca/cryptography-manylinux1:x86_64 +trigger: ['master', '3.9', '3.8', '3.7'] jobs: - job: Prebuild displayName: Pre-build checks pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 steps: - template: ./prebuild-checks.yml @@ -24,7 +20,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true')) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 steps: - template: ./docs-steps.yml @@ -56,7 +52,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: testRunTitle: '$(build.sourceBranchName)-linux' @@ -69,37 +65,6 @@ jobs: dependencies: apt -- job: ManyLinux1_CI_Tests - displayName: ManyLinux1 CI Tests - dependsOn: Prebuild - condition: | - and( - and( - succeeded(), - eq(variables['manylinux'], 'true') - ), - eq(dependencies.Prebuild.outputs['tests.run'], 'true') - ) - - pool: - vmImage: ubuntu-16.04 - - container: manylinux1 - - variables: - testRunTitle: '$(build.sourceBranchName)-manylinux1' - testRunPlatform: manylinux1 - openssl_version: '' - - steps: - - template: ./posix-steps.yml - parameters: - dependencies: yum - sudo_dependencies: '' - xvfb: false - patchcheck: false - - - job: Ubuntu_Coverage_CI_Tests displayName: Ubuntu CI Tests (coverage) dependsOn: Prebuild @@ -113,7 +78,7 @@ jobs: ) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 228f9db4f8ef233..1ffe0a97a2465f0 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -1,18 +1,14 @@ variables: - manylinux: false coverage: false -resources: - containers: - - container: manylinux1 - image: pyca/cryptography-manylinux1:x86_64 +pr: ['master', '3.9', '3.8', '3.7'] jobs: - job: Prebuild displayName: Pre-build checks pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 steps: - template: ./prebuild-checks.yml @@ -24,7 +20,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true')) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 steps: - template: ./docs-steps.yml @@ -56,7 +52,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' @@ -69,37 +65,6 @@ jobs: dependencies: apt -- job: ManyLinux1_PR_Tests - displayName: ManyLinux1 PR Tests - dependsOn: Prebuild - condition: | - and( - and( - succeeded(), - eq(variables['manylinux'], 'true') - ), - eq(dependencies.Prebuild.outputs['tests.run'], 'true') - ) - - pool: - vmImage: ubuntu-16.04 - - container: manylinux1 - - variables: - testRunTitle: '$(system.pullRequest.TargetBranch)-manylinux1' - testRunPlatform: manylinux1 - openssl_version: '' - - steps: - - template: ./posix-steps.yml - parameters: - dependencies: yum - sudo_dependencies: '' - xvfb: false - patchcheck: false - - - job: Ubuntu_Coverage_PR_Tests displayName: Ubuntu PR Tests (coverage) dependsOn: Prebuild @@ -113,7 +78,7 @@ jobs: ) pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' From f86af44658964a7d6c15f6e93c0165a9715fb11e Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Fri, 7 Aug 2020 19:57:03 -0700 Subject: [PATCH 126/486] Doc: Add a link to tutorial page from `open()` doc (GH-21737) Adds a link to the "Reading and Writing Files" page so users can more easily discover how file handles are handled with the `with` context manager vs without it. --- Doc/library/functions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 3c36b59befab915..43c47c1da9434c3 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1055,7 +1055,8 @@ are always available. They are listed here in alphabetical order. .. function:: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) Open *file* and return a corresponding :term:`file object`. If the file - cannot be opened, an :exc:`OSError` is raised. + cannot be opened, an :exc:`OSError` is raised. See + :ref:`tut-files` for more examples of how to use this function. *file* is a :term:`path-like object` giving the pathname (absolute or relative to the current working directory) of the file to be opened or an From 95439199e3108bf66caa99248f8930a1042b83f5 Mon Sep 17 00:00:00 2001 From: Konge Date: Sat, 8 Aug 2020 11:03:09 +0800 Subject: [PATCH 127/486] bpo-41497: Fix potential UnicodeDecodeError in dis CLI (GH-21757) --- Lib/dis.py | 2 +- .../next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst diff --git a/Lib/dis.py b/Lib/dis.py index 10e5f7fb08ab21c..e289e176c78ffd7 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -542,7 +542,7 @@ def _test(): import argparse parser = argparse.ArgumentParser() - parser.add_argument('infile', type=argparse.FileType(), nargs='?', default='-') + parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-') args = parser.parse_args() with args.infile as infile: source = infile.read() diff --git a/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst b/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst new file mode 100644 index 000000000000000..2c863ed7ffa3fad --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst @@ -0,0 +1 @@ +Fix potential UnicodeDecodeError in dis module. \ No newline at end of file From c38ff5dff6285a54c9f6cfa812f56bc2fc5f5806 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sat, 8 Aug 2020 17:32:41 +0800 Subject: [PATCH 128/486] bpo-40275: Remove test helpers aliases in test.support (GH-21771) --- Lib/ctypes/test/test_loading.py | 3 ++- Lib/test/support/__init__.py | 23 ++++------------------- Lib/test/test_os.py | 5 +++-- Lib/test/test_posixpath.py | 2 +- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 38b45f95fefae88..7b930f92c70cfb2 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -6,6 +6,7 @@ import unittest import test.support from test.support import import_helper +from test.support import os_helper from ctypes.util import find_library libc_name = None @@ -125,7 +126,7 @@ def test_load_dll_with_flags(self): else: ext = ".dll" - with test.support.temp_dir() as tmp: + with os_helper.temp_dir() as tmp: # We copy two files and load _sqlite3.dll (formerly .pyd), # which has a dependency on sqlite3.dll. Then we test # loading it in subprocesses to avoid it starting in memory diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index b517df7b53b6eaa..e9573d133521025 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -14,25 +14,6 @@ import types import unittest -from .import_helper import ( - CleanImport, DirsOnSysPath, _ignore_deprecated_imports, - _save_and_block_module, _save_and_remove_module, - forget, import_fresh_module, import_module, make_legacy_pyc, - modules_cleanup, modules_setup, unload) -from .os_helper import ( - FS_NONASCII, SAVEDCWD, TESTFN, TESTFN_ASCII, TESTFN_NONASCII, - TESTFN_UNENCODABLE, TESTFN_UNDECODABLE, - TESTFN_UNICODE, can_symlink, can_xattr, - change_cwd, create_empty_file, fd_count, - fs_is_case_insensitive, make_bad_fd, rmdir, - rmtree, skip_unless_symlink, skip_unless_xattr, - temp_cwd, temp_dir, temp_umask, unlink, - EnvironmentVarGuard, FakePath, _longpath) -from .warnings_helper import ( - WarningsRecorder, _filterwarnings, - check_no_resource_warning, check_no_warnings, - check_syntax_warning, check_warnings, ignore_warnings) - from .testresult import get_test_runner @@ -506,6 +487,7 @@ def check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=N def open_urlresource(url, *args, **kw): import urllib.request, urllib.parse + from .os_helper import unlink try: import gzip except ImportError: @@ -1326,6 +1308,8 @@ def skip_if_buggy_ucrt_strfptime(test): class PythonSymlink: """Creates a symlink for the current Python executable""" def __init__(self, link=None): + from .os_helper import TESTFN + self.link = link or os.path.abspath(TESTFN) self._linked = [] self.real = os.path.realpath(sys.executable) @@ -1980,6 +1964,7 @@ def skip_if_broken_multiprocessing_synchronize(): is no available semaphore implementation, or if creating a lock raises an OSError (on Linux only). """ + from .import_helper import import_module # Skip tests if the _multiprocessing extension is missing. import_module('_multiprocessing') diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 03152072c1bf536..5126c84cf30c68b 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -30,6 +30,7 @@ import uuid import warnings from test import support +from test.support import import_helper from test.support import os_helper from test.support import socket_helper from test.support import threading_helper @@ -2674,8 +2675,8 @@ def test_unlink_removes_junction(self): @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") class Win32NtTests(unittest.TestCase): def test_getfinalpathname_handles(self): - nt = support.import_module('nt') - ctypes = support.import_module('ctypes') + nt = import_helper.import_module('nt') + ctypes = import_helper.import_module('ctypes') import ctypes.wintypes kernel = ctypes.WinDLL('Kernel32.dll', use_last_error=True) diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index f37e82505796dbb..42fd8ef8b17465a 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -5,7 +5,7 @@ from test import test_genericpath from test.support import import_helper from test.support import os_helper -from test.support import FakePath +from test.support.os_helper import FakePath from unittest import mock try: From 30af576c3c54724c350e7dee3fd7bd22d9990d1e Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Sat, 8 Aug 2020 19:05:24 +0800 Subject: [PATCH 129/486] bpo-40275: Use new test.support helper submodules in tests (GH-21785) --- Lib/test/libregrtest/save_env.py | 6 +++--- Lib/test/test__osx_support.py | 17 +++++++++-------- Lib/test/test_dbm_ndbm.py | 5 ++--- Lib/test/test_zipfile64.py | 5 +++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 50ed35364961c84..4c9c692400b9202 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -77,7 +77,7 @@ def get_urllib_requests__url_tempfiles(self): return list(urllib.request._url_tempfiles) def restore_urllib_requests__url_tempfiles(self, tempfiles): for filename in tempfiles: - support.unlink(filename) + os_helper.unlink(filename) def get_urllib_requests__opener(self): return urllib.request._opener @@ -245,9 +245,9 @@ def restore_files(self, saved_value): fn = os_helper.TESTFN if fn not in saved_value and (fn + '/') not in saved_value: if os.path.isfile(fn): - support.unlink(fn) + os_helper.unlink(fn) elif os.path.isdir(fn): - support.rmtree(fn) + os_helper.rmtree(fn) _lc = [getattr(locale, lc) for lc in dir(locale) if lc.startswith('LC_')] diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index 1a5d649b40f5315..a3f41d2c5bd075f 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -9,6 +9,7 @@ import unittest import test.support +from test.support import os_helper import _osx_support @@ -39,9 +40,9 @@ def test__find_executable(self): if self.env['PATH']: self.env['PATH'] = self.env['PATH'] + ':' self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir) - test.support.unlink(self.prog_name) + os_helper.unlink(self.prog_name) self.assertIsNone(_osx_support._find_executable(self.prog_name)) - self.addCleanup(test.support.unlink, self.prog_name) + self.addCleanup(os_helper.unlink, self.prog_name) with open(self.prog_name, 'w') as f: f.write("#!/bin/sh\n/bin/echo OK\n") os.chmod(self.prog_name, stat.S_IRWXU) @@ -52,8 +53,8 @@ def test__read_output(self): if self.env['PATH']: self.env['PATH'] = self.env['PATH'] + ':' self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir) - test.support.unlink(self.prog_name) - self.addCleanup(test.support.unlink, self.prog_name) + os_helper.unlink(self.prog_name) + self.addCleanup(os_helper.unlink, self.prog_name) with open(self.prog_name, 'w') as f: f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n") os.chmod(self.prog_name, stat.S_IRWXU) @@ -143,8 +144,8 @@ def test__find_appropriate_compiler(self): suffix = (':' + self.env['PATH']) if self.env['PATH'] else '' self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix for c_name, c_output in compilers: - test.support.unlink(c_name) - self.addCleanup(test.support.unlink, c_name) + os_helper.unlink(c_name) + self.addCleanup(os_helper.unlink, c_name) with open(c_name, 'w') as f: f.write("#!/bin/sh\n/bin/echo " + c_output) os.chmod(c_name, stat.S_IRWXU) @@ -221,8 +222,8 @@ def test__remove_unsupported_archs(self): suffix = (':' + self.env['PATH']) if self.env['PATH'] else '' self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix c_name = 'clang' - test.support.unlink(c_name) - self.addCleanup(test.support.unlink, c_name) + os_helper.unlink(c_name) + self.addCleanup(os_helper.unlink, c_name) # exit status 255 means no PPC support in this compiler chain with open(c_name, 'w') as f: f.write("#!/bin/sh\nexit 255") diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index e17a1d9eca93169..639c8330cd7b9eb 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -1,4 +1,3 @@ -from test import support from test.support import import_helper from test.support import os_helper import_helper.import_module("dbm.ndbm") #skip if not supported @@ -16,7 +15,7 @@ def setUp(self): def tearDown(self): for suffix in ['', '.pag', '.dir', '.db']: - support.unlink(self.filename + suffix) + os_helper.unlink(self.filename + suffix) def test_keys(self): self.d = dbm.ndbm.open(self.filename, 'c') @@ -108,7 +107,7 @@ def test_write_readonly_file(self): def test_nonascii_filename(self): filename = os_helper.TESTFN_NONASCII for suffix in ['', '.pag', '.dir', '.db']: - self.addCleanup(support.unlink, filename + suffix) + self.addCleanup(os_helper.unlink, filename + suffix) with dbm.ndbm.open(filename, 'c') as db: db[b'key'] = b'value' self.assertTrue(any(os.path.exists(filename + suffix) diff --git a/Lib/test/test_zipfile64.py b/Lib/test/test_zipfile64.py index 3a788de221264da..810fdedef39dddb 100644 --- a/Lib/test/test_zipfile64.py +++ b/Lib/test/test_zipfile64.py @@ -17,6 +17,7 @@ from tempfile import TemporaryFile +from test.support import os_helper from test.support import TESTFN, requires_zlib TESTFN2 = TESTFN + "2" @@ -138,8 +139,8 @@ def testMoreThan64kFilesAppend(self): self.assertEqual(content, "%d" % (i**3 % 57)) def tearDown(self): - support.unlink(TESTFN) - support.unlink(TESTFN2) + os_helper.unlink(TESTFN) + os_helper.unlink(TESTFN2) if __name__ == "__main__": unittest.main() From e2f245c5575db1c7414eb439bc36500fc612b0d4 Mon Sep 17 00:00:00 2001 From: Yaroslav Pankovych <31005942+P-Alban@users.noreply.github.com> Date: Sat, 8 Aug 2020 21:48:21 +0300 Subject: [PATCH 130/486] bpo-41455: Provide a link to how the third generation is collected in the GC docs (GH-21703) Co-authored-by: Pablo Galindo --- Doc/library/gc.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 0c33c865304591e..2d85cd3431711ab 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -106,9 +106,9 @@ The :mod:`gc` module provides the following functions: allocations minus the number of deallocations exceeds *threshold0*, collection starts. Initially only generation ``0`` is examined. If generation ``0`` has been examined more than *threshold1* times since generation ``1`` has been - examined, then generation ``1`` is examined as well. Similarly, *threshold2* - controls the number of collections of generation ``1`` before collecting - generation ``2``. + examined, then generation ``1`` is examined as well. + With the third generation, things are a bit more complicated, + see `Collecting the oldest generation `_ for more information. .. function:: get_count() From 4e82b3119960c09bb2c35ebcd892ba2b78591488 Mon Sep 17 00:00:00 2001 From: Jiajie Zhong Date: Sun, 9 Aug 2020 03:29:03 +0800 Subject: [PATCH 131/486] Doc: Add output to example code in programming FAQ (GH-21346) Add output hint to document, part faq/programming, section [How do I write a function with output parameters (call by reference)?](https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference). This patch make the output hint just like prefix code block. --- Doc/faq/programming.rst | 71 +++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 61ffc5dbdaa7736..0731e92f6dbc608 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -518,14 +518,14 @@ desired effect in a number of ways. 1) By returning a tuple of the results:: - def func2(a, b): - a = 'new-value' # a and b are local names - b = b + 1 # assigned to new objects - return a, b # return new values - - x, y = 'old-value', 99 - x, y = func2(x, y) - print(x, y) # output: new-value 100 + >>> def func1(a, b): + ... a = 'new-value' # a and b are local names + ... b = b + 1 # assigned to new objects + ... return a, b # return new values + ... + >>> x, y = 'old-value', 99 + >>> func1(x, y) + ('new-value', 100) This is almost always the clearest solution. @@ -533,38 +533,41 @@ desired effect in a number of ways. 3) By passing a mutable (changeable in-place) object:: - def func1(a): - a[0] = 'new-value' # 'a' references a mutable list - a[1] = a[1] + 1 # changes a shared object - - args = ['old-value', 99] - func1(args) - print(args[0], args[1]) # output: new-value 100 + >>> def func2(a): + ... a[0] = 'new-value' # 'a' references a mutable list + ... a[1] = a[1] + 1 # changes a shared object + ... + >>> args = ['old-value', 99] + >>> func2(args) + >>> args + ['new-value', 100] 4) By passing in a dictionary that gets mutated:: - def func3(args): - args['a'] = 'new-value' # args is a mutable dictionary - args['b'] = args['b'] + 1 # change it in-place - - args = {'a': 'old-value', 'b': 99} - func3(args) - print(args['a'], args['b']) + >>> def func3(args): + ... args['a'] = 'new-value' # args is a mutable dictionary + ... args['b'] = args['b'] + 1 # change it in-place + ... + >>> args = {'a': 'old-value', 'b': 99} + >>> func3(args) + >>> args + {'a': 'new-value', 'b': 100} 5) Or bundle up values in a class instance:: - class callByRef: - def __init__(self, /, **args): - for key, value in args.items(): - setattr(self, key, value) - - def func4(args): - args.a = 'new-value' # args is a mutable callByRef - args.b = args.b + 1 # change object in-place - - args = callByRef(a='old-value', b=99) - func4(args) - print(args.a, args.b) + >>> class Namespace: + ... def __init__(self, /, **args): + ... for key, value in args.items(): + ... setattr(self, key, value) + ... + >>> def func4(args): + ... args.a = 'new-value' # args is a mutable Namespace + ... args.b = args.b + 1 # change object in-place + ... + >>> args = Namespace(a='old-value', b=99) + >>> func4(args) + >>> vars(args) + {'a': 'new-value', 'b': 100} There's almost never a good reason to get this complicated. From 7e3265cef1267974b1461db3567f5eb880080839 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 9 Aug 2020 04:50:53 -0600 Subject: [PATCH 132/486] bpo-35018: Sax parser should provide user access to lexical handlers (GH-20958) Co-Authored-By: Jonathan Gossage --- Doc/library/xml.sax.handler.rst | 62 ++++++- Doc/whatsnew/3.10.rst | 7 + Lib/test/test_sax.py | 157 +++++++++++++++++- Lib/xml/sax/handler.py | 45 +++++ .../2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst | 2 + 5 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index ae0877ca90db07b..3746a58c9b9558a 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -11,12 +11,12 @@ -------------- -The SAX API defines four kinds of handlers: content handlers, DTD handlers, -error handlers, and entity resolvers. Applications normally only need to -implement those interfaces whose events they are interested in; they can -implement the interfaces in a single object or in multiple objects. Handler -implementations should inherit from the base classes provided in the module -:mod:`xml.sax.handler`, so that all methods get default implementations. +The SAX API defines five kinds of handlers: content handlers, DTD handlers, +error handlers, entity resolvers and lexical handlers. Applications normally +only need to implement those interfaces whose events they are interested in; +they can implement the interfaces in a single object or in multiple objects. +Handler implementations should inherit from the base classes provided in the +module :mod:`xml.sax.handler`, so that all methods get default implementations. .. class:: ContentHandler @@ -47,6 +47,12 @@ implementations should inherit from the base classes provided in the module application. The methods of this object control whether errors are immediately converted to exceptions or are handled in some other way. + +.. class:: LexicalHandler + + Interface used by the parser to represent low freqency events which may not + be of interest to many applications. + In addition to these classes, :mod:`xml.sax.handler` provides symbolic constants for the feature and property names. @@ -114,7 +120,7 @@ for the feature and property names. .. data:: property_lexical_handler | value: ``"http://xml.org/sax/properties/lexical-handler"`` - | data type: xml.sax.sax2lib.LexicalHandler (not supported in Python 2) + | data type: xml.sax.handler.LexicalHandler (not supported in Python 2) | description: An optional extension handler for lexical events like comments. | access: read/write @@ -413,3 +419,45 @@ the passed-in exception object. information will continue to be passed to the application. Raising an exception in this method will cause parsing to end. + +.. _lexical-handler-objects: + +LexicalHandler Objects +---------------------- +Optional SAX2 handler for lexical events. + +This handler is used to obtain lexical information about an XML +document. Lexical information includes information describing the +document encoding used and XML comments embedded in the document, as +well as section boundaries for the DTD and for any CDATA sections. +The lexical handlers are used in the same manner as content handlers. + +Set the LexicalHandler of an XMLReader by using the setProperty method +with the property identifier +``'http://xml.org/sax/properties/lexical-handler'``. + + +.. method:: LexicalHandler.comment(content) + + Reports a comment anywhere in the document (including the DTD and + outside the document element). + +.. method:: LexicalHandler.startDTD(name, public_id, system_id) + + Reports the start of the DTD declarations if the document has an + associated DTD. + +.. method:: LexicalHandler.endDTD() + + Reports the end of DTD declaration. + +.. method:: LexicalHandler.startCDATA() + + Reports the start of a CDATA marked section. + + The contents of the CDATA marked section will be reported through + the characters handler. + +.. method:: LexicalHandler.endCDATA() + + Reports the end of a CDATA marked section. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 62bb1438416e6ca..2af0ea3f4dd6404 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -139,6 +139,13 @@ Add :data:`sys.orig_argv` attribute: the list of the original command line arguments passed to the Python executable. (Contributed by Victor Stinner in :issue:`23427`.) +xml +--- + +Add a :class:`~xml.sax.handler.LexicalHandler` class to the +:mod:`xml.sax.handler` module. +(Contributed by Jonathan Gossage and Zackery Spytz in :issue:`35018`.) + Optimizations ============= diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index cfc674be5d141df..801143f9b5f8100 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -13,7 +13,8 @@ from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ XMLFilterBase, prepare_input_source from xml.sax.expatreader import create_parser -from xml.sax.handler import feature_namespaces, feature_external_ges +from xml.sax.handler import (feature_namespaces, feature_external_ges, + LexicalHandler) from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl from io import BytesIO, StringIO import codecs @@ -1356,6 +1357,155 @@ def test_nsattrs_wattr(self): self.assertEqual(attrs.getQNameByName((ns_uri, "attr")), "ns:attr") +class LexicalHandlerTest(unittest.TestCase): + def setUp(self): + self.parser = None + + self.specified_version = '1.0' + self.specified_encoding = 'UTF-8' + self.specified_doctype = 'wish' + self.specified_entity_names = ('nbsp', 'source', 'target') + self.specified_comment = ('Comment in a DTD', + 'Really! You think so?') + self.test_data = StringIO() + self.test_data.write('\n'. + format(self.specified_version, + self.specified_encoding)) + self.test_data.write('\n'. + format(self.specified_comment[0])) + self.test_data.write('\n'. + format(self.specified_doctype)) + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write('\n'. + format(self.specified_entity_names[0])) + self.test_data.write('\n'. + format(self.specified_entity_names[1])) + self.test_data.write('\n'. + format(self.specified_entity_names[2])) + self.test_data.write(']>\n') + self.test_data.write('<{}>'.format(self.specified_doctype)) + self.test_data.write('Aristotle\n') + self.test_data.write('Alexander\n') + self.test_data.write('Supplication\n') + self.test_data.write('Teach me patience!\n') + self.test_data.write('
    &{};&{};&{};
    \n'. + format(self.specified_entity_names[1], + self.specified_entity_names[0], + self.specified_entity_names[2])) + self.test_data.write('\n'.format(self.specified_comment[1])) + self.test_data.write('\n'.format(self.specified_doctype)) + self.test_data.seek(0) + + # Data received from handlers - to be validated + self.version = None + self.encoding = None + self.standalone = None + self.doctype = None + self.publicID = None + self.systemID = None + self.end_of_dtd = False + self.comments = [] + + def test_handlers(self): + class TestLexicalHandler(LexicalHandler): + def __init__(self, test_harness, *args, **kwargs): + super().__init__(*args, **kwargs) + self.test_harness = test_harness + + def startDTD(self, doctype, publicID, systemID): + self.test_harness.doctype = doctype + self.test_harness.publicID = publicID + self.test_harness.systemID = systemID + + def endDTD(self): + self.test_harness.end_of_dtd = True + + def comment(self, text): + self.test_harness.comments.append(text) + + self.parser = create_parser() + self.parser.setContentHandler(ContentHandler()) + self.parser.setProperty( + 'http://xml.org/sax/properties/lexical-handler', + TestLexicalHandler(self)) + source = InputSource() + source.setCharacterStream(self.test_data) + self.parser.parse(source) + self.assertEqual(self.doctype, self.specified_doctype) + self.assertIsNone(self.publicID) + self.assertIsNone(self.systemID) + self.assertTrue(self.end_of_dtd) + self.assertEqual(len(self.comments), + len(self.specified_comment)) + self.assertEqual(f' {self.specified_comment[0]} ', self.comments[0]) + + +class CDATAHandlerTest(unittest.TestCase): + def setUp(self): + self.parser = None + self.specified_chars = [] + self.specified_chars.append(('Parseable character data', False)) + self.specified_chars.append(('<> &% - assorted other XML junk.', True)) + self.char_index = 0 # Used to index specified results within handlers + self.test_data = StringIO() + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write(f'{self.specified_chars[0][0]}\n') + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.write(f'\n') + self.test_data.write('\n') + self.test_data.write('\n') + self.test_data.seek(0) + + # Data received from handlers - to be validated + self.chardata = [] + self.in_cdata = False + + def test_handlers(self): + class TestLexicalHandler(LexicalHandler): + def __init__(self, test_harness, *args, **kwargs): + super().__init__(*args, **kwargs) + self.test_harness = test_harness + + def startCDATA(self): + self.test_harness.in_cdata = True + + def endCDATA(self): + self.test_harness.in_cdata = False + + class TestCharHandler(ContentHandler): + def __init__(self, test_harness, *args, **kwargs): + super().__init__(*args, **kwargs) + self.test_harness = test_harness + + def characters(self, content): + if content != '\n': + h = self.test_harness + t = h.specified_chars[h.char_index] + h.assertEqual(t[0], content) + h.assertEqual(t[1], h.in_cdata) + h.char_index += 1 + + self.parser = create_parser() + self.parser.setContentHandler(TestCharHandler(self)) + self.parser.setProperty( + 'http://xml.org/sax/properties/lexical-handler', + TestLexicalHandler(self)) + source = InputSource() + source.setCharacterStream(self.test_data) + self.parser.parse(source) + + self.assertFalse(self.in_cdata) + self.assertEqual(self.char_index, 2) + + def test_main(): run_unittest(MakeParserTest, ParseTest, @@ -1368,7 +1518,10 @@ def test_main(): StreamReaderWriterXmlgenTest, ExpatReaderTest, ErrorReportingTest, - XmlReaderTest) + XmlReaderTest, + LexicalHandlerTest, + CDATAHandlerTest) + if __name__ == "__main__": test_main() diff --git a/Lib/xml/sax/handler.py b/Lib/xml/sax/handler.py index 481733d2cbe6e5a..e8d417e51942329 100644 --- a/Lib/xml/sax/handler.py +++ b/Lib/xml/sax/handler.py @@ -340,3 +340,48 @@ def resolveEntity(self, publicId, systemId): property_xml_string, property_encoding, property_interning_dict] + + +class LexicalHandler: + """Optional SAX2 handler for lexical events. + + This handler is used to obtain lexical information about an XML + document, that is, information about how the document was encoded + (as opposed to what it contains, which is reported to the + ContentHandler), such as comments and CDATA marked section + boundaries. + + To set the LexicalHandler of an XMLReader, use the setProperty + method with the property identifier + 'http://xml.org/sax/properties/lexical-handler'.""" + + def comment(self, content): + """Reports a comment anywhere in the document (including the + DTD and outside the document element). + + content is a string that holds the contents of the comment.""" + + def startDTD(self, name, public_id, system_id): + """Report the start of the DTD declarations, if the document + has an associated DTD. + + A startEntity event will be reported before declaration events + from the external DTD subset are reported, and this can be + used to infer from which subset DTD declarations derive. + + name is the name of the document element type, public_id the + public identifier of the DTD (or None if none were supplied) + and system_id the system identfier of the external subset (or + None if none were supplied).""" + + def endDTD(self): + """Signals the end of DTD declarations.""" + + def startCDATA(self): + """Reports the beginning of a CDATA marked section. + + The contents of the CDATA marked section will be reported + through the characters event.""" + + def endCDATA(self): + """Reports the end of a CDATA marked section.""" diff --git a/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst b/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst new file mode 100644 index 000000000000000..f764323ae631cfc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst @@ -0,0 +1,2 @@ +Add the :class:`xml.sax.handler.LexicalHandler` class that is present in +other SAX XML implementations. From 0fc2e7a758cfb8f6226ecc9cdc13b83792804814 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 9 Aug 2020 13:08:19 -0400 Subject: [PATCH 133/486] Improve renamed test_run.RecursionLimitTest (GH-21794) PEP 8 style and new comments. --- Lib/idlelib/idle_test/test_run.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 9995dbe2eca5023..e2bdf1cfee35213 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -282,7 +282,8 @@ def test_close(self): self.assertRaises(TypeError, f.close, 1) -class TestSysRecursionLimitWrappers(unittest.TestCase): +class RecursionLimitTest(unittest.TestCase): + # Test (un)install_recursionlimit_wrappers and fixdoc. def test_bad_setrecursionlimit_calls(self): run.install_recursionlimit_wrappers() @@ -296,12 +297,12 @@ def test_roundtrip(self): run.install_recursionlimit_wrappers() self.addCleanup(run.uninstall_recursionlimit_wrappers) - # check that setting the recursion limit works + # Check that setting the recursion limit works. orig_reclimit = sys.getrecursionlimit() self.addCleanup(sys.setrecursionlimit, orig_reclimit) sys.setrecursionlimit(orig_reclimit + 3) - # check that the new limit is returned by sys.getrecursionlimit() + # Check that the new limit is returned by sys.getrecursionlimit(). new_reclimit = sys.getrecursionlimit() self.assertEqual(new_reclimit, orig_reclimit + 3) @@ -313,6 +314,7 @@ def test_default_recursion_limit_preserved(self): self.assertEqual(new_reclimit, orig_reclimit) def test_fixdoc(self): + # Put here until better place for miscellaneous test. def func(): "docstring" run.fixdoc(func, "more") self.assertEqual(func.__doc__, "docstring\n\nmore") From f32585d059bd86832706a301c59fb9c8bf36c242 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 9 Aug 2020 16:08:30 -0400 Subject: [PATCH 134/486] bpo-41468: Improve and test IDLE run error exit (GH-21798) A message box pops up when an unexpected error stops the run process. Tell users it is likely a random glitch, but report it if not. --- Lib/idlelib/NEWS.txt | 3 ++ Lib/idlelib/idle_test/test_run.py | 32 +++++++++++++++++-- Lib/idlelib/run.py | 23 ++++++++----- .../2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst | 1 + 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index e0a671983c746df..fd762077b1b3cf9 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-41468: Improve IDLE run crash error message (which users should +never see). + bpo-41373: Save files loaded with no line ending, as when blank, or different line endings, by setting its line ending to the system default. Fix regression in 3.8.4 and 3.9.0b4. diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index e2bdf1cfee35213..469c13d756d5e8b 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -1,9 +1,10 @@ -"Test run, coverage 42%." +"Test run, coverage 49%." from idlelib import run import unittest from unittest import mock -from test.support import captured_stderr +from idlelib.idle_test.mock_idle import Func +from test.support import captured_output, captured_stderr import io import sys @@ -323,5 +324,32 @@ def func(): "docstring" self.assertEqual(func.__doc__, "more") +class HandleErrorTest(unittest.TestCase): + # Method of MyRPCServer + func = Func() + @mock.patch('idlelib.run.thread.interrupt_main', new=func) + def test_error(self): + eq = self.assertEqual + with captured_output('__stderr__') as err: + try: + raise EOFError + except EOFError: + run.MyRPCServer.handle_error(None, 'abc', '123') + eq(run.exit_now, True) + run.exit_now = False + eq(err.getvalue(), '') + + try: + raise IndexError + except IndexError: + run.MyRPCServer.handle_error(None, 'abc', '123') + eq(run.quitting, True) + run.quitting = False + msg = err.getvalue() + self.assertIn('abc', msg) + self.assertIn('123', msg) + self.assertIn('IndexError', msg) + eq(self.func.called, 2) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 5bd84aadcd8011e..1e84ecc6584ef1c 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -387,14 +387,21 @@ def handle_error(self, request, client_address): thread.interrupt_main() except: erf = sys.__stderr__ - print('\n' + '-'*40, file=erf) - print('Unhandled server exception!', file=erf) - print('Thread: %s' % threading.current_thread().name, file=erf) - print('Client Address: ', client_address, file=erf) - print('Request: ', repr(request), file=erf) - traceback.print_exc(file=erf) - print('\n*** Unrecoverable, server exiting!', file=erf) - print('-'*40, file=erf) + print(textwrap.dedent(f""" + {'-'*40} + Unhandled exception in user code execution server!' + Thread: {threading.current_thread().name} + IDLE Client Address: {client_address} + Request: {request!r} + """), file=erf) + traceback.print_exc(limit=-20, file=erf) + print(textwrap.dedent(f""" + *** Unrecoverable, server exiting! + + Users should never see this message; it is likely transient. + If this recurs, report this with a copy of the message + and an explanation of how to make it repeat. + {'-'*40}"""), file=erf) quitting = True thread.interrupt_main() diff --git a/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst b/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst new file mode 100644 index 000000000000000..e41c7d574905cd5 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst @@ -0,0 +1 @@ +Improve IDLE run crash error message (which users should never see). From fb7748682cf9ec399391d9dee8da6332163ab5ca Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 10 Aug 2020 09:43:56 -0400 Subject: [PATCH 135/486] bpo-41514: Fix buggy IDLE test (GH-21808) test_run method test_fatal_error failed when run twice, as with python -m test -m test_fatal_error test_idle test_idle because func.called was not reinitialized to 0. This bug caused a failure on a refleak buildbot. --- Lib/idlelib/idle_test/test_run.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 469c13d756d5e8b..37c0d4525e56cd9 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -326,11 +326,11 @@ def func(): "docstring" class HandleErrorTest(unittest.TestCase): # Method of MyRPCServer - func = Func() - @mock.patch('idlelib.run.thread.interrupt_main', new=func) - def test_error(self): + def test_fatal_error(self): eq = self.assertEqual - with captured_output('__stderr__') as err: + with captured_output('__stderr__') as err,\ + mock.patch('idlelib.run.thread.interrupt_main', + new_callable=Func) as func: try: raise EOFError except EOFError: @@ -349,7 +349,7 @@ def test_error(self): self.assertIn('abc', msg) self.assertIn('123', msg) self.assertIn('IndexError', msg) - eq(self.func.called, 2) + eq(func.called, 2) if __name__ == '__main__': unittest.main(verbosity=2) From f207d5ad36eb505d7e3313a9c813f83919d89f95 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Mon, 10 Aug 2020 16:32:21 +0200 Subject: [PATCH 136/486] bpo-41324 Add a minimal decimal capsule API (#21519) --- Doc/c-api/concrete.rst | 1 + Doc/c-api/decimal.rst | 231 ++++++++++++++++ Include/pydecimal.h | 180 +++++++++++++ Lib/test/test_decimal.py | 176 ++++++++++++ .../2020-08-10-16-05-08.bpo-41324.waZD35.rst | 3 + Modules/_decimal/_decimal.c | 185 ++++++++++++- Modules/_decimal/tests/deccheck.py | 74 +++++ Modules/_testcapimodule.c | 253 ++++++++++++++++++ 8 files changed, 1096 insertions(+), 7 deletions(-) create mode 100644 Doc/c-api/decimal.rst create mode 100644 Include/pydecimal.h create mode 100644 Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index c1d9fa1b41a3fee..bf263d6e4c2641b 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -115,3 +115,4 @@ Other Objects coro.rst contextvars.rst datetime.rst + decimal.rst diff --git a/Doc/c-api/decimal.rst b/Doc/c-api/decimal.rst new file mode 100644 index 000000000000000..f530571ebae5771 --- /dev/null +++ b/Doc/c-api/decimal.rst @@ -0,0 +1,231 @@ +.. sectionauthor:: Stefan Krah + +.. highlight:: c + + +Decimal capsule API +=================== + +Capsule API functions can be used in the same manner as regular library +functions, provided that the API has been initialized. + + +Initialize +---------- + +Typically, a C extension module that uses the decimal API will do these +steps in its init function: + +.. code-block:: + + #include "pydecimal.h" + + static int decimal_initialized = 0; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + +Type checking, predicates, accessors +------------------------------------ + +.. c:function:: int PyDec_TypeCheck(const PyObject *dec) + + Return 1 if ``dec`` is a Decimal, 0 otherwise. This function does not set + any exceptions. + + +.. c:function:: int PyDec_IsSpecial(const PyObject *dec) + + Return 1 if ``dec`` is ``NaN``, ``sNaN`` or ``Infinity``, 0 otherwise. + + Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that + this is the only failure mode, so if ``dec`` has already been type-checked, no + errors can occur and the function can be treated as a simple predicate. + + +.. c:function:: int PyDec_IsNaN(const PyObject *dec) + + Return 1 if ``dec`` is ``NaN`` or ``sNaN``, 0 otherwise. + + Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that + this is the only failure mode, so if ``dec`` has already been type-checked, no + errors can occur and the function can be treated as a simple predicate. + + +.. c:function:: int PyDec_IsInfinite(const PyObject *dec) + + Return 1 if ``dec`` is ``Infinity``, 0 otherwise. + + Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that + this is the only failure mode, so if ``dec`` has already been type-checked, no + errors can occur and the function can be treated as a simple predicate. + + +.. c:function:: int64_t PyDec_GetDigits(const PyObject *dec) + + Return the number of digits in the coefficient. For ``Infinity``, the + number of digits is always zero. Typically, the same applies to ``NaN`` + and ``sNaN``, but both of these can have a payload that is equivalent to + a coefficient. Therefore, ``NaNs`` can have a nonzero return value. + + Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that + this is the only failure mode, so if ``dec`` has already been type-checked, no + errors can occur and the function can be treated as a simple accessor. + + +Exact conversions between decimals and primitive C types +-------------------------------------------------------- + +This API supports conversions for decimals with a coefficient up to 38 digits. + +Data structures +~~~~~~~~~~~~~~~ + +The conversion functions use the following status codes and data structures: + +.. code-block:: + + /* status cases for getting a triple */ + enum mpd_triple_class { + MPD_TRIPLE_NORMAL, + MPD_TRIPLE_INF, + MPD_TRIPLE_QNAN, + MPD_TRIPLE_SNAN, + MPD_TRIPLE_ERROR, + }; + + typedef struct { + enum mpd_triple_class tag; + uint8_t sign; + uint64_t hi; + uint64_t lo; + int64_t exp; + } mpd_uint128_triple_t; + +The status cases are explained below. ``sign`` is 0 for positive and 1 for negative. +``((uint128_t)hi << 64) + lo`` is the coefficient, ``exp`` is the exponent. + +The data structure is called "triple" because the decimal triple (sign, coeff, exp) +is an established term and (``hi``, ``lo``) represents a single ``uint128_t`` coefficient. + + +Functions +~~~~~~~~~ + +.. c:function:: mpd_uint128_triple_t PyDec_AsUint128Triple(const PyObject *dec) + + Convert a decimal to a triple. As above, it is guaranteed that the only + Python failure mode is a TypeError, checks can be omitted if the type is + known. + + For simplicity, the usage of the function and all special cases are + explained in code form and comments: + +.. code-block:: + + triple = PyDec_AsUint128Triple(dec); + switch (triple.tag) { + case MPD_TRIPLE_QNAN: + /* + * Success: handle a quiet NaN. + * 1) triple.sign is 0 or 1. + * 2) triple.exp is always 0. + * 3) If triple.hi or triple.lo are nonzero, the NaN has a payload. + */ + break; + + case MPD_TRIPLE_SNAN: + /* + * Success: handle a signaling NaN. + * 1) triple.sign is 0 or 1. + * 2) triple.exp is always 0. + * 3) If triple.hi or triple.lo are nonzero, the sNaN has a payload. + */ + break; + + case MPD_TRIPLE_INF: + /* + * Success: handle Infinity. + * 1) triple.sign is 0 or 1. + * 2) triple.exp is always 0. + * 3) triple.hi and triple.lo are always zero. + */ + break; + + case MPD_TRIPLE_NORMAL: + /* Success: handle a finite value. */ + break; + + case MPD_TRIPLE_ERROR: + /* TypeError check: can be omitted if the type of dec is known. */ + if (PyErr_Occurred()) { + return NULL; + } + + /* Too large for conversion. PyDec_AsUint128Triple() does not set an + exception so applications can choose themselves. Typically this + would be a ValueError. */ + PyErr_SetString(PyExc_ValueError, + "value out of bounds for a uint128 triple"); + return NULL; + } + +.. c:function:: PyObject *PyDec_FromUint128Triple(const mpd_uint128_triple_t *triple) + + Create a decimal from a triple. The following rules must be observed for + initializing the triple: + + 1) ``triple.sign`` must always be 0 (for positive) or 1 (for negative). + + 2) ``MPD_TRIPLE_QNAN``: ``triple.exp`` must be 0. If ``triple.hi`` or ``triple.lo`` + are nonzero, create a ``NaN`` with a payload. + + 3) ``MPD_TRIPLE_SNAN``: ``triple.exp`` must be 0. If ``triple.hi`` or ``triple.lo`` + are nonzero, create an ``sNaN`` with a payload. + + 4) ``MPD_TRIPLE_INF``: ``triple.exp``, ``triple.hi`` and ``triple.lo`` must be zero. + + 5) ``MPD_TRIPLE_NORMAL``: ``MPD_MIN_ETINY + 38 < triple.exp < MPD_MAX_EMAX - 38``. + ``triple.hi`` and ``triple.lo`` can be chosen freely. + + 6) ``MPD_TRIPLE_ERROR``: It is always an error to set this tag. + + + If one of the above conditions is not met, the function returns ``NaN`` if + the ``InvalidOperation`` trap is not set in the thread local context. Otherwise, + it sets the ``InvalidOperation`` exception and returns NULL. + + Additionally, though extremely unlikely give the small allocation sizes, + the function can set ``MemoryError`` and return ``NULL``. + + +Advanced API +------------ + +This API enables the use of ``libmpdec`` functions. Since Python is compiled with +hidden symbols, the API requires an external libmpdec and the ``mpdecimal.h`` +header. + + +Functions +~~~~~~~~~ + +.. c:function:: PyObject *PyDec_Alloc(void) + + Return a new decimal that can be used in the ``result`` position of ``libmpdec`` + functions. + +.. c:function:: mpd_t *PyDec_Get(PyObject *v) + + Get a pointer to the internal ``mpd_t`` of the decimal. Decimals are immutable, + so this function must only be used on a new Decimal that has been created by + PyDec_Alloc(). + +.. c:function:: const mpd_t *PyDec_GetConst(const PyObject *v) + + Get a pointer to the constant internal ``mpd_t`` of the decimal. diff --git a/Include/pydecimal.h b/Include/pydecimal.h new file mode 100644 index 000000000000000..9b6440e1c2ab1cb --- /dev/null +++ b/Include/pydecimal.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2020 Stefan Krah. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#ifndef CPYTHON_DECIMAL_H_ +#define CPYTHON_DECIMAL_H_ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************/ +/* Libmpdec API */ +/****************************************************************************/ + +#ifndef LIBMPDEC_MPDECIMAL_H_ +struct mpd_t; /* ABI-stable in the libmpdec-2.x series */ + +/* status cases for getting a triple */ +enum mpd_triple_class { + MPD_TRIPLE_NORMAL, + MPD_TRIPLE_INF, + MPD_TRIPLE_QNAN, + MPD_TRIPLE_SNAN, + MPD_TRIPLE_ERROR, +}; + +typedef struct { + enum mpd_triple_class tag; + uint8_t sign; + uint64_t hi; + uint64_t lo; + int64_t exp; +} mpd_uint128_triple_t; +#endif + + +/****************************************************************************/ +/* Capsule API */ +/****************************************************************************/ + +/* Simple API */ +#define PyDec_TypeCheck_INDEX 0 +#define PyDec_TypeCheck_RETURN int +#define PyDec_TypeCheck_ARGS (const PyObject *) + +#define PyDec_IsSpecial_INDEX 1 +#define PyDec_IsSpecial_RETURN int +#define PyDec_IsSpecial_ARGS (const PyObject *) + +#define PyDec_IsNaN_INDEX 2 +#define PyDec_IsNaN_RETURN int +#define PyDec_IsNaN_ARGS (const PyObject *) + +#define PyDec_IsInfinite_INDEX 3 +#define PyDec_IsInfinite_RETURN int +#define PyDec_IsInfinite_ARGS (const PyObject *) + +#define PyDec_GetDigits_INDEX 4 +#define PyDec_GetDigits_RETURN int64_t +#define PyDec_GetDigits_ARGS (const PyObject *) + +#define PyDec_AsUint128Triple_INDEX 5 +#define PyDec_AsUint128Triple_RETURN mpd_uint128_triple_t +#define PyDec_AsUint128Triple_ARGS (const PyObject *) + +#define PyDec_FromUint128Triple_INDEX 6 +#define PyDec_FromUint128Triple_RETURN PyObject * +#define PyDec_FromUint128Triple_ARGS (const mpd_uint128_triple_t *triple) + +/* Advanced API */ +#define PyDec_Alloc_INDEX 7 +#define PyDec_Alloc_RETURN PyObject * +#define PyDec_Alloc_ARGS (void) + +#define PyDec_Get_INDEX 8 +#define PyDec_Get_RETURN mpd_t * +#define PyDec_Get_ARGS (PyObject *) + +#define PyDec_GetConst_INDEX 9 +#define PyDec_GetConst_RETURN const mpd_t * +#define PyDec_GetConst_ARGS (const PyObject *) + +#define CPYTHON_DECIMAL_MAX_API 10 + + +#ifdef CPYTHON_DECIMAL_MODULE +/* Simple API */ +static PyDec_TypeCheck_RETURN PyDec_TypeCheck PyDec_TypeCheck_ARGS; +static PyDec_IsSpecial_RETURN PyDec_IsSpecial PyDec_IsSpecial_ARGS; +static PyDec_IsNaN_RETURN PyDec_IsNaN PyDec_IsNaN_ARGS; +static PyDec_IsInfinite_RETURN PyDec_IsInfinite PyDec_IsInfinite_ARGS; +static PyDec_GetDigits_RETURN PyDec_GetDigits PyDec_GetDigits_ARGS; +static PyDec_AsUint128Triple_RETURN PyDec_AsUint128Triple PyDec_AsUint128Triple_ARGS; +static PyDec_FromUint128Triple_RETURN PyDec_FromUint128Triple PyDec_FromUint128Triple_ARGS; + +/* Advanced API */ +static PyDec_Alloc_RETURN PyDec_Alloc PyDec_Alloc_ARGS; +static PyDec_Get_RETURN PyDec_Get PyDec_Get_ARGS; +static PyDec_GetConst_RETURN PyDec_GetConst PyDec_GetConst_ARGS; +#else +static void **_decimal_api; + +/* Simple API */ +#define PyDec_TypeCheck \ + (*(PyDec_TypeCheck_RETURN (*)PyDec_TypeCheck_ARGS) _decimal_api[PyDec_TypeCheck_INDEX]) + +#define PyDec_IsSpecial \ + (*(PyDec_IsSpecial_RETURN (*)PyDec_IsSpecial_ARGS) _decimal_api[PyDec_IsSpecial_INDEX]) + +#define PyDec_IsNaN \ + (*(PyDec_IsNaN_RETURN (*)PyDec_IsNaN_ARGS) _decimal_api[PyDec_IsNaN_INDEX]) + +#define PyDec_IsInfinite \ + (*(PyDec_IsInfinite_RETURN (*)PyDec_IsInfinite_ARGS) _decimal_api[PyDec_IsInfinite_INDEX]) + +#define PyDec_GetDigits \ + (*(PyDec_GetDigits_RETURN (*)PyDec_GetDigits_ARGS) _decimal_api[PyDec_GetDigits_INDEX]) + +#define PyDec_AsUint128Triple \ + (*(PyDec_AsUint128Triple_RETURN (*)PyDec_AsUint128Triple_ARGS) _decimal_api[PyDec_AsUint128Triple_INDEX]) + +#define PyDec_FromUint128Triple \ + (*(PyDec_FromUint128Triple_RETURN (*)PyDec_FromUint128Triple_ARGS) _decimal_api[PyDec_FromUint128Triple_INDEX]) + +/* Advanced API */ +#define PyDec_Alloc \ + (*(PyDec_Alloc_RETURN (*)PyDec_Alloc_ARGS) _decimal_api[PyDec_Alloc_INDEX]) + +#define PyDec_Get \ + (*(PyDec_Get_RETURN (*)PyDec_Get_ARGS) _decimal_api[PyDec_Get_INDEX]) + +#define PyDec_GetConst \ + (*(PyDec_GetConst_RETURN (*)PyDec_GetConst_ARGS) _decimal_api[PyDec_GetConst_INDEX]) + + +static int +import_decimal(void) +{ + _decimal_api = (void **)PyCapsule_Import("_decimal._API", 0); + if (_decimal_api == NULL) { + return -1; + } + + return 0; +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CPYTHON_DECIMAL_H_ */ diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 5d0992a66e6cea7..113b37ddaa9cd65 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -43,6 +43,13 @@ import inspect import threading +from _testcapi import decimal_is_special +from _testcapi import decimal_is_nan +from _testcapi import decimal_is_infinite +from _testcapi import decimal_get_digits +from _testcapi import decimal_as_triple +from _testcapi import decimal_from_triple + C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) @@ -4751,6 +4758,175 @@ def test_constants(self): self.assertEqual(C.DecTraps, C.DecErrors|C.DecOverflow|C.DecUnderflow) + def test_decimal_api_predicates(self): + # Capsule API + + d = C.Decimal("0") + self.assertFalse(decimal_is_special(d)) + self.assertFalse(decimal_is_nan(d)) + self.assertFalse(decimal_is_infinite(d)) + + d = C.Decimal("NaN") + self.assertTrue(decimal_is_special(d)) + self.assertTrue(decimal_is_nan(d)) + self.assertFalse(decimal_is_infinite(d)) + + d = C.Decimal("sNaN") + self.assertTrue(decimal_is_special(d)) + self.assertTrue(decimal_is_nan(d)) + self.assertFalse(decimal_is_infinite(d)) + + d = C.Decimal("inf") + self.assertTrue(decimal_is_special(d)) + self.assertFalse(decimal_is_nan(d)) + self.assertTrue(decimal_is_infinite(d)) + + def test_decimal_api_get_digits(self): + # Capsule API + + d = C.Decimal("0") + self.assertEqual(decimal_get_digits(d), 1) + + d = C.Decimal("1234567890") + self.assertEqual(decimal_get_digits(d), 10) + + d = C.Decimal("inf") + self.assertEqual(decimal_get_digits(d), 0) + + d = C.Decimal("NaN") + self.assertEqual(decimal_get_digits(d), 0) + + d = C.Decimal("sNaN") + self.assertEqual(decimal_get_digits(d), 0) + + d = C.Decimal("NaN1234567890") + self.assertEqual(decimal_get_digits(d), 10) + + d = C.Decimal("sNaN1234567890") + self.assertEqual(decimal_get_digits(d), 10) + + def test_decimal_api_triple(self): + # Capsule API + + def as_triple(d): + """Convert a decimal to a decimal triple with a split uint128_t + coefficient: + + (sign, hi, lo, exp) + + It is called 'triple' because (hi, lo) are regarded as a single + uint128_t that is split because not all compilers support uint128_t. + """ + sign, digits, exp = d.as_tuple() + + s = "".join(str(d) for d in digits) + coeff = int(s) if s else 0 + + if coeff < 0 or coeff >= 2**128: + raise ValueError("value out of bounds for a uint128 triple"); + + hi, lo = divmod(coeff, 2**64) + return (sign, hi, lo, exp) + + def from_triple(triple): + """Convert a decimal triple with a split uint128_t coefficient to a string. + """ + sign, hi, lo, exp = triple + coeff = hi * 2**64 + lo + + if coeff < 0 or coeff >= 2**128: + raise ValueError("value out of bounds for a uint128 triple"); + + digits = tuple(int(c) for c in str(coeff)) + + return P.Decimal((sign, digits, exp)) + + signs = ["", "-"] + + coefficients = [ + "000000000000000000000000000000000000000", + + "299999999999999999999999999999999999999", + "299999999999999999990000000000000000000", + "200000000000000000009999999999999999999", + "000000000000000000009999999999999999999", + + "299999999999999999999999999999000000000", + "299999999999999999999000000000999999999", + "299999999999000000000999999999999999999", + "299000000000999999999999999999999999999", + "000999999999999999999999999999999999999", + + "300000000000000000000000000000000000000", + "310000000000000000001000000000000000000", + "310000000000000000000000000000000000000", + "300000000000000000001000000000000000000", + + "340100000000100000000100000000100000000", + "340100000000100000000100000000000000000", + "340100000000100000000000000000100000000", + "340100000000000000000100000000100000000", + "340000000000100000000100000000100000000", + + "340282366920938463463374607431768211455", + ] + + exponents = [ + "E+0", "E+1", "E-1", + "E+%s" % str(C.MAX_EMAX-38), + "E-%s" % str(C.MIN_ETINY+38), + ] + + for sign in signs: + for coeff in coefficients: + for exp in exponents: + s = sign + coeff + exp + + ctriple = decimal_as_triple(C.Decimal(s)) + ptriple = as_triple(P.Decimal(s)) + self.assertEqual(ctriple, ptriple) + + c = decimal_from_triple(ctriple) + p = decimal_from_triple(ptriple) + self.assertEqual(str(c), str(p)) + + for s in ["NaN", "-NaN", "sNaN", "-sNaN", "NaN123", "sNaN123", "inf", "-inf"]: + ctriple = decimal_as_triple(C.Decimal(s)) + ptriple = as_triple(P.Decimal(s)) + self.assertEqual(ctriple, ptriple) + + c = decimal_from_triple(ctriple) + p = decimal_from_triple(ptriple) + self.assertEqual(str(c), str(p)) + + def test_decimal_api_errors(self): + # Capsule API + + self.assertRaises(TypeError, decimal_as_triple, "X") + self.assertRaises(ValueError, decimal_as_triple, C.Decimal(2**128)) + self.assertRaises(ValueError, decimal_as_triple, C.Decimal(-2**128)) + + self.assertRaises(TypeError, decimal_from_triple, "X") + self.assertRaises(ValueError, decimal_from_triple, ()) + self.assertRaises(ValueError, decimal_from_triple, (1, 2, 3, 4, 5)) + self.assertRaises(ValueError, decimal_from_triple, (2**8, 0, 0, 0)) + self.assertRaises(OverflowError, decimal_from_triple, (0, 2**64, 0, 0)) + self.assertRaises(OverflowError, decimal_from_triple, (0, 0, 2**64, 0)) + self.assertRaises(OverflowError, decimal_from_triple, (0, 0, 0, 2**63)) + self.assertRaises(OverflowError, decimal_from_triple, (0, 0, 0, -2**63-1)) + self.assertRaises(ValueError, decimal_from_triple, (0, 0, 0, "X")) + self.assertRaises(TypeError, decimal_from_triple, (0, 0, 0, ())) + + with C.localcontext(C.Context()): + self.assertRaises(C.InvalidOperation, decimal_from_triple, (2, 0, 0, 0)) + self.assertRaises(C.InvalidOperation, decimal_from_triple, (0, 0, 0, 2**63-1)) + self.assertRaises(C.InvalidOperation, decimal_from_triple, (0, 0, 0, -2**63)) + + self.assertRaises(TypeError, decimal_is_special, "X") + self.assertRaises(TypeError, decimal_is_nan, "X") + self.assertRaises(TypeError, decimal_is_infinite, "X") + self.assertRaises(TypeError, decimal_get_digits, "X") + class CWhitebox(unittest.TestCase): """Whitebox testing for _decimal""" diff --git a/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst b/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst new file mode 100644 index 000000000000000..e09332ab11e1d7f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst @@ -0,0 +1,3 @@ +Add a minimal decimal capsule API. The API supports fast conversions +between Decimals up to 38 digits and their triple representation as a C +struct. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index fb4e020f1260e6e..e7c44acba02fc2e 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,6 +33,8 @@ #include +#define CPYTHON_DECIMAL_MODULE +#include "pydecimal.h" #include "docstrings.h" @@ -5555,6 +5557,160 @@ static PyTypeObject PyDecContext_Type = }; +/****************************************************************************/ +/* C-API */ +/****************************************************************************/ + +static void *_decimal_api[CPYTHON_DECIMAL_MAX_API]; + +/* Simple API */ +static int +PyDec_TypeCheck(const PyObject *v) +{ + return PyDec_Check(v); +} + +static int +PyDec_IsSpecial(const PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_IsSpecial: argument must be a Decimal"); + return -1; + } + + return mpd_isspecial(MPD(v)); +} + +static int +PyDec_IsNaN(const PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_IsNaN: argument must be a Decimal"); + return -1; + } + + return mpd_isnan(MPD(v)); +} + +static int +PyDec_IsInfinite(const PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_IsInfinite: argument must be a Decimal"); + return -1; + } + + return mpd_isinfinite(MPD(v)); +} + +static int64_t +PyDec_GetDigits(const PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_GetDigits: argument must be a Decimal"); + return -1; + } + + return MPD(v)->digits; +} + +static mpd_uint128_triple_t +PyDec_AsUint128Triple(const PyObject *v) +{ + if (!PyDec_Check(v)) { + mpd_uint128_triple_t triple = { MPD_TRIPLE_ERROR, 0, 0, 0, 0 }; + PyErr_SetString(PyExc_TypeError, + "PyDec_AsUint128Triple: argument must be a Decimal"); + return triple; + } + + return mpd_as_uint128_triple(MPD(v)); +} + +static PyObject * +PyDec_FromUint128Triple(const mpd_uint128_triple_t *triple) +{ + PyObject *context; + PyObject *result; + uint32_t status = 0; + + CURRENT_CONTEXT(context); + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + if (mpd_from_uint128_triple(MPD(result), triple, &status) < 0) { + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + } + + return result; +} + +/* Advanced API */ +static PyObject * +PyDec_Alloc(void) +{ + return dec_alloc(); +} + +static mpd_t * +PyDec_Get(PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_Get: argument must be a Decimal"); + return NULL; + } + + return MPD(v); +} + +static const mpd_t * +PyDec_GetConst(const PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "PyDec_GetConst: argument must be a Decimal"); + return NULL; + } + + return MPD(v); +} + +static PyObject * +init_api(void) +{ + /* Simple API */ + _decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck; + _decimal_api[PyDec_IsSpecial_INDEX] = (void *)PyDec_IsSpecial; + _decimal_api[PyDec_IsNaN_INDEX] = (void *)PyDec_IsNaN; + _decimal_api[PyDec_IsInfinite_INDEX] = (void *)PyDec_IsInfinite; + _decimal_api[PyDec_GetDigits_INDEX] = (void *)PyDec_GetDigits; + _decimal_api[PyDec_AsUint128Triple_INDEX] = (void *)PyDec_AsUint128Triple; + _decimal_api[PyDec_FromUint128Triple_INDEX] = (void *)PyDec_FromUint128Triple; + + /* Advanced API */ + _decimal_api[PyDec_Alloc_INDEX] = (void *)PyDec_Alloc; + _decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get; + _decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst; + + return PyCapsule_New(_decimal_api, "_decimal._API", NULL); +} + + +/****************************************************************************/ +/* Module */ +/****************************************************************************/ + static PyMethodDef _decimal_methods [] = { { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, @@ -5665,17 +5821,27 @@ PyInit__decimal(void) DecCondMap *cm; struct ssize_constmap *ssize_cm; struct int_constmap *int_cm; + static PyObject *capsule = NULL; + static int initialized = 0; int i; /* Init libmpdec */ - mpd_traphandler = dec_traphandler; - mpd_mallocfunc = PyMem_Malloc; - mpd_reallocfunc = PyMem_Realloc; - mpd_callocfunc = mpd_callocfunc_em; - mpd_free = PyMem_Free; - mpd_setminalloc(_Py_DEC_MINALLOC); + if (!initialized) { + mpd_traphandler = dec_traphandler; + mpd_mallocfunc = PyMem_Malloc; + mpd_reallocfunc = PyMem_Realloc; + mpd_callocfunc = mpd_callocfunc_em; + mpd_free = PyMem_Free; + mpd_setminalloc(_Py_DEC_MINALLOC); + + capsule = init_api(); + if (capsule == NULL) { + return NULL; + } + initialized = 1; + } /* Init external C-API functions */ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5900,6 +6066,11 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); + /* Add capsule API */ + Py_INCREF(capsule); + if (PyModule_AddObject(m, "_API", capsule) < 0) { + goto error; + } return m; diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 5d9179e61689d00..15f104dc463cb82 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -49,6 +49,9 @@ from formathelper import rand_format, rand_locale from _pydecimal import _dec_from_triple +from _testcapi import decimal_as_triple +from _testcapi import decimal_from_triple + C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) EXIT_STATUS = 0 @@ -153,6 +156,45 @@ TernaryRestricted = ['__pow__', 'context.power'] +# ====================================================================== +# Triple tests +# ====================================================================== + +def c_as_triple(dec): + sign, hi, lo, exp = decimal_as_triple(dec) + + coeff = hi * 2**64 + lo + return (sign, coeff, exp) + +def c_from_triple(triple): + sign, coeff, exp = triple + + hi = coeff // 2**64 + lo = coeff % 2**64 + return decimal_from_triple((sign, hi, lo, exp)) + +def p_as_triple(dec): + sign, digits, exp = dec.as_tuple() + + s = "".join(str(d) for d in digits) + coeff = int(s) if s else 0 + + if coeff < 0 or coeff >= 2**128: + raise ValueError("value out of bounds for a uint128 triple"); + + return (sign, coeff, exp) + +def p_from_triple(triple): + sign, coeff, exp = triple + + if coeff < 0 or coeff >= 2**128: + raise ValueError("value out of bounds for a uint128 triple"); + + digits = tuple(int(c) for c in str(coeff)) + + return P.Decimal((sign, digits, exp)) + + # ====================================================================== # Unified Context # ====================================================================== @@ -846,12 +888,44 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) + ctriple = None + if t.funcname not in ['__radd__', '__rmul__']: # see skip handler + try: + ctriple = c_as_triple(t.rc) + except ValueError: + try: + ptriple = p_as_triple(t.rp) + except ValueError: + pass + else: + raise RuntimeError("ValueError not raised") + else: + cres = c_from_triple(ctriple) + t.cresults.append(ctriple) + t.cresults.append(str(cres)) + + ptriple = p_as_triple(t.rp) + pres = p_from_triple(ptriple) + t.presults.append(ptriple) + t.presults.append(str(pres)) + if t.with_maxcontext and isinstance(t.rmax, C.Decimal): t.maxresults.append(t.rmax.to_eng_string()) t.maxresults.append(t.rmax.as_tuple()) t.maxresults.append(str(t.rmax.imag)) t.maxresults.append(str(t.rmax.real)) + if ctriple is not None: + # NaN payloads etc. depend on precision and clamp. + if all_nan(t.rc) and all_nan(t.rmax): + t.maxresults.append(ctriple) + t.maxresults.append(str(cres)) + else: + maxtriple = c_as_triple(t.rmax) + maxres = c_from_triple(maxtriple) + t.maxresults.append(maxtriple) + t.maxresults.append(str(maxres)) + nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index fca94a83a5d04ed..593034ef65e2ca3 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -19,6 +19,7 @@ #include "Python.h" #include "datetime.h" +#include "pydecimal.h" #include "marshal.h" #include "structmember.h" // PyMemberDef #include @@ -2705,6 +2706,252 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) return Py_BuildValue("(lll)", days, seconds, microseconds); } +/* Test decimal API */ +static int decimal_initialized = 0; +static PyObject * +decimal_is_special(PyObject *module, PyObject *dec) +{ + int is_special; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + is_special = PyDec_IsSpecial(dec); + if (is_special < 0) { + return NULL; + } + + return PyBool_FromLong(is_special); +} + +static PyObject * +decimal_is_nan(PyObject *module, PyObject *dec) +{ + int is_nan; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + is_nan = PyDec_IsNaN(dec); + if (is_nan < 0) { + return NULL; + } + + return PyBool_FromLong(is_nan); +} + +static PyObject * +decimal_is_infinite(PyObject *module, PyObject *dec) +{ + int is_infinite; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + is_infinite = PyDec_IsInfinite(dec); + if (is_infinite < 0) { + return NULL; + } + + return PyBool_FromLong(is_infinite); +} + +static PyObject * +decimal_get_digits(PyObject *module, PyObject *dec) +{ + int64_t digits; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + digits = PyDec_GetDigits(dec); + if (digits < 0) { + return NULL; + } + + return PyLong_FromLongLong(digits); +} + +static PyObject * +decimal_as_triple(PyObject *module, PyObject *dec) +{ + PyObject *tuple = NULL; + PyObject *sign, *hi, *lo; + mpd_uint128_triple_t triple; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + triple = PyDec_AsUint128Triple(dec); + if (triple.tag == MPD_TRIPLE_ERROR && PyErr_Occurred()) { + return NULL; + } + + sign = PyLong_FromUnsignedLong(triple.sign); + if (sign == NULL) { + return NULL; + } + + hi = PyLong_FromUnsignedLongLong(triple.hi); + if (hi == NULL) { + Py_DECREF(sign); + return NULL; + } + + lo = PyLong_FromUnsignedLongLong(triple.lo); + if (lo == NULL) { + Py_DECREF(hi); + Py_DECREF(sign); + return NULL; + } + + switch (triple.tag) { + case MPD_TRIPLE_QNAN: + assert(triple.exp == 0); + tuple = Py_BuildValue("(OOOs)", sign, hi, lo, "n"); + break; + + case MPD_TRIPLE_SNAN: + assert(triple.exp == 0); + tuple = Py_BuildValue("(OOOs)", sign, hi, lo, "N"); + break; + + case MPD_TRIPLE_INF: + assert(triple.hi == 0); + assert(triple.lo == 0); + assert(triple.exp == 0); + tuple = Py_BuildValue("(OOOs)", sign, hi, lo, "F"); + break; + + case MPD_TRIPLE_NORMAL: + tuple = Py_BuildValue("(OOOL)", sign, hi, lo, triple.exp); + break; + + case MPD_TRIPLE_ERROR: + PyErr_SetString(PyExc_ValueError, + "value out of bounds for a uint128 triple"); + break; + + default: + PyErr_SetString(PyExc_RuntimeError, + "decimal_as_triple: internal error: unexpected tag"); + break; + } + + Py_DECREF(lo); + Py_DECREF(hi); + Py_DECREF(sign); + + return tuple; +} + +static PyObject * +decimal_from_triple(PyObject *module, PyObject *tuple) +{ + mpd_uint128_triple_t triple = { MPD_TRIPLE_ERROR, 0, 0, 0, 0 }; + PyObject *exp; + unsigned long sign; + + (void)module; + if (!decimal_initialized) { + if (import_decimal() < 0) { + return NULL; + } + + decimal_initialized = 1; + } + + if (!PyTuple_Check(tuple)) { + PyErr_SetString(PyExc_TypeError, "argument must be a tuple"); + return NULL; + } + + if (PyTuple_GET_SIZE(tuple) != 4) { + PyErr_SetString(PyExc_ValueError, "tuple size must be 4"); + return NULL; + } + + sign = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(tuple, 0)); + if (sign == (unsigned long)-1 && PyErr_Occurred()) { + return NULL; + } + if (sign > UINT8_MAX) { + PyErr_SetString(PyExc_ValueError, "sign must be 0 or 1"); + return NULL; + } + triple.sign = (uint8_t)sign; + + triple.hi = PyLong_AsUnsignedLongLong(PyTuple_GET_ITEM(tuple, 1)); + if (triple.hi == (unsigned long long)-1 && PyErr_Occurred()) { + return NULL; + } + + triple.lo = PyLong_AsUnsignedLongLong(PyTuple_GET_ITEM(tuple, 2)); + if (triple.lo == (unsigned long long)-1 && PyErr_Occurred()) { + return NULL; + } + + exp = PyTuple_GET_ITEM(tuple, 3); + if (PyLong_Check(exp)) { + triple.tag = MPD_TRIPLE_NORMAL; + triple.exp = PyLong_AsLongLong(exp); + if (triple.exp == -1 && PyErr_Occurred()) { + return NULL; + } + } + else if (PyUnicode_Check(exp)) { + if (PyUnicode_CompareWithASCIIString(exp, "F") == 0) { + triple.tag = MPD_TRIPLE_INF; + } + else if (PyUnicode_CompareWithASCIIString(exp, "n") == 0) { + triple.tag = MPD_TRIPLE_QNAN; + } + else if (PyUnicode_CompareWithASCIIString(exp, "N") == 0) { + triple.tag = MPD_TRIPLE_SNAN; + } + else { + PyErr_SetString(PyExc_ValueError, "not a valid exponent"); + return NULL; + } + } + else { + PyErr_SetString(PyExc_TypeError, "exponent must be int or string"); + return NULL; + } + + return PyDec_FromUint128Triple(&triple); +} + /* test_thread_state spawns a thread of its own, and that thread releases * `thread_done` when it's finished. The driver code has to know when the * thread finishes, because the thread uses a PyObject (the callable) that @@ -5314,6 +5561,12 @@ static PyMethodDef TestMethods[] = { {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O}, {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O}, {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O}, + {"decimal_is_special", decimal_is_special, METH_O}, + {"decimal_is_nan", decimal_is_nan, METH_O}, + {"decimal_is_infinite", decimal_is_infinite, METH_O}, + {"decimal_get_digits", decimal_get_digits, METH_O}, + {"decimal_as_triple", decimal_as_triple, METH_O}, + {"decimal_from_triple", decimal_from_triple, METH_O}, {"test_list_api", test_list_api, METH_NOARGS}, {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, From 0a3e16653d7b693586e1446548a52d09ff985188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 10 Aug 2020 15:48:20 +0100 Subject: [PATCH 137/486] bpo-16995: add support for base32 extended hex (base32hex) (GH-20441) cc @pganssle Automerge-Triggered-By: @pganssle --- Doc/library/base64.rst | 23 ++++- Doc/whatsnew/3.10.rst | 6 ++ Lib/base64.py | 86 ++++++++++++------- Lib/test/test_base64.py | 70 +++++++++++++++ .../2020-05-27-00-09-52.bpo-16995.4niOT7.rst | 2 + 5 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 1ff22a00d6199de..2f24bb63912fb6b 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -124,7 +124,7 @@ The modern interface provides: whether a lowercase alphabet is acceptable as input. For security purposes, the default is ``False``. - :rfc:`3548` allows for optional mapping of the digit 0 (zero) to the letter O + :rfc:`4648` allows for optional mapping of the digit 0 (zero) to the letter O (oh), and for optional mapping of the digit 1 (one) to either the letter I (eye) or letter L (el). The optional argument *map01* when not ``None``, specifies which letter the digit 1 should be mapped to (when *map01* is not ``None``, the @@ -136,6 +136,27 @@ The modern interface provides: input. +.. function:: b32hexencode(s) + + Similar to :func:`b32encode` but uses the Extended Hex Alphabet, as defined in + :rfc:`4648`. + + .. versionadded:: 3.10 + + +.. function:: b32hexdecode(s, casefold=False) + + Similar to :func:`b32decode` but uses the Extended Hex Alphabet, as defined in + :rfc:`4648`. + + This version does not allow the digit 0 (zero) to the letter O (oh) and digit + 1 (one) to either the letter I (eye) or letter L (el) mappings, all these + characters are included in the Extended Hex Alphabet and are not + interchangable. + + .. versionadded:: 3.10 + + .. function:: b16encode(s) Encode the :term:`bytes-like object` *s* using Base16 and return the diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 2af0ea3f4dd6404..eb5ae01a7c04d4c 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -103,6 +103,12 @@ New Modules Improved Modules ================ +base64 +------ + +Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support the +Base32 Encoding with Extended Hex Alphabet. + curses ------ diff --git a/Lib/base64.py b/Lib/base64.py index a28109f8a7f9c36..539ad16f0e86d68 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -16,7 +16,7 @@ 'encode', 'decode', 'encodebytes', 'decodebytes', # Generalized interface for other encodings 'b64encode', 'b64decode', 'b32encode', 'b32decode', - 'b16encode', 'b16decode', + 'b32hexencode', 'b32hexdecode', 'b16encode', 'b16decode', # Base85 and Ascii85 encodings 'b85encode', 'b85decode', 'a85encode', 'a85decode', # Standard Base64 encoding @@ -135,19 +135,40 @@ def urlsafe_b64decode(s): # Base32 encoding/decoding must be done in Python +_B32_ENCODE_DOCSTRING = ''' +Encode the bytes-like objects using {encoding} and return a bytes object. +''' +_B32_DECODE_DOCSTRING = ''' +Decode the {encoding} encoded bytes-like object or ASCII string s. + +Optional casefold is a flag specifying whether a lowercase alphabet is +acceptable as input. For security purposes, the default is False. +{extra_args} +The result is returned as a bytes object. A binascii.Error is raised if +the input is incorrectly padded or if there are non-alphabet +characters present in the input. +''' +_B32_DECODE_MAP01_DOCSTRING = ''' +RFC 3548 allows for optional mapping of the digit 0 (zero) to the +letter O (oh), and for optional mapping of the digit 1 (one) to +either the letter I (eye) or letter L (el). The optional argument +map01 when not None, specifies which letter the digit 1 should be +mapped to (when map01 is not None, the digit 0 is always mapped to +the letter O). For security purposes the default is None, so that +0 and 1 are not allowed in the input. +''' _b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' -_b32tab2 = None -_b32rev = None +_b32hexalphabet = b'0123456789ABCDEFGHIJKLMNOPQRSTUV' +_b32tab2 = {} +_b32rev = {} -def b32encode(s): - """Encode the bytes-like object s using Base32 and return a bytes object. - """ +def _b32encode(alphabet, s): global _b32tab2 # Delay the initialization of the table to not waste memory # if the function is never called - if _b32tab2 is None: - b32tab = [bytes((i,)) for i in _b32alphabet] - _b32tab2 = [a + b for a in b32tab for b in b32tab] + if alphabet not in _b32tab2: + b32tab = [bytes((i,)) for i in alphabet] + _b32tab2[alphabet] = [a + b for a in b32tab for b in b32tab] b32tab = None if not isinstance(s, bytes_types): @@ -158,7 +179,7 @@ def b32encode(s): s = s + b'\0' * (5 - leftover) # Don't use += ! encoded = bytearray() from_bytes = int.from_bytes - b32tab2 = _b32tab2 + b32tab2 = _b32tab2[alphabet] for i in range(0, len(s), 5): c = from_bytes(s[i: i + 5], 'big') encoded += (b32tab2[c >> 30] + # bits 1 - 10 @@ -177,29 +198,12 @@ def b32encode(s): encoded[-1:] = b'=' return bytes(encoded) -def b32decode(s, casefold=False, map01=None): - """Decode the Base32 encoded bytes-like object or ASCII string s. - - Optional casefold is a flag specifying whether a lowercase alphabet is - acceptable as input. For security purposes, the default is False. - - RFC 3548 allows for optional mapping of the digit 0 (zero) to the - letter O (oh), and for optional mapping of the digit 1 (one) to - either the letter I (eye) or letter L (el). The optional argument - map01 when not None, specifies which letter the digit 1 should be - mapped to (when map01 is not None, the digit 0 is always mapped to - the letter O). For security purposes the default is None, so that - 0 and 1 are not allowed in the input. - - The result is returned as a bytes object. A binascii.Error is raised if - the input is incorrectly padded or if there are non-alphabet - characters present in the input. - """ +def _b32decode(alphabet, s, casefold=False, map01=None): global _b32rev # Delay the initialization of the table to not waste memory # if the function is never called - if _b32rev is None: - _b32rev = {v: k for k, v in enumerate(_b32alphabet)} + if alphabet not in _b32rev: + _b32rev[alphabet] = {v: k for k, v in enumerate(alphabet)} s = _bytes_from_decode_data(s) if len(s) % 8: raise binascii.Error('Incorrect padding') @@ -220,7 +224,7 @@ def b32decode(s, casefold=False, map01=None): padchars = l - len(s) # Now decode the full quanta decoded = bytearray() - b32rev = _b32rev + b32rev = _b32rev[alphabet] for i in range(0, len(s), 8): quanta = s[i: i + 8] acc = 0 @@ -241,6 +245,26 @@ def b32decode(s, casefold=False, map01=None): return bytes(decoded) +def b32encode(s): + return _b32encode(_b32alphabet, s) +b32encode.__doc__ = _B32_ENCODE_DOCSTRING.format(encoding='base32') + +def b32decode(s, casefold=False, map01=None): + return _b32decode(_b32alphabet, s, casefold, map01) +b32decode.__doc__ = _B32_DECODE_DOCSTRING.format(encoding='base32', + extra_args=_B32_DECODE_MAP01_DOCSTRING) + +def b32hexencode(s): + return _b32encode(_b32hexalphabet, s) +b32hexencode.__doc__ = _B32_ENCODE_DOCSTRING.format(encoding='base32hex') + +def b32hexdecode(s, casefold=False): + # base32hex does not have the 01 mapping + return _b32decode(_b32hexalphabet, s, casefold) +b32hexdecode.__doc__ = _B32_DECODE_DOCSTRING.format(encoding='base32hex', + extra_args='') + + # RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns # lowercase. The RFC also recommends against accepting input case # insensitively. diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 1f67e46cd226770..4f62c4115f60aa1 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -351,6 +351,76 @@ def test_b32decode_error(self): with self.assertRaises(binascii.Error): base64.b32decode(data.decode('ascii')) + def test_b32hexencode(self): + test_cases = [ + # to_encode, expected + (b'', b''), + (b'\x00', b'00======'), + (b'a', b'C4======'), + (b'ab', b'C5H0===='), + (b'abc', b'C5H66==='), + (b'abcd', b'C5H66P0='), + (b'abcde', b'C5H66P35'), + ] + for to_encode, expected in test_cases: + with self.subTest(to_decode=to_encode): + self.assertEqual(base64.b32hexencode(to_encode), expected) + + def test_b32hexencode_other_types(self): + self.check_other_types(base64.b32hexencode, b'abcd', b'C5H66P0=') + self.check_encode_type_errors(base64.b32hexencode) + + def test_b32hexdecode(self): + test_cases = [ + # to_decode, expected, casefold + (b'', b'', False), + (b'00======', b'\x00', False), + (b'C4======', b'a', False), + (b'C5H0====', b'ab', False), + (b'C5H66===', b'abc', False), + (b'C5H66P0=', b'abcd', False), + (b'C5H66P35', b'abcde', False), + (b'', b'', True), + (b'00======', b'\x00', True), + (b'C4======', b'a', True), + (b'C5H0====', b'ab', True), + (b'C5H66===', b'abc', True), + (b'C5H66P0=', b'abcd', True), + (b'C5H66P35', b'abcde', True), + (b'c4======', b'a', True), + (b'c5h0====', b'ab', True), + (b'c5h66===', b'abc', True), + (b'c5h66p0=', b'abcd', True), + (b'c5h66p35', b'abcde', True), + ] + for to_decode, expected, casefold in test_cases: + with self.subTest(to_decode=to_decode, casefold=casefold): + self.assertEqual(base64.b32hexdecode(to_decode, casefold), + expected) + self.assertEqual(base64.b32hexdecode(to_decode.decode('ascii'), + casefold), expected) + + def test_b32hexdecode_other_types(self): + self.check_other_types(base64.b32hexdecode, b'C5H66===', b'abc') + self.check_decode_type_errors(base64.b32hexdecode) + + def test_b32hexdecode_error(self): + tests = [b'abc', b'ABCDEF==', b'==ABCDEF', b'c4======'] + prefixes = [b'M', b'ME', b'MFRA', b'MFRGG', b'MFRGGZA', b'MFRGGZDF'] + for i in range(0, 17): + if i: + tests.append(b'='*i) + for prefix in prefixes: + if len(prefix) + i != 8: + tests.append(prefix + b'='*i) + for data in tests: + with self.subTest(to_decode=data): + with self.assertRaises(binascii.Error): + base64.b32hexdecode(data) + with self.assertRaises(binascii.Error): + base64.b32hexdecode(data.decode('ascii')) + + def test_b16encode(self): eq = self.assertEqual eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF') diff --git a/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst b/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst new file mode 100644 index 000000000000000..88b95998d085f67 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst @@ -0,0 +1,2 @@ +Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support the +Base32 Encoding with Extended Hex Alphabet. From f400fbcc58301909519865e3d227d3169b602cc5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 10 Aug 2020 18:36:59 +0200 Subject: [PATCH 138/486] bpo-40548: Fix "Check for source changes (pull_request)" GH Action job (GH-21806) On Git 2.28, "git diff master..." (3 dots) no longer works when "fetch --depth=1" is used, whereas it works on Git 2.26. Replace "..." (3 dots) with ".." (2 dots) in the "git diff" command computing the list of modified files between the base branch and the PR branch. --- .github/workflows/build.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5649a6670e75f5c..df68fe271de7a8f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,20 @@ jobs: echo '::set-output name=run_tests::true' else git fetch origin $GITHUB_BASE_REF --depth=1 - git diff --name-only origin/$GITHUB_BASE_REF... | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more + # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), + # but it requires to download more commits (this job uses + # "git fetch --depth=1"). + # + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git + # 2.26, but Git 2.28 is stricter and fails with "no merge base". + # + # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on + # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF + # into the PR branch anyway. + # + # https://github.com/python/core-workflow/issues/373 + git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true fi build_win32: name: 'Windows (x86)' From e6f89ebd5a17f3c05d05e3217516c5b41c5696ce Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Mon, 10 Aug 2020 21:54:50 +0200 Subject: [PATCH 139/486] Replace import_fresh_module in decimal test files (GH-21815) --- Modules/_decimal/tests/bench.py | 9 +++------ Modules/_decimal/tests/deccheck.py | 7 ++++--- Modules/_decimal/tests/formathelper.py | 5 ++--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 3726db194e032f2..88fd7b5ae0be381 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -7,13 +7,10 @@ import time -try: - from test.support import import_fresh_module -except ImportError: - from test.test_support import import_fresh_module -C = import_fresh_module('decimal', fresh=['_decimal']) -P = import_fresh_module('decimal', blocked=['_decimal']) +import _decimal as C +import _pydecimal as P + # # NOTE: This is the pi function from the decimal documentation, modified diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 15f104dc463cb82..0b2a1c49336ef01 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -43,7 +43,6 @@ from queue import Queue, Empty from threading import Thread, Event, Lock -from test.support import import_fresh_module from randdec import randfloat, all_unary, all_binary, all_ternary from randdec import unary_optarg, binary_optarg, ternary_optarg from formathelper import rand_format, rand_locale @@ -52,8 +51,10 @@ from _testcapi import decimal_as_triple from _testcapi import decimal_from_triple -C = import_fresh_module('decimal', fresh=['_decimal']) -P = import_fresh_module('decimal', blocked=['_decimal']) +import _decimal as C +import _pydecimal as P + + EXIT_STATUS = 0 diff --git a/Modules/_decimal/tests/formathelper.py b/Modules/_decimal/tests/formathelper.py index 19b2aad4a503b1e..482e02a25c2a8c7 100644 --- a/Modules/_decimal/tests/formathelper.py +++ b/Modules/_decimal/tests/formathelper.py @@ -31,11 +31,10 @@ import os, sys, locale, random import platform, subprocess -from test.support import import_fresh_module from distutils.spawn import find_executable -C = import_fresh_module('decimal', fresh=['_decimal']) -P = import_fresh_module('decimal', blocked=['_decimal']) +import _decimal as C +import _pydecimal as P windows_lang_strings = [ From 5b0d4e177ae7e81ff4390e6adc91c10862e3c3a4 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Mon, 10 Aug 2020 22:39:46 +0200 Subject: [PATCH 140/486] MSVC: The ARM command line should not define MASM. (#21817) --- PCbuild/_decimal.vcxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index 4c71cdb6d1d77dc..0916f1a2d37887f 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -93,11 +93,11 @@ - _CRT_SECURE_NO_WARNINGS;MASM;%(PreprocessorDefinitions) - CONFIG_32;PPRO;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + CONFIG_32;PPRO;MASM;%(PreprocessorDefinitions) CONFIG_32;ANSI;%(PreprocessorDefinitions) CONFIG_64;ANSI;%(PreprocessorDefinitions) - CONFIG_64;%(PreprocessorDefinitions) + CONFIG_64;MASM;%(PreprocessorDefinitions) ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) From 8f9179c164b40b2432063bc0afc0e158fcbbe4f4 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 11 Aug 2020 05:24:02 +0800 Subject: [PATCH 141/486] bpo-40275: Fix failed test cases by using test helpers (GH-21811) --- Lib/test/test__osx_support.py | 3 +-- Lib/test/test_importlib/extension/test_case_sensitivity.py | 6 +++--- Lib/test/test_importlib/source/test_case_sensitivity.py | 6 +++--- Lib/test/test_selectors.py | 3 ++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index a3f41d2c5bd075f..907ae27d529b502 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -8,7 +8,6 @@ import sys import unittest -import test.support from test.support import os_helper import _osx_support @@ -20,7 +19,7 @@ def setUp(self): self.maxDiff = None self.prog_name = 'bogus_program_xxxx' self.temp_path_dir = os.path.abspath(os.getcwd()) - self.env = test.support.EnvironmentVarGuard() + self.env = os_helper.EnvironmentVarGuard() self.addCleanup(self.env.__exit__) for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py index 3a857847381a9a5..4d76fa014cd73b4 100644 --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -1,5 +1,5 @@ from importlib import _bootstrap_external -from test import support +from test.support import os_helper import unittest import sys from .. import util @@ -23,7 +23,7 @@ def find_module(self): @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_case_sensitive(self): - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.unset('PYTHONCASEOK') self.caseok_env_changed(should_exist=False) loader = self.find_module() @@ -31,7 +31,7 @@ def test_case_sensitive(self): @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_case_insensitivity(self): - with support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.set('PYTHONCASEOK', '1') self.caseok_env_changed(should_exist=True) loader = self.find_module() diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py index ad1cfdb7e5cc1a6..77c06a75fc77be9 100644 --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -7,7 +7,7 @@ machinery = util.import_importlib('importlib.machinery') import os -from test import support as test_support +from test.support import os_helper import unittest @@ -42,7 +42,7 @@ def sensitivity_test(self): @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_sensitive(self): - with test_support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.unset('PYTHONCASEOK') self.caseok_env_changed(should_exist=False) sensitive, insensitive = self.sensitivity_test() @@ -52,7 +52,7 @@ def test_sensitive(self): @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_insensitive(self): - with test_support.EnvironmentVarGuard() as env: + with os_helper.EnvironmentVarGuard() as env: env.set('PYTHONCASEOK', '1') self.caseok_env_changed(should_exist=True) sensitive, insensitive = self.sensitivity_test() diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index 2274c39a79a5327..851b1fc1b9e0c49 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -6,6 +6,7 @@ import socket import sys from test import support +from test.support import os_helper from test.support import socket_helper from time import sleep import unittest @@ -536,7 +537,7 @@ def test_register_bad_fd(self): # a file descriptor that's been closed should raise an OSError # with EBADF s = self.SELECTOR() - bad_f = support.make_bad_fd() + bad_f = os_helper.make_bad_fd() with self.assertRaises(OSError) as cm: s.register(bad_f, selectors.EVENT_READ) self.assertEqual(cm.exception.errno, errno.EBADF) From 4e75e263f1e128939b8e0ebe20de546704b21306 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 11 Aug 2020 05:32:35 -0500 Subject: [PATCH 142/486] bpo-1635741: Port multiprocessing ext to multiphase init (GH-21378) Port the _multiprocessing extension module to multiphase initialization (PEP 489). --- ...2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst | 1 + Modules/_multiprocessing/multiprocessing.c | 102 ++++++++++-------- 2 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst new file mode 100644 index 000000000000000..52e184dc3170741 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst @@ -0,0 +1 @@ +Port :mod:`multiprocessing` to multi-phase initialization diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 77e6c854068c0f2..25b8dc3967a4fb6 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -183,35 +183,17 @@ static PyMethodDef module_methods[] = { * Initialize */ -static struct PyModuleDef multiprocessing_module = { - PyModuleDef_HEAD_INIT, - "_multiprocessing", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__multiprocessing(void) +static int +multiprocessing_exec(PyObject *module) { - PyObject *module, *temp, *value = NULL; - - /* Initialize module */ - module = PyModule_Create(&multiprocessing_module); - if (!module) - return NULL; - #if defined(MS_WINDOWS) || \ (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) + /* Add _PyMp_SemLock type to module */ - if (PyType_Ready(&_PyMp_SemLockType) < 0) - return NULL; - Py_INCREF(&_PyMp_SemLockType); + if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) { + return -1; + } + { PyObject *py_sem_value_max; /* Some systems define SEM_VALUE_MAX as an unsigned value that @@ -223,25 +205,41 @@ PyInit__multiprocessing(void) py_sem_value_max = PyLong_FromLong(INT_MAX); else py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); - if (py_sem_value_max == NULL) - return NULL; - PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", - py_sem_value_max); + + if (py_sem_value_max == NULL) { + Py_DECREF(py_sem_value_max); + return -1; + } + if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", + py_sem_value_max) < 0) { + Py_DECREF(py_sem_value_max); + return -1; + } + Py_DECREF(py_sem_value_max); } - PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType); + #endif /* Add configuration macros */ - temp = PyDict_New(); - if (!temp) - return NULL; + PyObject *flags = PyDict_New(); + if (!flags) { + return -1; + } -#define ADD_FLAG(name) \ - value = Py_BuildValue("i", name); \ - if (value == NULL) { Py_DECREF(temp); return NULL; } \ - if (PyDict_SetItemString(temp, #name, value) < 0) { \ - Py_DECREF(temp); Py_DECREF(value); return NULL; } \ - Py_DECREF(value) +#define ADD_FLAG(name) \ + do { \ + PyObject *value = PyLong_FromLong(name); \ + if (value == NULL) { \ + Py_DECREF(flags); \ + return -1; \ + } \ + if (PyDict_SetItemString(flags, #name, value) < 0) { \ + Py_DECREF(flags); \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while (0) #if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) ADD_FLAG(HAVE_SEM_OPEN); @@ -256,8 +254,28 @@ PyInit__multiprocessing(void) ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); #endif - if (PyModule_AddObject(module, "flags", temp) < 0) - return NULL; + if (PyModule_AddObject(module, "flags", flags) < 0) { + Py_DECREF(flags); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot multiprocessing_slots[] = { + {Py_mod_exec, multiprocessing_exec}, + {0, NULL} +}; - return module; +static struct PyModuleDef multiprocessing_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_multiprocessing", + .m_methods = module_methods, + .m_slots = multiprocessing_slots, +}; + +PyMODINIT_FUNC +PyInit__multiprocessing(void) +{ + return PyModuleDef_Init(&multiprocessing_module); } From 712670d0c3a0c1d406262b470ea39a496004c9bf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Aug 2020 15:26:59 +0200 Subject: [PATCH 143/486] bpo-41521: Replace whitelist/blacklist with allowlist/denylist (GH-21822) Automerge-Triggered-By: @tiran --- Doc/library/http.cookiejar.rst | 12 ++++++------ Doc/library/urllib.parse.rst | 2 +- Lib/codecs.py | 2 +- Lib/ipaddress.py | 4 ++-- Lib/test/test___all__.py | 12 ++++++------ Lib/test/test_httplib.py | 4 ++-- Lib/test/test_httpservers.py | 4 ++-- Lib/test/test_nntplib.py | 6 +++--- Lib/test/test_tools/test_sundry.py | 10 +++++----- Lib/test/test_traceback.py | 4 ++-- Objects/typeobject.c | 4 ++-- Tools/clinic/clinic.py | 8 ++++---- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 9ac5d52a2ab09c7..0a9ee7eb516f417 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -462,16 +462,16 @@ receiving cookies. There are also some strictness switches that allow you to tighten up the rather loose Netscape protocol rules a little bit (at the cost of blocking some benign cookies). -A domain blacklist and whitelist is provided (both off by default). Only domains -not in the blacklist and present in the whitelist (if the whitelist is active) +A domain denylist and allowlist is provided (both off by default). Only domains +not in the denylist and present in the allowlist (if the allowlist is active) participate in cookie setting and returning. Use the *blocked_domains* constructor argument, and :meth:`blocked_domains` and :meth:`set_blocked_domains` methods (and the corresponding argument and methods -for *allowed_domains*). If you set a whitelist, you can turn it off again by +for *allowed_domains*). If you set an allowlist, you can turn it off again by setting it to :const:`None`. Domains in block or allow lists that do not start with a dot must equal the -cookie domain to be matched. For example, ``"example.com"`` matches a blacklist +cookie domain to be matched. For example, ``"example.com"`` matches a denylist entry of ``"example.com"``, but ``"www.example.com"`` does not. Domains that do start with a dot are matched by more specific domains too. For example, both ``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"`` @@ -494,7 +494,7 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not. .. method:: DefaultCookiePolicy.is_blocked(domain) - Return whether *domain* is on the blacklist for setting or receiving cookies. + Return whether *domain* is on the denylist for setting or receiving cookies. .. method:: DefaultCookiePolicy.allowed_domains() @@ -509,7 +509,7 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not. .. method:: DefaultCookiePolicy.is_not_allowed(domain) - Return whether *domain* is not on the whitelist for setting or receiving + Return whether *domain* is not on the allowlist for setting or receiving cookies. :class:`DefaultCookiePolicy` instances have the following attributes, which are diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 536cf952bda4343..f9c8ba7398f66fd 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -153,7 +153,7 @@ or on combining URL components into a URL string. .. versionchanged:: 3.3 The fragment is now parsed for all URL schemes (unless *allow_fragment* is - false), in accordance with :rfc:`3986`. Previously, a whitelist of + false), in accordance with :rfc:`3986`. Previously, an allowlist of schemes that support fragments existed. .. versionchanged:: 3.6 diff --git a/Lib/codecs.py b/Lib/codecs.py index 7f23e9775df804e..3935490d88c8d32 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -83,7 +83,7 @@ class CodecInfo(tuple): """Codec details when looking up the codec registry""" - # Private API to allow Python 3.4 to blacklist the known non-Unicode + # Private API to allow Python 3.4 to denylist the known non-Unicode # codecs in the standard library. A more general mechanism to # reliably distinguish test encodings from other codecs will hopefully # be defined for Python 3.5 diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index bc662c415b2a49f..160b16dbc162fcc 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1214,7 +1214,7 @@ def _parse_octet(cls, octet_str): """ if not octet_str: raise ValueError("Empty octet not permitted") - # Whitelist the characters, since int() allows a lot of bizarre stuff. + # Reject non-ASCII digits. if not (octet_str.isascii() and octet_str.isdigit()): msg = "Only decimal digits permitted in %r" raise ValueError(msg % octet_str) @@ -1719,7 +1719,7 @@ def _parse_hextet(cls, hextet_str): [0..FFFF]. """ - # Whitelist the characters, since int() allows a lot of bizarre stuff. + # Reject non-ASCII digits. if not cls._HEX_DIGITS.issuperset(hextet_str): raise ValueError("Only hex digits permitted in %r" % hextet_str) # We do the length check second, since the invalid character error diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 0a03dd20065feba..c6ce64864c0db6d 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -69,8 +69,8 @@ def walk_modules(self, basedir, modpath): yield path, modpath + fn[:-3] def test_all(self): - # Blacklisted modules and packages - blacklist = set([ + # List of denied modules and packages + denylist = set([ # Will raise a SyntaxError when compiling the exec statement '__future__', ]) @@ -85,13 +85,13 @@ def test_all(self): lib_dir = os.path.dirname(os.path.dirname(__file__)) for path, modname in self.walk_modules(lib_dir, ""): m = modname - blacklisted = False + denylisted = False while m: - if m in blacklist: - blacklisted = True + if m in denylist: + denylisted = True break m = m.rpartition('.')[0] - if blacklisted: + if denylisted: continue if support.verbose: print(modname) diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 3431bb80ea6de4f..a3f268be97921c3 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -1434,9 +1434,9 @@ def test_all(self): expected = {"responses"} # White-list documented dict() object # HTTPMessage, parse_headers(), and the HTTP status code constants are # intentionally omitted for simplicity - blacklist = {"HTTPMessage", "parse_headers"} + denylist = {"HTTPMessage", "parse_headers"} for name in dir(client): - if name.startswith("_") or name in blacklist: + if name.startswith("_") or name in denylist: continue module_object = getattr(client, name) if getattr(module_object, "__module__", None) == "http.client": diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index a7e1719ab60ee75..2859abb21fc9f5a 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -1189,9 +1189,9 @@ def test_windows_colon(self): class MiscTestCase(unittest.TestCase): def test_all(self): expected = [] - blacklist = {'executable', 'nobody_uid', 'test'} + denylist = {'executable', 'nobody_uid', 'test'} for name in dir(server): - if name.startswith('_') or name in blacklist: + if name.startswith('_') or name in denylist: continue module_object = getattr(server, name) if getattr(module_object, '__module__', None) == 'http.server': diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 1df64fa7c6b00b2..b11c19c84d3fb16 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -197,11 +197,11 @@ def test_article_head_body(self): self.assertTrue(resp.startswith("220 "), resp) self.check_article_resp(resp, article, art_num) # Tolerate running the tests from behind a NNTP virus checker - blacklist = lambda line: line.startswith(b'X-Antivirus') + denylist = lambda line: line.startswith(b'X-Antivirus') filtered_head_lines = [line for line in head.lines - if not blacklist(line)] + if not denylist(line)] filtered_lines = [line for line in article.lines - if not blacklist(line)] + if not denylist(line)] self.assertEqual(filtered_lines, filtered_head_lines + [b''] + body.lines) def test_capabilities(self): diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py index 8b5a963e25bd151..52369ec09a77fbc 100644 --- a/Lib/test/test_tools/test_sundry.py +++ b/Lib/test/test_tools/test_sundry.py @@ -16,18 +16,18 @@ class TestSundryScripts(unittest.TestCase): # At least make sure the rest don't have syntax errors. When tests are - # added for a script it should be added to the whitelist below. + # added for a script it should be added to the allowlist below. # scripts that have independent tests. - whitelist = ['reindent', 'pdeps', 'gprof2html', 'md5sum'] + allowlist = ['reindent', 'pdeps', 'gprof2html', 'md5sum'] # scripts that can't be imported without running - blacklist = ['make_ctype'] + denylist = ['make_ctype'] # scripts that use windows-only modules windows_only = ['win_add2path'] - # blacklisted for other reasons + # denylisted for other reasons other = ['analyze_dxp', '2to3'] - skiplist = blacklist + whitelist + windows_only + other + skiplist = denylist + allowlist + windows_only + other def test_sundry(self): old_modules = import_helper.modules_setup() diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index c5fbd8700ae9b1c..730596efd8bcecc 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -1191,9 +1191,9 @@ class MiscTest(unittest.TestCase): def test_all(self): expected = set() - blacklist = {'print_list'} + denylist = {'print_list'} for name in dir(traceback): - if name.startswith('_') or name in blacklist: + if name.startswith('_') or name in denylist: continue module_object = getattr(traceback, name) if getattr(module_object, '__module__', None) == 'traceback': diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 49b3c859e35c119..c66f8fcec8ed515 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4171,10 +4171,10 @@ object_set_class(PyObject *self, PyObject *value, void *closure) In theory the proper fix would be to identify which classes rely on this invariant and somehow disallow __class__ assignment only for them, perhaps via some mechanism like a new Py_TPFLAGS_IMMUTABLE flag (a - "blacklisting" approach). But in practice, since this problem wasn't + "denylisting" approach). But in practice, since this problem wasn't noticed late in the 3.5 RC cycle, we're taking the conservative approach and reinstating the same HEAPTYPE->HEAPTYPE check that we used - to have, plus a "whitelist". For now, the whitelist consists only of + to have, plus an "allowlist". For now, the allowlist consists only of ModuleType subtypes, since those are the cases that motivated the patch in the first place -- see https://bugs.python.org/issue22986 -- and since module objects are mutable we can be sure that they are diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 92334d9195fcce0..1bbbd4f9fb19334 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4433,7 +4433,7 @@ def state_parameter(self, line): if 'c_default' not in kwargs: # we can only represent very simple data values in C. - # detect whether default is okay, via a blacklist + # detect whether default is okay, via a denylist # of disallowed ast nodes. class DetectBadNodes(ast.NodeVisitor): bad = False @@ -4456,9 +4456,9 @@ def bad_node(self, node): # "starred": "a = [1, 2, 3]; *a" visit_Starred = bad_node - blacklist = DetectBadNodes() - blacklist.visit(module) - bad = blacklist.bad + denylist = DetectBadNodes() + denylist.visit(module) + bad = denylist.bad else: # if they specify a c_default, we can be more lenient about the default value. # but at least make an attempt at ensuring it's a valid expression. From 977dfefce2222414a40d94a9f7c8220f42a53dbf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Aug 2020 15:28:43 +0200 Subject: [PATCH 144/486] bpo-41521: Replace whitelist/blacklist with allowlist/denylist (GH-21823) Rename 5 test method names in test_codecs and test_typing. --- Lib/test/test_codecs.py | 8 ++++---- Lib/test/test_typing.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f0da35c039e11e6..3dd56820cd1078e 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2644,7 +2644,7 @@ def test_buffer_api_usage(self): view_decoded = codecs.decode(view, encoding) self.assertEqual(view_decoded, data) - def test_text_to_binary_blacklists_binary_transforms(self): + def test_text_to_binary_denylists_binary_transforms(self): # Check binary -> binary codecs give a good error for str input bad_input = "bad input type" for encoding in bytes_transform_encodings: @@ -2656,14 +2656,14 @@ def test_text_to_binary_blacklists_binary_transforms(self): bad_input.encode(encoding) self.assertIsNone(failure.exception.__cause__) - def test_text_to_binary_blacklists_text_transforms(self): + def test_text_to_binary_denylists_text_transforms(self): # Check str.encode gives a good error message for str -> str codecs msg = (r"^'rot_13' is not a text encoding; " r"use codecs.encode\(\) to handle arbitrary codecs") with self.assertRaisesRegex(LookupError, msg): "just an example message".encode("rot_13") - def test_binary_to_text_blacklists_binary_transforms(self): + def test_binary_to_text_denylists_binary_transforms(self): # Check bytes.decode and bytearray.decode give a good error # message for binary -> binary codecs data = b"encode first to ensure we meet any format restrictions" @@ -2678,7 +2678,7 @@ def test_binary_to_text_blacklists_binary_transforms(self): with self.assertRaisesRegex(LookupError, msg): bytearray(encoded_data).decode(encoding) - def test_binary_to_text_blacklists_text_transforms(self): + def test_binary_to_text_denylists_text_transforms(self): # Check str -> str codec gives a good error for binary input for bad_input in (b"immutable", bytearray(b"mutable")): with self.subTest(bad_input=bad_input): diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 7f96aff71045511..b3be99141afca99 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1387,7 +1387,7 @@ def close(self): self.assertIsSubclass(B, Custom) self.assertNotIsSubclass(A, Custom) - def test_builtin_protocol_whitelist(self): + def test_builtin_protocol_allowlist(self): with self.assertRaises(TypeError): class CustomProtocol(TestCase, Protocol): pass From f721b2780cdd04530fb50e4b78bf36b36d698fc4 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Tue, 11 Aug 2020 09:07:49 -0500 Subject: [PATCH 145/486] Add links to asttokens, leoAst, LibCST and parso to ast docs (GH-21773) --- Doc/library/ast.rst | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 25cb17811e7183e..755c60fba64115a 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1800,5 +1800,24 @@ to stdout. Otherwise, the content is read from stdin. .. seealso:: - `Green Tree Snakes `_, an external documentation resource, has good - details on working with Python ASTs. + `Green Tree Snakes `_, an external + documentation resource, has good details on working with Python ASTs. + + `ASTTokens `_ + annotates Python ASTs with the positions of tokens and text in the source + code that generated them. This is helpful for tools that make source code + transformations. + + `leoAst.py `_ unifies the + token-based and parse-tree-based views of python programs by inserting + two-way links between tokens and ast nodes. + + `LibCST `_ parses code as a Concrete Syntax + Tree that looks like an ast tree and keeps all formatting details. It's + useful for building automated refactoring (codemod) applications and + linters. + + `Parso `_ is a Python parser that supports + error recovery and round-trip parsing for different Python versions (in + multiple Python versions). Parso is also able to list multiple syntax errors + in your python file. \ No newline at end of file From 161d131fe6625ba347c81684e60c5e30e6328e42 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 11 Aug 2020 18:15:57 +0200 Subject: [PATCH 146/486] Add PEP 573 additions to What's New (GH-21374) --- Doc/whatsnew/3.9.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index db380bc1cdfa4e8..be7406e13c2cd44 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -1024,6 +1024,13 @@ C API Changes New Features ------------ +* :pep:`573`: Add :c:func:`PyType_FromModuleAndSpec` to associate + a module with a class; :c:func:`PyType_GetModule` and + :c:func:`PyType_GetModuleState` to retrieve the module and its state; and + :c:data:`PyCMethod` and :c:data:`METH_METHOD` to allow a method to + access the class it was defined in. + (Contributed by Marcel Plch and Petr Viktorin in :issue:`38787`.) + * Add :c:func:`PyFrame_GetCode` function: get a frame code. Add :c:func:`PyFrame_GetBack` function: get the frame next outer frame. (Contributed by Victor Stinner in :issue:`40421`.) From 664c2acac61da0158d0e84687e2d3ce255f58594 Mon Sep 17 00:00:00 2001 From: Ram Rachum Date: Tue, 11 Aug 2020 19:33:25 +0300 Subject: [PATCH 147/486] bpo-41475: Fix note in "What's new in 3.7" (#21733) --- Doc/whatsnew/3.7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 59b96621bdd4b51..279bbc697b5c632 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -171,7 +171,7 @@ on a per-module basis in Python 3.7 using a :mod:`__future__` import:: from __future__ import annotations -It will become the default in Python 4.0. +It will become the default in Python 3.10. .. seealso:: From c002fd18ffd4366ca9effdcabc29e386ea9e61d4 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Tue, 11 Aug 2020 21:14:51 +0200 Subject: [PATCH 148/486] Call randseed() before other imports in deccheck.py (GH-21834) --- Modules/_decimal/tests/deccheck.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 0b2a1c49336ef01..ca869f4dbf5d8c7 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -30,10 +30,14 @@ # +import random +import time + +RANDSEED = int(time.time()) +random.seed(RANDSEED) + import sys import os -import time -import random from copy import copy from collections import defaultdict @@ -1235,10 +1239,6 @@ def check_untested(funcdict, c_cls, p_cls): args.single = args.single[0] - randseed = int(time.time()) - random.seed(randseed) - - # Set up the testspecs list. A testspec is simply a dictionary # that determines the amount of different contexts that 'test_method' # will generate. @@ -1306,9 +1306,9 @@ def check_untested(funcdict, c_cls, p_cls): if args.multicore: q = Queue() elif args.single: - log("Random seed: %d", randseed) + log("Random seed: %d", RANDSEED) else: - log("\n\nRandom seed: %d\n\n", randseed) + log("\n\nRandom seed: %d\n\n", RANDSEED) FOUND_METHOD = False From cca98c3bbbf0ca6c04e2c6e5beb1443d5cb968a5 Mon Sep 17 00:00:00 2001 From: Christopher Yeh Date: Tue, 11 Aug 2020 15:27:08 -0700 Subject: [PATCH 149/486] Fix typo (GH-21820) --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 7028d240c59ebb4..5a10faa7bbd293b 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4205,7 +4205,7 @@ The constructors for both classes work the same: Note, the non-operator versions of :meth:`union`, :meth:`intersection`, - :meth:`difference`, and :meth:`symmetric_difference`, :meth:`issubset`, and + :meth:`difference`, :meth:`symmetric_difference`, :meth:`issubset`, and :meth:`issuperset` methods will accept any iterable as an argument. In contrast, their operator based counterparts require their arguments to be sets. This precludes error-prone constructions like ``set('abc') & 'cbs'`` From 2b3a627f2dfc4546a808edf6bb720964d036ab87 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Aug 2020 10:53:12 +0200 Subject: [PATCH 150/486] bpo-41521, typing: Rename _PROTO_WHITELIST to _PROTO_ALLOWLIST (#21825) --- Lib/typing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 5da032bbee8f1e8..fce8da4fe3cf05d 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1021,7 +1021,7 @@ def _allow_reckless_class_cheks(): return True -_PROTO_WHITELIST = { +_PROTO_ALLOWLIST = { 'collections.abc': [ 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', @@ -1140,8 +1140,8 @@ def _proto_hook(other): # ... otherwise check consistency of bases, and prohibit instantiation. for base in cls.__bases__: if not (base in (object, Generic) or - base.__module__ in _PROTO_WHITELIST and - base.__name__ in _PROTO_WHITELIST[base.__module__] or + base.__module__ in _PROTO_ALLOWLIST and + base.__name__ in _PROTO_ALLOWLIST[base.__module__] or issubclass(base, Generic) and base._is_protocol): raise TypeError('Protocols can only inherit from other' ' protocols, got %r' % base) From a44101b7193441e924853064cc53c9339d2b383a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Aug 2020 14:53:28 +0200 Subject: [PATCH 151/486] bpo-41520: codeop no longer ignores SyntaxWarning (GH-21838) --- Lib/codeop.py | 6 ++++-- Lib/test/test_codeop.py | 7 +++++++ .../next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst diff --git a/Lib/codeop.py b/Lib/codeop.py index 7e192ea6a10a03a..547629262d06892 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -84,9 +84,11 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError: pass - # Suppress warnings after the first compile to avoid duplication. + # Catch syntax warnings after the first compile + # to emit SyntaxWarning at most once. with warnings.catch_warnings(): - warnings.simplefilter("ignore") + warnings.simplefilter("error", SyntaxWarning) + try: code1 = compiler(source + "\n", filename, symbol) except SyntaxError as e: diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 6e821df6b0e7071..7984e5f1e5a69a7 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -4,6 +4,7 @@ """ import sys import unittest +import warnings from test import support from test.support import warnings_helper @@ -310,5 +311,11 @@ def test_warning(self): compile_command("0 is 0") self.assertEqual(len(w.warnings), 1) + # bpo-41520: check SyntaxWarning treated as an SyntaxError + with self.assertRaises(SyntaxError): + warnings.simplefilter('error', SyntaxWarning) + compile_command('1 is 1\n', symbol='exec') + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst b/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst new file mode 100644 index 000000000000000..ca5501c2aeec0de --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst @@ -0,0 +1 @@ +Fix :mod:`codeop` regression: it no longer ignores :exc:`SyntaxWarning`. From 14a4cc20d16b68a465253853269eb86d945ae77f Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Wed, 12 Aug 2020 16:00:05 +0200 Subject: [PATCH 152/486] Catch all skip_handler cases (GH-21842) --- Modules/_decimal/tests/deccheck.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index ca869f4dbf5d8c7..5de57d1f875a2d4 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -185,7 +185,7 @@ def p_as_triple(dec): coeff = int(s) if s else 0 if coeff < 0 or coeff >= 2**128: - raise ValueError("value out of bounds for a uint128 triple"); + raise ValueError("value out of bounds for a uint128 triple") return (sign, coeff, exp) @@ -193,7 +193,7 @@ def p_from_triple(triple): sign, coeff, exp = triple if coeff < 0 or coeff >= 2**128: - raise ValueError("value out of bounds for a uint128 triple"); + raise ValueError("value out of bounds for a uint128 triple") digits = tuple(int(c) for c in str(coeff)) @@ -894,7 +894,7 @@ def verify(t, stat): t.presults.append(str(t.rp.real)) ctriple = None - if t.funcname not in ['__radd__', '__rmul__']: # see skip handler + if str(t.rc) == str(t.rp): # see skip handler try: ctriple = c_as_triple(t.rc) except ValueError: From 7ac99f575ed0a0e6a7c195b24426eef2c8b06eff Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Aug 2020 21:49:22 +0200 Subject: [PATCH 153/486] bpo-40204: Allow pre-Sphinx 3 syntax in the doc (GH-21844) Enable Sphinx 3.2 "c_allow_pre_v3" option and disable the c_warn_on_allowed_pre_v3 option to make the documentation compatible with Sphinx 2 and Sphinx 3. --- Doc/conf.py | 10 ++++++++++ .../2020-08-12-18-35-40.bpo-40204.C8A_pe.rst | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst diff --git a/Doc/conf.py b/Doc/conf.py index bfb2a98fc63a2f1..079d17717f381c6 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -228,3 +228,13 @@ # Relative filename of the reference count data file. refcount_file = 'data/refcounts.dat' + +# Sphinx 2 and Sphinx 3 compatibility +# ----------------------------------- + +# bpo-40204: Allow Sphinx 2 syntax in the C domain +c_allow_pre_v3 = True + +# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the +# documentation is built with -W (warnings treated as errors). +c_warn_on_allowed_pre_v3 = False diff --git a/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst b/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst new file mode 100644 index 000000000000000..152f6c98b900484 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst @@ -0,0 +1,3 @@ +Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable +``c_warn_on_allowed_pre_v3`` option to make the documentation compatible +with Sphinx 2 and Sphinx 3. From 21746916c21e1be0eda7665cbc7a0790fa0c3bb8 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Thu, 13 Aug 2020 05:23:30 +0800 Subject: [PATCH 154/486] bpo-1635741: Clean sysdict and builtins of interpreter at exit (GH-21605) --- Python/pystate.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index d0cbf5cb8364bf4..f6d1956e9dce9ae 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -294,8 +294,6 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->codec_error_registry); Py_CLEAR(interp->modules); Py_CLEAR(interp->modules_by_index); - Py_CLEAR(interp->sysdict); - Py_CLEAR(interp->builtins); Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); Py_CLEAR(interp->import_func); @@ -308,6 +306,14 @@ PyInterpreterState_Clear(PyInterpreterState *interp) if (_PyRuntimeState_GetFinalizing(runtime) == NULL) { _PyWarnings_Fini(interp); } + /* We don't clear sysdict and builtins until the end of this function. + Because clearing other attributes can execute arbitrary Python code + which requires sysdict and builtins. */ + PyDict_Clear(interp->sysdict); + PyDict_Clear(interp->builtins); + Py_CLEAR(interp->sysdict); + Py_CLEAR(interp->builtins); + // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's // objects have been cleaned up at the point. From 500dd0b5e2c0725f81c27dfff3222465f3bd9b82 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 13 Aug 2020 09:48:41 +0100 Subject: [PATCH 155/486] bpo-41531: Fix compilation of dict literals with more than 0xFFFF elements (GH-21850) --- Lib/test/test_compile.py | 10 ++++++++++ .../2020-08-12-19-32-15.bpo-41531.WgPzjT.rst | 2 ++ Python/compile.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 3dd8c8d1db81034..6055192bf705036 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -752,6 +752,16 @@ def continue_in_while(): self.assertEqual(None, opcodes[0].argval) self.assertEqual('RETURN_VALUE', opcodes[1].opname) + def test_big_dict_literal(self): + # The compiler has a flushing point in "compiler_dict" that calls compiles + # a portion of the dictionary literal when the loop that iterates over the items + # reaches 0xFFFF elements but the code was not including the boundary element, + # dropping the key at position 0xFFFF. See bpo-41531 for more information + + dict_size = 0xFFFF + 1 + the_dict = "{" + ",".join(f"{x}:{x}" for x in range(dict_size)) + "}" + self.assertEqual(len(eval(the_dict)), dict_size) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object # stays within reasonable bounds (see issue #21523 for an example diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst new file mode 100644 index 000000000000000..8544664f39335d6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst @@ -0,0 +1,2 @@ +Fix a bug that was dropping keys when compiling dict literals with more than +0xFFFF elements. Patch by Pablo Galindo. diff --git a/Python/compile.c b/Python/compile.c index 5dbd9f221fdf143..2c5326686f8663c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3894,7 +3894,7 @@ compiler_dict(struct compiler *c, expr_ty e) } else { if (elements == 0xFFFF) { - if (!compiler_subdict(c, e, i - elements, i)) { + if (!compiler_subdict(c, e, i - elements, i + 1)) { return 0; } if (have_dict) { From b89d2cdd630c393f639c15d1e71b2764f8502e63 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 13 Aug 2020 09:22:48 -0500 Subject: [PATCH 156/486] bpo-1635741: Port _winapi ext to multi-stage init (GH-21371) --- ...2020-07-06-20-43-19.bpo-1635741.LYhsni.rst | 1 + Modules/_winapi.c | 151 +++++++++--------- 2 files changed, 79 insertions(+), 73 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst new file mode 100644 index 000000000000000..956fcd5d1ee29e0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst @@ -0,0 +1 @@ +Port :mod:`winapi` to multiphase initialization diff --git a/Modules/_winapi.c b/Modules/_winapi.c index ddb11aa5a820425..7ba14095c96e194 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -35,8 +35,10 @@ /* See http://www.python.org/2.4/license for licensing details. */ #include "Python.h" +#include "moduleobject.h" // PyModuleDef_Slot #include "structmember.h" // PyMemberDef + #define WINDOWS_LEAN_AND_MEAN #include "windows.h" #include @@ -78,6 +80,17 @@ check_CancelIoEx() return has_CancelIoEx; } +typedef struct { + PyTypeObject *overlapped_type; +} WinApiState; + +static inline WinApiState* +winapi_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (WinApiState *)state; +} /* * A Python object wrapping an OVERLAPPED structure and other useful data @@ -140,7 +153,9 @@ overlapped_dealloc(OverlappedObject *self) if (self->write_buffer.obj) PyBuffer_Release(&self->write_buffer); Py_CLEAR(self->read_buffer); - PyObject_Del(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); } /*[clinic input] @@ -305,55 +320,29 @@ static PyMemberDef overlapped_members[] = { {NULL} }; -PyTypeObject OverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_winapi.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) overlapped_dealloc, - /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, - /* tp_as_async */ 0, - /* tp_repr */ 0, - /* tp_as_number */ 0, - /* tp_as_sequence */ 0, - /* tp_as_mapping */ 0, - /* tp_hash */ 0, - /* tp_call */ 0, - /* tp_str */ 0, - /* tp_getattro */ 0, - /* tp_setattro */ 0, - /* tp_as_buffer */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ "OVERLAPPED structure wrapper", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ overlapped_methods, - /* tp_members */ overlapped_members, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ 0, +static PyType_Slot winapi_overlapped_type_slots[] = { + {Py_tp_dealloc, overlapped_dealloc}, + {Py_tp_doc, "OVERLAPPED structure wrapper"}, + {Py_tp_methods, overlapped_methods}, + {Py_tp_members, overlapped_members}, + {0,0} +}; + +static PyType_Spec winapi_overlapped_type_spec = { + .name = "_winapi.Overlapped", + .basicsize = sizeof(OverlappedObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = winapi_overlapped_type_slots, }; static OverlappedObject * -new_overlapped(HANDLE handle) +new_overlapped(PyObject *module, HANDLE handle) { - OverlappedObject *self; - - self = PyObject_New(OverlappedObject, &OverlappedType); + WinApiState *st = winapi_get_state(module); + OverlappedObject *self = PyObject_New(OverlappedObject, st->overlapped_type); if (!self) return NULL; + self->handle = handle; self->read_buffer = NULL; self->pending = 0; @@ -409,7 +398,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, OverlappedObject *overlapped = NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) return NULL; } @@ -1527,7 +1516,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, if (!buf) return NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) { Py_DECREF(buf); return NULL; @@ -1810,7 +1799,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, OverlappedObject *overlapped = NULL; if (use_overlapped) { - overlapped = new_overlapped(handle); + overlapped = new_overlapped(module, handle); if (!overlapped) return NULL; buf = &overlapped->write_buffer; @@ -1921,36 +1910,33 @@ static PyMethodDef winapi_functions[] = { {NULL, NULL} }; -static struct PyModuleDef winapi_module = { - PyModuleDef_HEAD_INIT, - "_winapi", - NULL, - -1, - winapi_functions, - NULL, - NULL, - NULL, - NULL -}; - #define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) - -PyMODINIT_FUNC -PyInit__winapi(void) + do { \ + PyObject *value = Py_BuildValue(fmt, con); \ + if (value == NULL) { \ + return -1; \ + } \ + if (PyDict_SetItemString(d, #con, value) < 0) { \ + Py_DECREF(value); \ + return -1; \ + } \ + Py_DECREF(value); \ + } while (0) + +static int winapi_exec(PyObject *m) { - PyObject *d; - PyObject *m; + WinApiState *st = winapi_get_state(m); - if (PyType_Ready(&OverlappedType) < 0) - return NULL; + st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL); + if (st->overlapped_type == NULL) { + return -1; + } - m = PyModule_Create(&winapi_module); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); + if (PyModule_AddType(m, st->overlapped_type) < 0) { + return -1; + } - PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType); + PyObject *d = PyModule_GetDict(m); /* constants */ WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE); @@ -2049,5 +2035,24 @@ PyInit__winapi(void) WINAPI_CONSTANT("i", NULL); - return m; + return 0; +} + +static PyModuleDef_Slot winapi_slots[] = { + {Py_mod_exec, winapi_exec}, + {0, NULL} +}; + +static struct PyModuleDef winapi_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_winapi", + .m_size = sizeof(WinApiState), + .m_methods = winapi_functions, + .m_slots = winapi_slots, +}; + +PyMODINIT_FUNC +PyInit__winapi(void) +{ + return PyModuleDef_Init(&winapi_module); } From 137f19b9b2ff04413e7590a3798e827d5c0ad729 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2020 19:15:38 +0200 Subject: [PATCH 157/486] bpo-40204: Fix Sphinx sytanx in howto/instrumentation.rst (GH-21858) Use generic '.. object::' to declare markers, rather than abusing '.. c:function::' which fails on Sphinx 3. --- Doc/howto/instrumentation.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 909deb5fed33fff..f0081e4ec28905a 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -272,9 +272,7 @@ should instead read: Available static markers ------------------------ -.. I'm reusing the "c:function" type for markers - -.. c:function:: function__entry(str filename, str funcname, int lineno) +.. object:: function__entry(str filename, str funcname, int lineno) This marker indicates that execution of a Python function has begun. It is only triggered for pure-Python (bytecode) functions. @@ -290,7 +288,7 @@ Available static markers * ``$arg3`` : ``int`` line number -.. c:function:: function__return(str filename, str funcname, int lineno) +.. object:: function__return(str filename, str funcname, int lineno) This marker is the converse of :c:func:`function__entry`, and indicates that execution of a Python function has ended (either via ``return``, or via an @@ -298,7 +296,7 @@ Available static markers The arguments are the same as for :c:func:`function__entry` -.. c:function:: line(str filename, str funcname, int lineno) +.. object:: line(str filename, str funcname, int lineno) This marker indicates a Python line is about to be executed. It is the equivalent of line-by-line tracing with a Python profiler. It is @@ -306,24 +304,24 @@ Available static markers The arguments are the same as for :c:func:`function__entry`. -.. c:function:: gc__start(int generation) +.. object:: gc__start(int generation) Fires when the Python interpreter starts a garbage collection cycle. ``arg0`` is the generation to scan, like :func:`gc.collect()`. -.. c:function:: gc__done(long collected) +.. object:: gc__done(long collected) Fires when the Python interpreter finishes a garbage collection cycle. ``arg0`` is the number of collected objects. -.. c:function:: import__find__load__start(str modulename) +.. object:: import__find__load__start(str modulename) Fires before :mod:`importlib` attempts to find and load the module. ``arg0`` is the module name. .. versionadded:: 3.7 -.. c:function:: import__find__load__done(str modulename, int found) +.. object:: import__find__load__done(str modulename, int found) Fires after :mod:`importlib`'s find_and_load function is called. ``arg0`` is the module name, ``arg1`` indicates if module was @@ -332,7 +330,7 @@ Available static markers .. versionadded:: 3.7 -.. c:function:: audit(str event, void *tuple) +.. object:: audit(str event, void *tuple) Fires when :func:`sys.audit` or :c:func:`PySys_Audit` is called. ``arg0`` is the event name as C string, ``arg1`` is a :c:type:`PyObject` @@ -375,14 +373,14 @@ If this file is installed in SystemTap's tapset directory (e.g. ``/usr/share/systemtap/tapset``), then these additional probepoints become available: -.. c:function:: python.function.entry(str filename, str funcname, int lineno, frameptr) +.. object:: python.function.entry(str filename, str funcname, int lineno, frameptr) This probe point indicates that execution of a Python function has begun. It is only triggered for pure-Python (bytecode) functions. -.. c:function:: python.function.return(str filename, str funcname, int lineno, frameptr) +.. object:: python.function.return(str filename, str funcname, int lineno, frameptr) - This probe point is the converse of :c:func:`python.function.return`, and + This probe point is the converse of ``python.function.return``, and indicates that execution of a Python function has ended (either via ``return``, or via an exception). It is only triggered for pure-Python (bytecode) functions. From 4a3b4b2aae2b2ff3ab0029e25ab170fc50d246d6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2020 19:16:02 +0200 Subject: [PATCH 158/486] bpo-40204: Fix duplicates in the documentation (GH-21857) Fix two Sphinx 3 issues: Doc/c-api/buffer.rst:304: WARNING: Duplicate C declaration, also defined in 'c-api/buffer'. Declaration is 'PyBUF_ND'. Doc/c-api/unicode.rst:1603: WARNING: Duplicate C declaration, also defined in 'c-api/unicode'. Declaration is 'PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors)'. --- Doc/c-api/buffer.rst | 2 +- Doc/c-api/unicode.rst | 37 ++++++++++++------------------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index fc1430efa8a4bb7..ddb28af88980c15 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -301,7 +301,7 @@ must be C-contiguous. +-----------------------------------+-------+---------+------------+--------+ | .. c:macro:: PyBUF_ANY_CONTIGUOUS | yes | yes | NULL | C or F | +-----------------------------------+-------+---------+------------+--------+ -| .. c:macro:: PyBUF_ND | yes | NULL | NULL | C | +| :c:macro:`PyBUF_ND` | yes | NULL | NULL | C | +-----------------------------------+-------+---------+------------+--------+ diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index f3f0c4c6c2b9b84..577cdf25114665f 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1487,17 +1487,21 @@ These are the mapping codec APIs: The following codec API is special in that maps Unicode to Unicode. -.. c:function:: PyObject* PyUnicode_Translate(PyObject *unicode, \ - PyObject *mapping, const char *errors) +.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors) - Translate a Unicode object using the given *mapping* object and return the - resulting Unicode object. Return ``NULL`` if an exception was raised by the + Translate a string by applying a character mapping table to it and return the + resulting Unicode object. Return ``NULL`` if an exception was raised by the codec. - The *mapping* object must map Unicode ordinal integers to Unicode strings, - integers (which are then interpreted as Unicode ordinals) or ``None`` - (causing deletion of the character). Unmapped character ordinals (ones - which cause a :exc:`LookupError`) are left untouched and are copied as-is. + The mapping table must map Unicode ordinal integers to Unicode ordinal integers + or ``None`` (causing deletion of the character). + + Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries + and sequences work well. Unmapped character ordinals (ones which cause a + :exc:`LookupError`) are left untouched and are copied as-is. + + *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to + use the default error handling. .. c:function:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, \ @@ -1600,23 +1604,6 @@ They all return ``NULL`` or ``-1`` if an exception occurs. characters are not included in the resulting strings. -.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, \ - const char *errors) - - Translate a string by applying a character mapping table to it and return the - resulting Unicode object. - - The mapping table must map Unicode ordinal integers to Unicode ordinal integers - or ``None`` (causing deletion of the character). - - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. - - *errors* has the usual meaning for codecs. It may be ``NULL`` which indicates to - use the default error handling. - - .. c:function:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq) Join a sequence of strings using the given *separator* and return the resulting From 3f8b7edaa617a4d55415a04740c4e12d9eaad613 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 13 Aug 2020 13:18:49 -0400 Subject: [PATCH 159/486] bpo-41520: Fix second codeop regression (GH-21848) * bpo-41520: Fix second codeop repression Fix the repression introduced by the initial regression fix. --- Lib/codeop.py | 4 ++-- Lib/test/test_codeop.py | 13 ++++++++----- .../2020-08-12-13-25-16.bpo-41520.BEUWa4.rst | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Lib/codeop.py b/Lib/codeop.py index 547629262d06892..4c10470aee7b7c1 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -85,9 +85,9 @@ def _maybe_compile(compiler, source, filename, symbol): pass # Catch syntax warnings after the first compile - # to emit SyntaxWarning at most once. + # to emit warnings (SyntaxWarning, DeprecationWarning) at most once. with warnings.catch_warnings(): - warnings.simplefilter("error", SyntaxWarning) + warnings.simplefilter("error") try: code1 = compiler(source + "\n", filename, symbol) diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 7984e5f1e5a69a7..45d0a7de9d92532 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -307,14 +307,17 @@ def test_filename(self): def test_warning(self): # Test that the warning is only returned once. - with warnings_helper.check_warnings((".*literal", SyntaxWarning)) as w: - compile_command("0 is 0") - self.assertEqual(len(w.warnings), 1) + with warnings_helper.check_warnings( + (".*literal", SyntaxWarning), + (".*invalid", DeprecationWarning), + ) as w: + compile_command(r"'\e' is 0") + self.assertEqual(len(w.warnings), 2) # bpo-41520: check SyntaxWarning treated as an SyntaxError - with self.assertRaises(SyntaxError): + with warnings.catch_warnings(), self.assertRaises(SyntaxError): warnings.simplefilter('error', SyntaxWarning) - compile_command('1 is 1\n', symbol='exec') + compile_command('1 is 1', symbol='exec') if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst b/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst index ca5501c2aeec0de..0e140d91bb4b61c 100644 --- a/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst +++ b/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst @@ -1 +1 @@ -Fix :mod:`codeop` regression: it no longer ignores :exc:`SyntaxWarning`. +Fix :mod:`codeop` regression that prevented turning compile warnings into errors. From 6998edb2d4da9c8dd54b1755251329110fbc8c58 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2020 19:20:28 +0200 Subject: [PATCH 160/486] bpo-41521: Replace denylist with blocklist is http.cookiejar doc (GH-21826) The http.cookiejar module has is_blocked() and blocked_domains() methods, so "blocklist" term sounds better than "denylist" in this module. Replace also denylisted with denied in test___all__. --- Doc/library/http.cookiejar.rst | 8 ++++---- Lib/test/test___all__.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 0a9ee7eb516f417..7b1aa80a01797cf 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -462,8 +462,8 @@ receiving cookies. There are also some strictness switches that allow you to tighten up the rather loose Netscape protocol rules a little bit (at the cost of blocking some benign cookies). -A domain denylist and allowlist is provided (both off by default). Only domains -not in the denylist and present in the allowlist (if the allowlist is active) +A domain blocklist and allowlist is provided (both off by default). Only domains +not in the blocklist and present in the allowlist (if the allowlist is active) participate in cookie setting and returning. Use the *blocked_domains* constructor argument, and :meth:`blocked_domains` and :meth:`set_blocked_domains` methods (and the corresponding argument and methods @@ -471,7 +471,7 @@ for *allowed_domains*). If you set an allowlist, you can turn it off again by setting it to :const:`None`. Domains in block or allow lists that do not start with a dot must equal the -cookie domain to be matched. For example, ``"example.com"`` matches a denylist +cookie domain to be matched. For example, ``"example.com"`` matches a blocklist entry of ``"example.com"``, but ``"www.example.com"`` does not. Domains that do start with a dot are matched by more specific domains too. For example, both ``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"`` @@ -494,7 +494,7 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not. .. method:: DefaultCookiePolicy.is_blocked(domain) - Return whether *domain* is on the denylist for setting or receiving cookies. + Return whether *domain* is on the blocklist for setting or receiving cookies. .. method:: DefaultCookiePolicy.allowed_domains() diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index c6ce64864c0db6d..15f42d2d114a686 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -85,13 +85,13 @@ def test_all(self): lib_dir = os.path.dirname(os.path.dirname(__file__)) for path, modname in self.walk_modules(lib_dir, ""): m = modname - denylisted = False + denied = False while m: if m in denylist: - denylisted = True + denied = True break m = m.rpartition('.')[0] - if denylisted: + if denied: continue if support.verbose: print(modname) From f57ddb007ea3939472c6af79d313d1ecf3f01666 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2020 21:41:54 +0200 Subject: [PATCH 161/486] bpo-40204: Add :noindex: in the documentation (GH-21859) Add :noindex: to duplicated documentation to fix "duplicate object description" errors. For example, fix this Sphinx 3 issue: Doc/library/configparser.rst:1146: WARNING: duplicate object description of configparser.ConfigParser.optionxform, other instance in library/configparser, use :noindex: for one of them --- Doc/library/aifc.rst | 2 + Doc/library/configparser.rst | 161 +++++++++++++++++---------------- Doc/library/difflib.rst | 2 + Doc/library/enum.rst | 1 + Doc/library/socket.rst | 2 + Doc/library/tarfile.rst | 1 + Doc/library/token.rst | 1 + Doc/library/turtle.rst | 3 + Doc/library/urllib.request.rst | 2 +- 9 files changed, 94 insertions(+), 81 deletions(-) diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 7328907730fb107..2e917cf7321b857 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -208,6 +208,7 @@ number of frames must be filled in. .. method:: aifc.tell() + :noindex: Return the current write position in the output file. Useful in combination with :meth:`setmark`. @@ -232,6 +233,7 @@ number of frames must be filled in. .. method:: aifc.close() + :noindex: Close the AIFF file. The header of the file is updated to reflect the actual size of the audio data. After calling this method, the object can no longer be diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 739477f55fddda8..2e22a549ee2813d 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -674,97 +674,98 @@ be overridden by subclasses or by attribute assignment. .. attribute:: ConfigParser.BOOLEAN_STATES - By default when using :meth:`~ConfigParser.getboolean`, config parsers - consider the following values ``True``: ``'1'``, ``'yes'``, ``'true'``, - ``'on'`` and the following values ``False``: ``'0'``, ``'no'``, ``'false'``, - ``'off'``. You can override this by specifying a custom dictionary of strings - and their Boolean outcomes. For example: - - .. doctest:: - - >>> custom = configparser.ConfigParser() - >>> custom['section1'] = {'funky': 'nope'} - >>> custom['section1'].getboolean('funky') - Traceback (most recent call last): - ... - ValueError: Not a boolean: nope - >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False} - >>> custom['section1'].getboolean('funky') - False - - Other typical Boolean pairs include ``accept``/``reject`` or - ``enabled``/``disabled``. + By default when using :meth:`~ConfigParser.getboolean`, config parsers + consider the following values ``True``: ``'1'``, ``'yes'``, ``'true'``, + ``'on'`` and the following values ``False``: ``'0'``, ``'no'``, ``'false'``, + ``'off'``. You can override this by specifying a custom dictionary of strings + and their Boolean outcomes. For example: + + .. doctest:: + + >>> custom = configparser.ConfigParser() + >>> custom['section1'] = {'funky': 'nope'} + >>> custom['section1'].getboolean('funky') + Traceback (most recent call last): + ... + ValueError: Not a boolean: nope + >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False} + >>> custom['section1'].getboolean('funky') + False + + Other typical Boolean pairs include ``accept``/``reject`` or + ``enabled``/``disabled``. .. method:: ConfigParser.optionxform(option) + :noindex: - This method transforms option names on every read, get, or set - operation. The default converts the name to lowercase. This also - means that when a configuration file gets written, all keys will be - lowercase. Override this method if that's unsuitable. - For example: + This method transforms option names on every read, get, or set + operation. The default converts the name to lowercase. This also + means that when a configuration file gets written, all keys will be + lowercase. Override this method if that's unsuitable. + For example: - .. doctest:: + .. doctest:: + + >>> config = """ + ... [Section1] + ... Key = Value + ... + ... [Section2] + ... AnotherKey = Value + ... """ + >>> typical = configparser.ConfigParser() + >>> typical.read_string(config) + >>> list(typical['Section1'].keys()) + ['key'] + >>> list(typical['Section2'].keys()) + ['anotherkey'] + >>> custom = configparser.RawConfigParser() + >>> custom.optionxform = lambda option: option + >>> custom.read_string(config) + >>> list(custom['Section1'].keys()) + ['Key'] + >>> list(custom['Section2'].keys()) + ['AnotherKey'] - >>> config = """ - ... [Section1] - ... Key = Value - ... - ... [Section2] - ... AnotherKey = Value - ... """ - >>> typical = configparser.ConfigParser() - >>> typical.read_string(config) - >>> list(typical['Section1'].keys()) - ['key'] - >>> list(typical['Section2'].keys()) - ['anotherkey'] - >>> custom = configparser.RawConfigParser() - >>> custom.optionxform = lambda option: option - >>> custom.read_string(config) - >>> list(custom['Section1'].keys()) - ['Key'] - >>> list(custom['Section2'].keys()) - ['AnotherKey'] - - .. note:: - The optionxform function transforms option names to a canonical form. - This should be an idempotent function: if the name is already in - canonical form, it should be returned unchanged. + .. note:: + The optionxform function transforms option names to a canonical form. + This should be an idempotent function: if the name is already in + canonical form, it should be returned unchanged. .. attribute:: ConfigParser.SECTCRE - A compiled regular expression used to parse section headers. The default - matches ``[section]`` to the name ``"section"``. Whitespace is considered - part of the section name, thus ``[ larch ]`` will be read as a section of - name ``" larch "``. Override this attribute if that's unsuitable. For - example: + A compiled regular expression used to parse section headers. The default + matches ``[section]`` to the name ``"section"``. Whitespace is considered + part of the section name, thus ``[ larch ]`` will be read as a section of + name ``" larch "``. Override this attribute if that's unsuitable. For + example: + + .. doctest:: + + >>> import re + >>> config = """ + ... [Section 1] + ... option = value + ... + ... [ Section 2 ] + ... another = val + ... """ + >>> typical = configparser.ConfigParser() + >>> typical.read_string(config) + >>> typical.sections() + ['Section 1', ' Section 2 '] + >>> custom = configparser.ConfigParser() + >>> custom.SECTCRE = re.compile(r"\[ *(?P
    [^]]+?) *\]") + >>> custom.read_string(config) + >>> custom.sections() + ['Section 1', 'Section 2'] - .. doctest:: + .. note:: - >>> import re - >>> config = """ - ... [Section 1] - ... option = value - ... - ... [ Section 2 ] - ... another = val - ... """ - >>> typical = configparser.ConfigParser() - >>> typical.read_string(config) - >>> typical.sections() - ['Section 1', ' Section 2 '] - >>> custom = configparser.ConfigParser() - >>> custom.SECTCRE = re.compile(r"\[ *(?P
    [^]]+?) *\]") - >>> custom.read_string(config) - >>> custom.sections() - ['Section 1', 'Section 2'] - - .. note:: - - While ConfigParser objects also use an ``OPTCRE`` attribute for recognizing - option lines, it's not recommended to override it because that would - interfere with constructor options *allow_no_value* and *delimiters*. + While ConfigParser objects also use an ``OPTCRE`` attribute for recognizing + option lines, it's not recommended to override it because that would + interfere with constructor options *allow_no_value* and *delimiters*. Legacy API Examples diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 7a898c21b52e03b..25e3511d017858f 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -24,6 +24,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. class:: SequenceMatcher + :noindex: This is a flexible class for comparing pairs of sequences of any type, so long as the sequence elements are :term:`hashable`. The basic algorithm predates, and is a @@ -651,6 +652,7 @@ The :class:`Differ` class has this constructor: .. class:: Differ(linejunk=None, charjunk=None) + :noindex: Optional keyword parameters *linejunk* and *charjunk* are for filter functions (or ``None``): diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index b327a0ad15f96c9..00bfb260c020472 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -50,6 +50,7 @@ helper, :class:`auto`. the bitwise operations without losing their :class:`Flag` membership. .. function:: unique + :noindex: Enum class decorator that ensures only one name is bound to any one value. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index d798c1a9d10a059..5bcac20a4c60485 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1695,7 +1695,9 @@ to sockets. .. method:: socket.setsockopt(level, optname, value: int) .. method:: socket.setsockopt(level, optname, value: buffer) + :noindex: .. method:: socket.setsockopt(level, optname, None, optlen: int) + :noindex: .. index:: module: struct diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index c204263d3a094c1..cca466b56979487 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -151,6 +151,7 @@ Some facts and figures: .. class:: TarFile + :noindex: Class for reading and writing tar archives. Do not use this class directly: use :func:`tarfile.open` instead. See :ref:`tarfile-objects`. diff --git a/Doc/library/token.rst b/Doc/library/token.rst index f8ebb275ebbc444..a1aceba96ce0306 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -70,6 +70,7 @@ the :mod:`tokenize` module. .. data:: TYPE_COMMENT + :noindex: Token value indicating that a type comment was recognized. Such tokens are only produced when :func:`ast.parse()` is invoked with diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index fed85045435b1b6..d3487537df99a95 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1069,6 +1069,7 @@ More drawing control ~~~~~~~~~~~~~~~~~~~~ .. function:: reset() + :noindex: Delete the turtle's drawings from the screen, re-center the turtle and set variables to the default values. @@ -1090,6 +1091,7 @@ More drawing control .. function:: clear() + :noindex: Delete the turtle's drawings from the screen. Do not move turtle. State and position of the turtle as well as drawings of other turtles are not affected. @@ -1362,6 +1364,7 @@ Using events ------------ .. function:: onclick(fun, btn=1, add=None) + :noindex: :param fun: a function with two arguments which will be called with the coordinates of the clicked point on the canvas diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 288ce14d36f0163..b37f230feb60153 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -946,7 +946,7 @@ tracking URIs for which authentication credentials should always be sent. If *is_authenticated* is specified as ``True``, *realm* is ignored. -.. method:: HTTPPasswordMgr.find_user_password(realm, authuri) +.. method:: HTTPPasswordMgrWithPriorAuth.find_user_password(realm, authuri) Same as for :class:`HTTPPasswordMgrWithDefaultRealm` objects From 5b5e05b42a35cafa1df1ab3e49472623dc985a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Srinivas=20Reddy=20Thatiparthy=20=28=E0=B0=B6=E0=B1=8D?= =?UTF-8?q?=E0=B0=B0=E0=B1=80=E0=B0=A8=E0=B0=BF=E0=B0=B5=E0=B0=BE=E0=B0=B8?= =?UTF-8?q?=E0=B1=8D=20=20=E0=B0=B0=E0=B1=86=E0=B0=A1=E0=B1=8D=E0=B0=A1?= =?UTF-8?q?=E0=B0=BF=20=E0=B0=A4=E0=B0=BE=E0=B0=9F=E0=B0=BF=E0=B0=AA?= =?UTF-8?q?=E0=B0=B0=E0=B1=8D=E0=B0=A4=E0=B0=BF=29?= Date: Fri, 14 Aug 2020 01:22:04 +0530 Subject: [PATCH 162/486] bpo-41066: Update the comparison section for os vs pathlib (GH-21261) --- Doc/library/pathlib.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index bf6fee44df2c885..f705d15b8d4f1a9 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1196,9 +1196,12 @@ os and os.path pathlib :func:`os.path.exists` :meth:`Path.exists` :func:`os.path.expanduser` :meth:`Path.expanduser` and :meth:`Path.home` +:func:`os.listdir` :meth:`Path.iterdir` :func:`os.path.isdir` :meth:`Path.is_dir` :func:`os.path.isfile` :meth:`Path.is_file` :func:`os.path.islink` :meth:`Path.is_symlink` +:func:`os.link` :meth:`Path.link_to` +:func:`os.symlink` :meth:`Path.symlink_to` :func:`os.readlink` :meth:`Path.readlink` :func:`os.stat` :meth:`Path.stat`, :meth:`Path.owner`, From 16b50406eaa0e930f0ba8edd443f57925db29911 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2020 22:11:50 +0200 Subject: [PATCH 163/486] bpo-40204, doc: Fix syntax of C variables (GH-21846) For example, fix the following Sphinx 3 errors: Doc/c-api/buffer.rst:102: WARNING: Error in declarator or parameters Invalid C declaration: Expected identifier in nested name. [error at 5] void \*obj -----^ Doc/c-api/arg.rst:130: WARNING: Unparseable C cross-reference: 'PyObject*' Invalid C declaration: Expected end of definition. [error at 8] PyObject* --------^ The modified documentation is compatible with Sphinx 2 and Sphinx 3. --- Doc/c-api/arg.rst | 26 +++++++++++----------- Doc/c-api/buffer.rst | 26 +++++++++++----------- Doc/c-api/call.rst | 14 ++++++------ Doc/c-api/capsule.rst | 2 +- Doc/c-api/dict.rst | 6 ++--- Doc/c-api/exceptions.rst | 4 ++-- Doc/c-api/file.rst | 4 ++-- Doc/c-api/init.rst | 48 ++++++++++++++++++++-------------------- Doc/c-api/intro.rst | 6 ++--- Doc/c-api/marshal.rst | 8 +++---- Doc/c-api/memory.rst | 26 +++++++++++----------- Doc/c-api/module.rst | 4 ++-- Doc/c-api/object.rst | 2 +- Doc/c-api/structures.rst | 18 +++++++-------- Doc/c-api/tuple.rst | 2 +- Doc/c-api/typeobj.rst | 4 ++-- Doc/c-api/unicode.rst | 2 +- Doc/c-api/veryhigh.rst | 4 ++-- Doc/whatsnew/3.3.rst | 4 ++-- 19 files changed, 105 insertions(+), 105 deletions(-) diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 26e872c5a348e35..bdaae44e240a029 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -129,12 +129,12 @@ which disallows mutable objects such as :class:`bytearray`. ``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a bytes object. The C variable may also be declared as :c:type:`PyObject\*`. + a bytes object. The C variable may also be declared as :c:type:`PyObject*`. ``Y`` (:class:`bytearray`) [PyByteArrayObject \*] Requires that the Python object is a :class:`bytearray` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject\*`. + a :class:`bytearray` object. The C variable may also be declared as :c:type:`PyObject*`. ``u`` (:class:`str`) [const Py_UNICODE \*] Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of @@ -181,7 +181,7 @@ which disallows mutable objects such as :class:`bytearray`. ``U`` (:class:`str`) [PyObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode - object. The C variable may also be declared as :c:type:`PyObject\*`. + object. The C variable may also be declared as :c:type:`PyObject*`. ``w*`` (read-write :term:`bytes-like object`) [Py_buffer] This format accepts any object which implements the read-write buffer @@ -194,10 +194,10 @@ which disallows mutable objects such as :class:`bytearray`. It only works for encoded data without embedded NUL bytes. This format requires two arguments. The first is only used as input, and - must be a :c:type:`const char\*` which points to the name of an encoding as a + must be a :c:type:`const char*` which points to the name of an encoding as a NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The - second argument must be a :c:type:`char\*\*`; the value of the pointer it + second argument must be a :c:type:`char**`; the value of the pointer it references will be set to a buffer with the contents of the argument text. The text will be encoded in the encoding specified by the first argument. @@ -217,10 +217,10 @@ which disallows mutable objects such as :class:`bytearray`. characters. It requires three arguments. The first is only used as input, and must be a - :c:type:`const char\*` which points to the name of an encoding as a + :c:type:`const char*` which points to the name of an encoding as a NUL-terminated string, or ``NULL``, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The - second argument must be a :c:type:`char\*\*`; the value of the pointer it + second argument must be a :c:type:`char**`; the value of the pointer it references will be set to a buffer with the contents of the argument text. The text will be encoded in the encoding specified by the first argument. The third argument must be a pointer to an integer; the referenced integer @@ -320,7 +320,7 @@ Other objects ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but takes two C arguments: the first is the address of a Python type object, the - second is the address of the C variable (of type :c:type:`PyObject\*`) into which + second is the address of the C variable (of type :c:type:`PyObject*`) into which the object pointer is stored. If the Python object does not have the required type, :exc:`TypeError` is raised. @@ -329,13 +329,13 @@ Other objects ``O&`` (object) [*converter*, *anything*] Convert a Python object to a C variable through a *converter* function. This takes two arguments: the first is a function, the second is the address of a C - variable (of arbitrary type), converted to :c:type:`void \*`. The *converter* + variable (of arbitrary type), converted to :c:type:`void *`. The *converter* function in turn is called as follows:: status = converter(object, address); where *object* is the Python object to be converted and *address* is the - :c:type:`void\*` argument that was passed to the :c:func:`PyArg_Parse\*` function. + :c:type:`void*` argument that was passed to the :c:func:`PyArg_Parse\*` function. The returned *status* should be ``1`` for a successful conversion and ``0`` if the conversion has failed. When the conversion fails, the *converter* function should raise an exception and leave the content of *address* unmodified. @@ -481,7 +481,7 @@ API Functions *args*; it must actually be a tuple. The length of the tuple must be at least *min* and no more than *max*; *min* and *max* may be equal. Additional arguments must be passed to the function, each of which should be a pointer to a - :c:type:`PyObject\*` variable; these will be filled in with the values from + :c:type:`PyObject*` variable; these will be filled in with the values from *args*; they will contain borrowed references. The variables which correspond to optional parameters not given by *args* will not be filled in; these should be initialized by the caller. This function returns true on success and false if @@ -650,8 +650,8 @@ Building values ``O&`` (object) [*converter*, *anything*] Convert *anything* to a Python object through a *converter* function. The - function is called with *anything* (which should be compatible with :c:type:`void - \*`) as its argument and should return a "new" Python object, or ``NULL`` if an + function is called with *anything* (which should be compatible with :c:type:`void*`) + as its argument and should return a "new" Python object, or ``NULL`` if an error occurred. ``(items)`` (:class:`tuple`) [*matching-items*] diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index ddb28af88980c15..e32719373cc7166 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -89,7 +89,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:type:: Py_buffer - .. c:member:: void \*buf + .. c:member:: void *buf A pointer to the start of the logical structure described by the buffer fields. This can be any location within the underlying physical memory @@ -99,7 +99,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. For :term:`contiguous` arrays, the value points to the beginning of the memory block. - .. c:member:: void \*obj + .. c:member:: void *obj A new reference to the exporting object. The reference is owned by the consumer and automatically decremented and set to ``NULL`` by @@ -145,7 +145,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. or a :c:macro:`PyBUF_WRITABLE` request, the consumer must disregard :c:member:`~Py_buffer.itemsize` and assume ``itemsize == 1``. - .. c:member:: const char \*format + .. c:member:: const char *format A *NUL* terminated string in :mod:`struct` module style syntax describing the contents of a single item. If this is ``NULL``, ``"B"`` (unsigned bytes) @@ -164,7 +164,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. to 64. Exporters MUST respect this limit, consumers of multi-dimensional buffers SHOULD be able to handle up to :c:macro:`PyBUF_MAX_NDIM` dimensions. - .. c:member:: Py_ssize_t \*shape + .. c:member:: Py_ssize_t *shape An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim` indicating the shape of the memory as an n-dimensional array. Note that @@ -177,7 +177,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. The shape array is read-only for the consumer. - .. c:member:: Py_ssize_t \*strides + .. c:member:: Py_ssize_t *strides An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim` giving the number of bytes to skip to get to a new element in each @@ -189,7 +189,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. The strides array is read-only for the consumer. - .. c:member:: Py_ssize_t \*suboffsets + .. c:member:: Py_ssize_t *suboffsets An array of :c:type:`Py_ssize_t` of length :c:member:`~Py_buffer.ndim`. If ``suboffsets[n] >= 0``, the values stored along the nth dimension are @@ -207,7 +207,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. The suboffsets array is read-only for the consumer. - .. c:member:: void \*internal + .. c:member:: void *internal This is for use internally by the exporting object. For example, this might be re-cast as an integer by the exporter and used to store flags @@ -438,12 +438,12 @@ Buffer-related functions Send a request to *exporter* to fill in *view* as specified by *flags*. If the exporter cannot provide a buffer of the exact type, it MUST raise - :c:data:`PyExc_BufferError`, set :c:member:`view->obj` to ``NULL`` and + :c:data:`PyExc_BufferError`, set ``view->obj`` to ``NULL`` and return ``-1``. - On success, fill in *view*, set :c:member:`view->obj` to a new reference + On success, fill in *view*, set ``view->obj`` to a new reference to *exporter* and return 0. In the case of chained buffer providers - that redirect requests to a single object, :c:member:`view->obj` MAY + that redirect requests to a single object, ``view->obj`` MAY refer to this object instead of *exporter* (See :ref:`Buffer Object Structures `). Successful calls to :c:func:`PyObject_GetBuffer` must be paired with calls @@ -455,7 +455,7 @@ Buffer-related functions .. c:function:: void PyBuffer_Release(Py_buffer *view) Release the buffer *view* and decrement the reference count for - :c:member:`view->obj`. This function MUST be called when the buffer + ``view->obj``. This function MUST be called when the buffer is no longer being used, otherwise reference leaks may occur. It is an error to call this function on a buffer that was not obtained via @@ -516,9 +516,9 @@ Buffer-related functions *view* as specified by flags, unless *buf* has been designated as read-only and :c:macro:`PyBUF_WRITABLE` is set in *flags*. - On success, set :c:member:`view->obj` to a new reference to *exporter* and + On success, set ``view->obj`` to a new reference to *exporter* and return 0. Otherwise, raise :c:data:`PyExc_BufferError`, set - :c:member:`view->obj` to ``NULL`` and return ``-1``; + ``view->obj`` to ``NULL`` and return ``-1``; If this function is used as part of a :ref:`getbufferproc `, *exporter* MUST be set to the exporting object and *flags* must be passed diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 0832e7e2193600b..31dc9c8031fdb6d 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -84,7 +84,7 @@ This is a pointer to a function with the following signature: and they must be unique. If there are no keyword arguments, then *kwnames* can instead be *NULL*. -.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET +.. c:macro:: PY_VECTORCALL_ARGUMENTS_OFFSET If this flag is set in a vectorcall *nargsf* argument, the callee is allowed to temporarily change ``args[-1]``. In other words, *args* points to @@ -283,7 +283,7 @@ please see individual documentation for details. This is the equivalent of the Python expression: ``callable(*args)``. - Note that if you only pass :c:type:`PyObject \*` args, + Note that if you only pass :c:type:`PyObject *` args, :c:func:`PyObject_CallFunctionObjArgs` is a faster alternative. .. versionchanged:: 3.4 @@ -304,17 +304,17 @@ please see individual documentation for details. This is the equivalent of the Python expression: ``obj.name(arg1, arg2, ...)``. - Note that if you only pass :c:type:`PyObject \*` args, + Note that if you only pass :c:type:`PyObject *` args, :c:func:`PyObject_CallMethodObjArgs` is a faster alternative. .. versionchanged:: 3.4 The types of *name* and *format* were changed from ``char *``. -.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) +.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...) Call a callable Python object *callable*, with a variable number of - :c:type:`PyObject \*` arguments. The arguments are provided as a variable number + :c:type:`PyObject *` arguments. The arguments are provided as a variable number of parameters followed by *NULL*. Return the result of the call on success, or raise an exception and return @@ -324,11 +324,11 @@ please see individual documentation for details. ``callable(arg1, arg2, ...)``. -.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ..., NULL) +.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) Call a method of the Python object *obj*, where the name of the method is given as a Python string object in *name*. It is called with a variable number of - :c:type:`PyObject \*` arguments. The arguments are provided as a variable number + :c:type:`PyObject *` arguments. The arguments are provided as a variable number of parameters followed by *NULL*. Return the result of the call on success, or raise an exception and return diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 78e21140b2f80cf..5eb313c89bfd592 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -15,7 +15,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. .. c:type:: PyCapsule This subtype of :c:type:`PyObject` represents an opaque value, useful for C - extension modules who need to pass an opaque value (as a :c:type:`void\*` + extension modules who need to pass an opaque value (as a :c:type:`void*` pointer) through Python code to other C code. It is often used to make a C function pointer defined in one module available to other modules, so the regular import mechanism can be used to access C APIs defined in dynamically diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 7493837ac622f62..769484134ed5154 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -73,7 +73,7 @@ Dictionary Objects .. index:: single: PyUnicode_FromString() Insert *val* into the dictionary *p* using *key* as a key. *key* should - be a :c:type:`const char\*`. The key object is created using + be a :c:type:`const char*`. The key object is created using ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on failure. This function *does not* steal a reference to *val*. @@ -116,7 +116,7 @@ Dictionary Objects .. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a - :c:type:`const char\*`, rather than a :c:type:`PyObject\*`. + :c:type:`const char*`, rather than a :c:type:`PyObject*`. Note that exceptions which occur while calling :meth:`__hash__` and :meth:`__eq__` methods and creating a temporary string object @@ -165,7 +165,7 @@ Dictionary Objects prior to the first call to this function to start the iteration; the function returns true for each pair in the dictionary, and false once all pairs have been reported. The parameters *pkey* and *pvalue* should either - point to :c:type:`PyObject\*` variables that will be filled in with each key + point to :c:type:`PyObject*` variables that will be filled in with each key and value, respectively, or may be ``NULL``. Any references returned through them are borrowed. *ppos* should not be altered during iteration. Its value represents offsets within the internal dictionary structure, and diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index b4722ff81979f4a..247b6d68eceae95 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -783,7 +783,7 @@ Standard Exceptions All standard Python exceptions are available as global variables whose names are ``PyExc_`` followed by the Python exception name. These have the type -:c:type:`PyObject\*`; they are all class objects. For completeness, here are all +:c:type:`PyObject*`; they are all class objects. For completeness, here are all the variables: .. index:: @@ -1003,7 +1003,7 @@ Standard Warning Categories All standard Python warning categories are available as global variables whose names are ``PyExc_`` followed by the Python exception name. These have the type -:c:type:`PyObject\*`; they are all class objects. For completeness, here are all +:c:type:`PyObject*`; they are all class objects. For completeness, here are all the variables: .. index:: diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 5370c4e350a0b58..ea027ee975c6515 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -8,7 +8,7 @@ File Objects .. index:: object: file These APIs are a minimal emulation of the Python 2 C API for built-in file -objects, which used to rely on the buffered I/O (:c:type:`FILE\*`) support +objects, which used to rely on the buffered I/O (:c:type:`FILE*`) support from the C standard library. In Python 3, files and streams use the new :mod:`io` module, which defines several layers over the low-level unbuffered I/O of the operating system. The functions described below are @@ -17,7 +17,7 @@ error reporting in the interpreter; third-party code is advised to access the :mod:`io` APIs instead. -.. c:function:: PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) +.. c:function:: PyObject* PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) Create a Python file object from the file descriptor of an already opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 68fed2acc447ee9..7f06648bcb4572f 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -81,7 +81,7 @@ When a flag is set by an option, the value of the flag is the number of times that the option was set. For example, ``-b`` sets :c:data:`Py_BytesWarningFlag` to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. -.. c:var:: Py_BytesWarningFlag +.. c:var:: int Py_BytesWarningFlag Issue a warning when comparing :class:`bytes` or :class:`bytearray` with :class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater @@ -89,7 +89,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-b` option. -.. c:var:: Py_DebugFlag +.. c:var:: int Py_DebugFlag Turn on parser debugging output (for expert only, depending on compilation options). @@ -97,7 +97,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment variable. -.. c:var:: Py_DontWriteBytecodeFlag +.. c:var:: int Py_DontWriteBytecodeFlag If set to non-zero, Python won't try to write ``.pyc`` files on the import of source modules. @@ -105,14 +105,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable. -.. c:var:: Py_FrozenFlag +.. c:var:: int Py_FrozenFlag Suppress error messages when calculating the module search path in :c:func:`Py_GetPath`. Private flag used by ``_freeze_importlib`` and ``frozenmain`` programs. -.. c:var:: Py_HashRandomizationFlag +.. c:var:: int Py_HashRandomizationFlag Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to a non-empty string. @@ -120,14 +120,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment variable to initialize the secret hash seed. -.. c:var:: Py_IgnoreEnvironmentFlag +.. c:var:: int Py_IgnoreEnvironmentFlag Ignore all :envvar:`PYTHON*` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. Set by the :option:`-E` and :option:`-I` options. -.. c:var:: Py_InspectFlag +.. c:var:: int Py_InspectFlag When a script is passed as first argument or the :option:`-c` option is used, enter interactive mode after executing the script or the command, even when @@ -136,11 +136,11 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment variable. -.. c:var:: Py_InteractiveFlag +.. c:var:: int Py_InteractiveFlag Set by the :option:`-i` option. -.. c:var:: Py_IsolatedFlag +.. c:var:: int Py_IsolatedFlag Run Python in isolated mode. In isolated mode :data:`sys.path` contains neither the script's directory nor the user's site-packages directory. @@ -149,7 +149,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. versionadded:: 3.4 -.. c:var:: Py_LegacyWindowsFSEncodingFlag +.. c:var:: int Py_LegacyWindowsFSEncodingFlag If the flag is non-zero, use the ``mbcs`` encoding instead of the UTF-8 encoding for the filesystem encoding. @@ -161,7 +161,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. availability:: Windows. -.. c:var:: Py_LegacyWindowsStdioFlag +.. c:var:: int Py_LegacyWindowsStdioFlag If the flag is non-zero, use :class:`io.FileIO` instead of :class:`WindowsConsoleIO` for :mod:`sys` standard streams. @@ -173,7 +173,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. availability:: Windows. -.. c:var:: Py_NoSiteFlag +.. c:var:: int Py_NoSiteFlag Disable the import of the module :mod:`site` and the site-dependent manipulations of :data:`sys.path` that it entails. Also disable these @@ -182,7 +182,7 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-S` option. -.. c:var:: Py_NoUserSiteDirectory +.. c:var:: int Py_NoUserSiteDirectory Don't add the :data:`user site-packages directory ` to :data:`sys.path`. @@ -190,12 +190,12 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-s` and :option:`-I` options, and the :envvar:`PYTHONNOUSERSITE` environment variable. -.. c:var:: Py_OptimizeFlag +.. c:var:: int Py_OptimizeFlag Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment variable. -.. c:var:: Py_QuietFlag +.. c:var:: int Py_QuietFlag Don't display the copyright and version messages even in interactive mode. @@ -203,14 +203,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. versionadded:: 3.2 -.. c:var:: Py_UnbufferedStdioFlag +.. c:var:: int Py_UnbufferedStdioFlag Force the stdout and stderr streams to be unbuffered. Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED` environment variable. -.. c:var:: Py_VerboseFlag +.. c:var:: int Py_VerboseFlag Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded. If greater or equal @@ -830,7 +830,7 @@ code, or when embedding the Python interpreter: .. c:type:: PyThreadState This data structure represents the state of a single thread. The only public - data member is :c:type:`PyInterpreterState \*`:attr:`interp`, which points to + data member is :attr:`interp` (:c:type:`PyInterpreterState *`), which points to this thread's interpreter state. @@ -1619,7 +1619,7 @@ The Python interpreter provides low-level support for thread-local storage (TLS) which wraps the underlying native TLS implementation to support the Python-level thread local storage API (:class:`threading.local`). The CPython C level APIs are similar to those offered by pthreads and Windows: -use a thread key and functions to associate a :c:type:`void\*` value per +use a thread key and functions to associate a :c:type:`void*` value per thread. The GIL does *not* need to be held when calling these functions; they supply @@ -1630,8 +1630,8 @@ you need to include :file:`pythread.h` to use thread-local storage. .. note:: None of these API functions handle memory management on behalf of the - :c:type:`void\*` values. You need to allocate and deallocate them yourself. - If the :c:type:`void\*` values happen to be :c:type:`PyObject\*`, these + :c:type:`void*` values. You need to allocate and deallocate them yourself. + If the :c:type:`void*` values happen to be :c:type:`PyObject*`, these functions don't do refcount operations on them either. .. _thread-specific-storage-api: @@ -1727,14 +1727,14 @@ undefined if the given :c:type:`Py_tss_t` has not been initialized by .. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value) - Return a zero value to indicate successfully associating a :c:type:`void\*` + Return a zero value to indicate successfully associating a :c:type:`void*` value with a TSS key in the current thread. Each thread has a distinct - mapping of the key to a :c:type:`void\*` value. + mapping of the key to a :c:type:`void*` value. .. c:function:: void* PyThread_tss_get(Py_tss_t *key) - Return the :c:type:`void\*` value associated with a TSS key in the current + Return the :c:type:`void*` value associated with a TSS key in the current thread. This returns ``NULL`` if no value is associated with the key in the current thread. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index e89a788de0d503e..7ca8693afab79c1 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -229,13 +229,13 @@ Objects, Types and Reference Counts .. index:: object: type Most Python/C API functions have one or more arguments as well as a return value -of type :c:type:`PyObject\*`. This type is a pointer to an opaque data type +of type :c:type:`PyObject*`. This type is a pointer to an opaque data type representing an arbitrary Python object. Since all Python object types are treated the same way by the Python language in most situations (e.g., assignments, scope rules, and argument passing), it is only fitting that they should be represented by a single C type. Almost all Python objects live on the heap: you never declare an automatic or static variable of type -:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject\*` can be +:c:type:`PyObject`, only pointer variables of type :c:type:`PyObject*` can be declared. The sole exception are the type objects; since these must never be deallocated, they are typically static :c:type:`PyTypeObject` objects. @@ -496,7 +496,7 @@ Types There are few other data types that play a significant role in the Python/C API; most are simple C types such as :c:type:`int`, :c:type:`long`, -:c:type:`double` and :c:type:`char\*`. A few structure types are used to +:c:type:`double` and :c:type:`char*`. A few structure types are used to describe static tables used to list the functions exported by a module or the data attributes of a new object type, and another is used to describe the value of a complex number. These will be discussed together with the functions that diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index 7b179e22e290e1c..7bb0dad2b6b6d50 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -43,7 +43,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: long PyMarshal_ReadLongFromFile(FILE *file) - Return a C :c:type:`long` from the data stream in a :c:type:`FILE\*` opened + Return a C :c:type:`long` from the data stream in a :c:type:`FILE*` opened for reading. Only a 32-bit value can be read in using this function, regardless of the native size of :c:type:`long`. @@ -53,7 +53,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: int PyMarshal_ReadShortFromFile(FILE *file) - Return a C :c:type:`short` from the data stream in a :c:type:`FILE\*` opened + Return a C :c:type:`short` from the data stream in a :c:type:`FILE*` opened for reading. Only a 16-bit value can be read in using this function, regardless of the native size of :c:type:`short`. @@ -63,7 +63,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) - Return a Python object from the data stream in a :c:type:`FILE\*` opened for + Return a Python object from the data stream in a :c:type:`FILE*` opened for reading. On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError` @@ -72,7 +72,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) - Return a Python object from the data stream in a :c:type:`FILE\*` opened for + Return a Python object from the data stream in a :c:type:`FILE*` opened for reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function assumes that no further objects will be read from the file, allowing it to aggressively load file data into memory so that the de-serialization can diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 8a8542f0479ec59..87425bcf1e71f27 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -109,7 +109,7 @@ zero bytes. .. c:function:: void* PyMem_RawMalloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the + Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -120,7 +120,7 @@ zero bytes. .. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -180,7 +180,7 @@ The :ref:`default memory allocator ` uses the .. c:function:: void* PyMem_Malloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the + Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -191,7 +191,7 @@ The :ref:`default memory allocator ` uses the .. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -233,14 +233,14 @@ The following type-oriented macros are provided for convenience. Note that .. c:function:: TYPE* PyMem_New(TYPE, size_t n) Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of - memory. Returns a pointer cast to :c:type:`TYPE\*`. The memory will not have + memory. Returns a pointer cast to :c:type:`TYPE*`. The memory will not have been initialized in any way. .. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n) Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n * - sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE\*`. On return, + sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE*`. On return, *p* will be a pointer to the new memory area, or ``NULL`` in the event of failure. @@ -282,7 +282,7 @@ The :ref:`default object allocator ` uses the .. c:function:: void* PyObject_Malloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the + Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -293,7 +293,7 @@ The :ref:`default object allocator ` uses the .. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void\*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -388,7 +388,7 @@ Customize Memory Allocators Enum used to identify an allocator domain. Domains: - .. c:var:: PYMEM_DOMAIN_RAW + .. c:macro:: PYMEM_DOMAIN_RAW Functions: @@ -397,7 +397,7 @@ Customize Memory Allocators * :c:func:`PyMem_RawCalloc` * :c:func:`PyMem_RawFree` - .. c:var:: PYMEM_DOMAIN_MEM + .. c:macro:: PYMEM_DOMAIN_MEM Functions: @@ -406,7 +406,7 @@ Customize Memory Allocators * :c:func:`PyMem_Calloc` * :c:func:`PyMem_Free` - .. c:var:: PYMEM_DOMAIN_OBJ + .. c:macro:: PYMEM_DOMAIN_OBJ Functions: @@ -519,11 +519,11 @@ Customize pymalloc Arena Allocator | ``void free(void *ctx, size_t size, void *ptr)`` | free an arena | +--------------------------------------------------+---------------------------------------+ -.. c:function:: PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) +.. c:function:: void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) Get the arena allocator. -.. c:function:: PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) +.. c:function:: void PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) Set the arena allocator. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 8a415dfa30a35e0..6e9474bfa40ebaf 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -325,7 +325,7 @@ The *m_slots* array must be terminated by a slot with id 0. The available slot types are: -.. c:var:: Py_mod_create +.. c:macro:: Py_mod_create Specifies a function that is called to create the module object itself. The *value* pointer of this slot must point to a function of the signature: @@ -357,7 +357,7 @@ The available slot types are: ``PyModuleDef`` has non-``NULL`` ``m_traverse``, ``m_clear``, ``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``. -.. c:var:: Py_mod_exec +.. c:macro:: Py_mod_exec Specifies a function that is called to *execute* the module. This is equivalent to executing the code of a Python module: typically, diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index b9c137ea352e78e..a387b4a2df13429 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -291,7 +291,7 @@ Object Protocol is equivalent to the Python expression ``type(o)``. This function increments the reference count of the return value. There's really no reason to use this function instead of the common expression ``o->ob_type``, which returns a - pointer of type :c:type:`PyTypeObject\*`, except when the incremented reference + pointer of type :c:type:`PyTypeObject*`, except when the incremented reference count is needed. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index b2392fa5e19c5a0..a9e1c6fbcc3f943 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -145,7 +145,7 @@ Implementing functions and methods .. c:type:: PyCFunction Type of the functions used to implement most Python callables in C. - Functions of this type take two :c:type:`PyObject\*` parameters and return + Functions of this type take two :c:type:`PyObject*` parameters and return one such value. If the return value is ``NULL``, an exception shall have been set. If not ``NULL``, the return value is interpreted as the return value of the function as exposed in Python. The function must return a new @@ -224,10 +224,10 @@ Implementing functions and methods +------------------+---------------+-------------------------------+ The :attr:`ml_meth` is a C function pointer. The functions may be of different -types, but they always return :c:type:`PyObject\*`. If the function is not of +types, but they always return :c:type:`PyObject*`. If the function is not of the :c:type:`PyCFunction`, the compiler will require a cast in the method table. Even though :c:type:`PyCFunction` defines the first parameter as -:c:type:`PyObject\*`, it is common that the method implementation uses the +:c:type:`PyObject*`, it is common that the method implementation uses the specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. @@ -239,7 +239,7 @@ There are these calling conventions: .. data:: METH_VARARGS This is the typical calling convention, where the methods have the type - :c:type:`PyCFunction`. The function expects two :c:type:`PyObject\*` values. + :c:type:`PyCFunction`. The function expects two :c:type:`PyObject*` values. The first one is the *self* object for methods; for module functions, it is the module object. The second parameter (often called *args*) is a tuple object representing all arguments. This parameter is typically processed @@ -260,7 +260,7 @@ There are these calling conventions: Fast calling convention supporting only positional arguments. The methods have the type :c:type:`_PyCFunctionFast`. The first parameter is *self*, the second parameter is a C array - of :c:type:`PyObject\*` values indicating the arguments and the third + of :c:type:`PyObject*` values indicating the arguments and the third parameter is the number of arguments (the length of the array). This is not part of the :ref:`limited API `. @@ -274,7 +274,7 @@ There are these calling conventions: with methods of type :c:type:`_PyCFunctionFastWithKeywords`. Keyword arguments are passed the same way as in the :ref:`vectorcall protocol `: - there is an additional fourth :c:type:`PyObject\*` parameter + there is an additional fourth :c:type:`PyObject*` parameter which is a tuple representing the names of the keyword arguments (which are guaranteed to be strings) or possibly ``NULL`` if there are no keywords. The values of the keyword @@ -312,7 +312,7 @@ There are these calling conventions: Methods with a single object argument can be listed with the :const:`METH_O` flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument. They have the type :c:type:`PyCFunction`, with the *self* parameter, and a - :c:type:`PyObject\*` parameter representing the single argument. + :c:type:`PyObject*` parameter representing the single argument. These two constants are not used to indicate the calling convention but the @@ -463,7 +463,7 @@ Accessing attributes of extension types | | | getter and setter | +-------------+------------------+-----------------------------------+ - The ``get`` function takes one :c:type:`PyObject\*` parameter (the + The ``get`` function takes one :c:type:`PyObject*` parameter (the instance) and a function pointer (the associated ``closure``):: typedef PyObject *(*getter)(PyObject *, void *); @@ -471,7 +471,7 @@ Accessing attributes of extension types It should return a new reference on success or ``NULL`` with a set exception on failure. - ``set`` functions take two :c:type:`PyObject\*` parameters (the instance and + ``set`` functions take two :c:type:`PyObject*` parameters (the instance and the value to be set) and a function pointer (the associated ``closure``):: typedef int (*setter)(PyObject *, PyObject *, void *); diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index c14cb2d38fd54ab..bf751e44acde094 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -161,7 +161,7 @@ type. .. c:type:: PyStructSequence_Field Describes a field of a struct sequence. As a struct sequence is modeled as a - tuple, all fields are typed as :c:type:`PyObject\*`. The index in the + tuple, all fields are typed as :c:type:`PyObject*`. The index in the :attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which field of the struct sequence is described. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 385c7f94c672f22..ddcb8ae3d0950ce 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1348,7 +1348,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The following macro is defined to ease writing rich comparison functions: - .. c:function:: PyObject \*Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op) + .. c:macro:: Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op) Return ``Py_True`` or ``Py_False`` from the function, depending on the result of a comparison. @@ -1386,7 +1386,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) than zero and contains the offset in the instance structure of the weak reference list head (ignoring the GC header, if present); this offset is used by :c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The - instance structure needs to include a field of type :c:type:`PyObject\*` which is + instance structure needs to include a field of type :c:type:`PyObject*` which is initialized to ``NULL``. Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 577cdf25114665f..5518214a793e0c5 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -199,7 +199,7 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: PyUnicode_MAX_CHAR_VALUE(PyObject *o) +.. c:macro:: PyUnicode_MAX_CHAR_VALUE(o) Return the maximum code point that is suitable for creating another string based on *o*, which must be in the "canonical" representation. This is diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index d6aecc394c9e70a..b908cb8354f73f4 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -16,11 +16,11 @@ parameter. The available start symbols are :const:`Py_eval_input`, :const:`Py_file_input`, and :const:`Py_single_input`. These are described following the functions which accept them as parameters. -Note also that several of these functions take :c:type:`FILE\*` parameters. One +Note also that several of these functions take :c:type:`FILE*` parameters. One particular issue which needs to be handled carefully is that the :c:type:`FILE` structure for different C libraries can be different and incompatible. Under Windows (at least), it is possible for dynamically linked extensions to actually -use different libraries, so care should be taken that :c:type:`FILE\*` parameters +use different libraries, so care should be taken that :c:type:`FILE*` parameters are only passed to these functions if it is certain that they were created by the same library that the Python runtime is using. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index f1a033c6dae61fd..361e6db07c3cdbf 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -2309,9 +2309,9 @@ Encoders: :c:func:`PyUnicode_AsUTF8String` * :c:func:`PyUnicode_EncodeUTF32` * :c:func:`PyUnicode_EncodeUTF16` -* :c:func:`PyUnicode_EncodeUnicodeEscape:` use +* :c:func:`PyUnicode_EncodeUnicodeEscape` use :c:func:`PyUnicode_AsUnicodeEscapeString` -* :c:func:`PyUnicode_EncodeRawUnicodeEscape:` use +* :c:func:`PyUnicode_EncodeRawUnicodeEscape` use :c:func:`PyUnicode_AsRawUnicodeEscapeString` * :c:func:`PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String` * :c:func:`PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString` From 38161c755cecfefced508fa2aabceffc191eced2 Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Thu, 13 Aug 2020 17:33:56 -0300 Subject: [PATCH 164/486] Fixed comment about pathlib.link_to: it was added in 3.8, not changed. (#21851) --- Doc/library/pathlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index f705d15b8d4f1a9..04810f5204397be 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1134,7 +1134,7 @@ call fails (for example because the path doesn't exist). Create a hard link pointing to a path named *target*. - .. versionchanged:: 3.8 + .. versionadded:: 3.8 .. method:: Path.write_bytes(data) From d856e612aa061c69ddb4d17b84622f4efb537674 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 14 Aug 2020 00:35:52 +0100 Subject: [PATCH 165/486] bpo-41526: Fixed layout of final page of the installer (GH-21871) --- .../next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst | 2 ++ Tools/msi/bundle/Default.thm | 4 ++-- Tools/msi/bundle/Default.wxl | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst diff --git a/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst b/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst new file mode 100644 index 000000000000000..756c8270599f276 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst @@ -0,0 +1,2 @@ +Fixed layout of final page of the installer by removing the special thanks +to Mark Hammond (with his permission). diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm index 7c37d2cafb399b4..f5ba43d838fcf7c 100644 --- a/Tools/msi/bundle/Default.thm +++ b/Tools/msi/bundle/Default.thm @@ -116,9 +116,9 @@ #(loc.SuccessHeader) - + - + #(loc.SuccessRestartText) diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index f0088d4e13e6bf0..791ce6eab74745c 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -107,9 +107,7 @@ Select Customize to review current options. &Restart New to Python? Start with the <a href="https://docs.python.org/[ShortVersion]/tutorial/index.html">online tutorial</a> and <a href="https://docs.python.org/[ShortVersion]/index.html">documentation</a>. At your terminal, type "py" to launch Python, or search for Python in your Start menu. -See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html">what's new</a> in this release, or find more info about <a href="https://docs.python.org/[ShortVersion]/using/windows.html">using Python on Windows</a>. - -Special thanks to Mark Hammond, without whose years of freely shared Windows expertise, Python for Windows would still be Python for DOS. +See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html">what's new</a> in this release, or find more info about <a href="https://docs.python.org/[ShortVersion]/using/windows.html">using Python on Windows</a>. Thank you for using [WixBundleName]. Thank you for using [WixBundleName]. From 51d3952b0b7bf1e561400290b136f6cf8c55493a Mon Sep 17 00:00:00 2001 From: Rishav Kundu Date: Fri, 14 Aug 2020 07:03:14 +0530 Subject: [PATCH 166/486] bpo-41410: Fix outdated info in mkstemp docs (GH-21701) Automerge-Triggered-By: @ericvsmith --- Doc/library/tempfile.rst | 5 ++--- Lib/tempfile.py | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index a59817c10392109..3a2b88c0cb6a205 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -175,9 +175,8 @@ The module defines the following user-callable items: If you want to force a bytes return value with otherwise default behavior, pass ``suffix=b''``. - If *text* is specified, it indicates whether to open the file in binary - mode (the default) or text mode. On some platforms, this makes no - difference. + If *text* is specified and true, the file is opened in text mode. + Otherwise, (the default) the file is opened in binary mode. :func:`mkstemp` returns a tuple containing an OS-level handle to an open file (as would be returned by :func:`os.open`) and the absolute pathname diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 1aa79bcb8a2a510..4d991623d80d594 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -308,8 +308,7 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False): otherwise a default directory is used. If 'text' is specified and true, the file is opened in text - mode. Else (the default) the file is opened in binary mode. On - some operating systems, this makes no difference. + mode. Else (the default) the file is opened in binary mode. If any of 'suffix', 'prefix' and 'dir' are not None, they must be the same type. If they are bytes, the returned name will be bytes; str From fd6664cecd2a35df3ff5359f3f5056ce03b702ab Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Thu, 13 Aug 2020 22:38:30 -0400 Subject: [PATCH 167/486] bpo-41025: Fix subclassing for zoneinfo.ZoneInfo (GH-20965) Prior to this change, attempting to subclass the C implementation of zoneinfo.ZoneInfo gave the following error: TypeError: unbound method ZoneInfo.__init_subclass__() needs an argument https://bugs.python.org/issue41025 --- Lib/test/test_zoneinfo/test_zoneinfo.py | 4 ++-- .../next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst | 2 ++ Modules/_zoneinfo.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index d16e0d2c3310686..a9375fd55857bc1 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -463,7 +463,7 @@ class CZoneInfoDatetimeSubclassTest(DatetimeSubclassMixin, CZoneInfoTest): pass -class ZoneInfoTestSubclass(ZoneInfoTest): +class ZoneInfoSubclassTest(ZoneInfoTest): @classmethod def setUpClass(cls): super().setUpClass() @@ -484,7 +484,7 @@ def test_subclass_own_cache(self): self.assertIsInstance(sub_obj, self.klass) -class CZoneInfoTestSubclass(ZoneInfoTest): +class CZoneInfoSubclassTest(ZoneInfoSubclassTest): module = c_zoneinfo diff --git a/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst b/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst new file mode 100644 index 000000000000000..21e184d0a40631e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst @@ -0,0 +1,2 @@ +Fixed an issue preventing the C implementation of :class:`zoneinfo.ZoneInfo` +from being subclassed. diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index bee84cbf8f9f422..12b3969959bacfb 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -2557,7 +2557,7 @@ static PyMethodDef zoneinfo_methods[] = { {"_unpickle", (PyCFunction)zoneinfo__unpickle, METH_VARARGS | METH_CLASS, PyDoc_STR("Private method used in unpickling.")}, {"__init_subclass__", (PyCFunction)(void (*)(void))zoneinfo_init_subclass, - METH_VARARGS | METH_KEYWORDS, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("Function to initialize subclasses.")}, {NULL} /* Sentinel */ }; From 7ece7127ab788d0cabef4412427d400e9e0f0777 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Aug 2020 12:20:05 +0200 Subject: [PATCH 168/486] bpo-40204: Fix reference to terms in the doc (GH-21865) Sphinx 3 requires to refer to terms with the exact case. For example, fix the Sphinx 3 warning: Doc/library/pkgutil.rst:71: WARNING: term Loader not found in case sensitive match.made a reference to loader instead. --- Doc/extending/newtypes_tutorial.rst | 2 +- Doc/glossary.rst | 2 +- Doc/library/collections.abc.rst | 2 +- Doc/library/concurrent.futures.rst | 3 ++- Doc/library/importlib.rst | 4 ++-- Doc/library/multiprocessing.rst | 3 ++- Doc/library/pkgutil.rst | 2 +- Doc/library/threading.rst | 3 ++- Doc/reference/datamodel.rst | 4 ++-- Doc/tutorial/classes.rst | 2 +- Doc/whatsnew/3.2.rst | 2 +- Doc/whatsnew/3.5.rst | 8 ++++---- Doc/whatsnew/3.6.rst | 2 +- Doc/whatsnew/3.7.rst | 2 +- 14 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 0eb6ffd026f4959..4da77e797d222c4 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -416,7 +416,7 @@ But this would be risky. Our type doesn't restrict the type of the ``first`` member, so it could be any kind of object. It could have a destructor that causes code to be executed that tries to access the ``first`` member; or that destructor could release the -:term:`Global interpreter Lock` and let arbitrary code run in other +:term:`Global interpreter Lock ` and let arbitrary code run in other threads that accesses and modifies our object. To be paranoid and protect ourselves against this possibility, we almost diff --git a/Doc/glossary.rst b/Doc/glossary.rst index e997d366777b384..7be755e4113108b 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -587,7 +587,7 @@ Glossary and :class:`tuple`) and some non-sequence types like :class:`dict`, :term:`file objects `, and objects of any classes you define with an :meth:`__iter__` method or with a :meth:`__getitem__` method - that implements :term:`Sequence` semantics. + that implements :term:`Sequence ` semantics. Iterables can be used in a :keyword:`for` loop and in many other places where a sequence is diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 2a3fb142f7297e5..dc7ae30b6d2fa28 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -185,7 +185,7 @@ ABC Inherits from Abstract Methods Mixin expressions. Custom implementations must provide the :meth:`__await__` method. - :term:`Coroutine` objects and instances of the + :term:`Coroutine ` objects and instances of the :class:`~collections.abc.Coroutine` ABC are all instances of this ABC. .. note:: diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index b21d5594c84fa02..675a9ffdd0711ae 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -221,7 +221,8 @@ ProcessPoolExecutor The :class:`ProcessPoolExecutor` class is an :class:`Executor` subclass that uses a pool of processes to execute calls asynchronously. :class:`ProcessPoolExecutor` uses the :mod:`multiprocessing` module, which -allows it to side-step the :term:`Global Interpreter Lock` but also means that +allows it to side-step the :term:`Global Interpreter Lock +` but also means that only picklable objects can be executed and returned. The ``__main__`` module must be importable by worker subprocesses. This means diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index f7286d2ade8bd1d..5fb0a4a120b98d3 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1073,7 +1073,7 @@ find and load modules. .. class:: WindowsRegistryFinder - :term:`Finder` for modules declared in the Windows registry. This class + :term:`Finder ` for modules declared in the Windows registry. This class implements the :class:`importlib.abc.MetaPathFinder` ABC. Only class methods are defined by this class to alleviate the need for @@ -1088,7 +1088,7 @@ find and load modules. .. class:: PathFinder - A :term:`Finder` for :data:`sys.path` and package ``__path__`` attributes. + A :term:`Finder ` for :data:`sys.path` and package ``__path__`` attributes. This class implements the :class:`importlib.abc.MetaPathFinder` ABC. Only class methods are defined by this class to alleviate the need for diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 69d652365038645..28510acd52bd46e 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -14,7 +14,8 @@ Introduction :mod:`multiprocessing` is a package that supports spawning processes using an API similar to the :mod:`threading` module. The :mod:`multiprocessing` package offers both local and remote concurrency, effectively side-stepping the -:term:`Global Interpreter Lock` by using subprocesses instead of threads. Due +:term:`Global Interpreter Lock ` by using +subprocesses instead of threads. Due to this, the :mod:`multiprocessing` module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows. diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 2066cbb9fc57cee..3b17b9a62198705 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -68,7 +68,7 @@ support. .. class:: ImpLoader(fullname, file, filename, etc) - :term:`Loader` that wraps Python's "classic" import algorithm. + :term:`Loader ` that wraps Python's "classic" import algorithm. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 458e39bf721c68a..7fcf93d74610eba 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -394,7 +394,8 @@ since it is impossible to detect the termination of alien threads. .. impl-detail:: - In CPython, due to the :term:`Global Interpreter Lock`, only one thread + In CPython, due to the :term:`Global Interpreter Lock + `, only one thread can execute Python code at once (even though certain performance-oriented libraries might overcome this limitation). If you want your application to make better use of the computational diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index c5a7f046992dd11..a817408c3b1ef55 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2601,7 +2601,7 @@ Awaitable Objects ----------------- An :term:`awaitable` object generally implements an :meth:`__await__` method. -:term:`Coroutine` objects returned from :keyword:`async def` functions +:term:`Coroutine objects ` returned from :keyword:`async def` functions are awaitable. .. note:: @@ -2626,7 +2626,7 @@ are awaitable. Coroutine Objects ----------------- -:term:`Coroutine` objects are :term:`awaitable` objects. +:term:`Coroutine objects ` are :term:`awaitable` objects. A coroutine's execution can be controlled by calling :meth:`__await__` and iterating over the result. When the coroutine has finished executing and returns, the iterator raises :exc:`StopIteration`, and the exception's diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 685552f99f440e9..0d780e3ba89643e 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -849,7 +849,7 @@ defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: Generators ========== -:term:`Generator`\s are a simple and powerful tool for creating iterators. They +:term:`Generators ` are a simple and powerful tool for creating iterators. They are written like regular functions but use the :keyword:`yield` statement whenever they want to return data. Each time :func:`next` is called on it, the generator resumes where it left off (it remembers all the data values and which diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index ca3eda05c515af4..06bee9966c0be24 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -2311,7 +2311,7 @@ Multi-threading =============== * The mechanism for serializing execution of concurrently running Python threads - (generally known as the :term:`GIL` or :term:`Global Interpreter Lock`) has + (generally known as the :term:`GIL` or Global Interpreter Lock) has been rewritten. Among the objectives were more predictable switching intervals and reduced overhead due to lock contention and the number of ensuing system calls. The notion of a "check interval" to allow thread diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index b4540ac1dd9028d..1defee4090f2884 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -412,7 +412,7 @@ uses were to provide type hints to function parameters and return values. It became evident that it would be beneficial for Python users, if the standard library included the base definitions and tools for type annotations. -:pep:`484` introduces a :term:`provisional module ` to +:pep:`484` introduces a :term:`provisional module ` to provide these standard definitions and tools, along with some conventions for situations where annotations are not available. @@ -726,7 +726,7 @@ New Modules typing ------ -The new :mod:`typing` :term:`provisional ` module +The new :mod:`typing` :term:`provisional ` module provides standard definitions and tools for function type annotations. See :ref:`Type Hints ` for more information. @@ -772,7 +772,7 @@ Steven Bethard, paul j3 and Daniel Eriksson in :issue:`14910`.) asyncio ------- -Since the :mod:`asyncio` module is :term:`provisional `, +Since the :mod:`asyncio` module is :term:`provisional `, all changes introduced in Python 3.5 have also been backported to Python 3.4.x. Notable changes in the :mod:`asyncio` module since Python 3.4.0: @@ -1867,7 +1867,7 @@ A new :func:`~sys.set_coroutine_wrapper` function allows setting a global hook that will be called whenever a :term:`coroutine object ` is created by an :keyword:`async def` function. A corresponding :func:`~sys.get_coroutine_wrapper` can be used to obtain a currently set -wrapper. Both functions are :term:`provisional `, +wrapper. Both functions are :term:`provisional `, and are intended for debugging purposes only. (Contributed by Yury Selivanov in :issue:`24017`.) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 04c1f7e71db3214..85a6657fdfbdacc 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -1597,7 +1597,7 @@ to filter block traces by their address space (domain). typing ------ -Since the :mod:`typing` module is :term:`provisional `, +Since the :mod:`typing` module is :term:`provisional `, all changes introduced in Python 3.6 have also been backported to Python 3.5.x. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 279bbc697b5c632..25b1e1e33e325cf 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -636,7 +636,7 @@ The :mod:`asyncio` module has received many new features, usability and :ref:`performance improvements `. Notable changes include: -* The new :term:`provisional ` :func:`asyncio.run` function can +* The new :term:`provisional ` :func:`asyncio.run` function can be used to run a coroutine from synchronous code by automatically creating and destroying the event loop. (Contributed by Yury Selivanov in :issue:`32314`.) From 448b0b618db8cf815534fff565e96e392a243d87 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sat, 15 Aug 2020 00:01:36 +0100 Subject: [PATCH 169/486] Fix typo in typing doc (GH-21879) Automerge-Triggered-By: @gvanrossum --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 44b537f1669e1ae..8208680669de6e2 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -325,7 +325,7 @@ every type as being compatible with :data:`Any` and :data:`Any` as being compatible with every type. This means that it is possible to perform any operation or method call on a -value of type on :data:`Any` and assign it to any variable:: +value of type :data:`Any` and assign it to any variable:: from typing import Any From 69e4da3159042e920d4ebf01ee045ce3a1cdd31f Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Sat, 15 Aug 2020 16:06:21 +0200 Subject: [PATCH 170/486] bpo-40878: xlc cannot handle C99 extern inline. (GH-21887) This applies to the default "extc99" mode. Python does not compile with "stdc99". --- Modules/_decimal/libmpdec/mpdecimal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index b3ec13a509bb4ca..f0e4d7f343a4382 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -64,7 +64,7 @@ #if defined(_MSC_VER) #define ALWAYS_INLINE __forceinline -#elif defined(LEGACY_COMPILER) +#elif defined(__IBMC__) || defined(LEGACY_COMPILER) #define ALWAYS_INLINE #undef inline #define inline From 369eaa5a6e00f463c40e1a77ef8a2603dcac3725 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Sun, 16 Aug 2020 02:01:19 +0900 Subject: [PATCH 171/486] bpo-31122: ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer closes connection during TLS negotiation (GH-18772) [bpo-31122](): ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer closes connection during TLS negotiation Reproducer: http://tiny.cc/f4ztnz (tiny url because some bot keeps renaming b.p.o.-nnn as bpo links) --- .../Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst | 1 + Modules/_ssl.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst diff --git a/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst b/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst new file mode 100644 index 000000000000000..2e70f7aee65c835 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst @@ -0,0 +1 @@ +ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer closes connection during TLS negotiation \ No newline at end of file diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 55a95ddf774e6d4..cb8f04a900a06e8 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -805,10 +805,11 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) errno = err.c; return PyErr_SetFromErrno(PyExc_OSError); } - Py_INCREF(s); - s->errorhandler(); - Py_DECREF(s); - return NULL; + else { + p = PY_SSL_ERROR_EOF; + type = PySSLEOFErrorObject; + errstr = "EOF occurred in violation of protocol"; + } } else { /* possible? */ p = PY_SSL_ERROR_SYSCALL; type = PySSLSyscallErrorObject; From d22c0f79f84058ed1ba3502eefdb015ea8abf7bf Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Sat, 15 Aug 2020 20:19:07 +0200 Subject: [PATCH 172/486] bpo-41540: AIX: skip test that is flaky with a default ulimit. (#21890) - AIX has extreme over-allocation that is in no relation to the physical RAM and swap. --- Lib/test/test_decimal.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 113b37ddaa9cd65..dbd58e8a6519b19 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5661,6 +5661,9 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) + # Issue 41540: + @unittest.skipIf(sys.platform.startswith("aix"), + "AIX: default ulimit: test is flaky because of extreme over-allocation") def test_maxcontext_exact_arith(self): # Make sure that exact operations do not raise MemoryError due From e4195d3658b1c4cf84ff210de5adca82c48ef96b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 15 Aug 2020 19:38:19 -0700 Subject: [PATCH 173/486] bpo-41513: Improve speed and accuracy of math.hypot() (GH-21803) --- Lib/test/test_math.py | 7 ++-- .../2020-08-09-18-16-05.bpo-41513.e6K6EK.rst | 2 + Modules/mathmodule.c | 41 +++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index e06b1e6a5b9b7c4..4d62eb1b119930d 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -795,7 +795,8 @@ def testHypot(self): # Verify scaling for extremely large values fourthmax = FLOAT_MAX / 4.0 for n in range(32): - self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n)) + self.assertTrue(math.isclose(hypot(*([fourthmax]*n)), + fourthmax * math.sqrt(n))) # Verify scaling for extremely small values for exp in range(32): @@ -904,8 +905,8 @@ class T(tuple): for n in range(32): p = (fourthmax,) * n q = (0.0,) * n - self.assertEqual(dist(p, q), fourthmax * math.sqrt(n)) - self.assertEqual(dist(q, p), fourthmax * math.sqrt(n)) + self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n))) + self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n))) # Verify scaling for extremely small values for exp in range(32): diff --git a/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst b/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst new file mode 100644 index 000000000000000..cfb9f98c376a020 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst @@ -0,0 +1,2 @@ +Minor algorithmic improvement to math.hypot() and math.dist() giving small +gains in speed and accuracy. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 411c6eb1935fab1..489802cc3674509 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2406,6 +2406,13 @@ math_fmod_impl(PyObject *module, double x, double y) /* Given an *n* length *vec* of values and a value *max*, compute: + sqrt(sum((x * scale) ** 2 for x in vec)) / scale + + where scale is the first power of two + greater than max. + +or compute: + max * sqrt(sum((x / max) ** 2 for x in vec)) The value of the *max* variable must be non-negative and @@ -2425,19 +2432,25 @@ The *csum* variable tracks the cumulative sum and *frac* tracks the cumulative fractional errors at each step. Since this variant assumes that |csum| >= |x| at each step, we establish the precondition by starting the accumulation from 1.0 which -represents the largest possible value of (x/max)**2. +represents the largest possible value of (x*scale)**2 or (x/max)**2. After the loop is finished, the initial 1.0 is subtracted out for a net zero effect on the final sum. Since *csum* will be greater than 1.0, the subtraction of 1.0 will not cause fractional digits to be dropped from *csum*. +To get the full benefit from compensated summation, the +largest addend should be in the range: 0.5 <= x <= 1.0. +Accordingly, scaling or division by *max* should not be skipped +even if not otherwise needed to prevent overflow or loss of precision. + */ static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { - double x, csum = 1.0, oldcsum, frac = 0.0; + double x, csum = 1.0, oldcsum, frac = 0.0, scale; + int max_e; Py_ssize_t i; if (Py_IS_INFINITY(max)) { @@ -2449,14 +2462,36 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) if (max == 0.0 || n <= 1) { return max; } + frexp(max, &max_e); + if (max_e >= -1023) { + scale = ldexp(1.0, -max_e); + assert(max * scale >= 0.5); + assert(max * scale < 1.0); + for (i=0 ; i < n ; i++) { + x = vec[i]; + assert(Py_IS_FINITE(x) && fabs(x) <= max); + x *= scale; + x = x*x; + assert(x <= 1.0); + assert(csum >= x); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + } + return sqrt(csum - 1.0 + frac) / scale; + } + /* When max_e < -1023, ldexp(1.0, -max_e) overflows. + So instead of multiplying by a scale, we just divide by *max*. + */ for (i=0 ; i < n ; i++) { x = vec[i]; assert(Py_IS_FINITE(x) && fabs(x) <= max); x /= max; x = x*x; + assert(x <= 1.0); + assert(csum >= x); oldcsum = csum; csum += x; - assert(csum >= x); frac += (oldcsum - csum) + x; } return max * sqrt(csum - 1.0 + frac); From 9c93d0014d0a20626833895dda2effce5fa86915 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 16 Aug 2020 16:10:13 +0100 Subject: [PATCH 174/486] bpo-41503: Fix race between setTarget and flush in logging.handlers.MemoryHandler (GH-21765) --- Lib/logging/handlers.py | 6 +++++- Lib/test/test_logging.py | 21 +++++++++++++++++++ .../2020-08-07-15-18-16.bpo-41503.IYftcu.rst | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 4a120e9f1ec48f2..867ef4ebc7600a0 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1324,7 +1324,11 @@ def setTarget(self, target): """ Set the target handler for this handler. """ - self.target = target + self.acquire() + try: + self.target = target + finally: + self.release() def flush(self): """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index eb5b926908a1924..d8b3727eb11851d 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1160,6 +1160,27 @@ def test_flush_on_close(self): # assert that no new lines have been added self.assert_log_lines(lines) # no change + def test_race_between_set_target_and_flush(self): + class MockRaceConditionHandler: + def __init__(self, mem_hdlr): + self.mem_hdlr = mem_hdlr + + def removeTarget(self): + self.mem_hdlr.setTarget(None) + + def handle(self, msg): + t = threading.Thread(target=self.removeTarget) + t.daemon = True + t.start() + + target = MockRaceConditionHandler(self.mem_hdlr) + self.mem_hdlr.setTarget(target) + + for _ in range(10): + time.sleep(0.005) + self.mem_logger.info("not flushed") + self.mem_logger.warning("flushed") + class ExceptionFormatter(logging.Formatter): """A special exception formatter.""" diff --git a/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst b/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst new file mode 100644 index 000000000000000..c34996d881937b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst @@ -0,0 +1 @@ +Fixed a race between setTarget and flush in logging.handlers.MemoryHandler. \ No newline at end of file From 23ba61ab74d36180f35c99c7a150bbabf0bc0c90 Mon Sep 17 00:00:00 2001 From: Soumendra Ganguly <67527439+8vasu@users.noreply.github.com> Date: Sun, 16 Aug 2020 10:51:00 -0500 Subject: [PATCH 175/486] Update the comment of termios.c (#21886) --- Modules/termios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/termios.c b/Modules/termios.c index 75e5e523206f418..178ae4ee6e41dd2 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -1,4 +1,4 @@ -/* termiosmodule.c -- POSIX terminal I/O module implementation. */ +/* termios.c -- POSIX terminal I/O module implementation. */ #include "Python.h" From 03e7aac8eb0b1b9c68811bc9a4ee6062ba142b68 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 17 Aug 2020 07:20:40 +0200 Subject: [PATCH 176/486] bpo-41521: Rename blacklist parameter to not_exported (GH-21824) Rename "blacklist" parameter of test.support.check__all__() to "not_exported". --- Doc/library/test.rst | 10 ++-- Lib/test/_test_multiprocessing.py | 6 +- Lib/test/support/__init__.py | 10 ++-- Lib/test/test_calendar.py | 12 ++-- Lib/test/test_cgi.py | 7 ++- Lib/test/test_configparser.py | 3 +- Lib/test/test_ftplib.py | 9 +-- Lib/test/test_gettext.py | 4 +- Lib/test/test_logging.py | 12 ++-- Lib/test/test_mailbox.py | 4 +- Lib/test/test_optparse.py | 4 +- Lib/test/test_pickletools.py | 57 ++++++++++--------- Lib/test/test_plistlib.py | 4 +- Lib/test/test_smtpd.py | 5 +- Lib/test/test_support.py | 8 +-- Lib/test/test_tarfile.py | 29 +++++----- Lib/test/test_threading.py | 4 +- Lib/test/test_wave.py | 3 +- Lib/test/test_xml_etree.py | 2 +- .../2020-08-11-14-59-13.bpo-41521.w2UYK7.rst | 2 + 20 files changed, 98 insertions(+), 97 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst diff --git a/Doc/library/test.rst b/Doc/library/test.rst index cd05ef07b4a2121..6495b4844449e59 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -878,7 +878,7 @@ The :mod:`test.support` module defines the following functions: missing. -.. function:: check__all__(test_case, module, name_of_module=None, extra=(), blacklist=()) +.. function:: check__all__(test_case, module, name_of_module=None, extra=(), not_exported=()) Assert that the ``__all__`` variable of *module* contains all public names. @@ -895,8 +895,8 @@ The :mod:`test.support` module defines the following functions: detected as "public", like objects without a proper ``__module__`` attribute. If provided, it will be added to the automatically detected ones. - The *blacklist* argument can be a set of names that must not be treated as part of - the public API even though their names indicate otherwise. + The *not_exported* argument can be a set of names that must not be treated + as part of the public API even though their names indicate otherwise. Example use:: @@ -912,10 +912,10 @@ The :mod:`test.support` module defines the following functions: class OtherTestCase(unittest.TestCase): def test__all__(self): extra = {'BAR_CONST', 'FOO_CONST'} - blacklist = {'baz'} # Undocumented name. + not_exported = {'baz'} # Undocumented name. # bar imports part of its API from _bar. support.check__all__(self, bar, ('bar', '_bar'), - extra=extra, blacklist=blacklist) + extra=extra, not_exported=not_exported) .. versionadded:: 3.6 diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 58663c02002e94d..6a0e1016aff8d03 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -5581,9 +5581,11 @@ def test_namespace(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - # Just make sure names in blacklist are excluded + # Just make sure names in not_exported are excluded support.check__all__(self, multiprocessing, extra=multiprocessing.__all__, - blacklist=['SUBDEBUG', 'SUBWARNING']) + not_exported=['SUBDEBUG', 'SUBWARNING']) + + # # Mixins # diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index e9573d133521025..4ba749454c18735 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1410,7 +1410,7 @@ def detect_api_mismatch(ref_api, other_api, *, ignore=()): def check__all__(test_case, module, name_of_module=None, extra=(), - blacklist=()): + not_exported=()): """Assert that the __all__ variable of 'module' contains all public names. The module's public names (its API) are detected automatically based on @@ -1427,7 +1427,7 @@ def check__all__(test_case, module, name_of_module=None, extra=(), '__module__' attribute. If provided, it will be added to the automatically detected ones. - The 'blacklist' argument can be a set of names that must not be treated + The 'not_exported' argument can be a set of names that must not be treated as part of the public API even though their names indicate otherwise. Usage: @@ -1443,10 +1443,10 @@ def test__all__(self): class OtherTestCase(unittest.TestCase): def test__all__(self): extra = {'BAR_CONST', 'FOO_CONST'} - blacklist = {'baz'} # Undocumented name. + not_exported = {'baz'} # Undocumented name. # bar imports part of its API from _bar. support.check__all__(self, bar, ('bar', '_bar'), - extra=extra, blacklist=blacklist) + extra=extra, not_exported=not_exported) """ @@ -1458,7 +1458,7 @@ def test__all__(self): expected = set(extra) for name in dir(module): - if name.startswith('_') or name in blacklist: + if name.startswith('_') or name in not_exported: continue obj = getattr(module, name) if (getattr(obj, '__module__', None) in name_of_module or diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 7c7ec1c931aa480..c641e8c418318d7 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -934,12 +934,12 @@ def test_html_output_year_css(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'mdays', 'January', 'February', 'EPOCH', - 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', - 'SATURDAY', 'SUNDAY', 'different_locale', 'c', - 'prweek', 'week', 'format', 'formatstring', 'main', - 'monthlen', 'prevmonth', 'nextmonth'} - support.check__all__(self, calendar, blacklist=blacklist) + not_exported = { + 'mdays', 'January', 'February', 'EPOCH', 'MONDAY', 'TUESDAY', + 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY', + 'different_locale', 'c', 'prweek', 'week', 'format', + 'formatstring', 'main', 'monthlen', 'prevmonth', 'nextmonth'} + support.check__all__(self, calendar, not_exported=not_exported) class TestSubClassingCase(unittest.TestCase): diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index 101942de947fb46..6b29759da44d01b 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -553,9 +553,10 @@ def test_parse_header(self): ("form-data", {"name": "files", "filename": 'fo"o;bar'})) def test_all(self): - blacklist = {"logfile", "logfp", "initlog", "dolog", "nolog", - "closelog", "log", "maxlen", "valid_boundary"} - support.check__all__(self, cgi, blacklist=blacklist) + not_exported = { + "logfile", "logfp", "initlog", "dolog", "nolog", "closelog", "log", + "maxlen", "valid_boundary"} + support.check__all__(self, cgi, not_exported=not_exported) BOUNDARY = "---------------------------721837373350705526688164684" diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 230ffc1ccf81a79..80a9f179ee2bbcd 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -2128,8 +2128,7 @@ def test_instance_assignment(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {"Error"} - support.check__all__(self, configparser, blacklist=blacklist) + support.check__all__(self, configparser, not_exported={"Error"}) if __name__ == '__main__': diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 65feb3aadedd672..39658f22aa18c32 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -1107,10 +1107,11 @@ def testTimeoutDirectAccess(self): class MiscTestCase(TestCase): def test__all__(self): - blacklist = {'MSG_OOB', 'FTP_PORT', 'MAXLINE', 'CRLF', 'B_CRLF', - 'Error', 'parse150', 'parse227', 'parse229', 'parse257', - 'print_line', 'ftpcp', 'test'} - support.check__all__(self, ftplib, blacklist=blacklist) + not_exported = { + 'MSG_OOB', 'FTP_PORT', 'MAXLINE', 'CRLF', 'B_CRLF', 'Error', + 'parse150', 'parse227', 'parse229', 'parse257', 'print_line', + 'ftpcp', 'test'} + support.check__all__(self, ftplib, not_exported=not_exported) def test_main(): diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index df9eae39eac3e3a..575914d62a0bce8 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -820,8 +820,8 @@ def test_cache(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'c2py', 'ENOENT'} - support.check__all__(self, gettext, blacklist=blacklist) + support.check__all__(self, gettext, + not_exported={'c2py', 'ENOENT'}) if __name__ == '__main__': diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index d8b3727eb11851d..00a4825d6da88d4 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -5363,12 +5363,12 @@ def test_basic(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'logThreads', 'logMultiprocessing', - 'logProcesses', 'currentframe', - 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', - 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', - 'root', 'threading'} - support.check__all__(self, logging, blacklist=blacklist) + not_exported = { + 'logThreads', 'logMultiprocessing', 'logProcesses', 'currentframe', + 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', + 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', 'root', + 'threading'} + support.check__all__(self, logging, not_exported=not_exported) # Set the locale to the platform-dependent default. I have no idea diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 346c9f1c559cd50..5924f244f39f8be 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -2296,8 +2296,8 @@ def test_nonempty_maildir_both(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {"linesep", "fcntl"} - support.check__all__(self, mailbox, blacklist=blacklist) + support.check__all__(self, mailbox, + not_exported={"linesep", "fcntl"}) def test_main(): diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index ed65b7798e3d2ab..1ed6bf9f919a2c3 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -1652,8 +1652,8 @@ def test_numeric_options(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'check_builtin', 'AmbiguousOptionError', 'NO_DEFAULT'} - support.check__all__(self, optparse, blacklist=blacklist) + not_exported = {'check_builtin', 'AmbiguousOptionError', 'NO_DEFAULT'} + support.check__all__(self, optparse, not_exported=not_exported) def test_main(): diff --git a/Lib/test/test_pickletools.py b/Lib/test/test_pickletools.py index 8cc6ca58cd04b43..f5e9ae41c3c1a48 100644 --- a/Lib/test/test_pickletools.py +++ b/Lib/test/test_pickletools.py @@ -63,34 +63,35 @@ def test_optimize_binput_and_memoize(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'bytes_types', - 'UP_TO_NEWLINE', 'TAKEN_FROM_ARGUMENT1', - 'TAKEN_FROM_ARGUMENT4', 'TAKEN_FROM_ARGUMENT4U', - 'TAKEN_FROM_ARGUMENT8U', 'ArgumentDescriptor', - 'read_uint1', 'read_uint2', 'read_int4', 'read_uint4', - 'read_uint8', 'read_stringnl', 'read_stringnl_noescape', - 'read_stringnl_noescape_pair', 'read_string1', - 'read_string4', 'read_bytes1', 'read_bytes4', - 'read_bytes8', 'read_bytearray8', 'read_unicodestringnl', - 'read_unicodestring1', 'read_unicodestring4', - 'read_unicodestring8', 'read_decimalnl_short', - 'read_decimalnl_long', 'read_floatnl', 'read_float8', - 'read_long1', 'read_long4', - 'uint1', 'uint2', 'int4', 'uint4', 'uint8', 'stringnl', - 'stringnl_noescape', 'stringnl_noescape_pair', 'string1', - 'string4', 'bytes1', 'bytes4', 'bytes8', 'bytearray8', - 'unicodestringnl', 'unicodestring1', 'unicodestring4', - 'unicodestring8', 'decimalnl_short', 'decimalnl_long', - 'floatnl', 'float8', 'long1', 'long4', - 'StackObject', - 'pyint', 'pylong', 'pyinteger_or_bool', 'pybool', 'pyfloat', - 'pybytes_or_str', 'pystring', 'pybytes', 'pybytearray', - 'pyunicode', 'pynone', 'pytuple', 'pylist', 'pydict', - 'pyset', 'pyfrozenset', 'pybuffer', 'anyobject', - 'markobject', 'stackslice', 'OpcodeInfo', 'opcodes', - 'code2op', - } - support.check__all__(self, pickletools, blacklist=blacklist) + not_exported = { + 'bytes_types', + 'UP_TO_NEWLINE', 'TAKEN_FROM_ARGUMENT1', + 'TAKEN_FROM_ARGUMENT4', 'TAKEN_FROM_ARGUMENT4U', + 'TAKEN_FROM_ARGUMENT8U', 'ArgumentDescriptor', + 'read_uint1', 'read_uint2', 'read_int4', 'read_uint4', + 'read_uint8', 'read_stringnl', 'read_stringnl_noescape', + 'read_stringnl_noescape_pair', 'read_string1', + 'read_string4', 'read_bytes1', 'read_bytes4', + 'read_bytes8', 'read_bytearray8', 'read_unicodestringnl', + 'read_unicodestring1', 'read_unicodestring4', + 'read_unicodestring8', 'read_decimalnl_short', + 'read_decimalnl_long', 'read_floatnl', 'read_float8', + 'read_long1', 'read_long4', + 'uint1', 'uint2', 'int4', 'uint4', 'uint8', 'stringnl', + 'stringnl_noescape', 'stringnl_noescape_pair', 'string1', + 'string4', 'bytes1', 'bytes4', 'bytes8', 'bytearray8', + 'unicodestringnl', 'unicodestring1', 'unicodestring4', + 'unicodestring8', 'decimalnl_short', 'decimalnl_long', + 'floatnl', 'float8', 'long1', 'long4', + 'StackObject', + 'pyint', 'pylong', 'pyinteger_or_bool', 'pybool', 'pyfloat', + 'pybytes_or_str', 'pystring', 'pybytes', 'pybytearray', + 'pyunicode', 'pynone', 'pytuple', 'pylist', 'pydict', + 'pyset', 'pyfrozenset', 'pybuffer', 'anyobject', + 'markobject', 'stackslice', 'OpcodeInfo', 'opcodes', + 'code2op', + } + support.check__all__(self, pickletools, not_exported=not_exported) def test_main(): diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index e5038d2e7f10a2c..e5c9b5b6b2cfea5 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -672,8 +672,8 @@ def test_keyed_archive_data(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {"PlistFormat", "PLISTHEADER"} - support.check__all__(self, plistlib, blacklist=blacklist) + not_exported = {"PlistFormat", "PLISTHEADER"} + support.check__all__(self, plistlib, not_exported=not_exported) if __name__ == '__main__': diff --git a/Lib/test/test_smtpd.py b/Lib/test/test_smtpd.py index d5d5abfcf370a8c..6303192d1b26cc3 100644 --- a/Lib/test/test_smtpd.py +++ b/Lib/test/test_smtpd.py @@ -1003,12 +1003,11 @@ def test_multiple_emails_with_extended_command_length(self): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = { + not_exported = { "program", "Devnull", "DEBUGSTREAM", "NEWLINE", "COMMASPACE", "DATA_SIZE_DEFAULT", "usage", "Options", "parseargs", - } - support.check__all__(self, smtpd, blacklist=blacklist) + support.check__all__(self, smtpd, not_exported=not_exported) if __name__ == "__main__": diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index b268511844b8281..71a66c27aa21df0 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -391,14 +391,14 @@ def test_detect_api_mismatch__ignore(self): def test_check__all__(self): extra = {'tempdir'} - blacklist = {'template'} + not_exported = {'template'} support.check__all__(self, tempfile, extra=extra, - blacklist=blacklist) + not_exported=not_exported) extra = {'TextTestResult', 'installHandler'} - blacklist = {'load_tests', "TestProgram", "BaseTestSuite"} + not_exported = {'load_tests', "TestProgram", "BaseTestSuite"} support.check__all__(self, unittest, @@ -407,7 +407,7 @@ def test_check__all__(self): "unittest.main", "unittest.runner", "unittest.signals", "unittest.async_case"), extra=extra, - blacklist=blacklist) + not_exported=not_exported) self.assertRaises(AssertionError, support.check__all__, self, unittest) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 4bf7248767c4b90..4ef20db09716362 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -2257,22 +2257,19 @@ def test_number_field_limits(self): tarfile.itn(0x10000000000, 6, tarfile.GNU_FORMAT) def test__all__(self): - blacklist = {'version', 'grp', 'pwd', 'symlink_exception', - 'NUL', 'BLOCKSIZE', 'RECORDSIZE', 'GNU_MAGIC', - 'POSIX_MAGIC', 'LENGTH_NAME', 'LENGTH_LINK', - 'LENGTH_PREFIX', 'REGTYPE', 'AREGTYPE', 'LNKTYPE', - 'SYMTYPE', 'CHRTYPE', 'BLKTYPE', 'DIRTYPE', 'FIFOTYPE', - 'CONTTYPE', 'GNUTYPE_LONGNAME', 'GNUTYPE_LONGLINK', - 'GNUTYPE_SPARSE', 'XHDTYPE', 'XGLTYPE', 'SOLARIS_XHDTYPE', - 'SUPPORTED_TYPES', 'REGULAR_TYPES', 'GNU_TYPES', - 'PAX_FIELDS', 'PAX_NAME_FIELDS', 'PAX_NUMBER_FIELDS', - 'stn', 'nts', 'nti', 'itn', 'calc_chksums', 'copyfileobj', - 'filemode', - 'EmptyHeaderError', 'TruncatedHeaderError', - 'EOFHeaderError', 'InvalidHeaderError', - 'SubsequentHeaderError', 'ExFileObject', - 'main'} - support.check__all__(self, tarfile, blacklist=blacklist) + not_exported = { + 'version', 'grp', 'pwd', 'symlink_exception', 'NUL', 'BLOCKSIZE', + 'RECORDSIZE', 'GNU_MAGIC', 'POSIX_MAGIC', 'LENGTH_NAME', + 'LENGTH_LINK', 'LENGTH_PREFIX', 'REGTYPE', 'AREGTYPE', 'LNKTYPE', + 'SYMTYPE', 'CHRTYPE', 'BLKTYPE', 'DIRTYPE', 'FIFOTYPE', 'CONTTYPE', + 'GNUTYPE_LONGNAME', 'GNUTYPE_LONGLINK', 'GNUTYPE_SPARSE', + 'XHDTYPE', 'XGLTYPE', 'SOLARIS_XHDTYPE', 'SUPPORTED_TYPES', + 'REGULAR_TYPES', 'GNU_TYPES', 'PAX_FIELDS', 'PAX_NAME_FIELDS', + 'PAX_NUMBER_FIELDS', 'stn', 'nts', 'nti', 'itn', 'calc_chksums', + 'copyfileobj', 'filemode', 'EmptyHeaderError', + 'TruncatedHeaderError', 'EOFHeaderError', 'InvalidHeaderError', + 'SubsequentHeaderError', 'ExFileObject', 'main'} + support.check__all__(self, tarfile, not_exported=not_exported) class CommandLineTest(unittest.TestCase): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 47e131ae27a148f..d02d3b346f9cc8e 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -1365,9 +1365,9 @@ class BarrierTests(lock_tests.BarrierTests): class MiscTestCase(unittest.TestCase): def test__all__(self): extra = {"ThreadError"} - blacklist = {'currentThread', 'activeCount'} + not_exported = {'currentThread', 'activeCount'} support.check__all__(self, threading, ('threading', '_thread'), - extra=extra, blacklist=blacklist) + extra=extra, not_exported=not_exported) class InterruptMainTests(unittest.TestCase): diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index eb231cb19c6d0a8..f85e40b31d0100f 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -107,8 +107,7 @@ class WavePCM32Test(WaveTest, unittest.TestCase): class MiscTestCase(unittest.TestCase): def test__all__(self): - blacklist = {'WAVE_FORMAT_PCM'} - support.check__all__(self, wave, blacklist=blacklist) + support.check__all__(self, wave, not_exported={'WAVE_FORMAT_PCM'}) class WaveLowLevelTest(unittest.TestCase): diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index c7d446185cfe4e7..d22c35d92c4e330 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -128,7 +128,7 @@ def test_sanity(self): def test_all(self): names = ("xml.etree.ElementTree", "_elementtree") - support.check__all__(self, ET, names, blacklist=("HTML_EMPTY",)) + support.check__all__(self, ET, names, not_exported=("HTML_EMPTY",)) def serialize(elem, to_string=True, encoding='unicode', **options): diff --git a/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst b/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst new file mode 100644 index 000000000000000..658372b1a7f2230 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst @@ -0,0 +1,2 @@ +:mod:`test.support`: Rename ``blacklist`` parameter of +:func:`~test.support.check__all__` to ``not_exported``. From 5d76e32612dd46ab7976eb402c9aab4907434cfa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 17 Aug 2020 08:41:42 +0200 Subject: [PATCH 177/486] bpo-40204: Fix duplicated productionlist names in the doc (GH-21900) Sphinx 3 disallows having more than one productionlist markup with the same name. Simply remove names in this case, since names are not shown anyway. For example, fix the Sphinx 3 warning: Doc/reference/introduction.rst:96: duplicate token description of *:name, other instance in reference/expressions --- Doc/library/string.rst | 2 +- Doc/reference/introduction.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/string.rst b/Doc/library/string.rst index fa906f799c1082c..62e86d6dd97066c 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -308,7 +308,7 @@ non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: -.. productionlist:: sf +.. productionlist:: format_spec: [[`fill`]`align`][`sign`][#][0][`width`][`grouping_option`][.`precision`][`type`] fill: align: "<" | ">" | "=" | "^" diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index bb7e3906dba6072..62480bd7dd9a614 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -93,7 +93,7 @@ Notation The descriptions of lexical analysis and syntax use a modified BNF grammar notation. This uses the following style of definition: -.. productionlist:: * +.. productionlist:: name: `lc_letter` (`lc_letter` | "_")* lc_letter: "a"..."z" From 3dcee04ab172d5c58739b4f42bc13d8b6465099c Mon Sep 17 00:00:00 2001 From: Allen <64019758+aboddie@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:38:55 -0400 Subject: [PATCH 178/486] Fix typo in message from assert statement (GH-21283) The error message was missing space between the action "acquire" and "_wait_semaphore" which is an attribute for instances of Condition. --- Lib/multiprocessing/synchronize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 4fcbefc8bbefd33..d0be48f1fd7a8f1 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -270,7 +270,7 @@ def wait(self, timeout=None): def notify(self, n=1): assert self._lock._semlock._is_mine(), 'lock is not owned' assert not self._wait_semaphore.acquire( - False), ('notify: Should not have been able to acquire' + False), ('notify: Should not have been able to acquire ' + '_wait_semaphore') # to take account of timeouts since last notify*() we subtract From 1e3285bd6760aa9a12522a6721e9e6720e84ed57 Mon Sep 17 00:00:00 2001 From: James Weaver Date: Mon, 17 Aug 2020 15:19:46 +0100 Subject: [PATCH 179/486] bpo-40782: Change asyncio.AbstractEventLoop.run_in_executor to be a method not a coroutine (GH-21852) asyncio.AbstractEventLoop.run_in_executor should be a method that returns an asyncio Future, not an async method. This matches the concrete implementations, and the documentation better. --- Lib/asyncio/events.py | 2 +- .../next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 70017cb86a0596f..0dce87b8ecc5861 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -283,7 +283,7 @@ def create_task(self, coro, *, name=None): def call_soon_threadsafe(self, callback, *args): raise NotImplementedError - async def run_in_executor(self, executor, func, *args): + def run_in_executor(self, executor, func, *args): raise NotImplementedError def set_default_executor(self, executor): diff --git a/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst b/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst new file mode 100644 index 000000000000000..d4c7e0e2419df44 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst @@ -0,0 +1 @@ +Change the method asyncio.AbstractEventLoop.run_in_executor to not be a coroutine. \ No newline at end of file From 4d20475f6e4250fb181c1f2a8cca265d1d1a3d1e Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 18 Aug 2020 04:36:19 +0800 Subject: [PATCH 180/486] bpo-1635741: Explict GC collect after PyInterpreterState_Clear() (GH-21902) Fix a reference cycle by triggering an explicit GC collection after calling PyInterpreterState_Clear(). --- Python/pylifecycle.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 2d219a4a3a8b0db..ab5a6767864dc59 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1286,10 +1286,8 @@ finalize_interp_clear(PyThreadState *tstate) /* Clear interpreter state and all thread states */ PyInterpreterState_Clear(tstate->interp); - /* Trigger a GC collection on subinterpreters*/ - if (!is_main_interp) { - _PyGC_CollectNoFail(); - } + /* Last explicit GC collection */ + _PyGC_CollectNoFail(); /* Clear all loghooks */ /* Both _PySys_Audit function and users still need PyObject, such as tuple. From 581b7d914d55d75dbe494f5e99500c05a8e17e38 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Mon, 17 Aug 2020 18:40:07 -0400 Subject: [PATCH 181/486] bpo-41568: Fix refleaks in zoneinfo subclasses (GH-21907) * Fix refleak in C module __init_subclass__ This was leaking a reference to the weak cache dictionary for every ZoneInfo subclass created. * Fix refleak in ZoneInfo subclass's clear_cache The previous version of the code accidentally cleared the global ZONEINFO_STRONG_CACHE variable (and inducing `ZoneInfo` to create a new strong cache) on calls to a subclass's `clear_cache()`. This would not affect guaranteed behavior, but it's still not the right thing to do (and it caused reference leaks). --- Modules/_zoneinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 12b3969959bacfb..2cee65fac6dd042 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -412,7 +412,6 @@ zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) } clear_strong_cache(type); - ZONEINFO_STRONG_CACHE = NULL; } else { PyObject *item = NULL; @@ -2471,6 +2470,7 @@ clear_strong_cache(const PyTypeObject *const type) } strong_cache_free(ZONEINFO_STRONG_CACHE); + ZONEINFO_STRONG_CACHE = NULL; } static PyObject * @@ -2525,6 +2525,7 @@ zoneinfo_init_subclass(PyTypeObject *cls, PyObject *args, PyObject **kwargs) } PyObject_SetAttrString((PyObject *)cls, "_weak_cache", weak_cache); + Py_DECREF(weak_cache); Py_RETURN_NONE; } @@ -2616,8 +2617,7 @@ module_free() Py_CLEAR(ZONEINFO_WEAK_CACHE); } - strong_cache_free(ZONEINFO_STRONG_CACHE); - ZONEINFO_STRONG_CACHE = NULL; + clear_strong_cache(&PyZoneInfo_ZoneInfoType); } static int From d0b19e9acee406bedb71fef76b3d727c6dfe71e6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 19 Aug 2020 12:29:47 +0100 Subject: [PATCH 182/486] Fix grammar in Doc/tutorial/controlflow.rst (GH-21885) Automerge-Triggered-By: @csabella --- Doc/tutorial/controlflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 5d5b01d8132771f..5d24a19cfc07967 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -661,7 +661,7 @@ Finally, consider this function definition which has a potential collision betwe return 'name' in kwds There is no possible call that will make it return ``True`` as the keyword ``'name'`` -will always to bind to the first parameter. For example:: +will always bind to the first parameter. For example:: >>> foo(1, **{'name': 2}) Traceback (most recent call last): From 988b40be7994bb915d98729223744d263e53e80f Mon Sep 17 00:00:00 2001 From: Sydney Pemberton <46042811+sydneypemberton1986@users.noreply.github.com> Date: Thu, 20 Aug 2020 05:30:21 -0500 Subject: [PATCH 183/486] bpo-40994: Ungroup items in collections.abc documentation for improved clarity (GH-21880) Use a less surprising document structure. Automerge-Triggered-By: @csabella --- Doc/library/collections.abc.rst | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index dc7ae30b6d2fa28..db0e25bb0772eb2 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -98,12 +98,20 @@ ABC Inherits from Abstract Methods Mixin .. class:: Container - Hashable - Sized - Callable - ABCs for classes that provide respectively the methods :meth:`__contains__`, - :meth:`__hash__`, :meth:`__len__`, and :meth:`__call__`. + ABC for classes that provide the :meth:`__contains__` method. + +.. class:: Hashable + + ABC for classes that provide the :meth:`__hash__` method. + +.. class:: Sized + + ABC for classes that provide the :meth:`__len__` method. + +.. class:: Callable + + ABC for classes that provide the :meth:`__call__` method. .. class:: Iterable From 82502d09e57d937c65d1a1af357ae5cec1c0a10f Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 20 Aug 2020 08:40:01 -0400 Subject: [PATCH 184/486] bpo-41572: Fix grammar in BaseTransport.close docstring (GH-21914) Fix grammar in BaseTransport.close docstring. https://bugs.python.org/issue41572 Signed-off-by: Cleber Rosa --- Lib/asyncio/transports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 513b1c024a4d6d8..45e155c94cad1b3 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -29,8 +29,8 @@ def close(self): Buffered data will be flushed asynchronously. No more data will be received. After all buffered data is flushed, the - protocol's connection_lost() method will (eventually) called - with None as its argument. + protocol's connection_lost() method will (eventually) be + called with None as its argument. """ raise NotImplementedError From 784161ef1442ccf744080a569f088179a3380844 Mon Sep 17 00:00:00 2001 From: Mathieu Dupuy Date: Thu, 20 Aug 2020 22:08:37 +0200 Subject: [PATCH 185/486] Doc: add a missing period (GH-21819) --- Doc/library/json.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/json.rst b/Doc/library/json.rst index b923c8e1670529e..e1a246aad6190b7 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -745,7 +745,7 @@ Command line options .. cmdoption:: --indent, --tab, --no-indent, --compact - Mutually exclusive options for whitespace control + Mutually exclusive options for whitespace control. .. versionadded:: 3.9 From 362448611a15f9b5027887ee5840827fa929380c Mon Sep 17 00:00:00 2001 From: "Ernest W. Durbin III" Date: Fri, 21 Aug 2020 17:34:06 -0400 Subject: [PATCH 186/486] Update references from travis-ci.org to travis-ci.com (GH-21919) --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 96c9561e7c8eb13..9a646a2ee5da2dd 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,9 @@ This is Python version 3.10.0 alpha 0 ===================================== -.. image:: https://travis-ci.org/python/cpython.svg?branch=master +.. image:: https://travis-ci.com/python/cpython.svg?branch=master :alt: CPython build status on Travis CI - :target: https://travis-ci.org/python/cpython + :target: https://travis-ci.com/python/cpython .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg :alt: CPython build status on GitHub Actions From dd0977440de9bb8d661929a877ed0139720ae69d Mon Sep 17 00:00:00 2001 From: wyz23x2 <52805709+wyz23x2@users.noreply.github.com> Date: Sat, 22 Aug 2020 06:28:54 +0800 Subject: [PATCH 187/486] bpo-41573: Update release versions in General FAQ (GH-21915) --- Doc/faq/general.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index eee3c3c203efa5c..cf70f16c6fe3281 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -142,9 +142,9 @@ to fix critical bugs. Alpha, beta and release candidate versions have an additional suffix. The suffix for an alpha version is "aN" for some small number N, the suffix for a beta version is "bN" for some small number N, and the suffix for a release -candidate version is "cN" for some small number N. In other words, all versions +candidate version is "rcN" for some small number N. In other words, all versions labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled -2.0cN, and *those* precede 2.0. +2.0rcN, and *those* precede 2.0. You may also find version numbers with a "+" suffix, e.g. "2.2+". These are unreleased versions, built directly from the CPython development repository. In @@ -309,8 +309,8 @@ releases. The latest stable releases can always be found on the `Python download page `_. There are two production-ready versions of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by -most widely used libraries. Although 2.x is still widely used, `it will not -be maintained after January 1, 2020 `_. +most widely used libraries. Although 2.x is still widely used, `it is not +maintained anymore `_. How many people are using Python? --------------------------------- From 201c4bf16f97035b7697b761f0cc212f0fb7ca3f Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Fri, 21 Aug 2020 19:29:34 -0300 Subject: [PATCH 188/486] Document vars behavior when __dict__ is missing (#21466) --- Doc/library/functions.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 43c47c1da9434c3..d381d43d8e99c35 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1734,6 +1734,9 @@ are always available. They are listed here in alphabetical order. locals dictionary is only useful for reads since updates to the locals dictionary are ignored. + A :exc:`TypeError` exception is raised if an object is specified but + it doesn't have a :attr:`~object.__dict__` attribute (for example, if + its class defines the :attr:`~object.__slots__` attribute). .. function:: zip(*iterables, strict=False) From cc068c355c64c962de418d5aa329ed14d7f42caf Mon Sep 17 00:00:00 2001 From: Will Binns Date: Mon, 24 Aug 2020 17:00:12 +0200 Subject: [PATCH 189/486] README: Add link to LICENSE (GH-21565) Thanks @wbnns for your contribution. --- README.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 9a646a2ee5da2dd..14f4f32bca79651 100644 --- a/README.rst +++ b/README.rst @@ -259,8 +259,9 @@ rights reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. -See the file "LICENSE" for information on the history of this software, terms & -conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. +See the `LICENSE `_ for +information on the history of this software, terms & conditions for usage, and a +DISCLAIMER OF ALL WARRANTIES. This Python distribution contains *no* GNU General Public License (GPL) code, so it may be used in proprietary projects. There are interfaces to some GNU From 198284b1a724c13cd4d58e79ba84e01d52061dd2 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 24 Aug 2020 17:40:08 -0700 Subject: [PATCH 190/486] bpo-41513: More accurate hypot() (GH-21916) --- .../2020-08-23-14-23-18.bpo-41513.DGqc_I.rst | 3 + Modules/mathmodule.c | 148 +++++++++++++----- 2 files changed, 114 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst diff --git a/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst b/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst new file mode 100644 index 000000000000000..b4d0d9b63cf87d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst @@ -0,0 +1,3 @@ +Improved the accuracy of math.hypot(). Internally, each step is computed +with extra precision so that the result is now almost always correctly +rounded. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 489802cc3674509..1d6174132814b2a 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2404,52 +2404,79 @@ math_fmod_impl(PyObject *module, double x, double y) } /* -Given an *n* length *vec* of values and a value *max*, compute: +Given a *vec* of values, compute the vector norm: - sqrt(sum((x * scale) ** 2 for x in vec)) / scale + sqrt(sum(x ** 2 for x in vec)) - where scale is the first power of two - greater than max. - -or compute: - - max * sqrt(sum((x / max) ** 2 for x in vec)) - -The value of the *max* variable must be non-negative and -equal to the absolute value of the largest magnitude -entry in the vector. If n==0, then *max* should be 0.0. +The *max* variable should be equal to the largest fabs(x). +The *n* variable is the length of *vec*. +If n==0, then *max* should be 0.0. If an infinity is present in the vec, *max* should be INF. - The *found_nan* variable indicates whether some member of the *vec* is a NaN. -To improve accuracy and to increase the number of cases where -vector_norm() is commutative, we use a variant of Neumaier -summation specialized to exploit that we always know that -|csum| >= |x|. - -The *csum* variable tracks the cumulative sum and *frac* tracks -the cumulative fractional errors at each step. Since this -variant assumes that |csum| >= |x| at each step, we establish -the precondition by starting the accumulation from 1.0 which -represents the largest possible value of (x*scale)**2 or (x/max)**2. - -After the loop is finished, the initial 1.0 is subtracted out -for a net zero effect on the final sum. Since *csum* will be -greater than 1.0, the subtraction of 1.0 will not cause -fractional digits to be dropped from *csum*. - -To get the full benefit from compensated summation, the -largest addend should be in the range: 0.5 <= x <= 1.0. -Accordingly, scaling or division by *max* should not be skipped -even if not otherwise needed to prevent overflow or loss of precision. +To avoid overflow/underflow and to achieve high accuracy giving results +that are almost always correctly rounded, four techniques are used: + +* lossless scaling using a power-of-two scaling factor +* accurate squaring using Veltkamp-Dekker splitting +* compensated summation using a variant of the Neumaier algorithm +* differential correction of the square root + +The usual presentation of the Neumaier summation algorithm has an +expensive branch depending on which operand has the larger +magnitude. We avoid this cost by arranging the calculation so that +fabs(csum) is always as large as fabs(x). + +To establish the invariant, *csum* is initialized to 1.0 which is +always larger than x**2 after scaling or division by *max*. +After the loop is finished, the initial 1.0 is subtracted out for a +net zero effect on the final sum. Since *csum* will be greater than +1.0, the subtraction of 1.0 will not cause fractional digits to be +dropped from *csum*. + +To get the full benefit from compensated summation, the largest +addend should be in the range: 0.5 <= |x| <= 1.0. Accordingly, +scaling or division by *max* should not be skipped even if not +otherwise needed to prevent overflow or loss of precision. + +The assertion that hi*hi >= 1.0 is a bit subtle. Each vector element +gets scaled to a magnitude below 1.0. The Veltkamp-Dekker splitting +algorithm gives a *hi* value that is correctly rounded to half +precision. When a value at or below 1.0 is correctly rounded, it +never goes above 1.0. And when values at or below 1.0 are squared, +they remain at or below 1.0, thus preserving the summation invariant. + +The square root differential correction is needed because a +correctly rounded square root of a correctly rounded sum of +squares can still be off by as much as one ulp. + +The differential correction starts with a value *x* that is +the difference between the square of *h*, the possibly inaccurately +rounded square root, and the accurately computed sum of squares. +The correction is the first order term of the Maclaurin series +expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). + +Essentially, this differential correction is equivalent to one +refinement step in the Newton divide-and-average square root +algorithm, effectively doubling the number of accurate bits. +This technique is used in Dekker's SQRT2 algorithm and again in +Borges' ALGORITHM 4 and 5. + +References: + +1. Veltkamp-Dekker splitting: http://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf +2. Compensated summation: http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf +3. Square root diffential correction: https://arxiv.org/pdf/1904.09481.pdf */ static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { + const double T27 = 134217729.0; /* ldexp(1.0, 27)+1.0) */ double x, csum = 1.0, oldcsum, frac = 0.0, scale; + double t, hi, lo, h; int max_e; Py_ssize_t i; @@ -2470,15 +2497,62 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) for (i=0 ; i < n ; i++) { x = vec[i]; assert(Py_IS_FINITE(x) && fabs(x) <= max); + x *= scale; - x = x*x; + assert(fabs(x) < 1.0); + + t = x * T27; + hi = t - (t - x); + lo = x - hi; + assert(hi + lo == x); + + x = hi * hi; assert(x <= 1.0); - assert(csum >= x); + assert(fabs(csum) >= fabs(x)); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + + x = 2.0 * hi * lo; + assert(fabs(csum) >= fabs(x)); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + + x = lo * lo; + assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; frac += (oldcsum - csum) + x; } - return sqrt(csum - 1.0 + frac) / scale; + h = sqrt(csum - 1.0 + frac); + + x = h; + t = x * T27; + hi = t - (t - x); + lo = x - hi; + assert (hi + lo == x); + + x = -hi * hi; + assert(fabs(csum) >= fabs(x)); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + + x = -2.0 * hi * lo; + assert(fabs(csum) >= fabs(x)); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + + x = -lo * lo; + assert(fabs(csum) >= fabs(x)); + oldcsum = csum; + csum += x; + frac += (oldcsum - csum) + x; + + x = csum - 1.0 + frac; + return (h + x / (2.0 * h)) / scale; } /* When max_e < -1023, ldexp(1.0, -max_e) overflows. So instead of multiplying by a scale, we just divide by *max*. @@ -2489,7 +2563,7 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) x /= max; x = x*x; assert(x <= 1.0); - assert(csum >= x); + assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; frac += (oldcsum - csum) + x; From 21285efd6ea603fa9b9c2bd25e3d750090b2b952 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Wed, 26 Aug 2020 09:42:22 -0700 Subject: [PATCH 191/486] bpo-32751: Wait for task cancel in asyncio.wait_for() when timeout <= 0 (#21895) When I was fixing bpo-32751 back in GH-7216 I missed the case when *timeout* is zero or negative. This takes care of that. Props to @aaliddell for noticing the inconsistency. --- Lib/asyncio/tasks.py | 9 ++++-- Lib/test/test_asyncio/test_tasks.py | 31 +++++++++++++++++++ .../2020-08-15-15-50-12.bpo-32751.85je5X.rst | 3 ++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index c37f0e1387980c0..7ecec9638489df2 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -445,8 +445,13 @@ async def wait_for(fut, timeout, *, loop=None): if fut.done(): return fut.result() - fut.cancel() - raise exceptions.TimeoutError() + await _cancel_and_wait(fut, loop=loop) + try: + fut.result() + except exceptions.CancelledError as exc: + raise exceptions.TimeoutError() from exc + else: + raise exceptions.TimeoutError() waiter = loop.create_future() timeout_handle = loop.call_later(timeout, _release_waiter, waiter) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index f9db066ce89837e..511961c32005a0e 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1131,6 +1131,9 @@ async def inner(): nonlocal task_done try: await asyncio.sleep(0.2) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise finally: task_done = True @@ -1145,6 +1148,34 @@ async def inner(): chained = cm.exception.__context__ self.assertEqual(type(chained), asyncio.CancelledError) + def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): + loop = asyncio.new_event_loop() + self.addCleanup(loop.close) + + task_done = False + + async def foo(): + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = self.new_task(loop, inner()) + await asyncio.sleep(_EPSILON) + await asyncio.wait_for(inner_task, timeout=0) + + with self.assertRaises(asyncio.TimeoutError) as cm: + loop.run_until_complete(foo()) + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + def test_wait_for_reraises_exception_during_cancellation(self): loop = asyncio.new_event_loop() self.addCleanup(loop.close) diff --git a/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst b/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst new file mode 100644 index 000000000000000..c172ce5d9e94870 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst @@ -0,0 +1,3 @@ +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete also in the case when *timeout* is +<= 0, like it does with positive timeouts. From 1638a58e86d316727d031c203d6a85982549c10d Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Wed, 26 Aug 2020 09:42:45 -0700 Subject: [PATCH 192/486] bpo-37658: Fix asyncio.wait_for() to respect waited task status (#21894) Currently, if `asyncio.wait_for()` itself is cancelled it will always raise `CancelledError` regardless if the underlying task is still running. This is similar to a race with the timeout, which is handled already. --- Lib/asyncio/tasks.py | 9 ++++++--- Lib/test/test_asyncio/test_tasks.py | 16 ++++++++++++++++ .../2020-08-15-15-21-40.bpo-37658.f9nivB.rst | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 7ecec9638489df2..8b05434f273b52e 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -465,9 +465,12 @@ async def wait_for(fut, timeout, *, loop=None): try: await waiter except exceptions.CancelledError: - fut.remove_done_callback(cb) - fut.cancel() - raise + if fut.done(): + return fut.result() + else: + fut.remove_done_callback(cb) + fut.cancel() + raise if fut.done(): return fut.result() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 511961c32005a0e..74fc1e4a42133c3 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1120,6 +1120,22 @@ def gen(): res = loop.run_until_complete(task) self.assertEqual(res, "ok") + def test_wait_for_cancellation_race_condition(self): + def gen(): + yield 0.1 + yield 0.1 + yield 0.1 + yield 0.1 + + loop = self.new_test_loop(gen) + + fut = self.new_future(loop) + loop.call_later(0.1, fut.set_result, "ok") + task = loop.create_task(asyncio.wait_for(fut, timeout=1)) + loop.call_later(0.1, task.cancel) + res = loop.run_until_complete(task) + self.assertEqual(res, "ok") + def test_wait_for_waits_for_task_cancellation(self): loop = asyncio.new_event_loop() self.addCleanup(loop.close) diff --git a/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst b/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst new file mode 100644 index 000000000000000..694fbbbf346dc8a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst @@ -0,0 +1,2 @@ +:meth:`asyncio.wait_for` now properly handles races between cancellation of +itself and the completion of the wrapped awaitable. From 20bba8b46c58b778ce5fb245fbb053b14d355ecc Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 26 Aug 2020 17:22:27 +0000 Subject: [PATCH 193/486] bpo-40077: Convert _operator to use PyType_FromSpec (GH-21954) --- .../2020-08-25-22-43-33.bpo-40077.vcxSUa.rst | 1 + Modules/_operator.c | 298 +++++++++--------- 2 files changed, 143 insertions(+), 156 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst new file mode 100644 index 000000000000000..ee950010e6d13f2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst @@ -0,0 +1 @@ +Convert :mod:`_operator` to use :c:func:`PyType_FromSpec`. diff --git a/Modules/_operator.c b/Modules/_operator.c index 8a54829e5bbcc83..c9d38aa34236673 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -3,6 +3,20 @@ #include "clinic/_operator.c.h" +typedef struct { + PyObject *itemgetter_type; + PyObject *attrgetter_type; + PyObject *methodcaller_type; +} _operator_state; + +static inline _operator_state* +get_operator_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_operator_state *)state; +} + /*[clinic input] module _operator [clinic start generated code]*/ @@ -942,8 +956,6 @@ typedef struct { Py_ssize_t index; // -1 unless *item* is a single non-negative integer index } itemgetterobject; -static PyTypeObject itemgetter_type; - /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -960,13 +972,15 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (nitems <= 1) { if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item)) return NULL; - } else + } else { item = args; - + } + _operator_state *state = PyType_GetModuleState(type); /* create itemgetterobject structure */ - ig = PyObject_GC_New(itemgetterobject, &itemgetter_type); - if (ig == NULL) + ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type); + if (ig == NULL) { return NULL; + } Py_INCREF(item); ig->item = item; @@ -994,9 +1008,11 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void itemgetter_dealloc(itemgetterobject *ig) { + PyTypeObject *tp = Py_TYPE(ig); PyObject_GC_UnTrack(ig); Py_XDECREF(ig->item); - PyObject_GC_Del(ig); + tp->tp_free(ig); + Py_DECREF(tp); } static int @@ -1093,49 +1109,25 @@ Return a callable object that fetches the given item(s) from its operand.\n\ After f = itemgetter(2), the call f(r) returns r[2].\n\ After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])"); -static PyTypeObject itemgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.itemgetter", /* tp_name */ - sizeof(itemgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)itemgetter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)itemgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)itemgetter_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - itemgetter_doc, /* tp_doc */ - (traverseproc)itemgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - itemgetter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itemgetter_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot itemgetter_type_slots[] = { + {Py_tp_doc, (void *)itemgetter_doc}, + {Py_tp_dealloc, itemgetter_dealloc}, + {Py_tp_call, itemgetter_call}, + {Py_tp_traverse, itemgetter_traverse}, + {Py_tp_methods, itemgetter_methods}, + {Py_tp_new, itemgetter_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, itemgetter_repr}, + {0, 0} }; +static PyType_Spec itemgetter_type_spec = { + .name = "operator.itemgetter", + .basicsize = sizeof(itemgetterobject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = itemgetter_type_slots, +}; /* attrgetter object **********************************************************/ @@ -1145,8 +1137,6 @@ typedef struct { PyObject *attr; } attrgetterobject; -static PyTypeObject attrgetter_type; - /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1246,8 +1236,9 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } + _operator_state *state = PyType_GetModuleState(type); /* create attrgetterobject structure */ - ag = PyObject_GC_New(attrgetterobject, &attrgetter_type); + ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type); if (ag == NULL) { Py_DECREF(attr); return NULL; @@ -1263,9 +1254,11 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void attrgetter_dealloc(attrgetterobject *ag) { + PyTypeObject *tp = Py_TYPE(ag); PyObject_GC_UnTrack(ag); Py_XDECREF(ag->attr); - PyObject_GC_Del(ag); + tp->tp_free(ag); + Py_DECREF(tp); } static int @@ -1438,47 +1431,24 @@ After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\ (r.name.first, r.name.last)."); -static PyTypeObject attrgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.attrgetter", /* tp_name */ - sizeof(attrgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)attrgetter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)attrgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)attrgetter_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - attrgetter_doc, /* tp_doc */ - (traverseproc)attrgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - attrgetter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - attrgetter_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot attrgetter_type_slots[] = { + {Py_tp_doc, (void *)attrgetter_doc}, + {Py_tp_dealloc, attrgetter_dealloc}, + {Py_tp_call, attrgetter_call}, + {Py_tp_traverse, attrgetter_traverse}, + {Py_tp_methods, attrgetter_methods}, + {Py_tp_new, attrgetter_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, attrgetter_repr}, + {0, 0} +}; + +static PyType_Spec attrgetter_type_spec = { + .name = "operator.attrgetter", + .basicsize = sizeof(attrgetterobject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = attrgetter_type_slots, }; @@ -1491,8 +1461,6 @@ typedef struct { PyObject *kwds; } methodcallerobject; -static PyTypeObject methodcaller_type; - /* AC 3.5: variable number of arguments, not currently support by AC */ static PyObject * methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1513,10 +1481,12 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } + _operator_state *state = PyType_GetModuleState(type); /* create methodcallerobject structure */ - mc = PyObject_GC_New(methodcallerobject, &methodcaller_type); - if (mc == NULL) + mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type); + if (mc == NULL) { return NULL; + } name = PyTuple_GET_ITEM(args, 0); Py_INCREF(name); @@ -1539,11 +1509,13 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void methodcaller_dealloc(methodcallerobject *mc) { + PyTypeObject *tp = Py_TYPE(mc); PyObject_GC_UnTrack(mc); Py_XDECREF(mc->name); Py_XDECREF(mc->args); Py_XDECREF(mc->kwds); - PyObject_GC_Del(mc); + tp->tp_free(mc); + Py_DECREF(tp); } static int @@ -1704,63 +1676,52 @@ After f = methodcaller('name'), the call f(r) returns r.name().\n\ After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\ r.name('date', foo=1)."); -static PyTypeObject methodcaller_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.methodcaller", /* tp_name */ - sizeof(methodcallerobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)methodcaller_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)methodcaller_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)methodcaller_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - methodcaller_doc, /* tp_doc */ - (traverseproc)methodcaller_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - methodcaller_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - methodcaller_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot methodcaller_type_slots[] = { + {Py_tp_doc, (void *)methodcaller_doc}, + {Py_tp_dealloc, methodcaller_dealloc}, + {Py_tp_call, methodcaller_call}, + {Py_tp_traverse, methodcaller_traverse}, + {Py_tp_methods, methodcaller_methods}, + {Py_tp_new, methodcaller_new}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_repr, methodcaller_repr}, + {0, 0} }; +static PyType_Spec methodcaller_type_spec = { + .name = "operator.methodcaller", + .basicsize = sizeof(methodcallerobject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = methodcaller_type_slots, +}; static int operator_exec(PyObject *module) { - PyTypeObject *types[] = { - &itemgetter_type, - &attrgetter_type, - &methodcaller_type - }; + _operator_state *state = get_operator_state(module); + state->attrgetter_type = PyType_FromModuleAndSpec(module, &attrgetter_type_spec, NULL); + if (state->attrgetter_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->attrgetter_type) < 0) { + return -1; + } - for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { - if (PyModule_AddType(module, types[i]) < 0) { - return -1; - } + state->itemgetter_type = PyType_FromModuleAndSpec(module, &itemgetter_type_spec, NULL); + if (state->itemgetter_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->itemgetter_type) < 0) { + return -1; + } + + state->methodcaller_type = PyType_FromModuleAndSpec(module, &methodcaller_type_spec, NULL); + if (state->methodcaller_type == NULL) { + return -1; + } + if (PyModule_AddType(module, (PyTypeObject *)state->methodcaller_type) < 0) { + return -1; } return 0; @@ -1772,17 +1733,42 @@ static struct PyModuleDef_Slot operator_slots[] = { {0, NULL} }; +static int +operator_traverse(PyObject *module, visitproc visit, void *arg) +{ + _operator_state *state = get_operator_state(module); + Py_VISIT(state->attrgetter_type); + Py_VISIT(state->itemgetter_type); + Py_VISIT(state->methodcaller_type); + return 0; +} + +static int +operator_clear(PyObject *module) +{ + _operator_state *state = get_operator_state(module); + Py_CLEAR(state->attrgetter_type); + Py_CLEAR(state->itemgetter_type); + Py_CLEAR(state->methodcaller_type); + return 0; +} + +static void +operator_free(void *module) +{ + operator_clear((PyObject *)module); +} static struct PyModuleDef operatormodule = { PyModuleDef_HEAD_INIT, - "_operator", - operator_doc, - 0, - operator_methods, - operator_slots, - NULL, - NULL, - NULL + .m_name = "_operator", + .m_doc = operator_doc, + .m_size = sizeof(_operator_state), + .m_methods = operator_methods, + .m_slots = operator_slots, + .m_traverse = operator_traverse, + .m_clear = operator_clear, + .m_free = operator_free, }; PyMODINIT_FUNC From b34ebb48974afff05fc3f24726613944f174da94 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 26 Aug 2020 13:09:40 -0700 Subject: [PATCH 194/486] Fix typos in comment (GH-21966) --- Modules/mathmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 1d6174132814b2a..1704d8efd31c3a2 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2440,7 +2440,7 @@ addend should be in the range: 0.5 <= |x| <= 1.0. Accordingly, scaling or division by *max* should not be skipped even if not otherwise needed to prevent overflow or loss of precision. -The assertion that hi*hi >= 1.0 is a bit subtle. Each vector element +The assertion that hi*hi <= 1.0 is a bit subtle. Each vector element gets scaled to a magnitude below 1.0. The Veltkamp-Dekker splitting algorithm gives a *hi* value that is correctly rounded to half precision. When a value at or below 1.0 is correctly rounded, it @@ -2458,7 +2458,7 @@ The correction is the first order term of the Maclaurin series expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). Essentially, this differential correction is equivalent to one -refinement step in the Newton divide-and-average square root +refinement step in Newton's divide-and-average square root algorithm, effectively doubling the number of accurate bits. This technique is used in Dekker's SQRT2 algorithm and again in Borges' ALGORITHM 4 and 5. From 4af75e349578d02be79d232dfc69cd108150b0ad Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 12 Jun 2018 23:30:45 +0900 Subject: [PATCH 195/486] bpo-33660: Fix PosixPath to resolve a relative path on root --- Lib/pathlib.py | 5 ++++- Lib/test/test_pathlib.py | 9 +++++++++ .../Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 9f5e27b91178e68..babc443dd3b3043 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -329,7 +329,10 @@ def _resolve(path, rest): # parent dir path, _, _ = path.rpartition(sep) continue - newpath = path + sep + name + if path.endswith(sep): + newpath = path + name + else: + newpath = path + sep + name if newpath in seen: # Already seen this path path = seen[newpath] diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 04f7c3d86671bfa..2cb6738a295b649 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2349,6 +2349,15 @@ def test_open_mode(self): st = os.stat(join('other_new_file')) self.assertEqual(stat.S_IMODE(st.st_mode), 0o644) + def test_resolve_root(self): + current_directory = os.getcwd() + try: + os.chdir('/') + p = self.cls('spam') + self.assertEqual(str(p.resolve()), '/spam') + finally: + os.chdir(current_directory) + def test_touch_mode(self): old_mask = os.umask(0) self.addCleanup(os.umask, old_mask) diff --git a/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst b/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst new file mode 100644 index 000000000000000..cce3dbb1c6ea5ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst @@ -0,0 +1,2 @@ +Fix pathlib.PosixPath to resolve a relative path located on the root +directory properly. From 71cd67adeb132eeda01c984d202300c2d8985d71 Mon Sep 17 00:00:00 2001 From: MingZhe Hu Date: Thu, 27 Aug 2020 08:42:37 +0800 Subject: [PATCH 196/486] bpo-41624: fix documentation of typing.Coroutine (GH-21952) --- Doc/library/typing.rst | 2 +- .../next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 8208680669de6e2..9f98f8ce3f642dc 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1365,7 +1365,7 @@ Corresponding to other types in :mod:`collections.abc` Asynchronous programming """""""""""""""""""""""" -.. class:: Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co]) +.. class:: Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co]) A generic version of :class:`collections.abc.Coroutine`. The variance and order of type variables diff --git a/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst b/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst new file mode 100644 index 000000000000000..bdbc5a445f3390e --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst @@ -0,0 +1 @@ +Fix the signature of :class:`typing.Coroutine`. From 38cc6830b681fa2db19f9cef8ce063b62dbe357b Mon Sep 17 00:00:00 2001 From: Mason <38963371+nosamproductions@users.noreply.github.com> Date: Wed, 26 Aug 2020 19:49:14 -0500 Subject: [PATCH 197/486] Add missing word (GH-21936) "data to lost" -> "data to be lost" --- Doc/library/multiprocessing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 28510acd52bd46e..f8e7556f25b4e08 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -861,7 +861,7 @@ For an example of the usage of queues for interprocess communication see A better name for this method might be ``allow_exit_without_flush()``. It is likely to cause enqueued - data to lost, and you almost certainly will not need to use it. + data to be lost, and you almost certainly will not need to use it. It is really only there if you need the current process to exit immediately without waiting to flush enqueued data to the underlying pipe, and you don't care about lost data. From cc8cc689b2c192ad84bbaebc72ba8fff9d225df6 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 27 Aug 2020 01:51:12 +0100 Subject: [PATCH 198/486] bpo-41609: Fix output of pdb's whatis command for instance methods (GH-21935) --- Lib/pdb.py | 12 +++--- Lib/test/test_pdb.py | 41 +++++++++++++++++++ .../2020-08-21-15-51-15.bpo-41609.JmiUKG.rst | 1 + 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 081023526c0ea04..d7d957159458be0 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1312,21 +1312,21 @@ def do_whatis(self, arg): # _getval() already printed the error return code = None - # Is it a function? + # Is it an instance method? try: - code = value.__code__ + code = value.__func__.__code__ except Exception: pass if code: - self.message('Function %s' % code.co_name) + self.message('Method %s' % code.co_name) return - # Is it an instance method? + # Is it a function? try: - code = value.__func__.__code__ + code = value.__code__ except Exception: pass if code: - self.message('Method %s' % code.co_name) + self.message('Function %s' % code.co_name) return # Is it a class? if value.__class__ is type: diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 1a2bbb382e86426..e56451360d64381 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -425,6 +425,47 @@ def test_list_commands(): (Pdb) continue """ +def test_pdb_whatis_command(): + """Test the whatis command + + >>> myvar = (1,2) + >>> def myfunc(): + ... pass + + >>> class MyClass: + ... def mymethod(self): + ... pass + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'whatis myvar', + ... 'whatis myfunc', + ... 'whatis MyClass', + ... 'whatis MyClass()', + ... 'whatis MyClass.mymethod', + ... 'whatis MyClass().mymethod', + ... 'continue', + ... ]): + ... test_function() + --Return-- + > (2)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) whatis myvar + + (Pdb) whatis myfunc + Function myfunc + (Pdb) whatis MyClass + Class test.test_pdb.MyClass + (Pdb) whatis MyClass() + + (Pdb) whatis MyClass.mymethod + Function mymethod + (Pdb) whatis MyClass().mymethod + Method mymethod + (Pdb) continue + """ def test_post_mortem(): """Test post mortem traceback debugging. diff --git a/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst b/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst new file mode 100644 index 000000000000000..ecaf40eee7babfd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst @@ -0,0 +1 @@ +The pdb whatis command correctly reports instance methods as 'Method' rather than 'Function'. \ No newline at end of file From 45893ba55bb3b5aa10b685114c9a1aab1956a890 Mon Sep 17 00:00:00 2001 From: wmeehan Date: Thu, 27 Aug 2020 01:45:25 -0400 Subject: [PATCH 199/486] bpo-41524: fix pointer bug in PyOS_mystr{n}icmp (GH-21845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bpo-41524: fix pointer bug in PyOS_mystr{n}icmp The existing implementations of PyOS_mystrnicmp and PyOS_mystricmp can increment pointers beyond the end of a string. This commit fixes those cases by moving the mutation out of the condition. * 📜🤖 Added by blurb_it. * Address comments Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- .../2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst | 2 ++ Python/pystrcmp.c | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst diff --git a/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst b/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst new file mode 100644 index 000000000000000..4704e29be29bb03 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst @@ -0,0 +1,2 @@ +Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented +pointers beyond the end of a string. \ No newline at end of file diff --git a/Python/pystrcmp.c b/Python/pystrcmp.c index f9c2277cb56dc70..9224ce4c7060552 100644 --- a/Python/pystrcmp.c +++ b/Python/pystrcmp.c @@ -6,21 +6,25 @@ int PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size) { + const unsigned char *p1, *p2; if (size == 0) return 0; - while ((--size > 0) && - (tolower((unsigned)*s1) == tolower((unsigned)*s2))) { - if (!*s1++ || !*s2++) - break; + p1 = (const unsigned char *)s1; + p2 = (const unsigned char *)s2; + for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2)); + p1++, p2++) { + ; } - return tolower((unsigned)*s1) - tolower((unsigned)*s2); + return tolower(*p1) - tolower(*p2); } int PyOS_mystricmp(const char *s1, const char *s2) { - while (*s1 && (tolower((unsigned)*s1++) == tolower((unsigned)*s2++))) { + const unsigned char *p1 = (const unsigned char *)s1; + const unsigned char *p2 = (const unsigned char *)s2; + for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) { ; } - return (tolower((unsigned)*s1) - tolower((unsigned)*s2)); + return (tolower(*p1) - tolower(*p2)); } From 417dedbcfb87ce2208181bb5530598b6108eb035 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 27 Aug 2020 05:28:16 -0600 Subject: [PATCH 200/486] bpo-41634: Fix a typo in the curses documentation (GH-21958) --- Doc/library/curses.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 0b687db1bd2c4db..3684d54d4ecadec 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -717,7 +717,7 @@ the following methods and attributes: window.addch(y, x, ch[, attr]) Paint character *ch* at ``(y, x)`` with attributes *attr*, overwriting any - character previously painter at that location. By default, the character + character previously painted at that location. By default, the character position and attributes are the current settings for the window object. .. note:: From 615822c769aaf40d9071afbe635937dfc68e0014 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 27 Aug 2020 15:36:48 +0200 Subject: [PATCH 201/486] bpo-38787: Clarify docs for PyType_GetModule and warn against common mistake (GH-20215) --- Doc/c-api/type.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index f387279d143eecb..7309d7ee2cd398f 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -117,6 +117,13 @@ Type Objects If no module is associated with the given type, sets :py:class:`TypeError` and returns ``NULL``. + This function is usually used to get the module in which a method is defined. + Note that in such a method, ``PyType_GetModule(Py_TYPE(self))`` + may not return the intended result. + ``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses + are not necessarily defined in the same module as their superclass. + See :c:type:`PyCMethod` to get the class that defines the method. + .. versionadded:: 3.9 .. c:function:: void* PyType_GetModuleState(PyTypeObject *type) @@ -151,9 +158,12 @@ The following functions and structs are used to create If *bases* is ``NULL``, the *Py_tp_base* slot is used instead. If that also is ``NULL``, the new type derives from :class:`object`. - The *module* must be a module object or ``NULL``. + The *module* argument can be used to record the module in which the new + class is defined. It must be a module object or ``NULL``. If not ``NULL``, the module is associated with the new type and can later be retreived with :c:func:`PyType_GetModule`. + The associated module is not inherited by subclasses; it must be specified + for each class individually. This function calls :c:func:`PyType_Ready` on the new type. From 8c2155bf3399d180b2962d4b0cd926215d42ee90 Mon Sep 17 00:00:00 2001 From: SarahPythonista <4283226+SarahPythonista@users.noreply.github.com> Date: Fri, 28 Aug 2020 11:47:58 -0700 Subject: [PATCH 202/486] Fix error in argparse documentation example (GH-17399) Automerge-Triggered-By: @rhettinger --- Doc/library/argparse.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 0b64dfe47f7689d..7a7a4cf94979a19 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1162,8 +1162,8 @@ keyword argument to :meth:`~ArgumentParser.add_argument`:: >>> parser.parse_args(['--foo', 'BAR']) Namespace(foo='BAR') >>> parser.parse_args([]) - usage: argparse.py [-h] [--foo FOO] - argparse.py: error: option --foo is required + usage: [-h] --foo FOO + : error: the following arguments are required: --foo As the example shows, if an option is marked as ``required``, :meth:`~ArgumentParser.parse_args` will report an error if that option is not From 22b8b97d10209cb29f502c1d3790d51d6648a3c6 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Sat, 29 Aug 2020 17:00:08 +0200 Subject: [PATCH 203/486] bpo-19521: Fix parallel build race condition on AIX (GH-21997) Patch by Michael Haubenwallner. --- Makefile.pre.in | 12 ++++++++++-- configure | 31 ++++++++++++++++++++++--------- configure.ac | 27 ++++++++++++++++++--------- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index 0a19313ea993971..5d3ac705a36253e 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -161,6 +161,10 @@ BLDSHARED= @BLDSHARED@ $(PY_CORE_LDFLAGS) LDCXXSHARED= @LDCXXSHARED@ DESTSHARED= $(BINLIBDEST)/lib-dynload +# List of exported symbols for AIX +EXPORTSYMS= @EXPORTSYMS@ +EXPORTSFROM= @EXPORTSFROM@ + # Executable suffix (.exe on Windows and Mac OS X) EXE= @EXEEXT@ BUILDEXE= @BUILDEXEEXT@ @@ -571,7 +575,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) # Build the interpreter -$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) +$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) $(EXPORTSYMS) $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) platform: $(BUILDPYTHON) pybuilddir.txt @@ -643,6 +647,10 @@ libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) libpython$(VERSION).sl: $(LIBRARY_OBJS) $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) +# List of exported symbols for AIX +Modules/python.exp: $(LIBRARY) + $(srcdir)/Modules/makexp_aix $@ "$(EXPORTSFROM)" $? + # Copy up the gdb python hooks into a position where they can be automatically # loaded by gdb during Lib/test/test_gdb.py # @@ -702,7 +710,7 @@ Makefile Modules/config.c: Makefile.pre \ @echo "The Makefile was updated, you may need to re-run make." -Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) +Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) $(EXPORTSYMS) $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ diff --git a/configure b/configure index 69e975a4e8ef3cb..4c18ae7e364ca1a 100755 --- a/configure +++ b/configure @@ -700,6 +700,8 @@ ARFLAGS ac_ct_AR AR GNULD +EXPORTSFROM +EXPORTSYMS LINKCC LDVERSION RUNSHARED @@ -5799,8 +5801,6 @@ LDVERSION="$VERSION" # If CXX is set, and if it is needed to link a main function that was # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: # python might then depend on the C++ runtime -# This is altered for AIX in order to build the export list before -# linking. { $as_echo "$as_me:${as_lineno-$LINENO}: checking LINKCC" >&5 $as_echo_n "checking LINKCC... " >&6; } @@ -5808,13 +5808,6 @@ if test -z "$LINKCC" then LINKCC='$(PURIFY) $(MAINCC)' case $ac_sys_system in - AIX*) - exp_extra="\"\"" - if test $ac_sys_release -ge 5 -o \ - $ac_sys_release -eq 4 -a `uname -r` -ge 2 ; then - exp_extra="." - fi - LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";; QNX*) # qcc must be used because the other compilers do not # support -N. @@ -5824,6 +5817,26 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINKCC" >&5 $as_echo "$LINKCC" >&6; } +# EXPORTSYMS holds the list of exported symbols for AIX. +# EXPORTSFROM holds the module name exporting symbols on AIX. +EXPORTSYMS= +EXPORTSFROM= + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking EXPORTSYMS" >&5 +$as_echo_n "checking EXPORTSYMS... " >&6; } +case $ac_sys_system in +AIX*) + EXPORTSYMS="Modules/python.exp" + if test $ac_sys_release -ge 5 -o \ + $ac_sys_release -eq 4 -a `uname -r` -ge 2 ; then + EXPORTSFROM=. # the main executable + fi + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXPORTSYMS" >&5 +$as_echo "$EXPORTSYMS" >&6; } + # GNULD is set to "yes" if the GNU linker is used. If this goes wrong # make sure we default having it set to "no": this is used by # distutils.unixccompiler to know if it should add --enable-new-dtags diff --git a/configure.ac b/configure.ac index 07c0585432b0654..3b40f39124dad50 100644 --- a/configure.ac +++ b/configure.ac @@ -1024,21 +1024,12 @@ LDVERSION="$VERSION" # If CXX is set, and if it is needed to link a main function that was # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: # python might then depend on the C++ runtime -# This is altered for AIX in order to build the export list before -# linking. AC_SUBST(LINKCC) AC_MSG_CHECKING(LINKCC) if test -z "$LINKCC" then LINKCC='$(PURIFY) $(MAINCC)' case $ac_sys_system in - AIX*) - exp_extra="\"\"" - if test $ac_sys_release -ge 5 -o \ - $ac_sys_release -eq 4 -a `uname -r` -ge 2 ; then - exp_extra="." - fi - LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";; QNX*) # qcc must be used because the other compilers do not # support -N. @@ -1047,6 +1038,24 @@ then fi AC_MSG_RESULT($LINKCC) +# EXPORTSYMS holds the list of exported symbols for AIX. +# EXPORTSFROM holds the module name exporting symbols on AIX. +EXPORTSYMS= +EXPORTSFROM= +AC_SUBST(EXPORTSYMS) +AC_SUBST(EXPORTSFROM) +AC_MSG_CHECKING(EXPORTSYMS) +case $ac_sys_system in +AIX*) + EXPORTSYMS="Modules/python.exp" + if test $ac_sys_release -ge 5 -o \ + $ac_sys_release -eq 4 -a `uname -r` -ge 2 ; then + EXPORTSFROM=. # the main executable + fi + ;; +esac +AC_MSG_RESULT($EXPORTSYMS) + # GNULD is set to "yes" if the GNU linker is used. If this goes wrong # make sure we default having it set to "no": this is used by # distutils.unixccompiler to know if it should add --enable-new-dtags From d0d6535256be35dd59ac43fe15b27e75a07b2f71 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 29 Aug 2020 09:11:04 -0700 Subject: [PATCH 204/486] bpo-41513: Save unnecessary steps in the hypot() calculation (#21994) --- Modules/mathmodule.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 1704d8efd31c3a2..4ff2a069a76c7bc 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2447,6 +2447,14 @@ precision. When a value at or below 1.0 is correctly rounded, it never goes above 1.0. And when values at or below 1.0 are squared, they remain at or below 1.0, thus preserving the summation invariant. +Another interesting assertion is that csum+lo*lo == csum. In the loop, +each scaled vector element has a magnitude less than 1.0. After the +Veltkamp split, *lo* has a maximum value of 2**-27. So the maximum +value of *lo* squared is 2**-54. The value of ulp(1.0)/2.0 is 2**-53. +Given that csum >= 1.0, we have: + lo**2 <= 2**-54 < 2**-53 == 1/2*ulp(1.0) <= ulp(csum)/2 +Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. + The square root differential correction is needed because a correctly rounded square root of a correctly rounded sum of squares can still be off by as much as one ulp. @@ -2519,11 +2527,8 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) csum += x; frac += (oldcsum - csum) + x; - x = lo * lo; - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac += (oldcsum - csum) + x; + assert(csum + lo * lo == csum); + frac += lo * lo; } h = sqrt(csum - 1.0 + frac); From 11a4193a9905b44d75c59b67eb8babd6ae26fdfa Mon Sep 17 00:00:00 2001 From: Roger Iyengar Date: Sat, 29 Aug 2020 19:47:38 -0400 Subject: [PATCH 205/486] Improve asyncio-dev 'Concurrency and Multithreading' docs (GH-20882) I added some information to the `Concurrency and Multithreading` section of the `Developing with asyncio` guide. This is all information that would have helped me when I started using asyncio. I incorrectly assumed that `loop.call_soon_threadsafe()` and `run_coroutine_threadsafe()` could be called from a thread in a process separate from the one that the event loop is running in. Explicitly stating that this will not work will probably help some people starting out with asyncio in the future. I also added references to some other functions that can be used for inter-process communication without blocking the event loop. The section already mentions running blocking code in a ThreadPoolExecutor, but I think listing these other options in this section will also be helpful. --- Doc/library/asyncio-dev.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 77f80671978369f..02a00033152aba7 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -107,6 +107,16 @@ The :meth:`loop.run_in_executor` method can be used with a blocking code in a different OS thread without blocking the OS thread that the event loop runs in. +There is currently no way to schedule coroutines or callbacks directly +from a different process (such as one started with +:mod:`multiprocessing`). The :ref:`Event Loop Methods ` +section lists APIs that can read from pipes and watch file descriptors +without blocking the event loop. In addition, asyncio's +:ref:`Subprocess ` APIs provide a way to start a +process and communicate with it from the event loop. Lastly, the +aforementioned :meth:`loop.run_in_executor` method can also be used +with a :class:`concurrent.futures.ProcessPoolExecutor` to execute +code in a different process. .. _asyncio-handle-blocking: From 2b28e546835be11773e7eb0189f7e5589d8f3da5 Mon Sep 17 00:00:00 2001 From: Tony Solomonik Date: Sun, 30 Aug 2020 07:53:08 +0300 Subject: [PATCH 206/486] closes bpo-41533: Fix a potential memory leak when allocating a stack (GH-21847) Free the stack allocated in va_build_stack if do_mkstack fails and the stack is not a small_stack --- .../Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst | 2 ++ Python/modsupport.c | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst new file mode 100644 index 000000000000000..e166f0c0b621a42 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst @@ -0,0 +1,2 @@ +Free the stack allocated in ``va_build_stack`` if ``do_mkstack`` fails and +the stack is not a ``small_stack``. diff --git a/Python/modsupport.c b/Python/modsupport.c index 2637039d4a1518c..2dabcf383409e9d 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -622,6 +622,9 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, va_end(lva); if (res < 0) { + if (stack != small_stack) { + PyMem_Free(stack); + } return NULL; } From bc89e0738eb5c9d08229ef90cd45af293de8fdf1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 30 Aug 2020 10:00:11 -0700 Subject: [PATCH 207/486] Further improve accuracy of math.hypot() (GH-22013) --- Modules/mathmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 4ff2a069a76c7bc..6621951ee97d2b0 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2455,6 +2455,9 @@ Given that csum >= 1.0, we have: lo**2 <= 2**-54 < 2**-53 == 1/2*ulp(1.0) <= ulp(csum)/2 Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. +To minimize loss of information during the accumulation of fractional +values, the lo**2 term has a separate accumulator. + The square root differential correction is needed because a correctly rounded square root of a correctly rounded sum of squares can still be off by as much as one ulp. @@ -2475,7 +2478,8 @@ Borges' ALGORITHM 4 and 5. 1. Veltkamp-Dekker splitting: http://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf 2. Compensated summation: http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf -3. Square root diffential correction: https://arxiv.org/pdf/1904.09481.pdf +3. Square root differential correction: https://arxiv.org/pdf/1904.09481.pdf +4. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 */ @@ -2483,7 +2487,7 @@ static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { const double T27 = 134217729.0; /* ldexp(1.0, 27)+1.0) */ - double x, csum = 1.0, oldcsum, frac = 0.0, scale; + double x, csum = 1.0, oldcsum, frac = 0.0, frac_lo = 0.0, scale; double t, hi, lo, h; int max_e; Py_ssize_t i; @@ -2528,8 +2532,9 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) frac += (oldcsum - csum) + x; assert(csum + lo * lo == csum); - frac += lo * lo; + frac_lo += lo * lo; } + frac += frac_lo; h = sqrt(csum - 1.0 + frac); x = h; From 3774d646142d56157398d997548360f4077dc871 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 30 Aug 2020 18:29:53 +0100 Subject: [PATCH 208/486] bpo-39994: Fix pprint handling of dict subclasses that override __repr__ (GH-21892) Co-authored-by: Palak Kumar Jha --- Lib/pprint.py | 6 --- Lib/test/test_pprint.py | 49 ++++++++++++++++++- Misc/ACKS | 1 + .../2020-08-15-18-17-21.bpo-39994.dOgPOh.rst | 1 + 4 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst diff --git a/Lib/pprint.py b/Lib/pprint.py index 7c1118a484b268f..213998e3491ef75 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -176,12 +176,6 @@ def _format(self, object, stream, indent, allowance, context, level): p(self, object, stream, indent, allowance, context, level + 1) del context[objid] return - elif isinstance(object, dict): - context[objid] = 1 - self._pprint_dict(object, stream, indent, allowance, - context, level + 1) - del context[objid] - return stream.write(rep) _dispatch = {} diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index cf3e4f093b16eea..8ee18e8fef84f78 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -18,6 +18,10 @@ class list3(list): def __repr__(self): return list.__repr__(self) +class list_custom_repr(list): + def __repr__(self): + return '*'*len(list.__repr__(self)) + class tuple2(tuple): pass @@ -25,6 +29,10 @@ class tuple3(tuple): def __repr__(self): return tuple.__repr__(self) +class tuple_custom_repr(tuple): + def __repr__(self): + return '*'*len(tuple.__repr__(self)) + class set2(set): pass @@ -32,6 +40,10 @@ class set3(set): def __repr__(self): return set.__repr__(self) +class set_custom_repr(set): + def __repr__(self): + return '*'*len(set.__repr__(self)) + class frozenset2(frozenset): pass @@ -39,6 +51,10 @@ class frozenset3(frozenset): def __repr__(self): return frozenset.__repr__(self) +class frozenset_custom_repr(frozenset): + def __repr__(self): + return '*'*len(frozenset.__repr__(self)) + class dict2(dict): pass @@ -46,6 +62,10 @@ class dict3(dict): def __repr__(self): return dict.__repr__(self) +class dict_custom_repr(dict): + def __repr__(self): + return '*'*len(dict.__repr__(self)) + class Unorderable: def __repr__(self): return str(id(self)) @@ -155,7 +175,8 @@ def test_unreadable(self): "expected not isreadable for %r" % (unreadable,)) def test_same_as_repr(self): - # Simple objects, small containers and classes that overwrite __repr__ + # Simple objects, small containers and classes that override __repr__ + # to directly call super's __repr__. # For those the result should be the same as repr(). # Ahem. The docs don't say anything about that -- this appears to # be testing an implementation quirk. Starting in Python 2.5, it's @@ -187,6 +208,32 @@ def test_same_as_repr(self): .replace('\n', ' '), native) self.assertEqual(pprint.saferepr(simple), native) + def test_container_repr_override_called(self): + N = 1000 + # Ensure that __repr__ override is called for subclasses of containers + + for cont in (list_custom_repr(), + list_custom_repr([1,2,3]), + list_custom_repr(range(N)), + tuple_custom_repr(), + tuple_custom_repr([1,2,3]), + tuple_custom_repr(range(N)), + set_custom_repr(), + set_custom_repr([1,2,3]), + set_custom_repr(range(N)), + frozenset_custom_repr(), + frozenset_custom_repr([1,2,3]), + frozenset_custom_repr(range(N)), + dict_custom_repr(), + dict_custom_repr({5: 6}), + dict_custom_repr(zip(range(N),range(N))), + ): + native = repr(cont) + expected = '*' * len(native) + self.assertEqual(pprint.pformat(cont), expected) + self.assertEqual(pprint.pformat(cont, width=1, indent=0), expected) + self.assertEqual(pprint.saferepr(cont), expected) + def test_basic_line_wrap(self): # verify basic line-wrapping operation o = {'RPM_cal': 0, diff --git a/Misc/ACKS b/Misc/ACKS index 1599b09c692b756..a2cdeb850405995 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -856,6 +856,7 @@ Per Øyvind Karlsen Anton Kasyanov Lou Kates Makoto Kato +Irit Katriel Hiroaki Kawai Dmitry Kazakov Brian Kearns diff --git a/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst b/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst new file mode 100644 index 000000000000000..46876c15ea199c9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst @@ -0,0 +1 @@ +Fixed pprint's handling of dict subclasses that override __repr__. From f4f3c6122708c2bd0d17f4e20eac82afe3291c3d Mon Sep 17 00:00:00 2001 From: Vinay Sharma Date: Mon, 31 Aug 2020 00:33:11 +0530 Subject: [PATCH 209/486] bpo-41344: Raise ValueError when creating shared memory of size 0 (GH-21556) --- Lib/multiprocessing/shared_memory.py | 2 ++ Lib/test/_test_multiprocessing.py | 12 ++++++++++++ .../Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst | 1 + 3 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst diff --git a/Lib/multiprocessing/shared_memory.py b/Lib/multiprocessing/shared_memory.py index a3a5fcf4aba1e7d..122b3fcebf3fedd 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -76,6 +76,8 @@ def __init__(self, name=None, create=False, size=0): raise ValueError("'size' must be a positive integer") if create: self._flags = _O_CREX | os.O_RDWR + if size == 0: + raise ValueError("'size' must be a positive number different from zero") if name is None and not self._flags & os.O_EXCL: raise ValueError("'name' can only be None if create=True") diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 6a0e1016aff8d03..fd3b4303f034c1f 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3880,6 +3880,18 @@ class OptionalAttachSharedMemory(shared_memory.SharedMemory): sms.close() + # Test creating a shared memory segment with negative size + with self.assertRaises(ValueError): + sms_invalid = shared_memory.SharedMemory(create=True, size=-1) + + # Test creating a shared memory segment with size 0 + with self.assertRaises(ValueError): + sms_invalid = shared_memory.SharedMemory(create=True, size=0) + + # Test creating a shared memory segment without size argument + with self.assertRaises(ValueError): + sms_invalid = shared_memory.SharedMemory(create=True) + def test_shared_memory_across_processes(self): # bpo-40135: don't define shared memory block's name in case of # the failure when we run multiprocessing tests in parallel. diff --git a/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst b/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst new file mode 100644 index 000000000000000..475bc9bddb0d54a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst @@ -0,0 +1 @@ +Prevent creating :class:`shared_memory.SharedMemory` objects with :code:`size=0`. From 82dc297d681cad11a4cde3e58480dd33161e4379 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sun, 30 Aug 2020 17:36:58 -0300 Subject: [PATCH 210/486] [doc] Fix markup in logging (GH-22008) --- Doc/library/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 3ff67f76cc3c5a5..a446c80ece6048c 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1222,7 +1222,7 @@ functions. | | opening the output file. If not specified, | | | the value 'backslashreplace' is used. Note | | | that if ``None`` is specified, it will be | - | | passed as such to func:`open`, which means | + | | passed as such to :func:`open`, which means | | | that it will be treated the same as passing | | | 'errors'. | +--------------+---------------------------------------------+ From af451891da17a812ca2676b087a40daf4f444372 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Mon, 31 Aug 2020 15:57:52 -0400 Subject: [PATCH 211/486] bpo-39010: Fix errors logged on proactor loop restart (#22017) Stopping and restarting a proactor event loop on windows can lead to spurious errors logged (ConnectionResetError while reading from the self pipe). This fixes the issue by ensuring that we don't attempt to start multiple copies of the self-pipe reading loop. --- Lib/asyncio/proactor_events.py | 8 ++++++++ Lib/asyncio/windows_events.py | 8 ++++++-- Lib/test/test_asyncio/test_proactor_events.py | 1 + Lib/test/test_asyncio/test_windows_events.py | 20 +++++++++++++++++++ .../2020-08-30-10-24-26.bpo-39010._mzXJW.rst | 2 ++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index d0b7100f5e05631..4670bd683ab32cc 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -768,6 +768,14 @@ def _loop_self_reading(self, f=None): try: if f is not None: f.result() # may raise + if self._self_reading_future is not f: + # When we scheduled this Future, we assigned it to + # _self_reading_future. If it's not there now, something has + # tried to cancel the loop while this callback was still in the + # queue (see windows_events.ProactorEventLoop.run_forever). In + # that case stop here instead of continuing to schedule a new + # iteration. + return f = self._proactor.recv(self._ssock, 4096) except exceptions.CancelledError: # _close_self_pipe() has been called, stop waiting for data diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index a6759b78bd801fa..5e7cd795895d654 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -318,8 +318,12 @@ def run_forever(self): if self._self_reading_future is not None: ov = self._self_reading_future._ov self._self_reading_future.cancel() - # self_reading_future was just cancelled so it will never be signalled - # Unregister it otherwise IocpProactor.close will wait for it forever + # self_reading_future was just cancelled so if it hasn't been + # finished yet, it never will be (it's possible that it has + # already finished and its callback is waiting in the queue, + # where it could still happen if the event loop is restarted). + # Unregister it otherwise IocpProactor.close will wait for it + # forever if ov is not None: self._proactor._unregister(ov) self._self_reading_future = None diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index d0ab38743ecd1fd..4c8906d531ce5cc 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -753,6 +753,7 @@ def test_loop_self_reading(self): def test_loop_self_reading_fut(self): fut = mock.Mock() + self.loop._self_reading_future = fut self.loop._loop_self_reading(fut) self.assertTrue(fut.result.called) self.proactor.recv.assert_called_with(self.ssock, 4096) diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 6b005702c9be734..33388a87d48f3f1 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -211,6 +211,26 @@ def test_wait_for_handle_cancel(self): fut.cancel() fut.cancel() + def test_read_self_pipe_restart(self): + # Regression test for https://bugs.python.org/issue39010 + # Previously, restarting a proactor event loop in certain states + # would lead to spurious ConnectionResetErrors being logged. + self.loop.call_exception_handler = mock.Mock() + # Start an operation in another thread so that the self-pipe is used. + # This is theoretically timing-dependent (the task in the executor + # must complete before our start/stop cycles), but in practice it + # seems to work every time. + f = self.loop.run_in_executor(None, lambda: None) + self.loop.stop() + self.loop.run_forever() + self.loop.stop() + self.loop.run_forever() + # If we don't wait for f to complete here, we may get another + # warning logged about a thread that didn't shut down cleanly. + self.loop.run_until_complete(f) + self.loop.close() + self.assertFalse(self.loop.call_exception_handler.called) + class WinPolicyTests(test_utils.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst b/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst new file mode 100644 index 000000000000000..0d9015b490e4cbe --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst @@ -0,0 +1,2 @@ +Restarting a ``ProactorEventLoop`` on Windows no longer logs spurious +``ConnectionResetErrors``. From a8f3c6ea6279a5d0341941585bd365d6905efff8 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Tue, 1 Sep 2020 03:07:29 -0300 Subject: [PATCH 212/486] [doc] Document VIRTUAL_ENV environment variable (GH-21970) --- Doc/using/venv-create.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index c8f6e8f87d5674d..8f850a74d413ce2 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -126,6 +126,10 @@ directory containing the virtual environment): | | PowerShell | PS C:\\> \\Scripts\\Activate.ps1 | +-------------+-----------------+-----------------------------------------+ +When a virtual environment is active, the :envvar:`VIRTUAL_ENV` environment +variable is set to the path of the virtual environment. This can be used to +check if one is running inside a virtual environment. + You don't specifically *need* to activate an environment; activation just prepends the virtual environment's binary directory to your path, so that "python" invokes the virtual environment's Python interpreter and you can run From f24388703f0363101e7553d65159d406f3e7d5ba Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Tue, 1 Sep 2020 05:40:27 -0400 Subject: [PATCH 213/486] bpo-41685: Temporarily pin setuptools to 49.2.1 in Docs venv. (GH-22038) See https://github.com/pypa/setuptools/pull/2361 --- Doc/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/Makefile b/Doc/Makefile index b8ca1edfbc60a58..87d5d07665c8636 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -142,7 +142,8 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) - $(VENVDIR)/bin/python3 -m pip install -U pip setuptools +# $(VENVDIR)/bin/python3 -m pip install -U pip setuptools + $(VENVDIR)/bin/python3 -m pip install -U pip setuptools==49.2.1 $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" From d5838e8fb7012683db1f4c7fb0cfcb66ca1b4d8d Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Tue, 1 Sep 2020 09:59:46 -0300 Subject: [PATCH 214/486] [doc] Add link to FileHandler in logging (GH-21940) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andrés Delfino --- Doc/library/logging.rst | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index a446c80ece6048c..19691d50937a71f 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1166,9 +1166,9 @@ functions. +--------------+---------------------------------------------+ | Format | Description | +==============+=============================================+ - | *filename* | Specifies that a FileHandler be created, | - | | using the specified filename, rather than a | - | | StreamHandler. | + | *filename* | Specifies that a :class:`FileHandler` be | + | | created, using the specified filename, | + | | rather than a :class:`StreamHandler`. | +--------------+---------------------------------------------+ | *filemode* | If *filename* is specified, open the file | | | in this :ref:`mode `. Defaults | @@ -1192,9 +1192,10 @@ functions. | | :ref:`level `. | +--------------+---------------------------------------------+ | *stream* | Use the specified stream to initialize the | - | | StreamHandler. Note that this argument is | - | | incompatible with *filename* - if both | - | | are present, a ``ValueError`` is raised. | + | | :class:`StreamHandler`. Note that this | + | | argument is incompatible with *filename* - | + | | if both are present, a ``ValueError`` is | + | | raised. | +--------------+---------------------------------------------+ | *handlers* | If specified, this should be an iterable of | | | already created handlers to add to the root | @@ -1213,18 +1214,18 @@ functions. +--------------+---------------------------------------------+ | *encoding* | If this keyword argument is specified along | | | with *filename*, its value is used when the | - | | FileHandler is created, and thus used when | - | | opening the output file. | + | | :class:`FileHandler` is created, and thus | + | | used when opening the output file. | +--------------+---------------------------------------------+ | *errors* | If this keyword argument is specified along | | | with *filename*, its value is used when the | - | | FileHandler is created, and thus used when | - | | opening the output file. If not specified, | - | | the value 'backslashreplace' is used. Note | - | | that if ``None`` is specified, it will be | - | | passed as such to :func:`open`, which means | - | | that it will be treated the same as passing | - | | 'errors'. | + | | :class:`FileHandler` is created, and thus | + | | used when opening the output file. If not | + | | specified, the value 'backslashreplace' is | + | | used. Note that if ``None`` is specified, | + | | it will be passed as such to :func:`open`, | + | | which means that it will be treated the | + | | same as passing 'errors'. | +--------------+---------------------------------------------+ .. versionchanged:: 3.2 From 71645ec61039f382569bd37bbd02d4c52343e518 Mon Sep 17 00:00:00 2001 From: han-solo Date: Tue, 1 Sep 2020 10:34:29 -0400 Subject: [PATCH 215/486] bpo-41681: Fix for `f-string/str.format` error description when using 2 `,` in format specifier (GH-22036) * Fixed `f-string/str.format` error description when using two `,` in format specifier. Co-authored-by: millefalcon --- Lib/test/test_format.py | 20 +++++++++++++++++++ Lib/test/test_fstring.py | 20 +++++++++++++++++++ .../2020-08-31-17-49-02.bpo-41681.3-VJiH.rst | 2 ++ Python/formatter_unicode.c | 6 ++++-- 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index e9e5bb9cf00a62d..dff8c6903218785 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -1,6 +1,7 @@ from test.support import verbose, TestFailed import locale import sys +import re import test.support as support import unittest @@ -495,6 +496,25 @@ def test_g_format_has_no_trailing_zeros(self): self.assertEqual(format(12300050.0, ".6g"), "1.23e+07") self.assertEqual(format(12300050.0, "#.6g"), "1.23000e+07") + def test_with_two_commas_in_format_specifier(self): + error_msg = re.escape("Cannot specify ',' with ','.") + with self.assertRaisesRegex(ValueError, error_msg): + '{:,,}'.format(1) + + def test_with_two_underscore_in_format_specifier(self): + error_msg = re.escape("Cannot specify '_' with '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + '{:__}'.format(1) + + def test_with_a_commas_and_an_underscore_in_format_specifier(self): + error_msg = re.escape("Cannot specify both ',' and '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + '{:,_}'.format(1) + + def test_with_an_underscore_and_a_comma_in_format_specifier(self): + error_msg = re.escape("Cannot specify both ',' and '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + '{:,_}'.format(1) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 35a62a0632e2e62..b9bede0d9b800ea 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -9,6 +9,7 @@ import ast import os +import re import types import decimal import unittest @@ -1198,6 +1199,25 @@ def test_invalid_syntax_error_message(self): with self.assertRaisesRegex(SyntaxError, "f-string: invalid syntax"): compile("f'{a $ b}'", "?", "exec") + def test_with_two_commas_in_format_specifier(self): + error_msg = re.escape("Cannot specify ',' with ','.") + with self.assertRaisesRegex(ValueError, error_msg): + f'{1:,,}' + + def test_with_two_underscore_in_format_specifier(self): + error_msg = re.escape("Cannot specify '_' with '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + f'{1:__}' + + def test_with_a_commas_and_an_underscore_in_format_specifier(self): + error_msg = re.escape("Cannot specify both ',' and '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + f'{1:,_}' + + def test_with_an_underscore_and_a_comma_in_format_specifier(self): + error_msg = re.escape("Cannot specify both ',' and '_'.") + with self.assertRaisesRegex(ValueError, error_msg): + f'{1:,_}' if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst new file mode 100644 index 000000000000000..ed557f92d85cac0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst @@ -0,0 +1,2 @@ +Fixes the wrong error description in the error raised by using 2 `,` in +format string in f-string and :meth:`str.format`. diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 74638ca22377295..ed95f267d476c7b 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -252,8 +252,10 @@ parse_internal_render_format_spec(PyObject *format_spec, ++pos; } if (end-pos && READ_spec(pos) == ',') { - invalid_comma_and_underscore(); - return 0; + if (format->thousands_separators == LT_UNDERSCORE_LOCALE) { + invalid_comma_and_underscore(); + return 0; + } } /* Parse field precision */ From 317a5f141067d722ce50e9d209c1812880bac204 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 1 Sep 2020 18:25:14 +0200 Subject: [PATCH 216/486] bpo-41617: Fix pycore_bitutils.h to support clang 3.0 (GH-22042) __builtin_bswap16() is not available in LLVM clang 3.0. --- Include/internal/pycore_bitutils.h | 10 ++++++---- .../Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst diff --git a/Include/internal/pycore_bitutils.h b/Include/internal/pycore_bitutils.h index 0bd3270fe82e5cb..1602fc68d94074d 100644 --- a/Include/internal/pycore_bitutils.h +++ b/Include/internal/pycore_bitutils.h @@ -17,10 +17,12 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#if defined(__clang__) || \ - (defined(__GNUC__) && \ - ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) - /* __builtin_bswap16() is available since GCC 4.8, +#if ((defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) \ + || (defined(__clang__) \ + && (__clang_major__ >= 4 \ + || (__clang_major__ == 3 && __clang_minor__ >= 2)))) + /* __builtin_bswap16() is available since GCC 4.8 and clang 3.2, __builtin_bswap32() is available since GCC 4.3, __builtin_bswap64() is available since GCC 4.3. */ # define _PY_HAVE_BUILTIN_BSWAP diff --git a/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst b/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst new file mode 100644 index 000000000000000..715eadbee896f1d --- /dev/null +++ b/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst @@ -0,0 +1,2 @@ +Fix ``pycore_bitutils.h`` header file to support old clang versions: +``__builtin_bswap16()`` is not available in LLVM clang 3.0. From 48d8587c3b1fedce4287c72f76c01d29bed1b73b Mon Sep 17 00:00:00 2001 From: Marek Madejski Date: Tue, 1 Sep 2020 18:42:41 +0200 Subject: [PATCH 217/486] bpo-41528: Use math module in turtle (GH-21837) Use angle-related functions from math module instead of reinventing the wheel. --- Lib/turtle.py | 18 +++++++++--------- .../2020-08-12-07-43-31.bpo-41528.bu83oD.rst | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst diff --git a/Lib/turtle.py b/Lib/turtle.py index ee67a351b54f196..92d4e5dda9c2dbe 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -263,12 +263,12 @@ def __sub__(self, other): def __neg__(self): return Vec2D(-self[0], -self[1]) def __abs__(self): - return (self[0]**2 + self[1]**2)**0.5 + return math.hypot(*self) def rotate(self, angle): """rotate self counterclockwise by angle """ perp = Vec2D(-self[1], self[0]) - angle = angle * math.pi / 180.0 + angle = math.radians(angle) c, s = math.cos(angle), math.sin(angle) return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s) def __getnewargs__(self): @@ -1597,7 +1597,7 @@ def radians(self): >>> turtle.heading() 1.5707963267948966 """ - self._setDegreesPerAU(2*math.pi) + self._setDegreesPerAU(math.tau) def _go(self, distance): """move turtle forward by specified distance""" @@ -1888,7 +1888,7 @@ def towards(self, x, y=None): elif isinstance(x, TNavigator): pos = x._position x, y = pos - self._position - result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 result /= self._degreesPerAU return (self._angleOffset + self._angleOrient*result) % self._fullcircle @@ -1903,7 +1903,7 @@ def heading(self): 67.0 """ x, y = self._orient - result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 result /= self._degreesPerAU return (self._angleOffset + self._angleOrient*result) % self._fullcircle @@ -1976,7 +1976,7 @@ def circle(self, radius, extent = None, steps = None): steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) w = 1.0 * extent / steps w2 = 0.5 * w - l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU) + l = 2.0 * radius * math.sin(math.radians(w2)*self._degreesPerAU) if radius < 0: l, w, w2 = -l, -w, -w2 tr = self._tracer() @@ -2861,7 +2861,7 @@ def settiltangle(self, angle): >>> turtle.fd(50) """ tilt = -angle * self._degreesPerAU * self._angleOrient - tilt = (tilt * math.pi / 180.0) % (2*math.pi) + tilt = math.radians(tilt) % math.tau self.pen(resizemode="user", tilt=tilt) def tiltangle(self, angle=None): @@ -2885,7 +2885,7 @@ def tiltangle(self, angle=None): >>> turtle.tiltangle() """ if angle is None: - tilt = -self._tilt * (180.0/math.pi) * self._angleOrient + tilt = -math.degrees(self._tilt) * self._angleOrient return (tilt / self._degreesPerAU) % self._fullcircle else: self.settiltangle(angle) @@ -2939,7 +2939,7 @@ def shapetransform(self, t11=None, t12=None, t21=None, t22=None): if t11 * t22 - t12 * t21 == 0: raise TurtleGraphicsError("Bad shape transform matrix: must not be singular") self._shapetrafo = (m11, m12, m21, m22) - alfa = math.atan2(-m21, m11) % (2 * math.pi) + alfa = math.atan2(-m21, m11) % math.tau sa, ca = math.sin(alfa), math.cos(alfa) a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22, sa*m11 + ca*m21, sa*m12 + ca*m22) diff --git a/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst b/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst new file mode 100644 index 000000000000000..a4ba57c2438ed65 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst @@ -0,0 +1 @@ +turtle uses math module functions to convert degrees to radians and vice versa and to calculate vector norm \ No newline at end of file From cb998cc0ede02afdc947a093c2dac89378997ee0 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 1 Sep 2020 19:39:46 +0100 Subject: [PATCH 218/486] bpo-41654: Fix deallocator of MemoryError to account for subclasses (GH-22020) When allocating MemoryError classes, there is some logic to use pre-allocated instances in a freelist only if the type that is being allocated is not a subclass of MemoryError. Unfortunately in the destructor this logic is not present so the freelist is altered even with subclasses of MemoryError. --- Lib/test/test_exceptions.py | 31 +++++++++++++++++++ .../2020-08-30-20-38-33.bpo-41654.HtnhAM.rst | 2 ++ Objects/exceptions.c | 14 +++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 2ffe8caa03f8121..1ec446887770ea9 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,6 +1,7 @@ # Python test set -- part 5, built-in exceptions import copy +import gc import os import sys import unittest @@ -1330,6 +1331,36 @@ def test_assert_shadowing(self): del AssertionError self.fail('Expected exception') + def test_memory_error_subclasses(self): + # bpo-41654: MemoryError instances use a freelist of objects that are + # linked using the 'dict' attribute when they are inactive/dead. + # Subclasses of MemoryError should not participate in the freelist + # schema. This test creates a MemoryError object and keeps it alive + # (therefore advancing the freelist) and then it creates and destroys a + # subclass object. Finally, it checks that creating a new MemoryError + # succeeds, proving that the freelist is not corrupted. + + class TestException(MemoryError): + pass + + try: + raise MemoryError + except MemoryError as exc: + inst = exc + + try: + raise TestException + except Exception: + pass + + for _ in range(10): + try: + raise MemoryError + except MemoryError as exc: + pass + + gc_collect() + class ImportErrorTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst new file mode 100644 index 000000000000000..e05c3133e12625b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst @@ -0,0 +1,2 @@ +Fix a crash that occurred when destroying subclasses of +:class:`MemoryError`. Patch by Pablo Galindo. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 1195ba17922dd74..b08cbdd6aed3572 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2286,8 +2286,11 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; - if (type != (PyTypeObject *) PyExc_MemoryError) + /* If this is a subclass of MemoryError, don't use the freelist + * and just return a fresh object */ + if (type != (PyTypeObject *) PyExc_MemoryError) { return BaseException_new(type, args, kwds); + } struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_freelist == NULL) { @@ -2313,9 +2316,16 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void MemoryError_dealloc(PyBaseExceptionObject *self) { - _PyObject_GC_UNTRACK(self); BaseException_clear(self); + /* If this is a subclass of MemoryError, we don't need to + * do anything in the free-list*/ + if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) { + return Py_TYPE(self)->tp_free((PyObject *)self); + } + + _PyObject_GC_UNTRACK(self); + struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_numfree >= MEMERRORS_SAVE) { Py_TYPE(self)->tp_free((PyObject *)self); From 2e88380a40d8d8292ba0e4b9f32be9fa8465ac0d Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Tue, 1 Sep 2020 14:18:07 -0700 Subject: [PATCH 219/486] bpo-39349: Add cancel_futures to Executor.shutdown base class (GH-22023) * Add cancel_futures parameter to the Executor base class, since it was missed in the original PR (https://github.com/python/cpython/pull/18057) that added cancel_futures. --- Lib/concurrent/futures/_base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index bf546f8ae1d1cc9..00eb54881f2958d 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -605,7 +605,7 @@ def result_iterator(): future.cancel() return result_iterator() - def shutdown(self, wait=True): + def shutdown(self, wait=True, *, cancel_futures=False): """Clean-up the resources associated with the Executor. It is safe to call this method several times. Otherwise, no other @@ -615,6 +615,9 @@ def shutdown(self, wait=True): wait: If True then shutdown will not return until all running futures have finished executing and the resources used by the executor have been reclaimed. + cancel_futures: If True then shutdown will cancel all pending + futures. Futures that are completed or running will not be + cancelled. """ pass From ef2f5f6c7584e17ee36795f7c182ebeb90834b33 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 1 Sep 2020 20:36:42 -0500 Subject: [PATCH 220/486] Note the buffer slots can be set with PyType_Spec with the unlimited API. (GH-22031) Follow up to f7c4e236429606e1c982cacf24e10fc86ef4462f. --- Doc/c-api/type.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 7309d7ee2cd398f..73f26875d8194a8 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -225,7 +225,8 @@ The following functions and structs are used to create * ``Py_nb_add`` to set :c:member:`PyNumberMethods.nb_add` * ``Py_sq_length`` to set :c:member:`PySequenceMethods.sq_length` - The following fields cannot be set using :c:type:`PyType_Spec` and :c:type:`PyType_Slot`: + The following fields cannot be set at all using :c:type:`PyType_Spec` and + :c:type:`PyType_Slot`: * :c:member:`~PyTypeObject.tp_dict` * :c:member:`~PyTypeObject.tp_mro` @@ -239,6 +240,10 @@ The following functions and structs are used to create (see :ref:`PyMemberDef `) * :c:member:`~PyTypeObject.tp_vectorcall_offset` (see :ref:`PyMemberDef `) + + The following fields cannot be set using :c:type:`PyType_Spec` and + :c:type:`PyType_Slot` under the limited API: + * :c:member:`~PyBufferProcs.bf_getbuffer` * :c:member:`~PyBufferProcs.bf_releasebuffer` @@ -246,6 +251,10 @@ The following functions and structs are used to create To avoid issues, use the *bases* argument of :py:func:`PyType_FromSpecWithBases` instead. + .. versionchanged:: 3.9 + + Slots in :c:type:`PyBufferProcs` in may be set in the unlimited API. + .. c:member:: void *PyType_Slot.pfunc The desired value of the slot. In most cases, this is a pointer From 8f223d434187d2c6b00507358312ab39530599bd Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Wed, 2 Sep 2020 00:21:12 -0300 Subject: [PATCH 221/486] [doc] Remove references to PyChecker. (GH-22011) --- Doc/faq/design.rst | 3 +-- Doc/faq/programming.rst | 16 ++++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 4e3cc575ee19649..8cf271c30240848 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -573,8 +573,7 @@ whether an instance or a class implements a particular ABC. The :class:`~collections.abc.MutableMapping`. For Python, many of the advantages of interface specifications can be obtained -by an appropriate test discipline for components. There is also a tool, -PyChecker, which can be used to find problems due to subclassing. +by an appropriate test discipline for components. A good test suite for a module can both provide a regression test and serve as a module interface specification and a set of examples. Many Python modules can diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 0731e92f6dbc608..d6a2f2cfc67eed7 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -57,22 +57,14 @@ They include: * PyCharm (https://www.jetbrains.com/pycharm/) -Is there a tool to help find bugs or perform static analysis? +Are there tools to help find bugs or perform static analysis? ------------------------------------------------------------- Yes. -PyChecker is a static analysis tool that finds bugs in Python source code and -warns about code complexity and style. You can get PyChecker from -http://pychecker.sourceforge.net/. - -`Pylint `_ is another tool that checks -if a module satisfies a coding standard, and also makes it possible to write -plug-ins to add a custom feature. In addition to the bug checking that -PyChecker performs, Pylint offers some additional features such as checking line -length, whether variable names are well-formed according to your coding -standard, whether declared interfaces are fully implemented, and more. -https://docs.pylint.org/ provides a full list of Pylint's features. +`Pylint `_ and +`Pyflakes `_ do basic checking that will +help you catch bugs sooner. Static type checkers such as `Mypy `_, `Pyre `_, and From f891b0251ee66f7ed13a01ef8c5004663c563831 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Wed, 2 Sep 2020 00:22:55 -0300 Subject: [PATCH 222/486] Remove reference to Boa Constructor. (GH-22012) --- Doc/faq/programming.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index d6a2f2cfc67eed7..66d210a55fac7e9 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -35,12 +35,6 @@ for Windows Extensions `__ project an as a part of the ActivePython distribution (see https://www.activestate.com/activepython\ ). -`Boa Constructor `_ is an IDE and GUI -builder that uses wxWidgets. It offers visual frame creation and manipulation, -an object inspector, many views on the source like object browsers, inheritance -hierarchies, doc string generated html documentation, an advanced debugger, -integrated help, and Zope support. - `Eric `_ is an IDE built on PyQt and the Scintilla editing component. From a61a78c5523174f2732e5a30e1a755c65a0acbb3 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 1 Sep 2020 22:00:50 -0700 Subject: [PATCH 223/486] Improve hypot() accuracy with three separate accumulators (GH-22032) --- Modules/mathmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 6621951ee97d2b0..d227a5d15dca2a7 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2456,7 +2456,7 @@ Given that csum >= 1.0, we have: Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. To minimize loss of information during the accumulation of fractional -values, the lo**2 term has a separate accumulator. +values, each term has a separate accumulator. The square root differential correction is needed because a correctly rounded square root of a correctly rounded sum of @@ -2487,7 +2487,7 @@ static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { const double T27 = 134217729.0; /* ldexp(1.0, 27)+1.0) */ - double x, csum = 1.0, oldcsum, frac = 0.0, frac_lo = 0.0, scale; + double x, csum = 1.0, oldcsum, scale, frac=0.0, frac_mid=0.0, frac_lo=0.0; double t, hi, lo, h; int max_e; Py_ssize_t i; @@ -2529,12 +2529,12 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac_mid += (oldcsum - csum) + x; assert(csum + lo * lo == csum); frac_lo += lo * lo; } - frac += frac_lo; + frac += frac_lo + frac_mid; h = sqrt(csum - 1.0 + frac); x = h; From 4af983899568eb651b8848aac6f90126b251938e Mon Sep 17 00:00:00 2001 From: han-solo Date: Wed, 2 Sep 2020 04:56:37 -0400 Subject: [PATCH 224/486] Fixed mistake in test for f-string error description (GH-22036) (GH-22059) --- Lib/test/test_format.py | 2 +- Lib/test/test_fstring.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index dff8c6903218785..d2744cdfdca60e4 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -514,7 +514,7 @@ def test_with_a_commas_and_an_underscore_in_format_specifier(self): def test_with_an_underscore_and_a_comma_in_format_specifier(self): error_msg = re.escape("Cannot specify both ',' and '_'.") with self.assertRaisesRegex(ValueError, error_msg): - '{:,_}'.format(1) + '{:_,}'.format(1) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index b9bede0d9b800ea..b53661aa0a46fc5 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1217,7 +1217,7 @@ def test_with_a_commas_and_an_underscore_in_format_specifier(self): def test_with_an_underscore_and_a_comma_in_format_specifier(self): error_msg = re.escape("Cannot specify both ',' and '_'.") with self.assertRaisesRegex(ValueError, error_msg): - f'{1:,_}' + f'{1:_,}' if __name__ == '__main__': unittest.main() From 79cb7a59942c491dedd0d64a6152b4a424ee4211 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 2 Sep 2020 04:45:13 -0500 Subject: [PATCH 225/486] bpo-1635741: Port _blake2 module to multi-phase init (GH-21856) Port the _blake2 extension module to the multi-phase initialization API (PEP 489). --- ...2020-08-13-07-18-05.bpo-1635741.FC13e7.rst | 1 + Modules/_blake2/blake2b_impl.c | 57 +++------ Modules/_blake2/blake2module.c | 121 ++++++++++++------ Modules/_blake2/blake2s_impl.c | 58 +++------ 4 files changed, 119 insertions(+), 118 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst new file mode 100644 index 000000000000000..cdfee874095fe5c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst @@ -0,0 +1 @@ +Port the :mod:`_blake2` extension module to the multi-phase initialization API (:pep:`489`). diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 7fb1296f8b2b90b..8e1acce56b1d291 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -34,7 +34,7 @@ #endif -extern PyTypeObject PyBlake2_BLAKE2bType; +extern PyType_Spec blake2b_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +391,24 @@ py_blake2b_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } + + PyTypeObject *type = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(type); } +static PyType_Slot blake2b_type_slots[] = { + {Py_tp_dealloc, py_blake2b_dealloc}, + {Py_tp_doc, (char *)py_blake2b_new__doc__}, + {Py_tp_methods, py_blake2b_methods}, + {Py_tp_getset, py_blake2b_getsetters}, + {Py_tp_new, py_blake2b_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2bType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2b", /* tp_name */ - sizeof(BLAKE2bObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2b_dealloc, /* tp_dealloc */ - 0, /*tp_vectorcall_offset*/ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2b_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2b_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2b_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - py_blake2b_new, /* tp_new */ +PyType_Spec blake2b_type_spec = { + .name = "_blake2.blake2b", + .basicsize = sizeof(BLAKE2bObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = blake2b_type_slots }; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index ff142c9f3ed3304..631de2cc0abc740 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -12,62 +12,81 @@ #include "impl/blake2.h" -extern PyTypeObject PyBlake2_BLAKE2bType; -extern PyTypeObject PyBlake2_BLAKE2sType; - +extern PyType_Spec blake2b_type_spec; +extern PyType_Spec blake2s_type_spec; PyDoc_STRVAR(blake2mod__doc__, "_blake2b provides BLAKE2b for hashlib\n" ); +typedef struct { + PyTypeObject* blake2b_type; + PyTypeObject* blake2s_type; +} Blake2State; + +static inline Blake2State* +blake2_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (Blake2State *)state; +} static struct PyMethodDef blake2mod_functions[] = { {NULL, NULL} }; -static struct PyModuleDef blake2_module = { - PyModuleDef_HEAD_INIT, - "_blake2", - blake2mod__doc__, - -1, - blake2mod_functions, - NULL, - NULL, - NULL, - NULL -}; +static int +_blake2_traverse(PyObject *module, visitproc visit, void *arg) +{ + Blake2State *state = blake2_get_state(module); + Py_VISIT(state->blake2b_type); + Py_VISIT(state->blake2s_type); + return 0; +} + +static int +_blake2_clear(PyObject *module) +{ + Blake2State *state = blake2_get_state(module); + Py_CLEAR(state->blake2b_type); + Py_CLEAR(state->blake2s_type); + return 0; +} + +static void +_blake2_free(void *module) +{ + _blake2_clear((PyObject *)module); +} #define ADD_INT(d, name, value) do { \ PyObject *x = PyLong_FromLong(value); \ - if (!x) { \ - Py_DECREF(m); \ - return NULL; \ - } \ + if (!x) \ + return -1; \ if (PyDict_SetItemString(d, name, x) < 0) { \ - Py_DECREF(m); \ - return NULL; \ + Py_DECREF(x); \ + return -1; \ } \ Py_DECREF(x); \ } while(0) - -PyMODINIT_FUNC -PyInit__blake2(void) +static int +blake2_exec(PyObject *m) { - PyObject *m; - PyObject *d; + Blake2State* st = blake2_get_state(m); - m = PyModule_Create(&blake2_module); - if (m == NULL) - return NULL; + st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2b_type_spec, NULL); + if (NULL == st->blake2b_type) + return -1; /* BLAKE2b */ - Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2bType) < 0) { - return NULL; + if (PyModule_AddType(m, st->blake2b_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2bType.tp_dict; + PyObject *d = st->blake2b_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); @@ -79,12 +98,17 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ - Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2sType) < 0) { - return NULL; + st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2s_type_spec, NULL); + + if (NULL == st->blake2s_type) + return -1; + + if (PyModule_AddType(m, st->blake2s_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2sType.tp_dict; + d = st->blake2s_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); @@ -95,5 +119,28 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - return m; + return 0; } + +static PyModuleDef_Slot _blake2_slots[] = { + {Py_mod_exec, blake2_exec}, + {0, NULL} +}; + +static struct PyModuleDef blake2_module = { + PyModuleDef_HEAD_INIT, + "_blake2", + .m_doc = blake2mod__doc__, + .m_size = sizeof(Blake2State), + .m_methods = blake2mod_functions, + .m_slots = _blake2_slots, + .m_traverse = _blake2_traverse, + .m_clear = _blake2_clear, + .m_free = _blake2_free, +}; + +PyMODINIT_FUNC +PyInit__blake2(void) +{ + return PyModuleDef_Init(&blake2_module); +} \ No newline at end of file diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index e3e90d0587b8054..e1de5df37d09886 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -33,8 +33,7 @@ #include "impl/blake2s-ref.c" #endif - -extern PyTypeObject PyBlake2_BLAKE2sType; +extern PyType_Spec blake2s_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +390,24 @@ py_blake2s_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } + + PyTypeObject *type = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(type); } +static PyType_Slot blake2s_type_slots[] = { + {Py_tp_dealloc, py_blake2s_dealloc}, + {Py_tp_doc, (char *)py_blake2s_new__doc__}, + {Py_tp_methods, py_blake2s_methods}, + {Py_tp_getset, py_blake2s_getsetters}, + {Py_tp_new, py_blake2s_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2sType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2s", /* tp_name */ - sizeof(BLAKE2sObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2s_dealloc, /* tp_dealloc */ - 0, /*tp_vectorcall_offset*/ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2s_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2s_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2s_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - py_blake2s_new, /* tp_new */ +PyType_Spec blake2s_type_spec = { + .name = "_blake2.blake2s", + .basicsize = sizeof(BLAKE2sObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = blake2s_type_slots }; From efdb3a716d0307368d68156abcb50e71a98f5325 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 2 Sep 2020 04:55:19 -0500 Subject: [PATCH 226/486] bpo-1635741: Port _sha3 module to multi-phase init (GH-21855) Port the _sha3 extension module to multi-phase init (PEP 489). Convert static types to heap types. --- ...2020-08-13-07-19-21.bpo-1653741.fubBkb.rst | 1 + Modules/_sha3/sha3module.c | 329 ++++++++++-------- 2 files changed, 194 insertions(+), 136 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst new file mode 100644 index 000000000000000..73a4fdbac48a24d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst @@ -0,0 +1 @@ +Port :mod:`_sha3` to multi-phase init. Convert static types to heap types. diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index c826b42df13f92f..da6dde6812f2648 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -122,6 +122,28 @@ #define SHA3_squeeze Keccak_HashSqueeze #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) +typedef struct { + PyTypeObject *sha3_224_type; + PyTypeObject *sha3_256_type; + PyTypeObject *sha3_384_type; + PyTypeObject *sha3_512_type; +#ifdef PY_WITH_KECCAK + PyTypeObject *keccak_224_type; + PyTypeObject *keccak_256_type; + PyTypeObject *keccak_384_type; + PyTypeObject *keccak_512_type; +#endif + PyTypeObject *shake_128_type; + PyTypeObject *shake_256_type; +} SHA3State; + +static inline SHA3State* +sha3_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA3State *)state; +} /*[clinic input] module _sha3 @@ -142,19 +164,6 @@ typedef struct { PyThread_type_lock lock; } SHA3object; -static PyTypeObject SHA3_224type; -static PyTypeObject SHA3_256type; -static PyTypeObject SHA3_384type; -static PyTypeObject SHA3_512type; -#ifdef PY_WITH_KECCAK -static PyTypeObject Keccak_224type; -static PyTypeObject Keccak_256type; -static PyTypeObject Keccak_384type; -static PyTypeObject Keccak_512type; -#endif -static PyTypeObject SHAKE128type; -static PyTypeObject SHAKE256type; - #include "clinic/sha3module.c.h" static SHA3object * @@ -184,42 +193,43 @@ static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) /*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/ { - SHA3object *self = NULL; - Py_buffer buf = {NULL, NULL}; - HashReturn res; - - self = newSHA3object(type); + SHA3object *self = newSHA3object(type); if (self == NULL) { goto error; } - if (type == &SHA3_224type) { + SHA3State *state = PyType_GetModuleState(type); + assert(state != NULL); + + HashReturn res; + if (type == state->sha3_224_type) { res = Keccak_HashInitialize_SHA3_224(&self->hash_state); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { res = Keccak_HashInitialize_SHA3_256(&self->hash_state); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { res = Keccak_HashInitialize_SHA3_384(&self->hash_state); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { res = Keccak_HashInitialize_SHA3_512(&self->hash_state); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak_224_type) { res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak_256_type) { res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak_384_type) { res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak_512_type) { res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake_128_type) { res = Keccak_HashInitialize_SHAKE128(&self->hash_state); - } else if (type == &SHAKE256type) { + } else if (type == state->shake_256_type) { res = Keccak_HashInitialize_SHAKE256(&self->hash_state); } else { PyErr_BadInternalCall(); goto error; } + Py_buffer buf = {NULL, NULL}; if (data) { GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); if (buf.len >= HASHLIB_GIL_MINSIZE) { @@ -262,7 +272,10 @@ SHA3_dealloc(SHA3object *self) if (self->lock) { PyThread_free_lock(self->lock); } + + PyTypeObject *tp = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(tp); } @@ -416,27 +429,31 @@ static PyObject * SHA3_get_name(SHA3object *self, void *closure) { PyTypeObject *type = Py_TYPE(self); - if (type == &SHA3_224type) { + + SHA3State *state = PyType_GetModuleState(type); + assert(state != NULL); + + if (type == state->sha3_224_type) { return PyUnicode_FromString("sha3_224"); - } else if (type == &SHA3_256type) { + } else if (type == state->sha3_256_type) { return PyUnicode_FromString("sha3_256"); - } else if (type == &SHA3_384type) { + } else if (type == state->sha3_384_type) { return PyUnicode_FromString("sha3_384"); - } else if (type == &SHA3_512type) { + } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); #ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { + } else if (type == state->keccak_224_type) { return PyUnicode_FromString("keccak_224"); - } else if (type == &Keccak_256type) { + } else if (type == state->keccak_256_type) { return PyUnicode_FromString("keccak_256"); - } else if (type == &Keccak_384type) { + } else if (type == state->keccak_384_type) { return PyUnicode_FromString("keccak_384"); - } else if (type == &Keccak_512type) { + } else if (type == state->keccak_512_type) { return PyUnicode_FromString("keccak_512"); #endif - } else if (type == &SHAKE128type) { + } else if (type == state->shake_128_type) { return PyUnicode_FromString("shake_128"); - } else if (type == &SHAKE256type) { + } else if (type == state->shake_256_type) { return PyUnicode_FromString("shake_256"); } else { PyErr_BadInternalCall(); @@ -476,7 +493,6 @@ SHA3_get_suffix(SHA3object *self, void *closure) return PyBytes_FromStringAndSize((const char *)suffix, 1); } - static PyGetSetDef SHA3_getseters[] = { {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, @@ -487,48 +503,24 @@ static PyGetSetDef SHA3_getseters[] = { {NULL} /* Sentinel */ }; +#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \ + static PyType_Slot type_slots_obj[] = { \ + {Py_tp_dealloc, SHA3_dealloc}, \ + {Py_tp_doc, (char*)type_doc}, \ + {Py_tp_methods, type_methods}, \ + {Py_tp_getset, SHA3_getseters}, \ + {Py_tp_new, py_sha3_new}, \ + {0,0} \ + } -#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ - static PyTypeObject type_obj = { \ - PyVarObject_HEAD_INIT(NULL, 0) \ - type_name, /* tp_name */ \ - sizeof(SHA3object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - /* methods */ \ - (destructor)SHA3_dealloc, /* tp_dealloc */ \ - 0, /* tp_vectorcall_offset */ \ - 0, /* tp_getattr */ \ - 0, /* tp_setattr */ \ - 0, /* tp_as_async */ \ - 0, /* tp_repr */ \ - 0, /* tp_as_number */ \ - 0, /* tp_as_sequence */ \ - 0, /* tp_as_mapping */ \ - 0, /* tp_hash */ \ - 0, /* tp_call */ \ - 0, /* tp_str */ \ - 0, /* tp_getattro */ \ - 0, /* tp_setattro */ \ - 0, /* tp_as_buffer */ \ - Py_TPFLAGS_DEFAULT, /* tp_flags */ \ - type_doc, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - type_methods, /* tp_methods */ \ - NULL, /* tp_members */ \ - SHA3_getseters, /* tp_getset */ \ - 0, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - 0, /* tp_init */ \ - 0, /* tp_alloc */ \ - py_sha3_new, /* tp_new */ \ +// Using PyType_GetModuleState() on these types is safe since they +// cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. +#define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ + static PyType_Spec type_spec_obj = { \ + .name = "_sha3." type_name, \ + .basicsize = sizeof(SHA3object), \ + .flags = Py_TPFLAGS_DEFAULT, \ + .slots = type_slots \ } PyDoc_STRVAR(sha3_224__doc__, @@ -551,11 +543,6 @@ PyDoc_STRVAR(sha3_512__doc__, \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); -SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); -SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); -SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); - #ifdef PY_WITH_KECCAK PyDoc_STRVAR(keccak_224__doc__, "keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ @@ -577,10 +564,32 @@ PyDoc_STRVAR(keccak_512__doc__, \n\ Return a new Keccak hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); -SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); -SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); -SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); +#endif + +SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_224_spec, "sha3_224", sha3_224_slots); + +SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_256_spec, "sha3_256", sha3_256_slots); + +SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots); + +SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(sha3_512_spec, "sha3_512", sha3_512_slots); + +#ifdef PY_WITH_KECCAK +SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_224_spec, "keccak_224", Keccak_224_slots); + +SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_256_spec, "keccak_256", Keccak_256_slots); + +SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_384_spec, "keccak_384", Keccak_384_slots); + +SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); +SHA3_TYPE_SPEC(Keccak_512_spec, "keccak_512", Keccak_512_slots); #endif @@ -684,70 +693,118 @@ PyDoc_STRVAR(shake_256__doc__, \n\ Return a new SHAKE hash object."); -SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); -SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE128_spec, "shake_128", SHAKE128slots); +SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SPEC(SHAKE256_spec, "shake_256", SHAKE256slots); -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; +static int +_sha3_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA3State *state = sha3_get_state(module); + Py_VISIT(state->sha3_224_type); + Py_VISIT(state->sha3_256_type); + Py_VISIT(state->sha3_384_type); + Py_VISIT(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_VISIT(state->keccak_224_type); + Py_VISIT(state->keccak_256_type); + Py_VISIT(state->keccak_384_type); + Py_VISIT(state->keccak_512_type); +#endif + Py_VISIT(state->shake_128_type); + Py_VISIT(state->shake_256_type); + return 0; +} -PyMODINIT_FUNC -PyInit__sha3(void) +static int +_sha3_clear(PyObject *module) { - PyObject *m = NULL; + SHA3State *state = sha3_get_state(module); + Py_CLEAR(state->sha3_224_type); + Py_CLEAR(state->sha3_256_type); + Py_CLEAR(state->sha3_384_type); + Py_CLEAR(state->sha3_512_type); +#ifdef PY_WITH_KECCAK + Py_CLEAR(state->keccak_224_type); + Py_CLEAR(state->keccak_256_type); + Py_CLEAR(state->keccak_384_type); + Py_CLEAR(state->keccak_512_type); +#endif + Py_CLEAR(state->shake_128_type); + Py_CLEAR(state->shake_256_type); + return 0; +} - if ((m = PyModule_Create(&_SHA3module)) == NULL) { - return NULL; - } +static void +_sha3_free(void *module) +{ + _sha3_clear((PyObject *)module); +} -#define init_sha3type(name, type) \ - do { \ - Py_SET_TYPE(type, &PyType_Type); \ - if (PyType_Ready(type) < 0) { \ - goto error; \ - } \ - Py_INCREF((PyObject *)type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - goto error; \ - } \ +static int +_sha3_exec(PyObject *m) +{ + SHA3State *st = sha3_get_state(m); + +#define init_sha3type(type, typespec) \ + do { \ + st->type = (PyTypeObject *)PyType_FromModuleAndSpec( \ + m, &typespec, NULL); \ + if (st->type == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(m, st->type) < 0) { \ + return -1; \ + } \ } while(0) - init_sha3type("sha3_224", &SHA3_224type); - init_sha3type("sha3_256", &SHA3_256type); - init_sha3type("sha3_384", &SHA3_384type); - init_sha3type("sha3_512", &SHA3_512type); + init_sha3type(sha3_224_type, sha3_224_spec); + init_sha3type(sha3_256_type, sha3_256_spec); + init_sha3type(sha3_384_type, sha3_384_spec); + init_sha3type(sha3_512_type, sha3_512_spec); #ifdef PY_WITH_KECCAK - init_sha3type("keccak_224", &Keccak_224type); - init_sha3type("keccak_256", &Keccak_256type); - init_sha3type("keccak_384", &Keccak_384type); - init_sha3type("keccak_512", &Keccak_512type); + init_sha3type(keccak_224_type, Keccak_224_spec); + init_sha3type(keccak_256_type, Keccak_256_spec); + init_sha3type(keccak_384_type, Keccak_384_spec); + init_sha3type(keccak_512_type, Keccak_512_spec); #endif - init_sha3type("shake_128", &SHAKE128type); - init_sha3type("shake_256", &SHAKE256type); - + init_sha3type(shake_128_type, SHAKE128_spec); + init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { - goto error; + return -1; } if (PyModule_AddStringConstant(m, "implementation", KeccakP1600_implementation) < 0) { - goto error; + return -1; } - return m; - error: - Py_DECREF(m); - return NULL; + return 0; +} + +static PyModuleDef_Slot _sha3_slots[] = { + {Py_mod_exec, _sha3_exec}, + {0, NULL} +}; + +/* Initialize this module. */ +static struct PyModuleDef _sha3module = { + PyModuleDef_HEAD_INIT, + .m_name = "_sha3", + .m_size = sizeof(SHA3State), + .m_slots = _sha3_slots, + .m_traverse = _sha3_traverse, + .m_clear = _sha3_clear, + .m_free = _sha3_free, +}; + + +PyMODINIT_FUNC +PyInit__sha3(void) +{ + return PyModuleDef_Init(&_sha3module); } From 9730d211059d5d9ea7ac0a5de48247b8678ce462 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 2 Sep 2020 12:29:31 +0200 Subject: [PATCH 227/486] bpo-40204: Update Sphinx to version 3.2.1 in Doc/Makefile (GH-22043) --- Doc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Makefile b/Doc/Makefile index 87d5d07665c8636..f1d0a267dd89d54 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -144,7 +144,7 @@ venv: $(PYTHON) -m venv $(VENVDIR) # $(VENVDIR)/bin/python3 -m pip install -U pip setuptools $(VENVDIR)/bin/python3 -m pip install -U pip setuptools==49.2.1 - $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb python-docs-theme + $(VENVDIR)/bin/python3 -m pip install -U Sphinx==3.2.1 blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" dist: From 074b2496ee70b62e6c0522cfe857d2a7c999a84f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 2 Sep 2020 13:11:21 +0200 Subject: [PATCH 228/486] bpo-41685: Don't pin setuptools version anymore in Doc/Makefile (GH-22062) setuptools 50.0.2 is now compatible with Python 3.10: https://github.com/pypa/setuptools/pull/2361 --- Doc/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index f1d0a267dd89d54..c11a7ca5c1bcb70 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -142,8 +142,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) -# $(VENVDIR)/bin/python3 -m pip install -U pip setuptools - $(VENVDIR)/bin/python3 -m pip install -U pip setuptools==49.2.1 + $(VENVDIR)/bin/python3 -m pip install -U pip setuptools $(VENVDIR)/bin/python3 -m pip install -U Sphinx==3.2.1 blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" From e00609001f999107b6ab1408e82f8a7dba0fcd82 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 2 Sep 2020 15:29:12 +0100 Subject: [PATCH 229/486] bpo-41675: Modernize siginterrupt calls (GH-22028) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit siginterrupt is deprecated: ./Modules/signalmodule.c:667:5: warning: ‘siginterrupt’ is deprecated: Use sigaction with SA_RESTART instead [-Wdeprecated-declarations] 667 | if (siginterrupt(signalnum, flag)<0) { --- .../2020-08-31-14-53-17.bpo-41675.VSoqWU.rst | 3 +++ Modules/signalmodule.c | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst new file mode 100644 index 000000000000000..aa102f8fe438458 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst @@ -0,0 +1,3 @@ +The implementation of :func:`signal.siginterrupt` now uses :c:func:`sigaction` +(if it is available in the system) instead of the deprecated :c:func:`siginterrupt`. +Patch by Pablo Galindo. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 7bc1b535e6e2caa..c49a3ea52e71de5 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -664,7 +664,19 @@ signal_siginterrupt_impl(PyObject *module, int signalnum, int flag) "signal number out of range"); return NULL; } - if (siginterrupt(signalnum, flag)<0) { +#ifdef HAVE_SIGACTION + struct sigaction act; + (void) sigaction(signalnum, NULL, &act); + if (flag) { + act.sa_flags &= ~SA_RESTART; + } + else { + act.sa_flags |= SA_RESTART; + } + if (sigaction(signalnum, &act, NULL) < 0) { +#else + if (siginterrupt(signalnum, flag) < 0) { +#endif PyErr_SetFromErrno(PyExc_OSError); return NULL; } From 61efe06b95ada92402929096836e3c41bcb0388e Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 2 Sep 2020 15:29:38 +0100 Subject: [PATCH 230/486] Fix invalid escape sequences in the peg_highlight Sphinx extension (GH-22047) --- Doc/tools/extensions/peg_highlight.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tools/extensions/peg_highlight.py b/Doc/tools/extensions/peg_highlight.py index f02515d3919cf24..8bc24670fbe0abe 100644 --- a/Doc/tools/extensions/peg_highlight.py +++ b/Doc/tools/extensions/peg_highlight.py @@ -59,7 +59,7 @@ class PEGLexer(RegexLexer): include("variables"), (r"\b(?!(NULL|EXTRA))([A-Z_]+)\b\s*(?!\()", Text,), ( - r"^\s*" + _name + "\s*" + "(\[.*\])?" + "\s*" + "(\(.+\))?" + "\s*(:)", + r"^\s*" + _name + r"\s*" + r"(\[.*\])?" + r"\s*" + r"(\(.+\))?" + r"\s*(:)", bygroups(Name.Function, None, None, Punctuation), ), (_name, Name.Function), From 94f963d27f1cfb1c7063aade71e9b93a6921c450 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 2 Sep 2020 11:29:06 -0500 Subject: [PATCH 231/486] closes bpo-41689: Preserve text signature from tp_doc in C heap type creation. (GH-22058) --- Lib/test/test_capi.py | 4 +++ .../2020-09-01-23-39-45.bpo-41689.zxHbLB.rst | 2 ++ Modules/_testcapimodule.c | 30 +++++++++++++++++++ Objects/typeobject.c | 15 ++++++++-- 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 892cc74ec391588..db62b47100ad3a2 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -401,6 +401,10 @@ def __del__(self): del L self.assertEqual(PyList.num, 0) + def test_heap_ctype_doc_and_text_signature(self): + self.assertEqual(_testcapi.HeapDocCType.__doc__, "somedoc") + self.assertEqual(_testcapi.HeapDocCType.__text_signature__, "(arg1, arg2)") + def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self): class HeapGcCTypeSubclass(_testcapi.HeapGcCType): def __init__(self): diff --git a/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst b/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst new file mode 100644 index 000000000000000..44cf58a4b063889 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst @@ -0,0 +1,2 @@ +Types created with :c:func:`PyType_FromSpec` now make any signature in their +``tp_doc`` slot accessible from ``__text_signature__``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 593034ef65e2ca3..7536d29535038c7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6462,6 +6462,30 @@ static PyTypeObject MethodDescriptor2_Type = { .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, }; +PyDoc_STRVAR(heapdocctype__doc__, +"HeapDocCType(arg1, arg2)\n" +"--\n" +"\n" +"somedoc"); + +typedef struct { + PyObject_HEAD +} HeapDocCTypeObject; + +static PyType_Slot HeapDocCType_slots[] = { + {Py_tp_doc, (char*)heapdocctype__doc__}, + {0}, +}; + +static PyType_Spec HeapDocCType_spec = { + "_testcapi.HeapDocCType", + sizeof(HeapDocCTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapDocCType_slots +}; + + PyDoc_STRVAR(heapgctype__doc__, "A heap type with GC, and with overridden dealloc.\n\n" "The 'value' attribute is set to 10 in __init__."); @@ -7130,6 +7154,12 @@ PyInit__testcapi(void) Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); + if (HeapDocCType == NULL) { + return NULL; + } + PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); if (HeapGcCType == NULL) { return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c66f8fcec8ed515..74040757a07021b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3018,15 +3018,14 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) else if (slot->slot == Py_tp_doc) { /* For the docstring slot, which usually points to a static string literal, we need to make a copy */ - const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); - size_t len = strlen(old_doc)+1; + size_t len = strlen(slot->pfunc)+1; char *tp_doc = PyObject_MALLOC(len); if (tp_doc == NULL) { type->tp_doc = NULL; PyErr_NoMemory(); goto fail; } - memcpy(tp_doc, old_doc, len); + memcpy(tp_doc, slot->pfunc, len); type->tp_doc = tp_doc; } else if (slot->slot == Py_tp_members) { @@ -3058,6 +3057,16 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) res->ht_cached_keys = _PyDict_NewKeysForClass(); } + if (type->tp_doc) { + PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); + if (!__doc__) + goto fail; + int ret = _PyDict_SetItemId(type->tp_dict, &PyId___doc__, __doc__); + Py_DECREF(__doc__); + if (ret < 0) + goto fail; + } + if (weaklistoffset) { type->tp_weaklistoffset = weaklistoffset; if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) From de11d22c428772a28f4786df61c9b8c3a03e668b Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 2 Sep 2020 17:44:19 +0100 Subject: [PATCH 232/486] bpo-41690: Use a loop to collect args in the parser instead of recursion (GH-22053) This program can segfault the parser by stack overflow: ``` import ast code = "f(" + ",".join(['a' for _ in range(100000)]) + ")" print("Ready!") ast.parse(code) ``` the reason is that the rule for arguments has a simple recursion when collecting args: args[expr_ty]: [...] | a=named_expression b=[',' c=args { c }] { [...] } --- Grammar/python.gram | 13 +- .../2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst | 2 + Parser/parser.c | 1092 +++++++++-------- Parser/pegen.c | 35 + Parser/pegen.h | 1 + 5 files changed, 628 insertions(+), 515 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index 1cba11407468d26..84835b731c540f2 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -535,22 +535,11 @@ arguments[expr_ty] (memo): | a=args [','] &')' { a } | incorrect_arguments args[expr_ty]: - | a=starred_expression b=[',' c=args { c }] { - _Py_Call(_PyPegen_dummy_name(p), - (b) ? CHECK(_PyPegen_seq_insert_in_front(p, a, ((expr_ty) b)->v.Call.args)) - : CHECK(_PyPegen_singleton_seq(p, a)), - (b) ? ((expr_ty) b)->v.Call.keywords : NULL, - EXTRA) } + | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) } | a=kwargs { _Py_Call(_PyPegen_dummy_name(p), CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)), CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)), EXTRA) } - | a=named_expression b=[',' c=args { c }] { - _Py_Call(_PyPegen_dummy_name(p), - (b) ? CHECK(_PyPegen_seq_insert_in_front(p, a, ((expr_ty) b)->v.Call.args)) - : CHECK(_PyPegen_singleton_seq(p, a)), - (b) ? ((expr_ty) b)->v.Call.keywords : NULL, - EXTRA) } kwargs[asdl_seq*]: | a=','.kwarg_or_starred+ ',' b=','.kwarg_or_double_starred+ { _PyPegen_join_sequences(p, a, b) } | ','.kwarg_or_starred+ diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst new file mode 100644 index 000000000000000..5711aa5a55f0708 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst @@ -0,0 +1,2 @@ +Fix a possible stack overflow in the parser when parsing functions and +classes with a huge ammount of arguments. Patch by Pablo Galindo. diff --git a/Parser/parser.c b/Parser/parser.c index 75dc7176a5e756d..3e724a260d90a93 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -334,34 +334,34 @@ static KeywordToken *reserved_keywords[] = { #define _loop1_105_type 1265 #define _loop0_106_type 1266 #define _loop0_107_type 1267 -#define _tmp_108_type 1268 -#define _tmp_109_type 1269 -#define _loop0_111_type 1270 -#define _gather_110_type 1271 -#define _loop0_113_type 1272 -#define _gather_112_type 1273 -#define _loop0_115_type 1274 -#define _gather_114_type 1275 -#define _loop0_117_type 1276 -#define _gather_116_type 1277 -#define _loop0_118_type 1278 -#define _loop0_120_type 1279 -#define _gather_119_type 1280 -#define _tmp_121_type 1281 -#define _loop0_123_type 1282 -#define _gather_122_type 1283 -#define _loop0_125_type 1284 -#define _gather_124_type 1285 -#define _tmp_126_type 1286 -#define _loop0_127_type 1287 +#define _loop0_109_type 1268 +#define _gather_108_type 1269 +#define _tmp_110_type 1270 +#define _loop0_112_type 1271 +#define _gather_111_type 1272 +#define _loop0_114_type 1273 +#define _gather_113_type 1274 +#define _loop0_116_type 1275 +#define _gather_115_type 1276 +#define _loop0_118_type 1277 +#define _gather_117_type 1278 +#define _loop0_119_type 1279 +#define _loop0_121_type 1280 +#define _gather_120_type 1281 +#define _tmp_122_type 1282 +#define _loop0_124_type 1283 +#define _gather_123_type 1284 +#define _loop0_126_type 1285 +#define _gather_125_type 1286 +#define _tmp_127_type 1287 #define _loop0_128_type 1288 #define _loop0_129_type 1289 -#define _tmp_130_type 1290 +#define _loop0_130_type 1290 #define _tmp_131_type 1291 -#define _loop0_132_type 1292 -#define _tmp_133_type 1293 -#define _loop0_134_type 1294 -#define _tmp_135_type 1295 +#define _tmp_132_type 1292 +#define _loop0_133_type 1293 +#define _tmp_134_type 1294 +#define _loop0_135_type 1295 #define _tmp_136_type 1296 #define _tmp_137_type 1297 #define _tmp_138_type 1298 @@ -377,10 +377,12 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_148_type 1308 #define _tmp_149_type 1309 #define _tmp_150_type 1310 -#define _loop1_151_type 1311 -#define _loop1_152_type 1312 -#define _tmp_153_type 1313 -#define _tmp_154_type 1314 +#define _tmp_151_type 1311 +#define _tmp_152_type 1312 +#define _loop1_153_type 1313 +#define _loop1_154_type 1314 +#define _tmp_155_type 1315 +#define _tmp_156_type 1316 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -650,34 +652,34 @@ static asdl_seq *_gather_103_rule(Parser *p); static asdl_seq *_loop1_105_rule(Parser *p); static asdl_seq *_loop0_106_rule(Parser *p); static asdl_seq *_loop0_107_rule(Parser *p); -static void *_tmp_108_rule(Parser *p); -static void *_tmp_109_rule(Parser *p); -static asdl_seq *_loop0_111_rule(Parser *p); -static asdl_seq *_gather_110_rule(Parser *p); -static asdl_seq *_loop0_113_rule(Parser *p); -static asdl_seq *_gather_112_rule(Parser *p); -static asdl_seq *_loop0_115_rule(Parser *p); -static asdl_seq *_gather_114_rule(Parser *p); -static asdl_seq *_loop0_117_rule(Parser *p); -static asdl_seq *_gather_116_rule(Parser *p); +static asdl_seq *_loop0_109_rule(Parser *p); +static asdl_seq *_gather_108_rule(Parser *p); +static void *_tmp_110_rule(Parser *p); +static asdl_seq *_loop0_112_rule(Parser *p); +static asdl_seq *_gather_111_rule(Parser *p); +static asdl_seq *_loop0_114_rule(Parser *p); +static asdl_seq *_gather_113_rule(Parser *p); +static asdl_seq *_loop0_116_rule(Parser *p); +static asdl_seq *_gather_115_rule(Parser *p); static asdl_seq *_loop0_118_rule(Parser *p); -static asdl_seq *_loop0_120_rule(Parser *p); -static asdl_seq *_gather_119_rule(Parser *p); -static void *_tmp_121_rule(Parser *p); -static asdl_seq *_loop0_123_rule(Parser *p); -static asdl_seq *_gather_122_rule(Parser *p); -static asdl_seq *_loop0_125_rule(Parser *p); -static asdl_seq *_gather_124_rule(Parser *p); -static void *_tmp_126_rule(Parser *p); -static asdl_seq *_loop0_127_rule(Parser *p); +static asdl_seq *_gather_117_rule(Parser *p); +static asdl_seq *_loop0_119_rule(Parser *p); +static asdl_seq *_loop0_121_rule(Parser *p); +static asdl_seq *_gather_120_rule(Parser *p); +static void *_tmp_122_rule(Parser *p); +static asdl_seq *_loop0_124_rule(Parser *p); +static asdl_seq *_gather_123_rule(Parser *p); +static asdl_seq *_loop0_126_rule(Parser *p); +static asdl_seq *_gather_125_rule(Parser *p); +static void *_tmp_127_rule(Parser *p); static asdl_seq *_loop0_128_rule(Parser *p); static asdl_seq *_loop0_129_rule(Parser *p); -static void *_tmp_130_rule(Parser *p); +static asdl_seq *_loop0_130_rule(Parser *p); static void *_tmp_131_rule(Parser *p); -static asdl_seq *_loop0_132_rule(Parser *p); -static void *_tmp_133_rule(Parser *p); -static asdl_seq *_loop0_134_rule(Parser *p); -static void *_tmp_135_rule(Parser *p); +static void *_tmp_132_rule(Parser *p); +static asdl_seq *_loop0_133_rule(Parser *p); +static void *_tmp_134_rule(Parser *p); +static asdl_seq *_loop0_135_rule(Parser *p); static void *_tmp_136_rule(Parser *p); static void *_tmp_137_rule(Parser *p); static void *_tmp_138_rule(Parser *p); @@ -693,10 +695,12 @@ static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); static void *_tmp_149_rule(Parser *p); static void *_tmp_150_rule(Parser *p); -static asdl_seq *_loop1_151_rule(Parser *p); -static asdl_seq *_loop1_152_rule(Parser *p); -static void *_tmp_153_rule(Parser *p); -static void *_tmp_154_rule(Parser *p); +static void *_tmp_151_rule(Parser *p); +static void *_tmp_152_rule(Parser *p); +static asdl_seq *_loop1_153_rule(Parser *p); +static asdl_seq *_loop1_154_rule(Parser *p); +static void *_tmp_155_rule(Parser *p); +static void *_tmp_156_rule(Parser *p); // file: statements? $ @@ -12198,7 +12202,7 @@ arguments_rule(Parser *p) return _res; } -// args: starred_expression [',' args] | kwargs | named_expression [',' args] +// args: ','.(starred_expression | named_expression !'=')+ [',' kwargs] | kwargs static expr_ty args_rule(Parser *p) { @@ -12218,31 +12222,22 @@ args_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // starred_expression [',' args] + { // ','.(starred_expression | named_expression !'=')+ [',' kwargs] if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression [',' args]")); - expr_ty a; + D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); + asdl_seq * a; void *b; if ( - (a = starred_expression_rule(p)) // starred_expression + (a = _gather_108_rule(p)) // ','.(starred_expression | named_expression !'=')+ && - (b = _tmp_108_rule(p), 1) // [',' args] + (b = _tmp_110_rule(p), 1) // [',' kwargs] ) { - D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression [',' args]")); - Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); - if (_token == NULL) { - D(p->level--); - return NULL; - } - int _end_lineno = _token->end_lineno; - UNUSED(_end_lineno); // Only used by EXTRA macro - int _end_col_offset = _token->end_col_offset; - UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _Py_Call ( _PyPegen_dummy_name ( p ) , ( b ) ? CHECK ( _PyPegen_seq_insert_in_front ( p , a , ( ( expr_ty ) b ) -> v . Call . args ) ) : CHECK ( _PyPegen_singleton_seq ( p , a ) ) , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); + D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); + _res = _PyPegen_collect_call_seqs ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -12252,7 +12247,7 @@ args_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s args[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression [',' args]")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); } { // kwargs if (p->error_indicator) { @@ -12287,42 +12282,6 @@ args_rule(Parser *p) D(fprintf(stderr, "%*c%s args[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwargs")); } - { // named_expression [',' args] - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression [',' args]")); - expr_ty a; - void *b; - if ( - (a = named_expression_rule(p)) // named_expression - && - (b = _tmp_109_rule(p), 1) // [',' args] - ) - { - D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression [',' args]")); - Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); - if (_token == NULL) { - D(p->level--); - return NULL; - } - int _end_lineno = _token->end_lineno; - UNUSED(_end_lineno); // Only used by EXTRA macro - int _end_col_offset = _token->end_col_offset; - UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _Py_Call ( _PyPegen_dummy_name ( p ) , ( b ) ? CHECK ( _PyPegen_seq_insert_in_front ( p , a , ( ( expr_ty ) b ) -> v . Call . args ) ) : CHECK ( _PyPegen_singleton_seq ( p , a ) ) , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s args[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression [',' args]")); - } _res = NULL; done: D(p->level--); @@ -12353,11 +12312,11 @@ kwargs_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _gather_110_rule(p)) // ','.kwarg_or_starred+ + (a = _gather_111_rule(p)) // ','.kwarg_or_starred+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _gather_112_rule(p)) // ','.kwarg_or_double_starred+ + (b = _gather_113_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); @@ -12379,13 +12338,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - asdl_seq * _gather_114_var; + asdl_seq * _gather_115_var; if ( - (_gather_114_var = _gather_114_rule(p)) // ','.kwarg_or_starred+ + (_gather_115_var = _gather_115_rule(p)) // ','.kwarg_or_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - _res = _gather_114_var; + _res = _gather_115_var; goto done; } p->mark = _mark; @@ -12398,13 +12357,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - asdl_seq * _gather_116_var; + asdl_seq * _gather_117_var; if ( - (_gather_116_var = _gather_116_rule(p)) // ','.kwarg_or_double_starred+ + (_gather_117_var = _gather_117_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - _res = _gather_116_var; + _res = _gather_117_var; goto done; } p->mark = _mark; @@ -12766,7 +12725,7 @@ star_targets_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop0_118_rule(p)) // ((',' star_target))* + (b = _loop0_119_rule(p)) // ((',' star_target))* && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -12820,7 +12779,7 @@ star_targets_seq_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_119_rule(p)) // ','.star_target+ + (a = _gather_120_rule(p)) // ','.star_target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -12883,7 +12842,7 @@ star_target_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (a = _tmp_121_rule(p)) // !'*' star_target + (a = _tmp_122_rule(p)) // !'*' star_target ) { D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); @@ -13405,7 +13364,7 @@ del_targets_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_122_rule(p)) // ','.del_target+ + (a = _gather_123_rule(p)) // ','.del_target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -13746,7 +13705,7 @@ targets_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_124_rule(p)) // ','.target+ + (a = _gather_125_rule(p)) // ','.target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -14458,7 +14417,7 @@ incorrect_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_126_rule(p), 1) // [args | expression for_if_clauses] + (_opt_var = _tmp_127_rule(p), 1) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ incorrect_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -14716,7 +14675,7 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_127_var; + asdl_seq * _loop0_128_var; expr_ty a; expr_ty expression_var; if ( @@ -14724,7 +14683,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_127_var = _loop0_127_rule(p)) // star_named_expressions* + (_loop0_128_var = _loop0_128_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -14781,10 +14740,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_128_var; + asdl_seq * _loop0_129_var; expr_ty a; if ( - (_loop0_128_var = _loop0_128_rule(p)) // ((star_targets '='))* + (_loop0_129_var = _loop0_129_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -14811,10 +14770,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_129_var; + asdl_seq * _loop0_130_var; expr_ty a; if ( - (_loop0_129_var = _loop0_129_rule(p)) // ((star_targets '='))* + (_loop0_130_var = _loop0_130_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -14840,7 +14799,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_130_var; + void *_tmp_131_var; expr_ty a; AugOperator* augassign_var; if ( @@ -14848,7 +14807,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_130_var = _tmp_130_rule(p)) // yield_expr | star_expressions + (_tmp_131_var = _tmp_131_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -15059,11 +15018,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_131_var; + void *_tmp_132_var; expr_ty a; asdl_seq* for_if_clauses_var; if ( - (_tmp_131_var = _tmp_131_rule(p)) // '[' | '(' | '{' + (_tmp_132_var = _tmp_132_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -15160,13 +15119,13 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* (slash_with_default | param_with_default+) param_no_default")); - asdl_seq * _loop0_132_var; - void *_tmp_133_var; + asdl_seq * _loop0_133_var; + void *_tmp_134_var; arg_ty param_no_default_var; if ( - (_loop0_132_var = _loop0_132_rule(p)) // param_no_default* + (_loop0_133_var = _loop0_133_rule(p)) // param_no_default* && - (_tmp_133_var = _tmp_133_rule(p)) // slash_with_default | param_with_default+ + (_tmp_134_var = _tmp_134_rule(p)) // slash_with_default | param_with_default+ && (param_no_default_var = param_no_default_rule(p)) // param_no_default ) @@ -15208,13 +15167,13 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); - asdl_seq * _loop0_134_var; - void *_tmp_135_var; + asdl_seq * _loop0_135_var; + void *_tmp_136_var; arg_ty lambda_param_no_default_var; if ( - (_loop0_134_var = _loop0_134_rule(p)) // lambda_param_no_default* + (_loop0_135_var = _loop0_135_rule(p)) // lambda_param_no_default* && - (_tmp_135_var = _tmp_135_rule(p)) // lambda_slash_with_default | lambda_param_with_default+ + (_tmp_136_var = _tmp_136_rule(p)) // lambda_slash_with_default | lambda_param_with_default+ && (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) @@ -15256,11 +15215,11 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); Token * _literal; - void *_tmp_136_var; + void *_tmp_137_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_136_var = _tmp_136_rule(p)) // ')' | ',' (')' | '**') + (_tmp_137_var = _tmp_137_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -15330,11 +15289,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_137_var; + void *_tmp_138_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_137_var = _tmp_137_rule(p)) // ':' | ',' (':' | '**') + (_tmp_138_var = _tmp_138_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -16843,12 +16802,12 @@ _loop1_22_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_138_var; + void *_tmp_139_var; while ( - (_tmp_138_var = _tmp_138_rule(p)) // star_targets '=' + (_tmp_139_var = _tmp_139_rule(p)) // star_targets '=' ) { - _res = _tmp_138_var; + _res = _tmp_139_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -17351,12 +17310,12 @@ _loop0_31_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_139_var; + void *_tmp_140_var; while ( - (_tmp_139_var = _tmp_139_rule(p)) // '.' | '...' + (_tmp_140_var = _tmp_140_rule(p)) // '.' | '...' ) { - _res = _tmp_139_var; + _res = _tmp_140_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -17417,12 +17376,12 @@ _loop1_32_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_140_var; + void *_tmp_141_var; while ( - (_tmp_140_var = _tmp_140_rule(p)) // '.' | '...' + (_tmp_141_var = _tmp_141_rule(p)) // '.' | '...' ) { - _res = _tmp_140_var; + _res = _tmp_141_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19579,12 +19538,12 @@ _loop1_68_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_141_var; + void *_tmp_142_var; while ( - (_tmp_141_var = _tmp_141_rule(p)) // '@' named_expression NEWLINE + (_tmp_142_var = _tmp_142_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_141_var; + _res = _tmp_142_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19811,12 +19770,12 @@ _loop1_72_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_142_var; + void *_tmp_143_var; while ( - (_tmp_142_var = _tmp_142_rule(p)) // ',' star_expression + (_tmp_143_var = _tmp_143_rule(p)) // ',' star_expression ) { - _res = _tmp_142_var; + _res = _tmp_143_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19996,12 +19955,12 @@ _loop1_75_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_143_var; + void *_tmp_144_var; while ( - (_tmp_143_var = _tmp_143_rule(p)) // ',' expression + (_tmp_144_var = _tmp_144_rule(p)) // ',' expression ) { - _res = _tmp_143_var; + _res = _tmp_144_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21026,12 +20985,12 @@ _loop1_90_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_144_var; + void *_tmp_145_var; while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'or' conjunction + (_tmp_145_var = _tmp_145_rule(p)) // 'or' conjunction ) { - _res = _tmp_144_var; + _res = _tmp_145_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21097,12 +21056,12 @@ _loop1_91_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_145_var; + void *_tmp_146_var; while ( - (_tmp_145_var = _tmp_145_rule(p)) // 'and' inversion + (_tmp_146_var = _tmp_146_rule(p)) // 'and' inversion ) { - _res = _tmp_145_var; + _res = _tmp_146_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22018,12 +21977,12 @@ _loop0_106_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_146_var; + void *_tmp_147_var; while ( - (_tmp_146_var = _tmp_146_rule(p)) // 'if' disjunction + (_tmp_147_var = _tmp_147_rule(p)) // 'if' disjunction ) { - _res = _tmp_146_var; + _res = _tmp_147_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22084,12 +22043,12 @@ _loop0_107_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_147_var; + void *_tmp_148_var; while ( - (_tmp_147_var = _tmp_147_rule(p)) // 'if' disjunction + (_tmp_148_var = _tmp_148_rule(p)) // 'if' disjunction ) { - _res = _tmp_147_var; + _res = _tmp_148_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22123,43 +22082,113 @@ _loop0_107_rule(Parser *p) return _seq; } -// _tmp_108: ',' args -static void * -_tmp_108_rule(Parser *p) +// _loop0_109: ',' (starred_expression | named_expression !'=') +static asdl_seq * +_loop0_109_rule(Parser *p) { D(p->level++); if (p->error_indicator) { D(p->level--); return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // ',' args + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + ssize_t _children_capacity = 1; + ssize_t _n = 0; + { // ',' (starred_expression | named_expression !'=') if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' args")); + D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | named_expression !'=')")); Token * _literal; - expr_ty c; - if ( + void *elem; + while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (c = args_rule(p)) // args + (elem = _tmp_149_rule(p)) // starred_expression | named_expression !'=' ) { - D(fprintf(stderr, "%*c+ _tmp_108[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' args")); - _res = c; + _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; + PyMem_Free(_children); D(p->level--); return NULL; } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | named_expression !'=')")); + } + asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_109_type, _seq); + D(p->level--); + return _seq; +} + +// _gather_108: (starred_expression | named_expression !'=') _loop0_109 +static asdl_seq * +_gather_108_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (starred_expression | named_expression !'=') _loop0_109 + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _gather_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_109")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_149_rule(p)) // starred_expression | named_expression !'=' + && + (seq = _loop0_109_rule(p)) // _loop0_109 + ) + { + D(fprintf(stderr, "%*c+ _gather_108[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_109")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_108[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' args")); + D(fprintf(stderr, "%*c%s _gather_108[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | named_expression !'=') _loop0_109")); } _res = NULL; done: @@ -22167,9 +22196,9 @@ _tmp_108_rule(Parser *p) return _res; } -// _tmp_109: ',' args +// _tmp_110: ',' kwargs static void * -_tmp_109_rule(Parser *p) +_tmp_110_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22178,22 +22207,22 @@ _tmp_109_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ',' args + { // ',' kwargs if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' args")); + D(fprintf(stderr, "%*c> _tmp_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); Token * _literal; - expr_ty c; + asdl_seq* k; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (c = args_rule(p)) // args + (k = kwargs_rule(p)) // kwargs ) { - D(fprintf(stderr, "%*c+ _tmp_109[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' args")); - _res = c; + D(fprintf(stderr, "%*c+ _tmp_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + _res = k; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -22202,8 +22231,8 @@ _tmp_109_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_109[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' args")); + D(fprintf(stderr, "%*c%s _tmp_110[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); } _res = NULL; done: @@ -22211,9 +22240,9 @@ _tmp_109_rule(Parser *p) return _res; } -// _loop0_111: ',' kwarg_or_starred +// _loop0_112: ',' kwarg_or_starred static asdl_seq * -_loop0_111_rule(Parser *p) +_loop0_112_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22237,7 +22266,7 @@ _loop0_111_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -22268,7 +22297,7 @@ _loop0_111_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22281,14 +22310,14 @@ _loop0_111_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_111_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); D(p->level--); return _seq; } -// _gather_110: kwarg_or_starred _loop0_111 +// _gather_111: kwarg_or_starred _loop0_112 static asdl_seq * -_gather_110_rule(Parser *p) +_gather_111_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22297,27 +22326,27 @@ _gather_110_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_111 + { // kwarg_or_starred _loop0_112 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_111")); + D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_112")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_111_rule(p)) // _loop0_111 + (seq = _loop0_112_rule(p)) // _loop0_112 ) { - D(fprintf(stderr, "%*c+ _gather_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_111")); + D(fprintf(stderr, "%*c+ _gather_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_112")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_110[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_111")); + D(fprintf(stderr, "%*c%s _gather_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_112")); } _res = NULL; done: @@ -22325,9 +22354,9 @@ _gather_110_rule(Parser *p) return _res; } -// _loop0_113: ',' kwarg_or_double_starred +// _loop0_114: ',' kwarg_or_double_starred static asdl_seq * -_loop0_113_rule(Parser *p) +_loop0_114_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22351,7 +22380,7 @@ _loop0_113_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -22382,7 +22411,7 @@ _loop0_113_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_113[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22395,14 +22424,14 @@ _loop0_113_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_113_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); D(p->level--); return _seq; } -// _gather_112: kwarg_or_double_starred _loop0_113 +// _gather_113: kwarg_or_double_starred _loop0_114 static asdl_seq * -_gather_112_rule(Parser *p) +_gather_113_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22411,27 +22440,27 @@ _gather_112_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_113 + { // kwarg_or_double_starred _loop0_114 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_113")); + D(fprintf(stderr, "%*c> _gather_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_114")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_113_rule(p)) // _loop0_113 + (seq = _loop0_114_rule(p)) // _loop0_114 ) { - D(fprintf(stderr, "%*c+ _gather_112[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_113")); + D(fprintf(stderr, "%*c+ _gather_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_114")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_112[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_113")); + D(fprintf(stderr, "%*c%s _gather_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_114")); } _res = NULL; done: @@ -22439,9 +22468,9 @@ _gather_112_rule(Parser *p) return _res; } -// _loop0_115: ',' kwarg_or_starred +// _loop0_116: ',' kwarg_or_starred static asdl_seq * -_loop0_115_rule(Parser *p) +_loop0_116_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22465,7 +22494,7 @@ _loop0_115_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -22496,7 +22525,7 @@ _loop0_115_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_115[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_116[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22509,14 +22538,14 @@ _loop0_115_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_115_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_116_type, _seq); D(p->level--); return _seq; } -// _gather_114: kwarg_or_starred _loop0_115 +// _gather_115: kwarg_or_starred _loop0_116 static asdl_seq * -_gather_114_rule(Parser *p) +_gather_115_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22525,27 +22554,27 @@ _gather_114_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_115 + { // kwarg_or_starred _loop0_116 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_115")); + D(fprintf(stderr, "%*c> _gather_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_116")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_115_rule(p)) // _loop0_115 + (seq = _loop0_116_rule(p)) // _loop0_116 ) { - D(fprintf(stderr, "%*c+ _gather_114[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_115")); + D(fprintf(stderr, "%*c+ _gather_115[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_116")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_114[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_115")); + D(fprintf(stderr, "%*c%s _gather_115[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_116")); } _res = NULL; done: @@ -22553,9 +22582,9 @@ _gather_114_rule(Parser *p) return _res; } -// _loop0_117: ',' kwarg_or_double_starred +// _loop0_118: ',' kwarg_or_double_starred static asdl_seq * -_loop0_117_rule(Parser *p) +_loop0_118_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22579,7 +22608,7 @@ _loop0_117_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -22610,7 +22639,7 @@ _loop0_117_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_117[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22623,14 +22652,14 @@ _loop0_117_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_117_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); D(p->level--); return _seq; } -// _gather_116: kwarg_or_double_starred _loop0_117 +// _gather_117: kwarg_or_double_starred _loop0_118 static asdl_seq * -_gather_116_rule(Parser *p) +_gather_117_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22639,27 +22668,27 @@ _gather_116_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_117 + { // kwarg_or_double_starred _loop0_118 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_117")); + D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_118")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_117_rule(p)) // _loop0_117 + (seq = _loop0_118_rule(p)) // _loop0_118 ) { - D(fprintf(stderr, "%*c+ _gather_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_117")); + D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_118")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_116[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_117")); + D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_118")); } _res = NULL; done: @@ -22667,9 +22696,9 @@ _gather_116_rule(Parser *p) return _res; } -// _loop0_118: (',' star_target) +// _loop0_119: (',' star_target) static asdl_seq * -_loop0_118_rule(Parser *p) +_loop0_119_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22693,13 +22722,13 @@ _loop0_118_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_148_var; + D(fprintf(stderr, "%*c> _loop0_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_150_var; while ( - (_tmp_148_var = _tmp_148_rule(p)) // ',' star_target + (_tmp_150_var = _tmp_150_rule(p)) // ',' star_target ) { - _res = _tmp_148_var; + _res = _tmp_150_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22715,7 +22744,7 @@ _loop0_118_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_119[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22728,14 +22757,14 @@ _loop0_118_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_119_type, _seq); D(p->level--); return _seq; } -// _loop0_120: ',' star_target +// _loop0_121: ',' star_target static asdl_seq * -_loop0_120_rule(Parser *p) +_loop0_121_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22759,7 +22788,7 @@ _loop0_120_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty elem; while ( @@ -22790,7 +22819,7 @@ _loop0_120_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_120[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22803,14 +22832,14 @@ _loop0_120_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_120_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_121_type, _seq); D(p->level--); return _seq; } -// _gather_119: star_target _loop0_120 +// _gather_120: star_target _loop0_121 static asdl_seq * -_gather_119_rule(Parser *p) +_gather_120_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22819,27 +22848,27 @@ _gather_119_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_target _loop0_120 + { // star_target _loop0_121 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_120")); + D(fprintf(stderr, "%*c> _gather_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_121")); expr_ty elem; asdl_seq * seq; if ( (elem = star_target_rule(p)) // star_target && - (seq = _loop0_120_rule(p)) // _loop0_120 + (seq = _loop0_121_rule(p)) // _loop0_121 ) { - D(fprintf(stderr, "%*c+ _gather_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_120")); + D(fprintf(stderr, "%*c+ _gather_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_121")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_119[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_120")); + D(fprintf(stderr, "%*c%s _gather_120[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_121")); } _res = NULL; done: @@ -22847,9 +22876,9 @@ _gather_119_rule(Parser *p) return _res; } -// _tmp_121: !'*' star_target +// _tmp_122: !'*' star_target static void * -_tmp_121_rule(Parser *p) +_tmp_122_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22863,7 +22892,7 @@ _tmp_121_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); expr_ty star_target_var; if ( _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16) // token='*' @@ -22871,12 +22900,12 @@ _tmp_121_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); _res = star_target_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_121[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_122[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); } _res = NULL; @@ -22885,9 +22914,9 @@ _tmp_121_rule(Parser *p) return _res; } -// _loop0_123: ',' del_target +// _loop0_124: ',' del_target static asdl_seq * -_loop0_123_rule(Parser *p) +_loop0_124_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22911,7 +22940,7 @@ _loop0_123_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); + D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); Token * _literal; expr_ty elem; while ( @@ -22942,7 +22971,7 @@ _loop0_123_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_123[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -22955,14 +22984,14 @@ _loop0_123_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_124_type, _seq); D(p->level--); return _seq; } -// _gather_122: del_target _loop0_123 +// _gather_123: del_target _loop0_124 static asdl_seq * -_gather_122_rule(Parser *p) +_gather_123_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22971,27 +23000,27 @@ _gather_122_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // del_target _loop0_123 + { // del_target _loop0_124 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123")); + D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_124")); expr_ty elem; asdl_seq * seq; if ( (elem = del_target_rule(p)) // del_target && - (seq = _loop0_123_rule(p)) // _loop0_123 + (seq = _loop0_124_rule(p)) // _loop0_124 ) { - D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_123")); + D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_124")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_122[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_123")); + D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_124")); } _res = NULL; done: @@ -22999,9 +23028,9 @@ _gather_122_rule(Parser *p) return _res; } -// _loop0_125: ',' target +// _loop0_126: ',' target static asdl_seq * -_loop0_125_rule(Parser *p) +_loop0_126_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23025,7 +23054,7 @@ _loop0_125_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' target")); + D(fprintf(stderr, "%*c> _loop0_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' target")); Token * _literal; expr_ty elem; while ( @@ -23056,7 +23085,7 @@ _loop0_125_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_126[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' target")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23069,14 +23098,14 @@ _loop0_125_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_125_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq); D(p->level--); return _seq; } -// _gather_124: target _loop0_125 +// _gather_125: target _loop0_126 static asdl_seq * -_gather_124_rule(Parser *p) +_gather_125_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23085,27 +23114,27 @@ _gather_124_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // target _loop0_125 + { // target _loop0_126 if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target _loop0_125")); + D(fprintf(stderr, "%*c> _gather_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target _loop0_126")); expr_ty elem; asdl_seq * seq; if ( (elem = target_rule(p)) // target && - (seq = _loop0_125_rule(p)) // _loop0_125 + (seq = _loop0_126_rule(p)) // _loop0_126 ) { - D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target _loop0_125")); + D(fprintf(stderr, "%*c+ _gather_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "target _loop0_126")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target _loop0_125")); + D(fprintf(stderr, "%*c%s _gather_125[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "target _loop0_126")); } _res = NULL; done: @@ -23113,9 +23142,9 @@ _gather_124_rule(Parser *p) return _res; } -// _tmp_126: args | expression for_if_clauses +// _tmp_127: args | expression for_if_clauses static void * -_tmp_126_rule(Parser *p) +_tmp_127_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23129,18 +23158,18 @@ _tmp_126_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_127[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_126[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_127[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses @@ -23148,7 +23177,7 @@ _tmp_126_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_seq* for_if_clauses_var; if ( @@ -23157,12 +23186,12 @@ _tmp_126_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_127[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_126[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_127[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } _res = NULL; @@ -23171,9 +23200,9 @@ _tmp_126_rule(Parser *p) return _res; } -// _loop0_127: star_named_expressions +// _loop0_128: star_named_expressions static asdl_seq * -_loop0_127_rule(Parser *p) +_loop0_128_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23197,7 +23226,7 @@ _loop0_127_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); asdl_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions @@ -23219,7 +23248,7 @@ _loop0_127_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23232,14 +23261,14 @@ _loop0_127_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); D(p->level--); return _seq; } -// _loop0_128: (star_targets '=') +// _loop0_129: (star_targets '=') static asdl_seq * -_loop0_128_rule(Parser *p) +_loop0_129_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23263,13 +23292,13 @@ _loop0_128_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_149_var; + D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_151_var; while ( - (_tmp_149_var = _tmp_149_rule(p)) // star_targets '=' + (_tmp_151_var = _tmp_151_rule(p)) // star_targets '=' ) { - _res = _tmp_149_var; + _res = _tmp_151_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -23285,7 +23314,7 @@ _loop0_128_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23298,14 +23327,14 @@ _loop0_128_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq); D(p->level--); return _seq; } -// _loop0_129: (star_targets '=') +// _loop0_130: (star_targets '=') static asdl_seq * -_loop0_129_rule(Parser *p) +_loop0_130_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23329,13 +23358,13 @@ _loop0_129_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_150_var; + D(fprintf(stderr, "%*c> _loop0_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_152_var; while ( - (_tmp_150_var = _tmp_150_rule(p)) // star_targets '=' + (_tmp_152_var = _tmp_152_rule(p)) // star_targets '=' ) { - _res = _tmp_150_var; + _res = _tmp_152_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -23351,7 +23380,7 @@ _loop0_129_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23364,14 +23393,14 @@ _loop0_129_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_130_type, _seq); D(p->level--); return _seq; } -// _tmp_130: yield_expr | star_expressions +// _tmp_131: yield_expr | star_expressions static void * -_tmp_130_rule(Parser *p) +_tmp_131_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23385,18 +23414,18 @@ _tmp_130_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -23404,18 +23433,18 @@ _tmp_130_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -23424,9 +23453,9 @@ _tmp_130_rule(Parser *p) return _res; } -// _tmp_131: '[' | '(' | '{' +// _tmp_132: '[' | '(' | '{' static void * -_tmp_131_rule(Parser *p) +_tmp_132_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23440,18 +23469,18 @@ _tmp_131_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -23459,18 +23488,18 @@ _tmp_131_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -23478,18 +23507,18 @@ _tmp_131_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -23498,9 +23527,9 @@ _tmp_131_rule(Parser *p) return _res; } -// _loop0_132: param_no_default +// _loop0_133: param_no_default static asdl_seq * -_loop0_132_rule(Parser *p) +_loop0_133_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23524,7 +23553,7 @@ _loop0_132_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -23546,7 +23575,7 @@ _loop0_132_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_132[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23559,14 +23588,14 @@ _loop0_132_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_132_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq); D(p->level--); return _seq; } -// _tmp_133: slash_with_default | param_with_default+ +// _tmp_134: slash_with_default | param_with_default+ static void * -_tmp_133_rule(Parser *p) +_tmp_134_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23580,18 +23609,18 @@ _tmp_133_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } { // param_with_default+ @@ -23599,18 +23628,18 @@ _tmp_133_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_151_var; + D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + asdl_seq * _loop1_153_var; if ( - (_loop1_151_var = _loop1_151_rule(p)) // param_with_default+ + (_loop1_153_var = _loop1_153_rule(p)) // param_with_default+ ) { - D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_151_var; + D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + _res = _loop1_153_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); } _res = NULL; @@ -23619,9 +23648,9 @@ _tmp_133_rule(Parser *p) return _res; } -// _loop0_134: lambda_param_no_default +// _loop0_135: lambda_param_no_default static asdl_seq * -_loop0_134_rule(Parser *p) +_loop0_135_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23645,7 +23674,7 @@ _loop0_134_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -23667,7 +23696,7 @@ _loop0_134_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_135[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23680,14 +23709,14 @@ _loop0_134_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_135_type, _seq); D(p->level--); return _seq; } -// _tmp_135: lambda_slash_with_default | lambda_param_with_default+ +// _tmp_136: lambda_slash_with_default | lambda_param_with_default+ static void * -_tmp_135_rule(Parser *p) +_tmp_136_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23701,18 +23730,18 @@ _tmp_135_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } { // lambda_param_with_default+ @@ -23720,18 +23749,18 @@ _tmp_135_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_152_var; + D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + asdl_seq * _loop1_154_var; if ( - (_loop1_152_var = _loop1_152_rule(p)) // lambda_param_with_default+ + (_loop1_154_var = _loop1_154_rule(p)) // lambda_param_with_default+ ) { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_152_var; + D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + _res = _loop1_154_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); } _res = NULL; @@ -23740,9 +23769,9 @@ _tmp_135_rule(Parser *p) return _res; } -// _tmp_136: ')' | ',' (')' | '**') +// _tmp_137: ')' | ',' (')' | '**') static void * -_tmp_136_rule(Parser *p) +_tmp_137_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23756,18 +23785,18 @@ _tmp_136_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -23775,21 +23804,21 @@ _tmp_136_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_153_var; + void *_tmp_155_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_153_var = _tmp_153_rule(p)) // ')' | '**' + (_tmp_155_var = _tmp_155_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_153_var); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_155_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -23798,9 +23827,9 @@ _tmp_136_rule(Parser *p) return _res; } -// _tmp_137: ':' | ',' (':' | '**') +// _tmp_138: ':' | ',' (':' | '**') static void * -_tmp_137_rule(Parser *p) +_tmp_138_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23814,18 +23843,18 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -23833,21 +23862,21 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_154_var; + void *_tmp_156_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_154_var = _tmp_154_rule(p)) // ':' | '**' + (_tmp_156_var = _tmp_156_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_154_var); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_156_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -23856,9 +23885,9 @@ _tmp_137_rule(Parser *p) return _res; } -// _tmp_138: star_targets '=' +// _tmp_139: star_targets '=' static void * -_tmp_138_rule(Parser *p) +_tmp_139_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23872,7 +23901,7 @@ _tmp_138_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -23881,7 +23910,7 @@ _tmp_138_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23891,7 +23920,7 @@ _tmp_138_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -23900,9 +23929,9 @@ _tmp_138_rule(Parser *p) return _res; } -// _tmp_139: '.' | '...' +// _tmp_140: '.' | '...' static void * -_tmp_139_rule(Parser *p) +_tmp_140_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23916,18 +23945,18 @@ _tmp_139_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23935,18 +23964,18 @@ _tmp_139_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -23955,9 +23984,9 @@ _tmp_139_rule(Parser *p) return _res; } -// _tmp_140: '.' | '...' +// _tmp_141: '.' | '...' static void * -_tmp_140_rule(Parser *p) +_tmp_141_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23971,18 +24000,18 @@ _tmp_140_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23990,18 +24019,18 @@ _tmp_140_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -24010,9 +24039,9 @@ _tmp_140_rule(Parser *p) return _res; } -// _tmp_141: '@' named_expression NEWLINE +// _tmp_142: '@' named_expression NEWLINE static void * -_tmp_141_rule(Parser *p) +_tmp_142_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24026,7 +24055,7 @@ _tmp_141_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -24038,7 +24067,7 @@ _tmp_141_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24048,7 +24077,7 @@ _tmp_141_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -24057,9 +24086,9 @@ _tmp_141_rule(Parser *p) return _res; } -// _tmp_142: ',' star_expression +// _tmp_143: ',' star_expression static void * -_tmp_142_rule(Parser *p) +_tmp_143_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24073,7 +24102,7 @@ _tmp_142_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -24082,7 +24111,7 @@ _tmp_142_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24092,7 +24121,7 @@ _tmp_142_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -24101,9 +24130,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: ',' expression +// _tmp_144: ',' expression static void * -_tmp_143_rule(Parser *p) +_tmp_144_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24117,7 +24146,7 @@ _tmp_143_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -24126,7 +24155,7 @@ _tmp_143_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24136,7 +24165,7 @@ _tmp_143_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -24145,9 +24174,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'or' conjunction +// _tmp_145: 'or' conjunction static void * -_tmp_144_rule(Parser *p) +_tmp_145_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24161,7 +24190,7 @@ _tmp_144_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -24170,7 +24199,7 @@ _tmp_144_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24180,7 +24209,7 @@ _tmp_144_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -24189,9 +24218,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: 'and' inversion +// _tmp_146: 'and' inversion static void * -_tmp_145_rule(Parser *p) +_tmp_146_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24205,7 +24234,7 @@ _tmp_145_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -24214,7 +24243,7 @@ _tmp_145_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24224,7 +24253,7 @@ _tmp_145_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -24233,9 +24262,9 @@ _tmp_145_rule(Parser *p) return _res; } -// _tmp_146: 'if' disjunction +// _tmp_147: 'if' disjunction static void * -_tmp_146_rule(Parser *p) +_tmp_147_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24249,7 +24278,7 @@ _tmp_146_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -24258,7 +24287,7 @@ _tmp_146_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24268,7 +24297,7 @@ _tmp_146_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -24277,9 +24306,9 @@ _tmp_146_rule(Parser *p) return _res; } -// _tmp_147: 'if' disjunction +// _tmp_148: 'if' disjunction static void * -_tmp_147_rule(Parser *p) +_tmp_148_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24293,7 +24322,7 @@ _tmp_147_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -24302,7 +24331,7 @@ _tmp_147_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24312,7 +24341,7 @@ _tmp_147_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -24321,9 +24350,66 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: ',' star_target +// _tmp_149: starred_expression | named_expression !'=' static void * -_tmp_148_rule(Parser *p) +_tmp_149_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // starred_expression + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + { // named_expression !'=' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression !'='")); + expr_ty named_expression_var; + if ( + (named_expression_var = named_expression_rule(p)) // named_expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression !'='")); + _res = named_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression !'='")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + +// _tmp_150: ',' star_target +static void * +_tmp_150_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24337,7 +24423,7 @@ _tmp_148_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -24346,7 +24432,7 @@ _tmp_148_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24356,7 +24442,7 @@ _tmp_148_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -24365,9 +24451,9 @@ _tmp_148_rule(Parser *p) return _res; } -// _tmp_149: star_targets '=' +// _tmp_151: star_targets '=' static void * -_tmp_149_rule(Parser *p) +_tmp_151_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24381,7 +24467,7 @@ _tmp_149_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -24390,12 +24476,12 @@ _tmp_149_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -24404,9 +24490,9 @@ _tmp_149_rule(Parser *p) return _res; } -// _tmp_150: star_targets '=' +// _tmp_152: star_targets '=' static void * -_tmp_150_rule(Parser *p) +_tmp_152_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24420,7 +24506,7 @@ _tmp_150_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -24429,12 +24515,12 @@ _tmp_150_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -24443,9 +24529,9 @@ _tmp_150_rule(Parser *p) return _res; } -// _loop1_151: param_with_default +// _loop1_153: param_with_default static asdl_seq * -_loop1_151_rule(Parser *p) +_loop1_153_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24469,7 +24555,7 @@ _loop1_151_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop1_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -24491,7 +24577,7 @@ _loop1_151_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_151[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -24509,14 +24595,14 @@ _loop1_151_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_151_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_153_type, _seq); D(p->level--); return _seq; } -// _loop1_152: lambda_param_with_default +// _loop1_154: lambda_param_with_default static asdl_seq * -_loop1_152_rule(Parser *p) +_loop1_154_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24540,7 +24626,7 @@ _loop1_152_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop1_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -24562,7 +24648,7 @@ _loop1_152_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -24580,14 +24666,14 @@ _loop1_152_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_152_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_154_type, _seq); D(p->level--); return _seq; } -// _tmp_153: ')' | '**' +// _tmp_155: ')' | '**' static void * -_tmp_153_rule(Parser *p) +_tmp_155_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24601,18 +24687,18 @@ _tmp_153_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -24620,18 +24706,18 @@ _tmp_153_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -24640,9 +24726,9 @@ _tmp_153_rule(Parser *p) return _res; } -// _tmp_154: ':' | '**' +// _tmp_156: ':' | '**' static void * -_tmp_154_rule(Parser *p) +_tmp_156_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24656,18 +24742,18 @@ _tmp_154_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -24675,18 +24761,18 @@ _tmp_154_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; diff --git a/Parser/pegen.c b/Parser/pegen.c index f615907f5f571f6..2507bc4b38280b0 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -2217,3 +2217,38 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args) "Generator expression must be parenthesized" ); } + + +expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) { + Py_ssize_t args_len = asdl_seq_LEN(a); + Py_ssize_t total_len = args_len; + + if (b == NULL) { + expr_ty first = asdl_seq_GET(a, 0); + expr_ty last = asdl_seq_GET(a, args_len - 1); + return _Py_Call(_PyPegen_dummy_name(p), a, NULL, EXTRA_EXPR(first, last)); + + } + + asdl_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); + asdl_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); + + if (starreds) { + total_len += asdl_seq_LEN(starreds); + } + + asdl_seq *args = _Py_asdl_seq_new(total_len, p->arena); + + Py_ssize_t i = 0; + for (i = 0; i < args_len; i++) { + asdl_seq_SET(args, i, asdl_seq_GET(a, i)); + } + for (; i < total_len; i++) { + asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len)); + } + + expr_ty first = asdl_seq_GET(args, 0); + expr_ty last = asdl_seq_GET(b, asdl_seq_LEN(b)-1); + + return _Py_Call(_PyPegen_dummy_name(p), args, keywords, EXTRA_EXPR(first, last)); +} diff --git a/Parser/pegen.h b/Parser/pegen.h index f407709863c69e9..3e74e3ac73e0a3e 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -257,6 +257,7 @@ stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty); KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int); asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); +expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *); expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *); asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *); int _PyPegen_check_barry_as_flufl(Parser *); From 17b31191afac8bf6d67a8ddc8f4d91c29a378f2b Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 2 Sep 2020 21:54:46 -0700 Subject: [PATCH 233/486] bpo-41696: Fix handling of debug mode in asyncio.run (#22069) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bpo-41696: Fix handling of debug mode in asyncio.run This allows PYTHONASYNCIODEBUG or -X dev to enable asyncio debug mode when using asyncio.run * 📜🤖 Added by blurb_it. Co-authored-by: hauntsaninja <> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Lib/asyncio/runners.py | 5 +++-- Lib/test/test_asyncio/test_runners.py | 3 +++ .../next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 03ce33300eba831..268635d68fb0c0e 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -5,7 +5,7 @@ from . import tasks -def run(main, *, debug=False): +def run(main, *, debug=None): """Execute the coroutine and return the result. This function runs the passed coroutine, taking care of @@ -39,7 +39,8 @@ async def main(): loop = events.new_event_loop() try: events.set_event_loop(loop) - loop.set_debug(debug) + if debug is not None: + loop.set_debug(debug) return loop.run_until_complete(main) finally: try: diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 3b58ddee443adf6..b9ae02dc3c04e09 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -87,6 +87,9 @@ async def main(expected): asyncio.run(main(False)) asyncio.run(main(True), debug=True) + with mock.patch('asyncio.coroutines._is_debug_mode', lambda: True): + asyncio.run(main(True)) + asyncio.run(main(False), debug=False) def test_asyncio_run_from_running_loop(self): async def main(): diff --git a/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst b/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst new file mode 100644 index 000000000000000..67bbbb857f18cb0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst @@ -0,0 +1 @@ +Fix handling of debug mode in :func:`asyncio.run`. This allows setting ``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode when using :func:`asyncio.run`. \ No newline at end of file From 0c9b56e3183738f644ce8ea3cabc208091accd63 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Thu, 3 Sep 2020 00:58:50 -0400 Subject: [PATCH 234/486] bpo-39010: Improve test shutdown (#22066) Simply closing the event loop isn't enough to avoid warnings. If we don't also shut down the event loop's default executor, it sometimes logs a "dangling thread" warning. Follow-up to GH-22017 --- Lib/test/test_asyncio/test_windows_events.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 33388a87d48f3f1..f276cd205a2f8e9 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -225,10 +225,18 @@ def test_read_self_pipe_restart(self): self.loop.run_forever() self.loop.stop() self.loop.run_forever() - # If we don't wait for f to complete here, we may get another - # warning logged about a thread that didn't shut down cleanly. + + # Shut everything down cleanly. This is an important part of the + # test - in issue 39010, the error occurred during loop.close(), + # so we want to close the loop during the test instead of leaving + # it for tearDown. + # + # First wait for f to complete to avoid a "future's result was never + # retrieved" error. self.loop.run_until_complete(f) - self.loop.close() + # Now shut down the loop itself (self.close_loop also shuts down the + # loop's default executor). + self.close_loop(self.loop) self.assertFalse(self.loop.call_exception_handler.called) From c05bce546dcc931e163626213b9c1f8f681fc988 Mon Sep 17 00:00:00 2001 From: Todd Date: Thu, 3 Sep 2020 01:22:36 -0400 Subject: [PATCH 235/486] bpo-39883: Use BSD0 license for code in docs (GH-17635) The PSF board approved this use. --- Doc/license.rst | 34 +++++++++++++++++++ LICENSE | 25 ++++++++++++++ .../2020-03-07-03-53-39.bpo-39883.1tnb4-.rst | 1 + 3 files changed, 60 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst diff --git a/Doc/license.rst b/Doc/license.rst index fa6d71a78042d15..4030825bbd28ee0 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -72,6 +72,19 @@ make these releases possible. Terms and conditions for accessing or otherwise using Python ============================================================ +Python software and documentation are licensed under the +:ref:`PSF License Agreement `. + +Starting with Python 3.8.6, examples, recipes, and other code in +the documentation are dual licensed under the PSF License Agreement +and the :ref:`Zero-Clause BSD license `. + +Some software incorporated into Python is under different licenses. +The licenses are listed with code falling under that license. +See :ref:`OtherLicenses` for an incomplete list of these licenses. + + +.. _PSF-license: PSF LICENSE AGREEMENT FOR PYTHON |release| ------------------------------------------ @@ -258,6 +271,27 @@ CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 SOFTWARE. +.. _BSD0: + +ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON |release| DOCUMENTATION +---------------------------------------------------------------------- + +.. parsed-literal:: + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + +.. _OtherLicenses: + Licenses and Acknowledgements for Incorporated Software ======================================================= diff --git a/LICENSE b/LICENSE index 66a3ac80d729a3a..f42f8adbed845d6 100644 --- a/LICENSE +++ b/LICENSE @@ -59,6 +59,17 @@ direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== +Python software and documentation are licensed under the +Python Software Foundation License Version 2. + +Starting with Python 3.8.6, examples, recipes, and other code in +the documentation are dual licensed under the PSF License Version 2 +and the Zero-Clause BSD license. + +Some software incorporated into Python is under different licenses. +The licenses are listed with code falling under that license. + + PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- @@ -252,3 +263,17 @@ FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION +---------------------------------------------------------------------- + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst b/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst new file mode 100644 index 000000000000000..4941d50a560e2e5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst @@ -0,0 +1 @@ +Make code, examples, and recipes in the Python documentation be licensed under the more permissive BSD0 license in addition to the existing Python 2.0 license. \ No newline at end of file From 66dcc0e9d0b9145e7b20cd1a0a1c04c191653e26 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 3 Sep 2020 03:21:06 -0500 Subject: [PATCH 236/486] bpo-1635741: Port _signal module to multi-phase init (PEP 489) (GH-22049) --- ...2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst | 1 + Modules/signalmodule.c | 168 +++++++++--------- 2 files changed, 87 insertions(+), 82 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst new file mode 100644 index 000000000000000..ff7cb352869a22f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst @@ -0,0 +1 @@ +Port the :mod:`_signal` extension module to multi-phase initialization (:pep:`489`). diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index c49a3ea52e71de5..262f2b66a57e299 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1377,77 +1377,63 @@ ITIMER_PROF -- decrements both when the process is executing and\n\ A signal handler function is called with two arguments:\n\ the first is the signal number, the second is the interrupted stack frame."); -static struct PyModuleDef signalmodule = { - PyModuleDef_HEAD_INIT, - "_signal", - module_doc, - -1, - signal_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__signal(void) -{ - PyObject *m, *d; - int i; - /* Create the module and add the functions */ - m = PyModule_Create(&signalmodule); - if (m == NULL) - return NULL; +static int +signal_exec(PyObject *m) +{ + /* add the functions */ #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) if (!initialized) { - if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) - return NULL; + if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) { + return -1; + } + } + + if (PyModule_AddType(m, &SiginfoType) < 0) { + return -1; } - Py_INCREF((PyObject*) &SiginfoType); - PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); initialized = 1; #endif /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); + PyObject *d = PyModule_GetDict(m); DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); if (!DefaultHandler || PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) { - goto finally; + return -1; } IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); if (!IgnoreHandler || PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) { - goto finally; + return -1; } if (PyModule_AddIntMacro(m, NSIG)) - goto finally; + return -1; #ifdef SIG_BLOCK if (PyModule_AddIntMacro(m, SIG_BLOCK)) - goto finally; + return -1; #endif #ifdef SIG_UNBLOCK if (PyModule_AddIntMacro(m, SIG_UNBLOCK)) - goto finally; + return -1; #endif #ifdef SIG_SETMASK if (PyModule_AddIntMacro(m, SIG_SETMASK)) - goto finally; + return -1; #endif IntHandler = PyDict_GetItemString(d, "default_int_handler"); if (!IntHandler) - goto finally; + return -1; Py_INCREF(IntHandler); _Py_atomic_store_relaxed(&Handlers[0].tripped, 0); - for (i = 1; i < NSIG; i++) { + for (int i = 1; i < NSIG; i++) { void (*t)(int); t = PyOS_getsig(i); _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); @@ -1468,168 +1454,168 @@ PyInit__signal(void) #ifdef SIGHUP if (PyModule_AddIntMacro(m, SIGHUP)) - goto finally; + return -1; #endif #ifdef SIGINT if (PyModule_AddIntMacro(m, SIGINT)) - goto finally; + return -1; #endif #ifdef SIGBREAK if (PyModule_AddIntMacro(m, SIGBREAK)) - goto finally; + return -1; #endif #ifdef SIGQUIT if (PyModule_AddIntMacro(m, SIGQUIT)) - goto finally; + return -1; #endif #ifdef SIGILL if (PyModule_AddIntMacro(m, SIGILL)) - goto finally; + return -1; #endif #ifdef SIGTRAP if (PyModule_AddIntMacro(m, SIGTRAP)) - goto finally; + return -1; #endif #ifdef SIGIOT if (PyModule_AddIntMacro(m, SIGIOT)) - goto finally; + return -1; #endif #ifdef SIGABRT if (PyModule_AddIntMacro(m, SIGABRT)) - goto finally; + return -1; #endif #ifdef SIGEMT if (PyModule_AddIntMacro(m, SIGEMT)) - goto finally; + return -1; #endif #ifdef SIGFPE if (PyModule_AddIntMacro(m, SIGFPE)) - goto finally; + return -1; #endif #ifdef SIGKILL if (PyModule_AddIntMacro(m, SIGKILL)) - goto finally; + return -1; #endif #ifdef SIGBUS if (PyModule_AddIntMacro(m, SIGBUS)) - goto finally; + return -1; #endif #ifdef SIGSEGV if (PyModule_AddIntMacro(m, SIGSEGV)) - goto finally; + return -1; #endif #ifdef SIGSYS if (PyModule_AddIntMacro(m, SIGSYS)) - goto finally; + return -1; #endif #ifdef SIGPIPE if (PyModule_AddIntMacro(m, SIGPIPE)) - goto finally; + return -1; #endif #ifdef SIGALRM if (PyModule_AddIntMacro(m, SIGALRM)) - goto finally; + return -1; #endif #ifdef SIGTERM if (PyModule_AddIntMacro(m, SIGTERM)) - goto finally; + return -1; #endif #ifdef SIGUSR1 if (PyModule_AddIntMacro(m, SIGUSR1)) - goto finally; + return -1; #endif #ifdef SIGUSR2 if (PyModule_AddIntMacro(m, SIGUSR2)) - goto finally; + return -1; #endif #ifdef SIGCLD if (PyModule_AddIntMacro(m, SIGCLD)) - goto finally; + return -1; #endif #ifdef SIGCHLD if (PyModule_AddIntMacro(m, SIGCHLD)) - goto finally; + return -1; #endif #ifdef SIGPWR if (PyModule_AddIntMacro(m, SIGPWR)) - goto finally; + return -1; #endif #ifdef SIGIO if (PyModule_AddIntMacro(m, SIGIO)) - goto finally; + return -1; #endif #ifdef SIGURG if (PyModule_AddIntMacro(m, SIGURG)) - goto finally; + return -1; #endif #ifdef SIGWINCH if (PyModule_AddIntMacro(m, SIGWINCH)) - goto finally; + return -1; #endif #ifdef SIGPOLL if (PyModule_AddIntMacro(m, SIGPOLL)) - goto finally; + return -1; #endif #ifdef SIGSTOP if (PyModule_AddIntMacro(m, SIGSTOP)) - goto finally; + return -1; #endif #ifdef SIGTSTP if (PyModule_AddIntMacro(m, SIGTSTP)) - goto finally; + return -1; #endif #ifdef SIGCONT if (PyModule_AddIntMacro(m, SIGCONT)) - goto finally; + return -1; #endif #ifdef SIGTTIN if (PyModule_AddIntMacro(m, SIGTTIN)) - goto finally; + return -1; #endif #ifdef SIGTTOU if (PyModule_AddIntMacro(m, SIGTTOU)) - goto finally; + return -1; #endif #ifdef SIGVTALRM if (PyModule_AddIntMacro(m, SIGVTALRM)) - goto finally; + return -1; #endif #ifdef SIGPROF if (PyModule_AddIntMacro(m, SIGPROF)) - goto finally; + return -1; #endif #ifdef SIGXCPU if (PyModule_AddIntMacro(m, SIGXCPU)) - goto finally; + return -1; #endif #ifdef SIGXFSZ if (PyModule_AddIntMacro(m, SIGXFSZ)) - goto finally; + return -1; #endif #ifdef SIGRTMIN if (PyModule_AddIntMacro(m, SIGRTMIN)) - goto finally; + return -1; #endif #ifdef SIGRTMAX if (PyModule_AddIntMacro(m, SIGRTMAX)) - goto finally; + return -1; #endif #ifdef SIGINFO if (PyModule_AddIntMacro(m, SIGINFO)) - goto finally; + return -1; #endif #ifdef ITIMER_REAL if (PyModule_AddIntMacro(m, ITIMER_REAL)) - goto finally; + return -1; #endif #ifdef ITIMER_VIRTUAL if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL)) - goto finally; + return -1; #endif #ifdef ITIMER_PROF if (PyModule_AddIntMacro(m, ITIMER_PROF)) - goto finally; + return -1; #endif #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) @@ -1637,18 +1623,18 @@ PyInit__signal(void) PyExc_OSError, NULL); if (!ItimerError || PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) { - goto finally; + return -1; } #endif #ifdef CTRL_C_EVENT if (PyModule_AddIntMacro(m, CTRL_C_EVENT)) - goto finally; + return -1; #endif #ifdef CTRL_BREAK_EVENT if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT)) - goto finally; + return -1; #endif #ifdef MS_WINDOWS @@ -1657,12 +1643,30 @@ PyInit__signal(void) #endif if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; + return -1; } - finally: - return m; + return 0; +} + +static PyModuleDef_Slot signal_slots[] = { + {Py_mod_exec, signal_exec}, + {0, NULL} +}; + +static struct PyModuleDef signalmodule = { + PyModuleDef_HEAD_INIT, + "_signal", + .m_doc = module_doc, + .m_size = 0, + .m_methods = signal_methods, + .m_slots = signal_slots +}; + +PyMODINIT_FUNC +PyInit__signal(void) +{ + return PyModuleDef_Init(&signalmodule); } static void From 686da9625e2fbb928a76872b750aeec2cd2c46ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20=C5=A0a=C5=A1ko?= Date: Thu, 3 Sep 2020 12:00:10 +0200 Subject: [PATCH 237/486] [doc] Fix a typo in the graphlib docs (#22030) --- Doc/library/graphlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/graphlib.rst b/Doc/library/graphlib.rst index 820615e72301576..0faca2186b268cc 100644 --- a/Doc/library/graphlib.rst +++ b/Doc/library/graphlib.rst @@ -121,7 +121,7 @@ if ts.is_active(): ... - if possible to simply do:: + it is possible to simply do:: if ts: ... From 54d6e21b8b1fbae59b0b23d8b0d0429cedd5592e Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 3 Sep 2020 15:29:32 +0100 Subject: [PATCH 238/486] bpo-41697: Correctly handle KeywordOrStarred when parsing arguments in the parser (GH-22077) --- Grammar/python.gram | 2 +- Parser/parser.c | 11 ++++++++++- Parser/pegen.c | 17 +++++++++-------- Parser/pegen.h | 4 +++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Grammar/python.gram b/Grammar/python.gram index 84835b731c540f2..524e88eb389968e 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -535,7 +535,7 @@ arguments[expr_ty] (memo): | a=args [','] &')' { a } | incorrect_arguments args[expr_ty]: - | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) } + | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) } | a=kwargs { _Py_Call(_PyPegen_dummy_name(p), CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)), CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)), diff --git a/Parser/parser.c b/Parser/parser.c index 3e724a260d90a93..8a7cb62fd7cf8dd 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -12237,7 +12237,16 @@ args_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); - _res = _PyPegen_collect_call_seqs ( p , a , b ); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + D(p->level--); + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); diff --git a/Parser/pegen.c b/Parser/pegen.c index 2507bc4b38280b0..4beb2abdd296aae 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -2219,14 +2219,15 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args) } -expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) { +expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b, + int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { Py_ssize_t args_len = asdl_seq_LEN(a); Py_ssize_t total_len = args_len; if (b == NULL) { - expr_ty first = asdl_seq_GET(a, 0); - expr_ty last = asdl_seq_GET(a, args_len - 1); - return _Py_Call(_PyPegen_dummy_name(p), a, NULL, EXTRA_EXPR(first, last)); + return _Py_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset, + end_lineno, end_col_offset, arena); } @@ -2237,7 +2238,7 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) { total_len += asdl_seq_LEN(starreds); } - asdl_seq *args = _Py_asdl_seq_new(total_len, p->arena); + asdl_seq *args = _Py_asdl_seq_new(total_len, arena); Py_ssize_t i = 0; for (i = 0; i < args_len; i++) { @@ -2247,8 +2248,8 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b) { asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len)); } - expr_ty first = asdl_seq_GET(args, 0); - expr_ty last = asdl_seq_GET(b, asdl_seq_LEN(b)-1); + return _Py_Call(_PyPegen_dummy_name(p), args, keywords, lineno, + col_offset, end_lineno, end_col_offset, arena); + - return _Py_Call(_PyPegen_dummy_name(p), args, keywords, EXTRA_EXPR(first, last)); } diff --git a/Parser/pegen.h b/Parser/pegen.h index 3e74e3ac73e0a3e..c81681efad20807 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -257,7 +257,9 @@ stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty); KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int); asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); -expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *); +expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *, + int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *); asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *); int _PyPegen_check_barry_as_flufl(Parser *); From 8aded84080a40b7ed2d7ce17dc74526a532cf0b6 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 3 Sep 2020 15:29:55 +0100 Subject: [PATCH 239/486] Fix 'gather' rules in the python parser generator (GH-22021) Currently, empty sequences in gather rules make the conditional for gather rules fail as empty sequences evaluate as "False". We need to explicitly check for "None" (the failure condition) to avoid false negatives. --- Lib/test/test_peg_generator/test_pegen.py | 16 +++++++++++++++- Tools/peg_generator/pegen/python_generator.py | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_peg_generator/test_pegen.py b/Lib/test/test_peg_generator/test_pegen.py index 5b4e964d698adec..bcfee3f2c5f8c31 100644 --- a/Lib/test/test_peg_generator/test_pegen.py +++ b/Lib/test/test_peg_generator/test_pegen.py @@ -74,7 +74,7 @@ def test_typed_rules(self) -> None: "Rule('term', 'int', Rhs([Alt([NamedItem(None, NameLeaf('NUMBER'))])]))" ) - def test_repeat_with_separator_rules(self) -> None: + def test_gather(self) -> None: grammar = """ start: ','.thing+ NEWLINE thing: NUMBER @@ -85,6 +85,20 @@ def test_repeat_with_separator_rules(self) -> None: "Rule('start', None, Rhs([Alt([NamedItem(None, Gather(StringLeaf(\"','\"), NameLeaf('thing'" )) self.assertEqual(str(rules["thing"]), "thing: NUMBER") + parser_class = make_parser(grammar) + node = parse_string("42\n", parser_class) + assert node == [ + [[TokenInfo(NUMBER, string="42", start=(1, 0), end=(1, 2), line="42\n")]], + TokenInfo(NEWLINE, string="\n", start=(1, 2), end=(1, 3), line="42\n"), + ] + node = parse_string("1, 2\n", parser_class) + assert node == [ + [ + [TokenInfo(NUMBER, string="1", start=(1, 0), end=(1, 1), line="1, 2\n")], + [TokenInfo(NUMBER, string="2", start=(1, 3), end=(1, 4), line="1, 2\n")], + ], + TokenInfo(NEWLINE, string="\n", start=(1, 4), end=(1, 5), line="1, 2\n"), + ] def test_expr_grammar(self) -> None: grammar = """ diff --git a/Tools/peg_generator/pegen/python_generator.py b/Tools/peg_generator/pegen/python_generator.py index 45a75975dbf5e08..b786de7fee5b43c 100644 --- a/Tools/peg_generator/pegen/python_generator.py +++ b/Tools/peg_generator/pegen/python_generator.py @@ -217,6 +217,9 @@ def visit_Alt(self, node: Alt, is_loop: bool, is_gather: bool) -> None: else: self.print("and") self.visit(item) + if is_gather: + self.print("is not None") + self.print("):") with self.indent(): action = node.action From 085e838a4f12ae7a56aea50ba1b746c9dd1b947e Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Thu, 3 Sep 2020 19:44:12 +0100 Subject: [PATCH 240/486] [doc] Update documentation on logging optimization. (GH-22075) --- Doc/howto/logging.rst | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index 6316e086ef43ba2..b4dd9206c9d5245 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -1078,20 +1078,22 @@ need more precise control over what logging information is collected. Here's a list of things you can do to avoid processing during logging which you don't need: -+-----------------------------------------------+----------------------------------------+ -| What you don't want to collect | How to avoid collecting it | -+===============================================+========================================+ -| Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. | -| | This avoids calling | -| | :func:`sys._getframe`, which may help | -| | to speed up your code in environments | -| | like PyPy (which can't speed up code | -| | that uses :func:`sys._getframe`). | -+-----------------------------------------------+----------------------------------------+ -| Threading information. | Set ``logging.logThreads`` to ``0``. | -+-----------------------------------------------+----------------------------------------+ -| Process information. | Set ``logging.logProcesses`` to ``0``. | -+-----------------------------------------------+----------------------------------------+ ++-----------------------------------------------------+---------------------------------------------------+ +| What you don't want to collect | How to avoid collecting it | ++=====================================================+===================================================+ +| Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. | +| | This avoids calling :func:`sys._getframe`, which | +| | may help to speed up your code in environments | +| | like PyPy (which can't speed up code that uses | +| | :func:`sys._getframe`). | ++-----------------------------------------------------+---------------------------------------------------+ +| Threading information. | Set ``logging.logThreads`` to ``False``. | ++-----------------------------------------------------+---------------------------------------------------+ +| Current process ID (:func:`os.getpid`) | Set ``logging.logProcesses`` to ``False``. | ++-----------------------------------------------------+---------------------------------------------------+ +| Current process name when using ``multiprocessing`` | Set ``logging.logMultiprocessing`` to ``False``. | +| to manage multiple processes. | | ++-----------------------------------------------------+---------------------------------------------------+ Also note that the core logging module only includes the basic handlers. If you don't import :mod:`logging.handlers` and :mod:`logging.config`, they won't From 13d3a0ff5131848a7de1ba8b78dec7a9b1d49f40 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 4 Sep 2020 08:47:40 +0000 Subject: [PATCH 241/486] bpo-41700: Skip test if the locale is not supported (GH-22081) --- Lib/test/test_c_locale_coercion.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 8340a9eb2ea3a36..fcc85992345dbc8 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -407,7 +407,10 @@ def test_PYTHONCOERCECLOCALE_set_to_one(self): # skip the test if the LC_CTYPE locale is C or coerced old_loc = locale.setlocale(locale.LC_CTYPE, None) self.addCleanup(locale.setlocale, locale.LC_CTYPE, old_loc) - loc = locale.setlocale(locale.LC_CTYPE, "") + try: + loc = locale.setlocale(locale.LC_CTYPE, "") + except locale.Error as e: + self.skipTest(str(e)) if loc == "C": self.skipTest("test requires LC_CTYPE locale different than C") if loc in TARGET_LOCALES : From 6a2f0f04ea3f07e49a9ef42cb02fbb9b23463123 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 4 Sep 2020 14:51:05 +0200 Subject: [PATCH 242/486] bpo-41713: _signal doesn't use multi-phase init (GH-22087) Partially revert commit 71d1bd9569c8a497e279f2fea6fe47cd70a87ea3: don't use multi-phase initialization (PEP 489) for the _signal extension module. --- ...2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst | 1 - Modules/signalmodule.c | 20 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst deleted file mode 100644 index ff7cb352869a22f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst +++ /dev/null @@ -1 +0,0 @@ -Port the :mod:`_signal` extension module to multi-phase initialization (:pep:`489`). diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 262f2b66a57e299..3440894b2159d57 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1649,26 +1649,32 @@ signal_exec(PyObject *m) return 0; } -static PyModuleDef_Slot signal_slots[] = { - {Py_mod_exec, signal_exec}, - {0, NULL} -}; static struct PyModuleDef signalmodule = { PyModuleDef_HEAD_INIT, "_signal", .m_doc = module_doc, - .m_size = 0, + .m_size = -1, .m_methods = signal_methods, - .m_slots = signal_slots }; + PyMODINIT_FUNC PyInit__signal(void) { - return PyModuleDef_Init(&signalmodule); + PyObject *mod = PyModule_Create(&signalmodule); + if (mod == NULL) { + return NULL; + } + + if (signal_exec(mod) < 0) { + Py_DECREF(mod); + return NULL; + } + return mod; } + static void finisignal(void) { From 07a15d6464900a918a493b96a987d0996e1ac3f0 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 4 Sep 2020 20:55:41 +0300 Subject: [PATCH 243/486] bpo-41638: Improve ProgrammingError message for absent parameter. (GH-21999) It contains now the name of the parameter instead of its index when parameters are supplied as a dict. --- .../next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst | 3 +++ Modules/_sqlite/statement.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst diff --git a/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst b/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst new file mode 100644 index 000000000000000..8ab7b5e9903dcbf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst @@ -0,0 +1,3 @@ +:exc:`~sqlite3.ProgrammingError` message for absent parameter in :mod:`sqlite3` +contains now the name of the parameter instead of its index when parameters +are supplied as a dict. diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 9de8f9b67228f5c..26599b423eb8b91 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -295,7 +295,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para Py_DECREF(binding_name_obj); if (!current_param) { if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { - PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); + PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding parameter :%s.", binding_name); } return; } From 22ad153cfb6847bf61b1bbc169f9a3389e9f8029 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 4 Sep 2020 21:19:30 +0300 Subject: [PATCH 244/486] bpo-40486: Specify what happens if directory content change diring iteration (GH-22025) --- Doc/library/glob.rst | 4 +++- Doc/library/os.rst | 11 +++++++++-- Doc/library/pathlib.rst | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 280e9f082660249..3fdba6937c1de0f 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -43,7 +43,9 @@ For example, ``'[?]'`` matches the character ``'?'``. (like :file:`/usr/src/Python-1.5/Makefile`) or relative (like :file:`../../Tools/\*/\*.gif`), and can contain shell-style wildcards. Broken symlinks are included in the results (as in the shell). Whether or not the - results are sorted depends on the file system. + results are sorted depends on the file system. If a file that satisfies + conditions is removed or added during the call of this function, whether + a path name for that file be included is unspecified. If *root_dir* is not ``None``, it should be a :term:`path-like object` specifying the root directory for searching. It has the same effect on diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 275b2d390e7cf54..8c3bc5fb87d61b9 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1852,6 +1852,8 @@ features: Return a list containing the names of the entries in the directory given by *path*. The list is in arbitrary order, and does not include the special entries ``'.'`` and ``'..'`` even if they are present in the directory. + If a file is removed from or added to the directory during the call of + this function, whether a name for that file be included is unspecified. *path* may be a :term:`path-like object`. If *path* is of type ``bytes`` (directly or indirectly through the :class:`PathLike` interface), @@ -2257,7 +2259,9 @@ features: Return an iterator of :class:`os.DirEntry` objects corresponding to the entries in the directory given by *path*. The entries are yielded in arbitrary order, and the special entries ``'.'`` and ``'..'`` are not - included. + included. If a file is removed from or added to the directory after + creating the iterator, whether an entry for that file be included is + unspecified. Using :func:`scandir` instead of :func:`listdir` can significantly increase the performance of code that also needs file type or file @@ -3007,7 +3011,10 @@ features: *filenames* is a list of the names of the non-directory files in *dirpath*. Note that the names in the lists contain no path components. To get a full path (which begins with *top*) to a file or directory in *dirpath*, do - ``os.path.join(dirpath, name)``. + ``os.path.join(dirpath, name)``. Whether or not the lists are sorted + depends on the file system. If a file is removed from or added to the + *dirpath* directory during generating the lists, whether a name for that + file be included is unspecified. If optional argument *topdown* is ``True`` or not specified, the triple for a directory is generated before the triples for any of its subdirectories diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 04810f5204397be..23486b625072f36 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -890,6 +890,11 @@ call fails (for example because the path doesn't exist). PosixPath('docs/_static') PosixPath('docs/Makefile') + The children are yielded in arbitrary order, and the special entries + ``'.'`` and ``'..'`` are not included. If a file is removed from or added + to the directory after creating the iterator, whether an path object for + that file be included is unspecified. + .. method:: Path.lchmod(mode) Like :meth:`Path.chmod` but, if the path points to a symbolic link, the From f7095172353467d3ab635426808cb1ca8a2cda9a Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 4 Sep 2020 22:33:17 +0200 Subject: [PATCH 245/486] bpo-41721: Add xlc options (GH-22096) --- configure | 5 ++++- configure.ac | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 4c18ae7e364ca1a..ad74754e9a72154 100755 --- a/configure +++ b/configure @@ -7592,11 +7592,14 @@ $as_echo "$MACOSX_DEPLOYMENT_TARGET" >&6; } ;; esac -# ICC needs -fp-model strict or floats behave badly case "$CC" in *icc*) + # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" ;; +*xlc*) + CFLAGS_NODIST="$CFLAGS_NODIST -qalias=noansi -qmaxmem=-1" + ;; esac if test "$assertions" = 'true'; then diff --git a/configure.ac b/configure.ac index 3b40f39124dad50..f0bc8c625844b6b 100644 --- a/configure.ac +++ b/configure.ac @@ -1993,11 +1993,14 @@ yes) ;; esac -# ICC needs -fp-model strict or floats behave badly case "$CC" in *icc*) + # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" ;; +*xlc*) + CFLAGS_NODIST="$CFLAGS_NODIST -qalias=noansi -qmaxmem=-1" + ;; esac if test "$assertions" = 'true'; then From 92d2702923a6c5d0c106324277a02069dba3c909 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 4 Sep 2020 14:57:48 -0600 Subject: [PATCH 246/486] bpo-38585: Remove references to defusedexpat (GH-22095) defusedexpat is not maintained. --- Doc/library/xml.rst | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index fb86b6f5564d767..1981cab7cd438d7 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -20,7 +20,7 @@ Python's interfaces for processing XML are grouped in the ``xml`` package. The XML modules are not secure against erroneous or maliciously constructed data. If you need to parse untrusted or unauthenticated data see the :ref:`xml-vulnerabilities` and - :ref:`defused-packages` sections. + :ref:`defusedxml-package` sections. It is important to note that modules in the :mod:`xml` package require that there be at least one SAX-compliant XML parser available. The Expat parser is @@ -113,9 +113,9 @@ decompression bomb The documentation for `defusedxml`_ on PyPI has further information about all known attack vectors with examples and references. -.. _defused-packages: +.. _defusedxml-package: -The :mod:`defusedxml` and :mod:`defusedexpat` Packages +The :mod:`defusedxml` Package ------------------------------------------------------ `defusedxml`_ is a pure Python package with modified subclasses of all stdlib @@ -124,16 +124,8 @@ package is recommended for any server code that parses untrusted XML data. The package also ships with example exploits and extended documentation on more XML exploits such as XPath injection. -`defusedexpat`_ provides a modified libexpat and a patched -:mod:`pyexpat` module that have countermeasures against entity expansion -DoS attacks. The :mod:`defusedexpat` module still allows a sane and configurable amount of entity -expansions. The modifications may be included in some future release of Python, -but will not be included in any bugfix releases of -Python because they break backward compatibility. - .. _defusedxml: https://pypi.org/project/defusedxml/ -.. _defusedexpat: https://pypi.org/project/defusedexpat/ .. _Billion Laughs: https://en.wikipedia.org/wiki/Billion_laughs .. _ZIP bomb: https://en.wikipedia.org/wiki/Zip_bomb .. _DTD: https://en.wikipedia.org/wiki/Document_type_definition From 5e28015237260f6d61db5bc53ef4f1134813069b Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Sat, 5 Sep 2020 00:45:54 +0100 Subject: [PATCH 247/486] bpo-41627: Distinguish 32 and 64-bit user site packages on Windows (GH-22098) Also fixes the error message returned when sysconfig fails to interpolate a variable correctly. --- Lib/site.py | 3 ++- Lib/sysconfig.py | 22 +++++++++++-------- .../2020-09-04-21-35-28.bpo-41627.sx2KN1.rst | 2 ++ 3 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst diff --git a/Lib/site.py b/Lib/site.py index 8979365cafc37e7..4c095774729c5e6 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -274,7 +274,8 @@ def _get_path(userbase): version = sys.version_info if os.name == 'nt': - return f'{userbase}\\Python{version[0]}{version[1]}\\site-packages' + ver_nodot = sys.winver.replace('.', '') + return f'{userbase}\\Python{ver_nodot}\\site-packages' if sys.platform == 'darwin' and sys._framework: return f'{userbase}/lib/python/site-packages' diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index bf04ac541e6b027..6c87b06634c4579 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -53,12 +53,12 @@ }, # NOTE: When modifying "purelib" scheme, update site._get_path() too. 'nt_user': { - 'stdlib': '{userbase}/Python{py_version_nodot}', - 'platstdlib': '{userbase}/Python{py_version_nodot}', - 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', - 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', - 'include': '{userbase}/Python{py_version_nodot}/Include', - 'scripts': '{userbase}/Python{py_version_nodot}/Scripts', + 'stdlib': '{userbase}/Python{py_version_nodot_plat}', + 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', + 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'include': '{userbase}/Python{py_version_nodot_plat}/Include', + 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', 'data': '{userbase}', }, 'posix_user': { @@ -149,10 +149,10 @@ def is_python_build(check_home=False): def _subst_vars(s, local_vars): try: return s.format(**local_vars) - except KeyError: + except KeyError as var: try: return s.format(**os.environ) - except KeyError as var: + except KeyError: raise AttributeError('{%s}' % var) from None def _extend_dict(target_dict, other_dict): @@ -431,6 +431,7 @@ def _init_non_posix(vars): vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + vars['TZPATH'] = '' # # public APIs @@ -543,10 +544,13 @@ def get_config_vars(*args): except AttributeError: # sys.abiflags may not be defined on all platforms. _CONFIG_VARS['abiflags'] = '' + try: + _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') + except AttributeError: + _CONFIG_VARS['py_version_nodot_plat'] = '' if os.name == 'nt': _init_non_posix(_CONFIG_VARS) - _CONFIG_VARS['TZPATH'] = '' if os.name == 'posix': _init_posix(_CONFIG_VARS) # For backward compatibility, see issue19555 diff --git a/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst b/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst new file mode 100644 index 000000000000000..043bd5e9341c3c7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst @@ -0,0 +1,2 @@ +The user site directory for 32-bit now includes a ``-32`` suffix to +distinguish it from the 64-bit interpreter's directory. From 4d317c74fd62ecb246a4de30e91a74e00a392ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= Date: Sat, 5 Sep 2020 21:10:01 +0200 Subject: [PATCH 248/486] bpo-41687: Fix sendfile implementation to work with Solaris (#22040) --- Lib/test/test_asyncio/test_sendfile.py | 6 ++++++ .../2020-09-01-15-57-51.bpo-41687.m1b1KA.rst | 1 + Modules/posixmodule.c | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst diff --git a/Lib/test/test_asyncio/test_sendfile.py b/Lib/test/test_asyncio/test_sendfile.py index a30d9b9b4d9a012..01c698653ec67e5 100644 --- a/Lib/test/test_asyncio/test_sendfile.py +++ b/Lib/test/test_asyncio/test_sendfile.py @@ -446,6 +446,12 @@ def test_sendfile_ssl_close_peer_after_receiving(self): self.assertEqual(srv_proto.data, self.DATA) self.assertEqual(self.file.tell(), len(self.DATA)) + # On Solaris, lowering SO_RCVBUF on a TCP connection after it has been + # established has no effect. Due to its age, this bug affects both Oracle + # Solaris as well as all other OpenSolaris forks (unless they fixed it + # themselves). + @unittest.skipIf(sys.platform.startswith('sunos'), + "Doesn't work on Solaris") def test_sendfile_close_peer_in_the_middle_of_receiving(self): srv_proto, cli_proto = self.prepare_sendfile(close_after=1024) with self.assertRaises(ConnectionError): diff --git a/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst b/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst new file mode 100644 index 000000000000000..284f500735701ef --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst @@ -0,0 +1 @@ +Fix implementation of sendfile to be compatible with Solaris. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a6a4b9f012f009a..00ba7580302bbab 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9518,6 +9518,25 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, if (!Py_off_t_converter(offobj, &offset)) return NULL; +#if defined(__sun) && defined(__SVR4) + // On Solaris, sendfile raises EINVAL rather than returning 0 + // when the offset is equal or bigger than the in_fd size. + int res; + struct stat st; + + do { + Py_BEGIN_ALLOW_THREADS + res = fstat(in_fd, &st); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) + return (!async_err) ? posix_error() : NULL; + + if (offset >= st.st_size) { + return Py_BuildValue("i", 0); + } +#endif + do { Py_BEGIN_ALLOW_THREADS ret = sendfile(out_fd, in_fd, &offset, count); From 48d490d249ea18d4ac80e036a292eb0ab4fed916 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Sat, 5 Sep 2020 22:43:31 +0200 Subject: [PATCH 249/486] bpo-40318: Migrate to SQLite3 trace v2 API (GH-19581) Ref. https://sqlite.org/c3ref/trace_v2.html Co-authored-by: Pablo Galindo --- .../2020-04-18-14-16-02.bpo-40318.K2UdRx.rst | 1 + Modules/_sqlite/connection.c | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst diff --git a/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst b/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst new file mode 100644 index 000000000000000..3d5fcfb74a0fe58 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst @@ -0,0 +1 @@ +Use SQLite3 trace v2 API, if it is available. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 958be7d869794af..1bf9710763a5aba 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -43,6 +43,10 @@ #define HAVE_BACKUP_API #endif +#if SQLITE_VERSION_NUMBER >= 3014000 +#define HAVE_TRACE_V2 +#endif + _Py_IDENTIFIER(cursor); static const char * const begin_statements[] = { @@ -962,13 +966,29 @@ static int _progress_handler(void* user_arg) return rc; } +#ifdef HAVE_TRACE_V2 +/* + * From https://sqlite.org/c3ref/trace_v2.html: + * The integer return value from the callback is currently ignored, though this + * may change in future releases. Callback implementations should return zero + * to ensure future compatibility. + */ +static int _trace_callback(unsigned int type, void* user_arg, void* prepared_statement, void* statement_string) +#else static void _trace_callback(void* user_arg, const char* statement_string) +#endif { PyObject *py_statement = NULL; PyObject *ret = NULL; PyGILState_STATE gilstate; +#ifdef HAVE_TRACE_V2 + if (type != SQLITE_TRACE_STMT) { + return 0; + } +#endif + gilstate = PyGILState_Ensure(); py_statement = PyUnicode_DecodeUTF8(statement_string, strlen(statement_string), "replace"); @@ -988,6 +1008,9 @@ static void _trace_callback(void* user_arg, const char* statement_string) } PyGILState_Release(gilstate); +#ifdef HAVE_TRACE_V2 + return 0; +#endif } static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) @@ -1046,6 +1069,11 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s Py_RETURN_NONE; } +/* + * Ref. + * - https://sqlite.org/c3ref/c_trace.html + * - https://sqlite.org/c3ref/trace_v2.html + */ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* trace_callback; @@ -1063,10 +1091,18 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel if (trace_callback == Py_None) { /* None clears the trace callback previously set */ +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0); +#else sqlite3_trace(self->db, 0, (void*)0); +#endif Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, _trace_callback, trace_callback); +#else sqlite3_trace(self->db, _trace_callback, trace_callback); +#endif Py_INCREF(trace_callback); Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } From ec713f8882b7b47d58b8eb79046b138c02eae4dd Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 5 Sep 2020 16:53:47 -0400 Subject: [PATCH 250/486] Fix documented Python version for venv --upgrade-deps (GH-22113) Fixes incorrect Python version added for `venv` `--upgrade-deps` in #13100. This feature was added in Python 3.9 not 3.8. Relates to: - - https://github.com/python/cpython/commit/1cba1c9abadf76f458ecf883a48515aa3b534dbd Automerge-Triggered-By: @vsajip --- Doc/using/venv-create.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 8f850a74d413ce2..ddb36f94667d9f5 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -67,7 +67,7 @@ The command, if run with ``-h``, will show the available options:: Once an environment has been created, you may wish to activate it, e.g. by sourcing an activate script in its bin directory. -.. versionchanged:: 3.8 +.. versionchanged:: 3.9 Add ``--upgrade-deps`` option to upgrade pip + setuptools to the latest on PyPI .. versionchanged:: 3.4 From 2389c4cc71874fccca05cae4cd910e459dfef03a Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sat, 5 Sep 2020 20:40:25 -0300 Subject: [PATCH 251/486] [doc] Fix padding in some typing definitions (GH-22114) Automerge-Triggered-By: @gvanrossum --- Doc/library/typing.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 9f98f8ce3f642dc..6d6b76c1d089560 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1195,7 +1195,7 @@ Corresponding to collections in :mod:`collections.abc` .. class:: AbstractSet(Sized, Collection[T_co]) - A generic version of :class:`collections.abc.Set`. + A generic version of :class:`collections.abc.Set`. .. deprecated:: 3.9 :class:`collections.abc.Set` now supports ``[]``. See :pep:`585`. @@ -1224,7 +1224,7 @@ Corresponding to collections in :mod:`collections.abc` .. class:: Container(Generic[T_co]) - A generic version of :class:`collections.abc.Container`. + A generic version of :class:`collections.abc.Container`. .. deprecated:: 3.9 :class:`collections.abc.Container` now supports ``[]``. See :pep:`585`. @@ -1245,11 +1245,11 @@ Corresponding to collections in :mod:`collections.abc` .. class:: Mapping(Sized, Collection[KT], Generic[VT_co]) - A generic version of :class:`collections.abc.Mapping`. - This type can be used as follows:: + A generic version of :class:`collections.abc.Mapping`. + This type can be used as follows:: - def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: - return word_list[word] + def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: + return word_list[word] .. deprecated:: 3.9 :class:`collections.abc.Mapping` now supports ``[]``. See :pep:`585`. @@ -1263,7 +1263,7 @@ Corresponding to collections in :mod:`collections.abc` .. class:: MutableMapping(Mapping[KT, VT]) - A generic version of :class:`collections.abc.MutableMapping`. + A generic version of :class:`collections.abc.MutableMapping`. .. deprecated:: 3.9 :class:`collections.abc.MutableMapping` now supports ``[]``. See :pep:`585`. @@ -1277,14 +1277,14 @@ Corresponding to collections in :mod:`collections.abc` .. class:: MutableSet(AbstractSet[T]) - A generic version of :class:`collections.abc.MutableSet`. + A generic version of :class:`collections.abc.MutableSet`. .. deprecated:: 3.9 :class:`collections.abc.MutableSet` now supports ``[]``. See :pep:`585`. .. class:: Sequence(Reversible[T_co], Collection[T_co]) - A generic version of :class:`collections.abc.Sequence`. + A generic version of :class:`collections.abc.Sequence`. .. deprecated:: 3.9 :class:`collections.abc.Sequence` now supports ``[]``. See :pep:`585`. @@ -1301,14 +1301,14 @@ Corresponding to other types in :mod:`collections.abc` .. class:: Iterable(Generic[T_co]) - A generic version of :class:`collections.abc.Iterable`. + A generic version of :class:`collections.abc.Iterable`. .. deprecated:: 3.9 :class:`collections.abc.Iterable` now supports ``[]``. See :pep:`585`. .. class:: Iterator(Iterable[T_co]) - A generic version of :class:`collections.abc.Iterator`. + A generic version of :class:`collections.abc.Iterator`. .. deprecated:: 3.9 :class:`collections.abc.Iterator` now supports ``[]``. See :pep:`585`. @@ -1353,7 +1353,7 @@ Corresponding to other types in :mod:`collections.abc` .. class:: Reversible(Iterable[T_co]) - A generic version of :class:`collections.abc.Reversible`. + A generic version of :class:`collections.abc.Reversible`. .. deprecated:: 3.9 :class:`collections.abc.Reversible` now supports ``[]``. See :pep:`585`. From a204785596611a4f9613f548398e680e4106c7f7 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sat, 5 Sep 2020 21:39:23 -0600 Subject: [PATCH 252/486] closes bpo-41723: Fix an error in the py_compile documentation. (GH-22110) --- Doc/library/py_compile.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 9b5c8ee645a3864..4fba4cba4d3568e 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -35,7 +35,7 @@ byte-code cache files in the directory containing the source code. in ``.pyc``. For example, if *file* is ``/foo/bar/baz.py`` *cfile* will default to ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. If *dfile* is - specified, it is used as the name of the source file in error messages when + specified, it is used as the name of the source file in error messages instead of *file*. If *doraise* is true, a :exc:`PyCompileError` is raised when an error is encountered while compiling *file*. If *doraise* is false (the default), an error string is written to ``sys.stderr``, but no exception From 56445365a5870c66b66c1a92d238170b21dc20ca Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Sun, 6 Sep 2020 05:09:51 -0500 Subject: [PATCH 253/486] bpo-1635741: Port _sha1, _sha512, _md5 to multiphase init (GH-21818) Port the _sha1, _sha512, and _md5 extension modules to multi-phase initialization API (PEP 489). --- ...2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst | 2 + Modules/clinic/md5module.c.h | 21 +- Modules/clinic/sha1module.c.h | 21 +- Modules/clinic/sha512module.c.h | 21 +- Modules/md5module.c | 154 +++++++----- Modules/sha1module.c | 156 +++++++----- Modules/sha512module.c | 235 ++++++++++-------- 7 files changed, 359 insertions(+), 251 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst new file mode 100644 index 000000000000000..12af3d01ed8eff4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst @@ -0,0 +1,2 @@ +Port the :mod:`_sha1`, :mod:`_sha512`, and :mod:`_md5` extension modules +to multi-phase initialization API (:pep:`489`). diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index c109f9efec6b604..4762f2800d4b829 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(MD5Type_copy__doc__, "Return a copy of the hash object."); #define MD5TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))MD5Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, MD5Type_copy__doc__}, static PyObject * -MD5Type_copy_impl(MD5object *self); +MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); static PyObject * -MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored)) +MD5Type_copy(MD5object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return MD5Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = MD5Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(MD5Type_digest__doc__, @@ -115,4 +126,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=dbe3abc60086f3ef input=a9049054013a1b77]*/ +/*[clinic end generated code: output=53ff7f22dbaaea36 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index fc37b1ab880ffa0..3a3ab58c1233cf4 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA1Type_copy__doc__, "Return a copy of the hash object."); #define SHA1TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA1Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA1Type_copy__doc__}, static PyObject * -SHA1Type_copy_impl(SHA1object *self); +SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); static PyObject * -SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored)) +SHA1Type_copy(SHA1object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA1Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA1Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA1Type_digest__doc__, @@ -115,4 +126,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=3ddd637ae17e14b3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=abf1ab2545cea5a2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index b8185b62bb66961..f1192d74f9a1ab1 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA512Type_copy__doc__, "Return a copy of the hash object."); #define SHA512TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA512Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, static PyObject * -SHA512Type_copy_impl(SHAobject *self); +SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * -SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +SHA512Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA512Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA512Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA512Type_digest__doc__, @@ -166,4 +177,4 @@ _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=bbfa72d8703c82b5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9ff9f11937fabf35 input=a9049054013a1b77]*/ diff --git a/Modules/md5module.c b/Modules/md5module.c index e4d9db40f22df36..5cd4e9451013219 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -318,22 +318,32 @@ md5_done(struct md5_state *md5, unsigned char *out) * ------------------------------------------------------------------------ */ -static PyTypeObject MD5type; +typedef struct { + PyTypeObject* md5_type; +} MD5State; +static inline MD5State* +md5_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (MD5State *)state; +} static MD5object * -newMD5object(void) +newMD5object(MD5State * st) { - return (MD5object *)PyObject_New(MD5object, &MD5type); + return (MD5object *)PyObject_New(MD5object, st->md5_type); } - /* Internal methods for a hash object */ static void MD5_dealloc(PyObject *ptr) { + PyTypeObject *tp = Py_TYPE(ptr); PyObject_Del(ptr); + Py_DECREF(tp); } @@ -342,16 +352,19 @@ MD5_dealloc(PyObject *ptr) /*[clinic input] MD5Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -MD5Type_copy_impl(MD5object *self) -/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/ +MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) +/*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ { - MD5object *newobj; + MD5State *st = PyType_GetModuleState(cls); - if ((newobj = newMD5object())==NULL) + MD5object *newobj; + if ((newobj = newMD5object(st))==NULL) return NULL; newobj->hash_state = self->hash_state; @@ -445,7 +458,6 @@ md5_get_digest_size(PyObject *self, void *closure) return PyLong_FromLong(MD5_DIGESTSIZE); } - static PyGetSetDef MD5_getseters[] = { {"block_size", (getter)MD5_get_block_size, NULL, @@ -462,40 +474,19 @@ static PyGetSetDef MD5_getseters[] = { {NULL} /* Sentinel */ }; -static PyTypeObject MD5type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_md5.md5", /*tp_name*/ - sizeof(MD5object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - MD5_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - MD5_methods, /* tp_methods */ - NULL, /* tp_members */ - MD5_getseters, /* tp_getset */ +static PyType_Slot md5_type_slots[] = { + {Py_tp_dealloc, MD5_dealloc}, + {Py_tp_methods, MD5_methods}, + {Py_tp_getset, MD5_getseters}, + {0,0} }; +static PyType_Spec md5_type_spec = { + .name = "_md5.md5", + .basicsize = sizeof(MD5object), + .flags = Py_TPFLAGS_DEFAULT, + .slots = md5_type_slots +}; /* The single module-level function: new() */ @@ -519,7 +510,8 @@ _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newMD5object()) == NULL) { + MD5State *st = md5_get_state(module); + if ((new = newMD5object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -549,37 +541,69 @@ static struct PyMethodDef MD5_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_md5_traverse(PyObject *module, visitproc visit, void *arg) +{ + MD5State *state = md5_get_state(module); + Py_VISIT(state->md5_type); + return 0; +} + +static int +_md5_clear(PyObject *module) +{ + MD5State *state = md5_get_state(module); + Py_CLEAR(state->md5_type); + return 0; +} + +static void +_md5_free(void *module) +{ + _md5_clear((PyObject *)module); +} /* Initialize this module. */ +static int +md5_exec(PyObject *m) +{ + MD5State *st = md5_get_state(m); + + st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &md5_type_spec, NULL); + + if (st->md5_type == NULL) { + return -1; + } + + Py_INCREF((PyObject *)st->md5_type); + if (PyModule_AddObject(m, "MD5Type", (PyObject *)st->md5_type) < 0) { + Py_DECREF(st->md5_type); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _md5_slots[] = { + {Py_mod_exec, md5_exec}, + {0, NULL} +}; + static struct PyModuleDef _md5module = { PyModuleDef_HEAD_INIT, - "_md5", - NULL, - -1, - MD5_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_md5", + .m_size = sizeof(MD5State), + .m_methods = MD5_functions, + .m_slots = _md5_slots, + .m_traverse = _md5_traverse, + .m_clear = _md5_clear, + .m_free = _md5_free, }; PyMODINIT_FUNC PyInit__md5(void) { - PyObject *m; - - Py_SET_TYPE(&MD5type, &PyType_Type); - if (PyType_Ready(&MD5type) < 0) { - return NULL; - } - - m = PyModule_Create(&_md5module); - if (m == NULL) { - return NULL; - } - - Py_INCREF((PyObject *)&MD5type); - PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); - return m; + return PyModuleDef_Init(&_md5module); } diff --git a/Modules/sha1module.c b/Modules/sha1module.c index b0656d83b3ae8bd..c22437de256b660 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -295,13 +295,22 @@ sha1_done(struct sha1_state *sha1, unsigned char *out) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA1type; +typedef struct { + PyTypeObject* sha1_type; +} SHA1State; +static inline SHA1State* +sha1_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA1State *)state; +} static SHA1object * -newSHA1object(void) +newSHA1object(SHA1State *st) { - return (SHA1object *)PyObject_New(SHA1object, &SHA1type); + return (SHA1object *)PyObject_New(SHA1object, st->sha1_type); } @@ -310,7 +319,9 @@ newSHA1object(void) static void SHA1_dealloc(PyObject *ptr) { + PyTypeObject *tp = Py_TYPE(ptr); PyObject_Del(ptr); + Py_DECREF(tp); } @@ -319,16 +330,19 @@ SHA1_dealloc(PyObject *ptr) /*[clinic input] SHA1Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -SHA1Type_copy_impl(SHA1object *self) -/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ +SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls) +/*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/ { - SHA1object *newobj; + SHA1State *st = PyType_GetModuleState(cls); - if ((newobj = newSHA1object()) == NULL) + SHA1object *newobj; + if ((newobj = newSHA1object(st)) == NULL) return NULL; newobj->hash_state = self->hash_state; @@ -422,7 +436,6 @@ sha1_get_digest_size(PyObject *self, void *closure) return PyLong_FromLong(SHA1_DIGESTSIZE); } - static PyGetSetDef SHA1_getseters[] = { {"block_size", (getter)SHA1_get_block_size, NULL, @@ -439,40 +452,19 @@ static PyGetSetDef SHA1_getseters[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA1type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha1.sha1", /*tp_name*/ - sizeof(SHA1object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA1_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA1_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA1_getseters, /* tp_getset */ +static PyType_Slot sha1_type_slots[] = { + {Py_tp_dealloc, SHA1_dealloc}, + {Py_tp_methods, SHA1_methods}, + {Py_tp_getset, SHA1_getseters}, + {0,0} }; +static PyType_Spec sha1_type_spec = { + .name = "_sha1.sha1", + .basicsize = sizeof(SHA1object), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha1_type_slots +}; /* The single module-level function: new() */ @@ -496,7 +488,8 @@ _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA1object()) == NULL) { + SHA1State *st = sha1_get_state(module); + if ((new = newSHA1object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -526,37 +519,72 @@ static struct PyMethodDef SHA1_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_sha1_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA1State *state = sha1_get_state(module); + Py_VISIT(state->sha1_type); + return 0; +} + +static int +_sha1_clear(PyObject *module) +{ + SHA1State *state = sha1_get_state(module); + Py_CLEAR(state->sha1_type); + return 0; +} + +static void +_sha1_free(void *module) +{ + _sha1_clear((PyObject *)module); +} + +static int +_sha1_exec(PyObject *module) +{ + SHA1State* st = sha1_get_state(module); + + st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha1_type_spec, NULL); + + if (st->sha1_type == NULL) { + return -1; + } + + Py_INCREF(st->sha1_type); + if (PyModule_AddObject(module, + "SHA1Type", + (PyObject *)st->sha1_type) < 0) { + Py_DECREF(st->sha1_type); + return -1; + } + + return 0; +} + /* Initialize this module. */ +static PyModuleDef_Slot _sha1_slots[] = { + {Py_mod_exec, _sha1_exec}, + {0, NULL} +}; + static struct PyModuleDef _sha1module = { PyModuleDef_HEAD_INIT, - "_sha1", - NULL, - -1, - SHA1_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_sha1", + .m_size = sizeof(SHA1State), + .m_methods = SHA1_functions, + .m_slots = _sha1_slots, + .m_traverse = _sha1_traverse, + .m_clear = _sha1_clear, + .m_free = _sha1_free }; PyMODINIT_FUNC PyInit__sha1(void) { - PyObject *m; - - Py_SET_TYPE(&SHA1type, &PyType_Type); - if (PyType_Ready(&SHA1type) < 0) { - return NULL; - } - - m = PyModule_Create(&_sha1module); - if (m == NULL) { - return NULL; - } - - Py_INCREF((PyObject *)&SHA1type); - PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); - return m; + return PyModuleDef_Init(&_sha1module); } diff --git a/Modules/sha512module.c b/Modules/sha512module.c index aa2aeedcc6c6499..725098def4d0623 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -422,20 +422,29 @@ sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA384type; -static PyTypeObject SHA512type; +typedef struct { + PyTypeObject* sha384_type; + PyTypeObject* sha512_type; +} SHA512State; +static inline SHA512State* +sha512_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA512State *)state; +} static SHAobject * -newSHA384object(void) +newSHA384object(SHA512State *st) { - return (SHAobject *)PyObject_New(SHAobject, &SHA384type); + return (SHAobject *)PyObject_New(SHAobject, st->sha384_type); } static SHAobject * -newSHA512object(void) +newSHA512object(SHA512State *st) { - return (SHAobject *)PyObject_New(SHAobject, &SHA512type); + return (SHAobject *)PyObject_New(SHAobject, st->sha512_type); } /* Internal methods for a hash object */ @@ -443,7 +452,9 @@ newSHA512object(void) static void SHA512_dealloc(PyObject *ptr) { + PyTypeObject *tp = Py_TYPE(ptr); PyObject_Del(ptr); + Py_DECREF(tp); } @@ -452,21 +463,27 @@ SHA512_dealloc(PyObject *ptr) /*[clinic input] SHA512Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -SHA512Type_copy_impl(SHAobject *self) -/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/ +SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=85ea5b47837a08e6 input=f673a18f66527c90]*/ { SHAobject *newobj; + SHA512State *st = PyType_GetModuleState(cls); - if (Py_IS_TYPE((PyObject*)self, &SHA512type)) { - if ( (newobj = newSHA512object())==NULL) + if (Py_IS_TYPE((PyObject*)self, st->sha512_type)) { + if ( (newobj = newSHA512object(st))==NULL) { return NULL; - } else { - if ( (newobj = newSHA384object())==NULL) + } + } + else { + if ( (newobj = newSHA384object(st))==NULL) { return NULL; + } } SHAcopy(self, newobj); @@ -574,74 +591,37 @@ static PyMemberDef SHA_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA384type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha384", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +static PyType_Slot sha512_sha384_type_slots[] = { + {Py_tp_dealloc, SHA512_dealloc}, + {Py_tp_methods, SHA_methods}, + {Py_tp_members, SHA_members}, + {Py_tp_getset, SHA_getseters}, + {0,0} +}; + +static PyType_Spec sha512_sha384_type_spec = { + .name = "_sha512.sha384", + .basicsize = sizeof(SHAobject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha512_sha384_type_slots }; -static PyTypeObject SHA512type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha512", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +static PyType_Slot sha512_sha512_type_slots[] = { + {Py_tp_dealloc, SHA512_dealloc}, + {Py_tp_methods, SHA_methods}, + {Py_tp_members, SHA_members}, + {Py_tp_getset, SHA_getseters}, + {0,0} }; +// Using PyType_GetModuleState() on this type is safe since +// it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. +static PyType_Spec sha512_sha512_type_spec = { + .name = "_sha512.sha512", + .basicsize = sizeof(SHAobject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha512_sha512_type_slots +}; /* The single module-level function: new() */ @@ -662,10 +642,12 @@ _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) SHAobject *new; Py_buffer buf; + SHA512State *st = sha512_get_state(module); + if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA512object()) == NULL) { + if ((new = newSHA512object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -704,10 +686,12 @@ _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) SHAobject *new; Py_buffer buf; + SHA512State *st = sha512_get_state(module); + if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA384object()) == NULL) { + if ((new = newSHA384object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -738,43 +722,80 @@ static struct PyMethodDef SHA_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_sha512_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA512State *state = sha512_get_state(module); + Py_VISIT(state->sha384_type); + Py_VISIT(state->sha512_type); + return 0; +} -/* Initialize this module. */ +static int +_sha512_clear(PyObject *module) +{ + SHA512State *state = sha512_get_state(module); + Py_CLEAR(state->sha384_type); + Py_CLEAR(state->sha512_type); + return 0; +} -static struct PyModuleDef _sha512module = { - PyModuleDef_HEAD_INIT, - "_sha512", - NULL, - -1, - SHA_functions, - NULL, - NULL, - NULL, - NULL -}; +static void +_sha512_free(void *module) +{ + _sha512_clear((PyObject *)module); +} -PyMODINIT_FUNC -PyInit__sha512(void) + +/* Initialize this module. */ +static int +_sha512_exec(PyObject *m) { - PyObject *m; + SHA512State* st = sha512_get_state(m); - Py_SET_TYPE(&SHA384type, &PyType_Type); - if (PyType_Ready(&SHA384type) < 0) { - return NULL; + st->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &sha512_sha384_type_spec, NULL); + + st->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &sha512_sha512_type_spec, NULL); + + if (st->sha384_type == NULL || st->sha512_type == NULL) { + return -1; } - Py_SET_TYPE(&SHA512type, &PyType_Type); - if (PyType_Ready(&SHA512type) < 0) { - return NULL; + + Py_INCREF(st->sha384_type); + if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha384_type) < 0) { + Py_DECREF(st->sha384_type); + return -1; } - m = PyModule_Create(&_sha512module); - if (m == NULL) { - return NULL; + Py_INCREF(st->sha512_type); + if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha512_type) < 0) { + Py_DECREF(st->sha512_type); + return -1; } - Py_INCREF((PyObject *)&SHA384type); - PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); - Py_INCREF((PyObject *)&SHA512type); - PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); - return m; + return 0; +} + +static PyModuleDef_Slot _sha512_slots[] = { + {Py_mod_exec, _sha512_exec}, + {0, NULL} +}; + +static struct PyModuleDef _sha512module = { + PyModuleDef_HEAD_INIT, + .m_name = "_sha512", + .m_size = sizeof(SHA512State), + .m_methods = SHA_functions, + .m_slots = _sha512_slots, + .m_traverse = _sha512_traverse, + .m_clear = _sha512_clear, + .m_free = _sha512_free +}; + +PyMODINIT_FUNC +PyInit__sha512(void) +{ + return PyModuleDef_Init(&_sha512module); } From 92673838b049e1119b285dff63aef04d93275a95 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 6 Sep 2020 15:10:07 -0700 Subject: [PATCH 254/486] bpo-41513: Expand comments and add references for a better understanding (GH-22123) --- Modules/mathmodule.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index d227a5d15dca2a7..29137ae91a22ff5 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2419,9 +2419,9 @@ To avoid overflow/underflow and to achieve high accuracy giving results that are almost always correctly rounded, four techniques are used: * lossless scaling using a power-of-two scaling factor -* accurate squaring using Veltkamp-Dekker splitting -* compensated summation using a variant of the Neumaier algorithm -* differential correction of the square root +* accurate squaring using Veltkamp-Dekker splitting [1] +* compensated summation using a variant of the Neumaier algorithm [2] +* differential correction of the square root [3] The usual presentation of the Neumaier summation algorithm has an expensive branch depending on which operand has the larger @@ -2456,7 +2456,11 @@ Given that csum >= 1.0, we have: Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. To minimize loss of information during the accumulation of fractional -values, each term has a separate accumulator. +values, each term has a separate accumulator. This also breaks up +sequential dependencies in the inner loop so the CPU can maximize +floating point throughput. [5] On a 2.6 GHz Haswell, adding one +dimension has an incremental cost of only 5ns -- for example when +moving from hypot(x,y) to hypot(x,y,z). The square root differential correction is needed because a correctly rounded square root of a correctly rounded sum of @@ -2466,7 +2470,7 @@ The differential correction starts with a value *x* that is the difference between the square of *h*, the possibly inaccurately rounded square root, and the accurately computed sum of squares. The correction is the first order term of the Maclaurin series -expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). +expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). [4] Essentially, this differential correction is equivalent to one refinement step in Newton's divide-and-average square root @@ -2474,12 +2478,24 @@ algorithm, effectively doubling the number of accurate bits. This technique is used in Dekker's SQRT2 algorithm and again in Borges' ALGORITHM 4 and 5. +Without proof for all cases, hypot() cannot claim to be always +correctly rounded. However for n <= 1000, prior to the final addition +that rounds the overall result, the internal accuracy of "h" together +with its correction of "x / (2.0 * h)" is at least 100 bits. [6] +Also, hypot() was tested against a Decimal implementation with +prec=300. After 100 million trials, no incorrectly rounded examples +were found. In addition, perfect commutativity (all permutations are +exactly equal) was verified for 1 billion random inputs with n=5. [7] + References: 1. Veltkamp-Dekker splitting: http://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf 2. Compensated summation: http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf 3. Square root differential correction: https://arxiv.org/pdf/1904.09481.pdf 4. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 +5. https://bugs.python.org/file49439/hypot.png +6. https://bugs.python.org/file49435/best_frac.py +7. https://bugs.python.org/file49448/test_hypot_commutativity.py */ From 23b3576cb355d6fd011a60198b6c7524e2c5157c Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Mon, 7 Sep 2020 02:29:38 -0300 Subject: [PATCH 255/486] [doc] Add link to Generic in typing (GH-22125) --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 6d6b76c1d089560..3125ae97808a9e5 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -818,7 +818,7 @@ These are not used in annotations. They are building blocks for creating generic Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more + as for generic function definitions. See :class:`Generic` for more information on generic types. Generic functions work as follows:: def repeat(x: T, n: int) -> Sequence[T]: From 0be5f5fefdfcd23e94aa9a7638e6f21f934242aa Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 7 Sep 2020 03:27:55 -0500 Subject: [PATCH 256/486] bpo-1635741 port zlib module to multi-phase init (GH-21995) Port the zlib extension module to multi-phase initialization (PEP 489). --- ...2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst | 1 + Modules/clinic/zlibmodule.c.h | 236 ++++++----- Modules/zlibmodule.c | 378 ++++++++++-------- 3 files changed, 363 insertions(+), 252 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst new file mode 100644 index 000000000000000..4d6ce1185ed936c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst @@ -0,0 +1 @@ +Port the :mod:`zlib` extension module to multi-phase initialization (:pep:`489`). diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 61dfa9a87b5fb65..14e955db64e7290 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -329,25 +329,25 @@ PyDoc_STRVAR(zlib_Compress_compress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_COMPRESS_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_Compress_compress, METH_O, zlib_Compress_compress__doc__}, + {"compress", (PyCFunction)(void(*)(void))zlib_Compress_compress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_compress__doc__}, static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data); +zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data); static PyObject * -zlib_Compress_compress(compobject *self, PyObject *arg) +zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"y*:compress", _keywords, 0}; Py_buffer data = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &data)) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); - goto exit; - } - return_value = zlib_Compress_compress_impl(self, &data); + return_value = zlib_Compress_compress_impl(self, cls, &data); exit: /* Cleanup for data */ @@ -376,51 +376,26 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, + {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length); +zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data, Py_ssize_t max_length); static PyObject * -zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &data, &max_length)) { goto exit; } - if (!noptargs) { - goto skip_optional_pos; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - max_length = ival; - } -skip_optional_pos: - return_value = zlib_Decompress_decompress_impl(self, &data, max_length); + return_value = zlib_Decompress_decompress_impl(self, cls, &data, max_length); exit: /* Cleanup for data */ @@ -444,29 +419,24 @@ PyDoc_STRVAR(zlib_Compress_flush__doc__, " can still be compressed."); #define ZLIB_COMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_FASTCALL, zlib_Compress_flush__doc__}, + {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_flush__doc__}, static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode); +zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode); static PyObject * -zlib_Compress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"|i:flush", _keywords, 0}; int mode = Z_FINISH; - if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - mode = _PyLong_AsInt(args[0]); - if (mode == -1 && PyErr_Occurred()) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &mode)) { goto exit; } -skip_optional: - return_value = zlib_Compress_flush_impl(self, mode); + return_value = zlib_Compress_flush_impl(self, cls, mode); exit: return return_value; @@ -481,15 +451,26 @@ PyDoc_STRVAR(zlib_Compress_copy__doc__, "Return a copy of the compression object."); #define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))zlib_Compress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_copy__doc__}, static PyObject * -zlib_Compress_copy_impl(compobject *self); +zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Compress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Compress_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Compress_copy_impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -502,15 +483,26 @@ PyDoc_STRVAR(zlib_Compress___copy____doc__, "\n"); #define ZLIB_COMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)zlib_Compress___copy__, METH_NOARGS, zlib_Compress___copy____doc__}, + {"__copy__", (PyCFunction)(void(*)(void))zlib_Compress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___copy____doc__}, static PyObject * -zlib_Compress___copy___impl(compobject *self); +zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Compress___copy__(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Compress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Compress___copy___impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Compress___copy___impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -523,7 +515,29 @@ PyDoc_STRVAR(zlib_Compress___deepcopy____doc__, "\n"); #define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)zlib_Compress___deepcopy__, METH_O, zlib_Compress___deepcopy____doc__}, + {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Compress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___deepcopy____doc__}, + +static PyObject * +zlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo); + +static PyObject * +zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + PyObject *memo; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &memo)) { + goto exit; + } + return_value = zlib_Compress___deepcopy___impl(self, cls, memo); + +exit: + return return_value; +} #endif /* defined(HAVE_ZLIB_COPY) */ @@ -536,15 +550,26 @@ PyDoc_STRVAR(zlib_Decompress_copy__doc__, "Return a copy of the decompression object."); #define ZLIB_DECOMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))zlib_Decompress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_copy__doc__}, static PyObject * -zlib_Decompress_copy_impl(compobject *self); +zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Decompress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Decompress_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Decompress_copy_impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -557,15 +582,26 @@ PyDoc_STRVAR(zlib_Decompress___copy____doc__, "\n"); #define ZLIB_DECOMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)zlib_Decompress___copy__, METH_NOARGS, zlib_Decompress___copy____doc__}, + {"__copy__", (PyCFunction)(void(*)(void))zlib_Decompress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___copy____doc__}, static PyObject * -zlib_Decompress___copy___impl(compobject *self); +zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * -zlib_Decompress___copy__(compobject *self, PyObject *Py_UNUSED(ignored)) +zlib_Decompress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return zlib_Decompress___copy___impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = zlib_Decompress___copy___impl(self, cls); + +exit: + return return_value; } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -578,7 +614,29 @@ PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__, "\n"); #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)zlib_Decompress___deepcopy__, METH_O, zlib_Decompress___deepcopy____doc__}, + {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Decompress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___deepcopy____doc__}, + +static PyObject * +zlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo); + +static PyObject * +zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + PyObject *memo; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &memo)) { + goto exit; + } + return_value = zlib_Decompress___deepcopy___impl(self, cls, memo); + +exit: + return return_value; +} #endif /* defined(HAVE_ZLIB_COPY) */ @@ -592,37 +650,25 @@ PyDoc_STRVAR(zlib_Decompress_flush__doc__, " the initial size of the output buffer."); #define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_FASTCALL, zlib_Decompress_flush__doc__}, + {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_flush__doc__}, static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length); +zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, + Py_ssize_t length); static PyObject * -zlib_Decompress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"|n:flush", _keywords, 0}; Py_ssize_t length = DEF_BUF_SIZE; - if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &length)) { goto exit; } - if (nargs < 1) { - goto skip_optional; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[0]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - length = ival; - } -skip_optional: - return_value = zlib_Decompress_flush_impl(self, length); + return_value = zlib_Decompress_flush_impl(self, cls, length); exit: return return_value; @@ -757,4 +803,4 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=be34f273564e39a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6736bae59fab268b input=a9049054013a1b77]*/ diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index fd3064952869bf8..def617671f18fd1 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -37,18 +37,16 @@ typedef struct { PyTypeObject *Comptype; PyTypeObject *Decomptype; PyObject *ZlibError; -} _zlibstate; +} zlibstate; -static inline _zlibstate* +static inline zlibstate* get_zlib_state(PyObject *module) { void *state = PyModule_GetState(module); assert(state != NULL); - return (_zlibstate *)state; + return (zlibstate *)state; } -#define _zlibstate_global ((_zlibstate *)PyModule_GetState(PyState_FindModule(&zlibmodule))) - typedef struct { PyObject_HEAD @@ -62,7 +60,7 @@ typedef struct } compobject; static void -zlib_error(z_stream zst, int err, const char *msg) +zlib_error(zlibstate *state, z_stream zst, int err, const char *msg) { const char *zmsg = Z_NULL; /* In case of a version mismatch, zst.msg won't be initialized. @@ -85,9 +83,9 @@ zlib_error(z_stream zst, int err, const char *msg) } } if (zmsg == Z_NULL) - PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s", err, msg); + PyErr_Format(state->ZlibError, "Error %d %s", err, msg); else - PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); + PyErr_Format(state->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); } /*[clinic input] @@ -216,19 +214,20 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) /*[clinic end generated code: output=d80906d73f6294c8 input=638d54b6315dbed3]*/ { PyObject *RetVal = NULL; - Byte *ibuf; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; - int err, flush; + Py_ssize_t obuflen = DEF_BUF_SIZE; + int flush; z_stream zst; - ibuf = data->buf; - ibuflen = data->len; + zlibstate *state = get_zlib_state(module); + + Byte *ibuf = data->buf; + Py_ssize_t ibuflen = data->len; zst.opaque = NULL; zst.zalloc = PyZlib_Malloc; zst.zfree = PyZlib_Free; zst.next_in = ibuf; - err = deflateInit(&zst, level); + int err = deflateInit(&zst, level); switch (err) { case Z_OK: @@ -238,11 +237,11 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) "Out of memory while compressing data"); goto error; case Z_STREAM_ERROR: - PyErr_SetString(_zlibstate_global->ZlibError, "Bad compression level"); + PyErr_SetString(state->ZlibError, "Bad compression level"); goto error; default: deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); + zlib_error(state, zst, err, "while compressing data"); goto error; } @@ -263,7 +262,7 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) if (err == Z_STREAM_ERROR) { deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); + zlib_error(state, zst, err, "while compressing data"); goto error; } @@ -281,7 +280,7 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level) return RetVal; } else - zlib_error(zst, err, "while finishing compression"); + zlib_error(state, zst, err, "while finishing compression"); error: Py_XDECREF(RetVal); return NULL; @@ -312,6 +311,8 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, int err, flush; z_stream zst; + zlibstate *state = get_zlib_state(module); + if (bufsize < 0) { PyErr_SetString(PyExc_ValueError, "bufsize must be non-negative"); return NULL; @@ -338,7 +339,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; default: inflateEnd(&zst); - zlib_error(zst, err, "while preparing to decompress data"); + zlib_error(state, zst, err, "while preparing to decompress data"); goto error; } @@ -369,7 +370,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; default: inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); + zlib_error(state, zst, err, "while decompressing data"); goto error; } @@ -380,13 +381,13 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, if (err != Z_STREAM_END) { inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); + zlib_error(state, zst, err, "while decompressing data"); goto error; } err = inflateEnd(&zst); if (err != Z_OK) { - zlib_error(zst, err, "while finishing decompression"); + zlib_error(state, zst, err, "while finishing decompression"); goto error; } @@ -434,16 +435,14 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict) /*[clinic end generated code: output=8b5bed9c8fc3814d input=2fa3d026f90ab8d5]*/ { - compobject *self = NULL; - int err; - + zlibstate *state = get_zlib_state(module); if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "zdict length does not fit in an unsigned int"); - goto error; + return NULL; } - self = newcompobject(_zlibstate_global->Comptype); + compobject *self = newcompobject(state->Comptype); if (self == NULL) goto error; self->zst.opaque = NULL; @@ -451,7 +450,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, self->zst.zfree = PyZlib_Free; self->zst.next_in = NULL; self->zst.avail_in = 0; - err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); + int err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); switch (err) { case Z_OK: self->is_initialised = 1; @@ -479,7 +478,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); goto error; default: - zlib_error(self->zst, err, "while creating compression object"); + zlib_error(state, self->zst, err, "while creating compression object"); goto error; } @@ -490,11 +489,9 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, } static int -set_inflate_zdict(compobject *self) +set_inflate_zdict(zlibstate *state, compobject *self) { Py_buffer zdict_buf; - int err; - if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { return -1; } @@ -504,11 +501,12 @@ set_inflate_zdict(compobject *self) PyBuffer_Release(&zdict_buf); return -1; } + int err; err = inflateSetDictionary(&self->zst, zdict_buf.buf, (unsigned int)zdict_buf.len); PyBuffer_Release(&zdict_buf); if (err != Z_OK) { - zlib_error(self->zst, err, "while setting zdict"); + zlib_error(state, self->zst, err, "while setting zdict"); return -1; } return 0; @@ -530,8 +528,7 @@ static PyObject * zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) /*[clinic end generated code: output=3069b99994f36906 input=d3832b8511fc977b]*/ { - int err; - compobject *self; + zlibstate *state = get_zlib_state(module); if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { PyErr_SetString(PyExc_TypeError, @@ -539,7 +536,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) return NULL; } - self = newcompobject(_zlibstate_global->Decomptype); + compobject *self = newcompobject(state->Decomptype); if (self == NULL) return NULL; self->zst.opaque = NULL; @@ -551,18 +548,18 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) Py_INCREF(zdict); self->zdict = zdict; } - err = inflateInit2(&self->zst, wbits); + int err = inflateInit2(&self->zst, wbits); switch (err) { case Z_OK: self->is_initialised = 1; if (self->zdict != NULL && wbits < 0) { #ifdef AT_LEAST_ZLIB_1_2_2_1 - if (set_inflate_zdict(self) < 0) { + if (set_inflate_zdict(state, self) < 0) { Py_DECREF(self); return NULL; } #else - PyErr_Format(_zlibstate_global->ZlibError, + PyErr_Format(state->ZlibError, "zlib version %s does not allow raw inflate with dictionary", ZLIB_VERSION); Py_DECREF(self); @@ -580,7 +577,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) "Can't allocate memory for decompression object"); return NULL; default: - zlib_error(self->zst, err, "while creating decompression object"); + zlib_error(state, self->zst, err, "while creating decompression object"); Py_DECREF(self); return NULL; } @@ -617,6 +614,7 @@ Decomp_dealloc(compobject *self) /*[clinic input] zlib.Compress.compress + cls: defining_class data: Py_buffer Binary data to be compressed. / @@ -629,15 +627,18 @@ Call the flush() method to clear these buffers. [clinic start generated code]*/ static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data) -/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ +zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data) +/*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ { PyObject *RetVal = NULL; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; + Py_ssize_t obuflen = DEF_BUF_SIZE; int err; + zlibstate *state = PyType_GetModuleState(cls); + self->zst.next_in = data->buf; - ibuflen = data->len; + Py_ssize_t ibuflen = data->len; ENTER_ZLIB(self); @@ -654,7 +655,7 @@ zlib_Compress_compress_impl(compobject *self, Py_buffer *data) Py_END_ALLOW_THREADS if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while compressing data"); + zlib_error(state, self->zst, err, "while compressing data"); goto error; } @@ -722,6 +723,7 @@ save_unconsumed_input(compobject *self, Py_buffer *data, int err) /*[clinic input] zlib.Decompress.decompress + cls: defining_class data: Py_buffer The binary data to decompress. / @@ -738,14 +740,19 @@ Call the flush() method to clear these buffers. [clinic start generated code]*/ static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length) -/*[clinic end generated code: output=6e5173c74e710352 input=0a95d05a3bceaeaa]*/ +zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data, Py_ssize_t max_length) +/*[clinic end generated code: output=b024a93c2c922d57 input=bfb37b3864cfb606]*/ { int err = Z_OK; Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit; PyObject *RetVal = NULL; + PyObject *module = PyType_GetModule(cls); + if (module == NULL) + return NULL; + + zlibstate *state = get_zlib_state(module); if (max_length < 0) { PyErr_SetString(PyExc_ValueError, "max_length must be non-negative"); return NULL; @@ -790,8 +797,9 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, break; default: if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) + if (set_inflate_zdict(state, self) < 0) { goto abort; + } else break; } @@ -815,7 +823,7 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, but there wasn't more output when we tried again, so it is not an error condition. */ - zlib_error(self->zst, err, "while decompressing data"); + zlib_error(state, self->zst, err, "while decompressing data"); goto abort; } @@ -833,6 +841,7 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, /*[clinic input] zlib.Compress.flush + cls: defining_class mode: int(c_default="Z_FINISH") = zlib.Z_FINISH One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. If mode == Z_FINISH, the compressor object can no longer be @@ -844,13 +853,14 @@ Return a bytes object containing any remaining compressed data. [clinic start generated code]*/ static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode) -/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ +zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) +/*[clinic end generated code: output=c7efd13efd62add2 input=286146e29442eb6c]*/ { int err; Py_ssize_t length = DEF_BUF_SIZE; PyObject *RetVal = NULL; + zlibstate *state = PyType_GetModuleState(cls); /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in doing any work at all; just return an empty string. */ if (mode == Z_NO_FLUSH) { @@ -873,7 +883,7 @@ zlib_Compress_flush_impl(compobject *self, int mode) Py_END_ALLOW_THREADS if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while flushing"); + zlib_error(state, self->zst, err, "while flushing"); Py_CLEAR(RetVal); goto error; } @@ -886,7 +896,7 @@ zlib_Compress_flush_impl(compobject *self, int mode) if (err == Z_STREAM_END && mode == Z_FINISH) { err = deflateEnd(&self->zst); if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing compression"); + zlib_error(state, self->zst, err, "while finishing compression"); Py_CLEAR(RetVal); goto error; } @@ -898,7 +908,7 @@ zlib_Compress_flush_impl(compobject *self, int mode) not an error condition. */ } else if (err != Z_OK && err != Z_BUF_ERROR) { - zlib_error(self->zst, err, "while flushing"); + zlib_error(state, self->zst, err, "while flushing"); Py_CLEAR(RetVal); goto error; } @@ -917,24 +927,25 @@ zlib_Compress_flush_impl(compobject *self, int mode) /*[clinic input] zlib.Compress.copy + cls: defining_class + Return a copy of the compression object. [clinic start generated code]*/ static PyObject * -zlib_Compress_copy_impl(compobject *self) -/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ +zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=c4d2cfb4b0d7350b input=235497e482d40986]*/ { - compobject *retval = NULL; - int err; + zlibstate *state = PyType_GetModuleState(cls); - retval = newcompobject(_zlibstate_global->Comptype); + compobject *retval = newcompobject(state->Comptype); if (!retval) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - err = deflateCopy(&retval->zst, &self->zst); + int err = deflateCopy(&retval->zst, &self->zst); switch (err) { case Z_OK: break; @@ -946,7 +957,7 @@ zlib_Compress_copy_impl(compobject *self) "Can't allocate memory for compression object"); goto error; default: - zlib_error(self->zst, err, "while copying compression object"); + zlib_error(state, self->zst, err, "while copying compression object"); goto error; } Py_INCREF(self->unused_data); @@ -971,51 +982,57 @@ zlib_Compress_copy_impl(compobject *self) /*[clinic input] zlib.Compress.__copy__ + + cls: defining_class + [clinic start generated code]*/ static PyObject * -zlib_Compress___copy___impl(compobject *self) -/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/ +zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=074613db332cb668 input=5c0188367ab0fe64]*/ { - return zlib_Compress_copy_impl(self); + return zlib_Compress_copy_impl(self, cls); } /*[clinic input] zlib.Compress.__deepcopy__ + cls: defining_class memo: object / [clinic start generated code]*/ static PyObject * -zlib_Compress___deepcopy__(compobject *self, PyObject *memo) -/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/ +zlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo) +/*[clinic end generated code: output=24b3aed785f54033 input=c90347319a514430]*/ { - return zlib_Compress_copy_impl(self); + return zlib_Compress_copy_impl(self, cls); } /*[clinic input] zlib.Decompress.copy + cls: defining_class + Return a copy of the decompression object. [clinic start generated code]*/ static PyObject * -zlib_Decompress_copy_impl(compobject *self) -/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ +zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=a7ddc016e1d0a781 input=20ef3aa208282ff2]*/ { - compobject *retval = NULL; - int err; + zlibstate *state = PyType_GetModuleState(cls); - retval = newcompobject(_zlibstate_global->Decomptype); + compobject *retval = newcompobject(state->Decomptype); if (!retval) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - err = inflateCopy(&retval->zst, &self->zst); + int err = inflateCopy(&retval->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1027,7 +1044,7 @@ zlib_Decompress_copy_impl(compobject *self) "Can't allocate memory for decompression object"); goto error; default: - zlib_error(self->zst, err, "while copying decompression object"); + zlib_error(state, self->zst, err, "while copying decompression object"); goto error; } @@ -1053,28 +1070,33 @@ zlib_Decompress_copy_impl(compobject *self) /*[clinic input] zlib.Decompress.__copy__ + + cls: defining_class + [clinic start generated code]*/ static PyObject * -zlib_Decompress___copy___impl(compobject *self) -/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/ +zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=cf1e6473744f53fa input=cc3143067b622bdf]*/ { - return zlib_Decompress_copy_impl(self); + return zlib_Decompress_copy_impl(self, cls); } /*[clinic input] zlib.Decompress.__deepcopy__ + cls: defining_class memo: object / [clinic start generated code]*/ static PyObject * -zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) -/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/ +zlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, + PyObject *memo) +/*[clinic end generated code: output=34f7b719a0c0d51b input=fc13b9c58622544e]*/ { - return zlib_Decompress_copy_impl(self); + return zlib_Decompress_copy_impl(self, cls); } #endif @@ -1082,6 +1104,7 @@ zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) /*[clinic input] zlib.Decompress.flush + cls: defining_class length: Py_ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE the initial size of the output buffer. / @@ -1090,21 +1113,30 @@ Return a bytes object containing any remaining decompressed data. [clinic start generated code]*/ static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) -/*[clinic end generated code: output=68c75ea127cbe654 input=427f2a05a8c2113a]*/ +zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, + Py_ssize_t length) +/*[clinic end generated code: output=4532fc280bd0f8f2 input=42f1f4b75230e2cd]*/ { int err, flush; Py_buffer data; PyObject *RetVal = NULL; Py_ssize_t ibuflen; + PyObject *module = PyType_GetModule(cls); + if (module == NULL) { + return NULL; + } + + zlibstate *state = get_zlib_state(module); + if (length <= 0) { PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); return NULL; } - if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) + if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) { return NULL; + } ENTER_ZLIB(self); @@ -1131,8 +1163,9 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) break; default: if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) + if (set_inflate_zdict(state, self) < 0) { goto abort; + } else break; } @@ -1144,8 +1177,9 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) } while (err != Z_STREAM_END && ibuflen != 0); save: - if (save_unconsumed_input(self, &data, err) < 0) + if (save_unconsumed_input(self, &data, err) < 0) { goto abort; + } /* If at end of stream, clean up any memory allocated by zlib. */ if (err == Z_STREAM_END) { @@ -1153,14 +1187,15 @@ zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) self->is_initialised = 0; err = inflateEnd(&self->zst); if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing decompression"); + zlib_error(state, self->zst, err, "while finishing decompression"); goto abort; } } if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + (Byte *)PyBytes_AS_STRING(RetVal)) == 0) { goto success; + } abort: Py_CLEAR(RetVal); @@ -1337,9 +1372,9 @@ PyDoc_STRVAR(zlib_module_documentation, "objects support decompress() and flush()."); static int -zlib_clear(PyObject *m) +zlib_clear(PyObject *mod) { - _zlibstate *state = get_zlib_state(m); + zlibstate *state = get_zlib_state(mod); Py_CLEAR(state->Comptype); Py_CLEAR(state->Decomptype); Py_CLEAR(state->ZlibError); @@ -1347,9 +1382,9 @@ zlib_clear(PyObject *m) } static int -zlib_traverse(PyObject *m, visitproc visit, void *arg) +zlib_traverse(PyObject *mod, visitproc visit, void *arg) { - _zlibstate *state = get_zlib_state(m); + zlibstate *state = get_zlib_state(mod); Py_VISIT(state->Comptype); Py_VISIT(state->Decomptype); Py_VISIT(state->ZlibError); @@ -1357,93 +1392,122 @@ zlib_traverse(PyObject *m, visitproc visit, void *arg) } static void -zlib_free(void *m) +zlib_free(void *mod) { - zlib_clear((PyObject *)m); + zlib_clear((PyObject *)mod); } -static struct PyModuleDef zlibmodule = { - PyModuleDef_HEAD_INIT, - "zlib", - zlib_module_documentation, - sizeof(_zlibstate), - zlib_methods, - NULL, - zlib_traverse, - zlib_clear, - zlib_free, -}; - -PyMODINIT_FUNC -PyInit_zlib(void) +static int +zlib_exec(PyObject *mod) { - PyObject *m, *ver; - m = PyState_FindModule(&zlibmodule); - if (m != NULL) { - Py_INCREF(m); - return m; + zlibstate *state = get_zlib_state(mod); + + state->Comptype = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &Comptype_spec, NULL); + if (state->Comptype == NULL) { + return -1; } - m = PyModule_Create(&zlibmodule); - if (m == NULL) - return NULL; - PyTypeObject *Comptype = (PyTypeObject *)PyType_FromSpec(&Comptype_spec); - if (Comptype == NULL) - return NULL; - get_zlib_state(m)->Comptype = Comptype; + state->Decomptype = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &Decomptype_spec, NULL); + if (state->Decomptype == NULL) { + return -1; + } - PyTypeObject *Decomptype = (PyTypeObject *)PyType_FromSpec(&Decomptype_spec); - if (Decomptype == NULL) - return NULL; - get_zlib_state(m)->Decomptype = Decomptype; + state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); + if (state->ZlibError == NULL) { + return -1; + } - PyObject *ZlibError = PyErr_NewException("zlib.error", NULL, NULL); - if (ZlibError != NULL) { - Py_INCREF(ZlibError); - PyModule_AddObject(m, "error", ZlibError); - get_zlib_state(m)->ZlibError = ZlibError; + Py_INCREF(state->ZlibError); + if (PyModule_AddObject(mod, "error", state->ZlibError) < 0) { + Py_DECREF(state->ZlibError); + return -1; } - PyModule_AddIntMacro(m, MAX_WBITS); - PyModule_AddIntMacro(m, DEFLATED); - PyModule_AddIntMacro(m, DEF_MEM_LEVEL); - PyModule_AddIntMacro(m, DEF_BUF_SIZE); + +#define ZLIB_ADD_INT_MACRO(c) \ + do { \ + if ((PyModule_AddIntConstant(mod, #c, c)) < 0) { \ + return -1; \ + } \ + } while(0) + + ZLIB_ADD_INT_MACRO(MAX_WBITS); + ZLIB_ADD_INT_MACRO(DEFLATED); + ZLIB_ADD_INT_MACRO(DEF_MEM_LEVEL); + ZLIB_ADD_INT_MACRO(DEF_BUF_SIZE); // compression levels - PyModule_AddIntMacro(m, Z_NO_COMPRESSION); - PyModule_AddIntMacro(m, Z_BEST_SPEED); - PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); - PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_NO_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_BEST_SPEED); + ZLIB_ADD_INT_MACRO(Z_BEST_COMPRESSION); + ZLIB_ADD_INT_MACRO(Z_DEFAULT_COMPRESSION); // compression strategies - PyModule_AddIntMacro(m, Z_FILTERED); - PyModule_AddIntMacro(m, Z_HUFFMAN_ONLY); + ZLIB_ADD_INT_MACRO(Z_FILTERED); + ZLIB_ADD_INT_MACRO(Z_HUFFMAN_ONLY); #ifdef Z_RLE // 1.2.0.1 - PyModule_AddIntMacro(m, Z_RLE); + ZLIB_ADD_INT_MACRO(Z_RLE); #endif #ifdef Z_FIXED // 1.2.2.2 - PyModule_AddIntMacro(m, Z_FIXED); + ZLIB_ADD_INT_MACRO(Z_FIXED); #endif - PyModule_AddIntMacro(m, Z_DEFAULT_STRATEGY); + ZLIB_ADD_INT_MACRO(Z_DEFAULT_STRATEGY); // allowed flush values - PyModule_AddIntMacro(m, Z_NO_FLUSH); - PyModule_AddIntMacro(m, Z_PARTIAL_FLUSH); - PyModule_AddIntMacro(m, Z_SYNC_FLUSH); - PyModule_AddIntMacro(m, Z_FULL_FLUSH); - PyModule_AddIntMacro(m, Z_FINISH); + ZLIB_ADD_INT_MACRO(Z_NO_FLUSH); + ZLIB_ADD_INT_MACRO(Z_PARTIAL_FLUSH); + ZLIB_ADD_INT_MACRO(Z_SYNC_FLUSH); + ZLIB_ADD_INT_MACRO(Z_FULL_FLUSH); + ZLIB_ADD_INT_MACRO(Z_FINISH); #ifdef Z_BLOCK // 1.2.0.5 for inflate, 1.2.3.4 for deflate - PyModule_AddIntMacro(m, Z_BLOCK); + ZLIB_ADD_INT_MACRO(Z_BLOCK); #endif #ifdef Z_TREES // 1.2.3.4, only for inflate - PyModule_AddIntMacro(m, Z_TREES); + ZLIB_ADD_INT_MACRO(Z_TREES); #endif - ver = PyUnicode_FromString(ZLIB_VERSION); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_VERSION", ver); + PyObject *ver = PyUnicode_FromString(ZLIB_VERSION); + if (ver == NULL) { + return -1; + } + + if (PyModule_AddObject(mod, "ZLIB_VERSION", ver) < 0) { + Py_DECREF(ver); + return -1; + } ver = PyUnicode_FromString(zlibVersion()); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_RUNTIME_VERSION", ver); + if (ver == NULL) { + return -1; + } + + if (PyModule_AddObject(mod, "ZLIB_RUNTIME_VERSION", ver) < 0) { + Py_DECREF(ver); + return -1; + } + + if (PyModule_AddStringConstant(mod, "__version__", "1.0") < 0) { + return -1; + } + return 0; +} - PyModule_AddStringConstant(m, "__version__", "1.0"); +static PyModuleDef_Slot zlib_slots[] = { + {Py_mod_exec, zlib_exec}, + {0, NULL} +}; - PyState_AddModule(m, &zlibmodule); - return m; +static struct PyModuleDef zlibmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "zlib", + .m_doc = zlib_module_documentation, + .m_size = sizeof(zlibstate), + .m_methods = zlib_methods, + .m_slots = zlib_slots, + .m_traverse = zlib_traverse, + .m_clear = zlib_clear, + .m_free = zlib_free, +}; + +PyMODINIT_FUNC +PyInit_zlib(void) +{ + return PyModuleDef_Init(&zlibmodule); } From 13e530ac78e2ccdca4b8ece757dcf73e3dbe6d5d Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 7 Sep 2020 03:48:44 -0500 Subject: [PATCH 257/486] bpo-1635741: Port _opcode module to multi-phase init (PEP 489) (GH-22050) --- ...2020-09-01-17-06-02.bpo-1635741.5jZymK.rst | 2 ++ Modules/_opcode.c | 21 +++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst new file mode 100644 index 000000000000000..c3bc9a78a2e054b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst @@ -0,0 +1,2 @@ +Port the :mod:`_opcode` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 42a8732694afef6..d8de0762e765af1 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -36,8 +36,9 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, return -1; } oparg_int = (int)PyLong_AsLong(oparg); - if ((oparg_int == -1) && PyErr_Occurred()) + if ((oparg_int == -1) && PyErr_Occurred()) { return -1; + } } else if (oparg != Py_None) { PyErr_SetString(PyExc_ValueError, @@ -67,30 +68,22 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, return effect; } - - - static PyMethodDef opcode_functions[] = { _OPCODE_STACK_EFFECT_METHODDEF {NULL, NULL, 0, NULL} }; - static struct PyModuleDef opcodemodule = { PyModuleDef_HEAD_INIT, - "_opcode", - "Opcode support module.", - -1, - opcode_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_opcode", + .m_doc = "Opcode support module.", + .m_size = 0, + .m_methods = opcode_functions }; PyMODINIT_FUNC PyInit__opcode(void) { - return PyModule_Create(&opcodemodule); + return PyModuleDef_Init(&opcodemodule); } From b2a773d3bcb1705de6ff4fda086efe6359540b96 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 7 Sep 2020 08:12:40 -0500 Subject: [PATCH 258/486] bpo-1635741: Port _overlapped module to multi-phase init (GH-22051) Port the _overlapped extension module to multi-phase initialization (PEP 489). --- ...2020-09-01-17-22-35.bpo-1635741.CnRME3.rst | 2 + Modules/overlapped.c | 173 +++++++++++------- 2 files changed, 108 insertions(+), 67 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst new file mode 100644 index 000000000000000..76f985bb87b4e9f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst @@ -0,0 +1,2 @@ +Port the :mod:`_overlapped` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 5e7a1bbba76787c..3829932070a9611 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -100,6 +100,19 @@ typedef struct { }; } OverlappedObject; +typedef struct { + PyTypeObject *overlapped_type; +} OverlappedState; + +static inline OverlappedState* +overlapped_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (OverlappedState *)state; +} + + /* * Map Windows error codes to subclasses of OSError */ @@ -706,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self) } Overlapped_clear(self); - PyObject_Del(self); SetLastError(olderr); + + PyTypeObject *tp = Py_TYPE(self); + PyObject_Del(self); + Py_DECREF(tp); } @@ -1846,45 +1862,22 @@ static PyGetSetDef Overlapped_getsets[] = { {NULL}, }; -PyTypeObject OverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_overlapped.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) Overlapped_dealloc, - /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, - /* tp_as_async */ 0, - /* tp_repr */ 0, - /* tp_as_number */ 0, - /* tp_as_sequence */ 0, - /* tp_as_mapping */ 0, - /* tp_hash */ 0, - /* tp_call */ 0, - /* tp_str */ 0, - /* tp_getattro */ 0, - /* tp_setattro */ 0, - /* tp_as_buffer */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ _overlapped_Overlapped__doc__, - /* tp_traverse */ (traverseproc)Overlapped_traverse, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ Overlapped_methods, - /* tp_members */ Overlapped_members, - /* tp_getset */ Overlapped_getsets, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ _overlapped_Overlapped, +static PyType_Slot overlapped_type_slots[] = { + {Py_tp_dealloc, Overlapped_dealloc}, + {Py_tp_doc, (char *)_overlapped_Overlapped__doc__}, + {Py_tp_traverse, Overlapped_traverse}, + {Py_tp_methods, Overlapped_methods}, + {Py_tp_members, Overlapped_members}, + {Py_tp_getset, Overlapped_getsets}, + {Py_tp_new, _overlapped_Overlapped}, + {0,0} +}; + +static PyType_Spec overlapped_type_spec = { + .name = "_overlapped.Overlapped", + .basicsize = sizeof(OverlappedObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = overlapped_type_slots }; static PyMethodDef overlapped_functions[] = { @@ -1904,41 +1897,65 @@ static PyMethodDef overlapped_functions[] = { {NULL} }; -static struct PyModuleDef overlapped_module = { - PyModuleDef_HEAD_INIT, - "_overlapped", - NULL, - -1, - overlapped_functions, - NULL, - NULL, - NULL, - NULL -}; +static int +overlapped_traverse(PyObject *module, visitproc visit, void *arg) +{ + OverlappedState *state = overlapped_get_state(module); + Py_VISIT(state->overlapped_type); + return 0; +} -#define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) +static int +overlapped_clear(PyObject *module) +{ + OverlappedState *state = overlapped_get_state(module); + Py_CLEAR(state->overlapped_type); + return 0; +} -PyMODINIT_FUNC -PyInit__overlapped(void) +static void +overlapped_free(void *module) { - PyObject *m, *d; + overlapped_clear((PyObject *)module); +} +#define WINAPI_CONSTANT(fmt, con) \ + do { \ + PyObject *value = Py_BuildValue(fmt, con); \ + if (value == NULL) { \ + return -1; \ + } \ + if (PyModule_AddObject(module, #con, value) < 0 ) { \ + Py_DECREF(value); \ + return -1; \ + } \ + } while (0) + +static int +overlapped_exec(PyObject *module) +{ /* Ensure WSAStartup() called before initializing function pointers */ - m = PyImport_ImportModule("_socket"); - if (!m) - return NULL; - Py_DECREF(m); + PyObject *socket_module = PyImport_ImportModule("_socket"); + if (!socket_module) { + return -1; + } - if (initialize_function_pointers() < 0) - return NULL; + Py_DECREF(socket_module); - m = PyModule_Create(&overlapped_module); - if (PyModule_AddType(m, &OverlappedType) < 0) { - return NULL; + if (initialize_function_pointers() < 0) { + return -1; } - d = PyModule_GetDict(m); + OverlappedState *st = overlapped_get_state(module); + st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &overlapped_type_spec, NULL); + if (st->overlapped_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, st->overlapped_type) < 0) { + return -1; + } WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); @@ -1952,5 +1969,27 @@ PyInit__overlapped(void) WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT); WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET); - return m; + return 0; +} + +static PyModuleDef_Slot overlapped_slots[] = { + {Py_mod_exec, overlapped_exec}, + {0, NULL} +}; + +static struct PyModuleDef overlapped_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_overlapped", + .m_size = sizeof(OverlappedState), + .m_methods = overlapped_functions, + .m_slots = overlapped_slots, + .m_traverse = overlapped_traverse, + .m_clear = overlapped_clear, + .m_free = overlapped_free +}; + +PyMODINIT_FUNC +PyInit__overlapped(void) +{ + return PyModuleDef_Init(&overlapped_module); } From e8f801664e21fefd7678be1c7b9a865865ec71ec Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 7 Sep 2020 10:14:25 -0500 Subject: [PATCH 259/486] bpo-1635741 port _curses_panel to multi-phase init (PEP 489) (GH-21986) --- ...2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst | 2 + Modules/_curses_panel.c | 268 ++++++++++-------- Modules/clinic/_curses_panel.c.h | 158 ++++++++--- 3 files changed, 273 insertions(+), 155 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst new file mode 100644 index 000000000000000..a39673a26307a93 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst @@ -0,0 +1,2 @@ +Port the :mod:`_curses_panel` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index f124803493d88b5..1a8f0b636821ff9 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -18,43 +18,42 @@ static const char PyCursesVersion[] = "2.1"; typedef struct { PyObject *PyCursesError; - PyObject *PyCursesPanel_Type; -} _curses_panelstate; + PyTypeObject *PyCursesPanel_Type; +} _curses_panel_state; -static inline _curses_panelstate* -get_curses_panelstate(PyObject *module) +static inline _curses_panel_state * +get_curses_panel_state(PyObject *module) { void *state = PyModule_GetState(module); assert(state != NULL); - return (_curses_panelstate *)state; + return (_curses_panel_state *)state; } static int -_curses_panel_clear(PyObject *m) +_curses_panel_clear(PyObject *mod) { - Py_CLEAR(get_curses_panelstate(m)->PyCursesError); + _curses_panel_state *state = get_curses_panel_state(mod); + Py_CLEAR(state->PyCursesError); + Py_CLEAR(state->PyCursesPanel_Type); return 0; } static int -_curses_panel_traverse(PyObject *m, visitproc visit, void *arg) +_curses_panel_traverse(PyObject *mod, visitproc visit, void *arg) { - Py_VISIT(Py_TYPE(m)); - Py_VISIT(get_curses_panelstate(m)->PyCursesError); + Py_VISIT(Py_TYPE(mod)); + _curses_panel_state *state = get_curses_panel_state(mod); + Py_VISIT(state->PyCursesError); + Py_VISIT(state->PyCursesPanel_Type); return 0; } static void -_curses_panel_free(void *m) +_curses_panel_free(void *mod) { - _curses_panel_clear((PyObject *) m); + _curses_panel_clear((PyObject *) mod); } -static struct PyModuleDef _curses_panelmodule; - -#define _curses_panelstate_global \ -((_curses_panelstate *) PyModule_GetState(PyState_FindModule(&_curses_panelmodule))) - /* Utility Functions */ /* @@ -63,15 +62,17 @@ static struct PyModuleDef _curses_panelmodule; */ static PyObject * -PyCursesCheckERR(int code, const char *fname) +PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname) { if (code != ERR) { Py_RETURN_NONE; - } else { + } + else { if (fname == NULL) { - PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_ERR); - } else { - PyErr_Format(_curses_panelstate_global->PyCursesError, "%s() returned ERR", fname); + PyErr_SetString(state->PyCursesError, catchall_ERR); + } + else { + PyErr_Format(state->PyCursesError, "%s() returned ERR", fname); } return NULL; } @@ -89,9 +90,6 @@ typedef struct { PyCursesWindowObject *wo; /* for reference counts */ } PyCursesPanelObject; -#define PyCursesPanel_Check(v) \ - Py_IS_TYPE(v, _curses_panelstate_global->PyCursesPanel_Type) - /* Some helper functions. The problem is that there's always a window associated with a panel. To ensure that Python's GC doesn't pull this window from under our feet we need to keep track of references @@ -182,67 +180,81 @@ class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type" /*[clinic input] _curses_panel.panel.bottom + cls: defining_class + Push the panel to the bottom of the stack. [clinic start generated code]*/ static PyObject * -_curses_panel_panel_bottom_impl(PyCursesPanelObject *self) -/*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/ +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=8ec7fbbc08554021 input=6b7d2c0578b5a1c4]*/ { - return PyCursesCheckERR(bottom_panel(self->pan), "bottom"); + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, bottom_panel(self->pan), "bottom"); } /*[clinic input] _curses_panel.panel.hide + cls: defining_class + Hide the panel. This does not delete the object, it just makes the window on screen invisible. [clinic start generated code]*/ static PyObject * -_curses_panel_panel_hide_impl(PyCursesPanelObject *self) -/*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/ +_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=cc6ab7203cdc1450 input=1bfc741f473e6055]*/ { - return PyCursesCheckERR(hide_panel(self->pan), "hide"); + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, hide_panel(self->pan), "hide"); } /*[clinic input] _curses_panel.panel.show + cls: defining_class + Display the panel (which might have been hidden). [clinic start generated code]*/ static PyObject * -_curses_panel_panel_show_impl(PyCursesPanelObject *self) -/*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/ +_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=dc3421de375f0409 input=8122e80151cb4379]*/ { - return PyCursesCheckERR(show_panel(self->pan), "show"); + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, show_panel(self->pan), "show"); } /*[clinic input] _curses_panel.panel.top + cls: defining_class + Push panel to the top of the stack. [clinic start generated code]*/ static PyObject * -_curses_panel_panel_top_impl(PyCursesPanelObject *self) -/*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/ +_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=10a072e511e873f7 input=1f372d597dda3379]*/ { - return PyCursesCheckERR(top_panel(self->pan), "top"); + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, top_panel(self->pan), "top"); } /* Allocation and deallocation of Panel Objects */ static PyObject * -PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) +PyCursesPanel_New(_curses_panel_state *state, PANEL *pan, + PyCursesWindowObject *wo) { - PyCursesPanelObject *po; + PyCursesPanelObject *po = PyObject_New(PyCursesPanelObject, + state->PyCursesPanel_Type); + if (po == NULL) { + return NULL; + } - po = PyObject_New(PyCursesPanelObject, - (PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type); - if (po == NULL) return NULL; po->pan = pan; if (insert_lop(po) < 0) { po->wo = NULL; @@ -355,6 +367,7 @@ _curses_panel_panel_hidden_impl(PyCursesPanelObject *self) /*[clinic input] _curses_panel.panel.move + cls: defining_class y: int x: int / @@ -363,10 +376,12 @@ Move the panel to the screen coordinates (y, x). [clinic start generated code]*/ static PyObject * -_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x) -/*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/ +_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, + int y, int x) +/*[clinic end generated code: output=ce546c93e56867da input=60a0e7912ff99849]*/ { - return PyCursesCheckERR(move_panel(self->pan, y, x), "move_panel"); + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, move_panel(self->pan, y, x), "move_panel"); } /*[clinic input] @@ -386,6 +401,7 @@ _curses_panel_panel_window_impl(PyCursesPanelObject *self) /*[clinic input] _curses_panel.panel.replace + cls: defining_class win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") / @@ -394,22 +410,22 @@ Change the window associated with the panel to the window win. static PyObject * _curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyCursesWindowObject *win) -/*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/ +/*[clinic end generated code: output=c71f95c212d58ae7 input=dbec7180ece41ff5]*/ { - PyCursesPanelObject *po; - int rtn; + _curses_panel_state *state = PyType_GetModuleState(cls); - po = find_po(self->pan); + PyCursesPanelObject *po = find_po(self->pan); if (po == NULL) { PyErr_SetString(PyExc_RuntimeError, "replace_panel: can't find Panel Object"); return NULL; } - rtn = replace_panel(self->pan, win->win); + int rtn = replace_panel(self->pan, win->win); if (rtn == ERR) { - PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); + PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR"); return NULL; } Py_INCREF(win); @@ -420,6 +436,7 @@ _curses_panel_panel_replace_impl(PyCursesPanelObject *self, /*[clinic input] _curses_panel.panel.set_userptr + cls: defining_class obj: object / @@ -427,38 +444,43 @@ Set the panel's user pointer to obj. [clinic start generated code]*/ static PyObject * -_curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyObject *obj) -/*[clinic end generated code: output=6fb145b3af88cf4a input=d2c6a9dbefabbf39]*/ +_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyObject *obj) +/*[clinic end generated code: output=db74f3db07b28080 input=e3fee2ff7b1b8e48]*/ { - PyObject *oldobj; - int rc; PyCursesInitialised; Py_INCREF(obj); - oldobj = (PyObject *) panel_userptr(self->pan); - rc = set_panel_userptr(self->pan, (void*)obj); + PyObject *oldobj = (PyObject *) panel_userptr(self->pan); + int rc = set_panel_userptr(self->pan, (void*)obj); if (rc == ERR) { /* In case of an ncurses error, decref the new object again */ Py_DECREF(obj); } Py_XDECREF(oldobj); - return PyCursesCheckERR(rc, "set_panel_userptr"); + + _curses_panel_state *state = PyType_GetModuleState(cls); + return PyCursesCheckERR(state, rc, "set_panel_userptr"); } /*[clinic input] _curses_panel.panel.userptr + cls: defining_class + Return the user pointer for the panel. [clinic start generated code]*/ static PyObject * -_curses_panel_panel_userptr_impl(PyCursesPanelObject *self) -/*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/ +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=eea6e6f39ffc0179 input=f22ca4f115e30a80]*/ { - PyObject *obj; + _curses_panel_state *state = PyType_GetModuleState(cls); + PyCursesInitialised; - obj = (PyObject *) panel_userptr(self->pan); + PyObject *obj = (PyObject *) panel_userptr(self->pan); if (obj == NULL) { - PyErr_SetString(_curses_panelstate_global->PyCursesError, "no userptr set"); + PyErr_SetString(state->PyCursesError, "no userptr set"); return NULL; } @@ -494,11 +516,10 @@ static PyType_Slot PyCursesPanel_Type_slots[] = { }; static PyType_Spec PyCursesPanel_Type_spec = { - "_curses_panel.panel", - sizeof(PyCursesPanelObject), - 0, - Py_TPFLAGS_DEFAULT, - PyCursesPanel_Type_slots + .name = "_curses_panel.panel", + .basicsize = sizeof(PyCursesPanelObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = PyCursesPanel_Type_slots }; /* Wrapper for panel_above(NULL). This function returns the bottom @@ -549,12 +570,14 @@ static PyObject * _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win) /*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/ { + _curses_panel_state *state = get_curses_panel_state(module); + PANEL *pan = new_panel(win->win); if (pan == NULL) { - PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); + PyErr_SetString(state->PyCursesError, catchall_NULL); return NULL; } - return (PyObject *)PyCursesPanel_New(pan, win); + return (PyObject *)PyCursesPanel_New(state, pan, win); } @@ -610,7 +633,6 @@ _curses_panel_update_panels_impl(PyObject *module) Py_RETURN_NONE; } - /* List of functions defined in the module */ static PyMethodDef PyCurses_methods[] = { @@ -622,57 +644,75 @@ static PyMethodDef PyCurses_methods[] = { }; /* Initialization function for the module */ - - -static struct PyModuleDef _curses_panelmodule = { - PyModuleDef_HEAD_INIT, - "_curses_panel", - NULL, - sizeof(_curses_panelstate), - PyCurses_methods, - NULL, - _curses_panel_traverse, - _curses_panel_clear, - _curses_panel_free -}; - -PyMODINIT_FUNC -PyInit__curses_panel(void) +static int +_curses_panel_exec(PyObject *mod) { - PyObject *m, *d, *v; - - /* Create the module and add the functions */ - m = PyModule_Create(&_curses_panelmodule); - if (m == NULL) - goto fail; - d = PyModule_GetDict(m); - + _curses_panel_state *state = get_curses_panel_state(mod); /* Initialize object type */ - v = PyType_FromSpec(&PyCursesPanel_Type_spec); - if (v == NULL) - goto fail; - ((PyTypeObject *)v)->tp_new = NULL; - get_curses_panelstate(m)->PyCursesPanel_Type = v; + state->PyCursesPanel_Type = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &PyCursesPanel_Type_spec, NULL); + if (state->PyCursesPanel_Type == NULL) { + return -1; + } + + if (PyModule_AddType(mod, state->PyCursesPanel_Type) < 0) { + return -1; + } import_curses(); - if (PyErr_Occurred()) - goto fail; + if (PyErr_Occurred()) { + return -1; + } /* For exception _curses_panel.error */ - get_curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); - PyDict_SetItemString(d, "error", get_curses_panelstate(m)->PyCursesError); + state->PyCursesError = PyErr_NewException( + "_curses_panel.error", NULL, NULL); + + Py_INCREF(state->PyCursesError); + if (PyModule_AddObject(mod, "error", state->PyCursesError) < 0) { + Py_DECREF(state->PyCursesError); + return -1; + } /* Make the version available */ - v = PyUnicode_FromString(PyCursesVersion); - PyDict_SetItemString(d, "version", v); - PyDict_SetItemString(d, "__version__", v); + PyObject *v = PyUnicode_FromString(PyCursesVersion); + if (v == NULL) { + return -1; + } + + PyObject *d = PyModule_GetDict(mod); + if (PyDict_SetItemString(d, "version", v) < 0) { + Py_DECREF(v); + return -1; + } + if (PyDict_SetItemString(d, "__version__", v) < 0) { + Py_DECREF(v); + return -1; + } + Py_DECREF(v); - Py_INCREF(get_curses_panelstate(m)->PyCursesPanel_Type); - PyModule_AddObject(m, "panel", - (PyObject *)get_curses_panelstate(m)->PyCursesPanel_Type); - return m; - fail: - Py_XDECREF(m); - return NULL; + return 0; } + +static PyModuleDef_Slot _curses_slots[] = { + {Py_mod_exec, _curses_panel_exec}, + {0, NULL} +}; + +static struct PyModuleDef _curses_panelmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_curses_panel", + .m_size = sizeof(_curses_panel_state), + .m_methods = PyCurses_methods, + .m_slots = _curses_slots, + .m_traverse = _curses_panel_traverse, + .m_clear = _curses_panel_clear, + .m_free = _curses_panel_free +}; + +PyMODINIT_FUNC +PyInit__curses_panel(void) +{ + return PyModuleDef_Init(&_curses_panelmodule); +} \ No newline at end of file diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index cff274657658adc..45898070b1f5433 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "Push the panel to the bottom of the stack."); #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ - {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, + {"bottom", (PyCFunction)(void(*)(void))_curses_panel_panel_bottom, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, static PyObject * -_curses_panel_panel_bottom_impl(PyCursesPanelObject *self); +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_bottom_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":bottom", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_bottom_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_hide__doc__, @@ -29,15 +40,26 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__, "This does not delete the object, it just makes the window on screen invisible."); #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ - {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, + {"hide", (PyCFunction)(void(*)(void))_curses_panel_panel_hide, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, static PyObject * -_curses_panel_panel_hide_impl(PyCursesPanelObject *self); +_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_hide_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":hide", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_hide_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_show__doc__, @@ -47,15 +69,26 @@ PyDoc_STRVAR(_curses_panel_panel_show__doc__, "Display the panel (which might have been hidden)."); #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ - {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, + {"show", (PyCFunction)(void(*)(void))_curses_panel_panel_show, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, static PyObject * -_curses_panel_panel_show_impl(PyCursesPanelObject *self); +_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_show_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":show", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_show_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_top__doc__, @@ -65,15 +98,26 @@ PyDoc_STRVAR(_curses_panel_panel_top__doc__, "Push panel to the top of the stack."); #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ - {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, + {"top", (PyCFunction)(void(*)(void))_curses_panel_panel_top, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, static PyObject * -_curses_panel_panel_top_impl(PyCursesPanelObject *self); +_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * -_curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_top_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":top", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_top_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_panel_above__doc__, @@ -137,30 +181,26 @@ PyDoc_STRVAR(_curses_panel_panel_move__doc__, "Move the panel to the screen coordinates (y, x)."); #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ - {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, + {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, static PyObject * -_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); +_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, + int y, int x); static PyObject * -_curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) +_curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; int y; int x; - if (!_PyArg_CheckPositional("move", nargs, 2, 2)) { - goto exit; - } - y = _PyLong_AsInt(args[0]); - if (y == -1 && PyErr_Occurred()) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &y, &x)) { goto exit; } - x = _PyLong_AsInt(args[1]); - if (x == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = _curses_panel_panel_move_impl(self, y, x); + return_value = _curses_panel_panel_move_impl(self, cls, y, x); exit: return return_value; @@ -191,24 +231,26 @@ PyDoc_STRVAR(_curses_panel_panel_replace__doc__, "Change the window associated with the panel to the window win."); #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ - {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, + {"replace", (PyCFunction)(void(*)(void))_curses_panel_panel_replace, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, static PyObject * _curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyCursesWindowObject *win); static PyObject * -_curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) +_curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; PyCursesWindowObject *win; - if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { - _PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg); + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &PyCursesWindow_Type, &win)) { goto exit; } - win = (PyCursesWindowObject *)arg; - return_value = _curses_panel_panel_replace_impl(self, win); + return_value = _curses_panel_panel_replace_impl(self, cls, win); exit: return return_value; @@ -221,7 +263,29 @@ PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, "Set the panel\'s user pointer to obj."); #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ - {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, + {"set_userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_set_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, + +static PyObject * +_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls, PyObject *obj); + +static PyObject * +_curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; + PyObject *obj; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &obj)) { + goto exit; + } + return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); + +exit: + return return_value; +} PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, "userptr($self, /)\n" @@ -230,15 +294,27 @@ PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, "Return the user pointer for the panel."); #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ - {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, + {"userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, static PyObject * -_curses_panel_panel_userptr_impl(PyCursesPanelObject *self); +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self, + PyTypeObject *cls); static PyObject * -_curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +_curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _curses_panel_panel_userptr_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":userptr", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _curses_panel_panel_userptr_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, @@ -325,4 +401,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=1226d5f94361ebfb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ From d6f7febe5bd42af44a817c9c1b5bebb4c3798ee3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 7 Sep 2020 18:55:22 +0300 Subject: [PATCH 260/486] bpo-41720: Add "return NotImplemented" in turtle.Vec2D.__rmul__(). (GH-22092) --- Lib/test/test_turtle.py | 18 ++++++++++++++++-- Lib/turtle.py | 1 + .../2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 46ff4a3aac709a7..86d65075144753c 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -130,6 +130,14 @@ def assertVectorsAlmostEqual(self, vec1, vec2): self.assertAlmostEqual( i, j, msg='values at index {} do not match'.format(idx)) +class Multiplier: + + def __mul__(self, other): + return f'M*{other}' + + def __rmul__(self, other): + return f'{other}*M' + class TestVec2D(VectorComparisonMixin, unittest.TestCase): @@ -211,9 +219,15 @@ def test_vector_multiply(self): self.assertAlmostEqual(answer, expected) vec = Vec2D(0.5, 3) - answer = vec * 10 expected = Vec2D(5, 30) - self.assertVectorsAlmostEqual(answer, expected) + self.assertVectorsAlmostEqual(vec * 10, expected) + self.assertVectorsAlmostEqual(10 * vec, expected) + self.assertVectorsAlmostEqual(vec * 10.0, expected) + self.assertVectorsAlmostEqual(10.0 * vec, expected) + + M = Multiplier() + self.assertEqual(vec * M, Vec2D(f"{vec[0]}*M", f"{vec[1]}*M")) + self.assertEqual(M * vec, f'M*{vec}') def test_vector_negative(self): vec = Vec2D(10, -10) diff --git a/Lib/turtle.py b/Lib/turtle.py index 92d4e5dda9c2dbe..81cfcfe8a701441 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -258,6 +258,7 @@ def __mul__(self, other): def __rmul__(self, other): if isinstance(other, int) or isinstance(other, float): return Vec2D(self[0]*other, self[1]*other) + return NotImplemented def __sub__(self, other): return Vec2D(self[0]-other[0], self[1]-other[1]) def __neg__(self): diff --git a/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst b/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst new file mode 100644 index 000000000000000..5d2a5094ddeaa66 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst @@ -0,0 +1,2 @@ +Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not int or +float. From 231ffd1809e77e3b86f71727abacda7c15e3cc56 Mon Sep 17 00:00:00 2001 From: Artem Bulgakov Date: Mon, 7 Sep 2020 19:46:33 +0300 Subject: [PATCH 261/486] bpo-41316: Make tarfile follow specs for FNAME (GH-21511) tarfile writes full path to FNAME field of GZIP format instead of just basename if user specified absolute path. Some archive viewers may process file incorrectly. Also it creates security issue because anyone can know structure of directories on system and know username or other personal information. RFC1952 says about FNAME: This is the original name of the file being compressed, with any directory components removed. So tarfile must remove directory names from FNAME and write only basename of file. Automerge-Triggered-By: @jaraco --- Lib/tarfile.py | 2 ++ Lib/test/test_tarfile.py | 14 +++++++++++++- Misc/ACKS | 1 + .../2020-07-28-12-08-58.bpo-41316.bSCbK4.rst | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 6769066cabd6fcb..1fae29430fefffe 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -420,6 +420,8 @@ def _init_write_gz(self): self.__write(b"\037\213\010\010" + timestamp + b"\002\377") if self.name.endswith(".gz"): self.name = self.name[:-3] + # Honor "directory components removed" from RFC1952 + self.name = os.path.basename(self.name) # RFC1952 says we must use ISO-8859-1 for the FNAME field. self.__write(self.name.encode("iso-8859-1", "replace") + NUL) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 4ef20db09716362..7b34d53d216013a 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1417,12 +1417,15 @@ def write(self, data): pax_headers={'non': 'empty'}) self.assertFalse(f.closed) + class GzipWriteTest(GzipTest, WriteTest): pass + class Bz2WriteTest(Bz2Test, WriteTest): pass + class LzmaWriteTest(LzmaTest, WriteTest): pass @@ -1465,8 +1468,17 @@ def test_file_mode(self): finally: os.umask(original_umask) + class GzipStreamWriteTest(GzipTest, StreamWriteTest): - pass + def test_source_directory_not_leaked(self): + """ + Ensure the source directory is not included in the tar header + per bpo-41316. + """ + tarfile.open(tmpname, self.mode).close() + payload = pathlib.Path(tmpname).read_text(encoding='latin-1') + assert os.path.dirname(tmpname) not in payload + class Bz2StreamWriteTest(Bz2Test, StreamWriteTest): decompressor = bz2.BZ2Decompressor if bz2 else None diff --git a/Misc/ACKS b/Misc/ACKS index a2cdeb850405995..8b0d7a45da16953 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -242,6 +242,7 @@ Colm Buckley Erik de Bueger Jan-Hein Bührman Lars Buitinck +Artem Bulgakov Dick Bulterman Bill Bumgarner Jimmy Burgett diff --git a/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst b/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst new file mode 100644 index 000000000000000..139a170866ed49e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst @@ -0,0 +1 @@ +Fix the :mod:`tarfile` module to write only basename of TAR file to GZIP compression header. \ No newline at end of file From eb44630c363321f2b734ca610231122b6debbc1e Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 7 Sep 2020 23:26:54 +0200 Subject: [PATCH 262/486] bpo-40744: Drop support for SQLite pre 3.7.3 (GH-20909) Remove code required to support SQLite pre 3.7.3. Co-written-by: Berker Peksag Co-written-by: Sergey Fedoseev --- Doc/library/sqlite3.rst | 8 +-- Doc/whatsnew/3.10.rst | 5 ++ Lib/sqlite3/test/backup.py | 1 - Lib/sqlite3/test/dbapi.py | 6 -- Lib/sqlite3/test/hooks.py | 6 -- Lib/sqlite3/test/regression.py | 1 - Lib/sqlite3/test/transactions.py | 4 -- Lib/sqlite3/test/types.py | 2 - .../2020-05-30-08-10-23.bpo-40744.jKURVV.rst | 4 ++ Modules/_sqlite/connection.c | 57 +++---------------- Modules/_sqlite/module.c | 25 +++----- setup.py | 4 +- 12 files changed, 29 insertions(+), 94 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index ccb82278bdaa133..13aa8c512d03197 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -18,7 +18,8 @@ application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. The sqlite3 module was written by Gerhard Häring. It provides a SQL interface -compliant with the DB-API 2.0 specification described by :pep:`249`. +compliant with the DB-API 2.0 specification described by :pep:`249`, and +requires SQLite 3.7.3 or newer. To use the module, you must first create a :class:`Connection` object that represents the database. Here the data will be stored in the @@ -591,8 +592,6 @@ Connection Objects dest = sqlite3.connect(':memory:') source.backup(dest) - Availability: SQLite 3.6.11 or higher - .. versionadded:: 3.7 @@ -701,9 +700,6 @@ Cursor Objects statements because we cannot determine the number of rows a query produced until all rows were fetched. - With SQLite versions before 3.6.5, :attr:`rowcount` is set to 0 if - you make a ``DELETE FROM table`` without any condition. - .. attribute:: lastrowid This read-only attribute provides the rowid of the last modified row. It is diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index eb5ae01a7c04d4c..f6f276a8bfa4955 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -191,10 +191,15 @@ that may require changes to your code. Build Changes ============= + * The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now required to build Python. (Contributed by Victor Stinner in :issue:`36020`.) +* :mod:`sqlite3` requires SQLite 3.7.3 or higher. + (Contributed by Sergey Fedoseev and Erlend E. Aasland :issue:`40744`.) + + C API Changes ============= diff --git a/Lib/sqlite3/test/backup.py b/Lib/sqlite3/test/backup.py index 903bacf490301cb..2752a4db337ddd8 100644 --- a/Lib/sqlite3/test/backup.py +++ b/Lib/sqlite3/test/backup.py @@ -2,7 +2,6 @@ import unittest -@unittest.skipIf(sqlite.sqlite_version_info < (3, 6, 11), "Backup API not supported") class BackupTests(unittest.TestCase): def setUp(self): cx = self.cx = sqlite.connect(":memory:") diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index 119da12170331fd..a8dfeb9b2d69330 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -185,12 +185,6 @@ def CheckOpenUri(self): with self.assertRaises(sqlite.OperationalError): cx.execute('insert into test(id) values(1)') - @unittest.skipIf(sqlite.sqlite_version_info >= (3, 3, 1), - 'needs sqlite versions older than 3.3.1') - def CheckSameThreadErrorOnOldVersion(self): - with self.assertRaises(sqlite.NotSupportedError) as cm: - sqlite.connect(':memory:', check_same_thread=False) - self.assertEqual(str(cm.exception), 'shared connections not available') class CursorTests(unittest.TestCase): def setUp(self): diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index b08adf1d8097b39..2e620ecdf864cb9 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -61,8 +61,6 @@ def upper(self): self.assertEqual(result[0][0], 'b') self.assertEqual(result[1][0], 'a') - @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 1), - 'old SQLite versions crash on this test') def CheckCollationIsUsed(self): def mycoll(x, y): # reverse order @@ -240,16 +238,12 @@ def trace(statement): traced_statements.append(statement) con.set_trace_callback(trace) con.execute("create table foo(x)") - # Can't execute bound parameters as their values don't appear - # in traced statements before SQLite 3.6.21 - # (cf. http://www.sqlite.org/draft/releaselog/3_6_21.html) con.execute('insert into foo(x) values ("%s")' % unicode_value) con.commit() self.assertTrue(any(unicode_value in stmt for stmt in traced_statements), "Unicode data %s garbled in trace callback: %s" % (ascii(unicode_value), ', '.join(map(ascii, traced_statements)))) - @unittest.skipIf(sqlite.sqlite_version_info < (3, 3, 9), "sqlite3_prepare_v2 is not available") def CheckTraceCallbackContent(self): # set_trace_callback() shouldn't produce duplicate content (bpo-26187) traced_statements = [] diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index cbd46d4978afb96..0735a5c129226d9 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -87,7 +87,6 @@ def CheckStatementFinalizationOnCloseDb(self): cur.execute("select 1 x union select " + str(i)) con.close() - @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), 'needs sqlite 3.2.2 or newer') def CheckOnConflictRollback(self): con = sqlite.connect(":memory:") con.execute("create table foo(x, unique(x) on conflict rollback)") diff --git a/Lib/sqlite3/test/transactions.py b/Lib/sqlite3/test/transactions.py index b8a13de55bc7209..c463f7490da573d 100644 --- a/Lib/sqlite3/test/transactions.py +++ b/Lib/sqlite3/test/transactions.py @@ -111,16 +111,12 @@ def CheckToggleAutoCommit(self): res = self.cur2.fetchall() self.assertEqual(len(res), 1) - @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), - 'test hangs on sqlite versions older than 3.2.2') def CheckRaiseTimeout(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") with self.assertRaises(sqlite.OperationalError): self.cur2.execute("insert into test(i) values (5)") - @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), - 'test hangs on sqlite versions older than 3.2.2') def CheckLocking(self): """ This tests the improved concurrency with pysqlite 2.3.4. You needed diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py index d26a9cb93f08882..75a9d5601d58081 100644 --- a/Lib/sqlite3/test/types.py +++ b/Lib/sqlite3/test/types.py @@ -401,8 +401,6 @@ def CheckSqliteTimestamp(self): ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) - @unittest.skipIf(sqlite.sqlite_version_info < (3, 1), - 'the date functions are available on 3.1 or later') def CheckSqlTimestamp(self): now = datetime.datetime.utcnow() self.cur.execute("insert into test(ts) values (current_timestamp)") diff --git a/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst b/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst new file mode 100644 index 000000000000000..2d1d1f9a20e32e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst @@ -0,0 +1,4 @@ +The :mod:`sqlite3` module uses SQLite API functions that require SQLite +v3.7.3 or higher. This patch removes support for older SQLite versions, and +explicitly requires SQLite 3.7.3 both at build, compile and runtime. Patch by +Sergey Fedoseev and Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 1bf9710763a5aba..f765ba1df246694 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -33,16 +33,6 @@ #define ACTION_FINALIZE 1 #define ACTION_RESET 2 -#if SQLITE_VERSION_NUMBER >= 3003008 -#ifndef SQLITE_OMIT_LOAD_EXTENSION -#define HAVE_LOAD_EXTENSION -#endif -#endif - -#if SQLITE_VERSION_NUMBER >= 3006011 -#define HAVE_BACKUP_API -#endif - #if SQLITE_VERSION_NUMBER >= 3014000 #define HAVE_TRACE_V2 #endif @@ -61,18 +51,6 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); -static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) -{ - /* in older SQLite versions, calling sqlite3_result_error in callbacks - * triggers a bug in SQLite that leads either to irritating results or - * segfaults, depending on the SQLite version */ -#if SQLITE_VERSION_NUMBER >= 3003003 - sqlite3_result_error(ctx, errmsg, len); -#else - PyErr_SetString(pysqlite_OperationalError, errmsg); -#endif -} - int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { @@ -182,10 +160,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); self->thread_ident = PyThread_get_thread_ident(); - if (!check_same_thread && sqlite3_libversion_number() < 3003001) { - PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available"); - return -1; - } self->check_same_thread = check_same_thread; self->function_pinboard_trace_callback = NULL; @@ -620,7 +594,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined function raised exception", -1); + sqlite3_result_error(context, "user-defined function raised exception", -1); } PyGILState_Release(threadstate); @@ -652,7 +626,7 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); + sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); goto error; } } @@ -676,7 +650,7 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); + sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); } error: @@ -693,7 +667,6 @@ void _pysqlite_final_callback(sqlite3_context* context) _Py_IDENTIFIER(finalize); int ok; PyObject *exception, *value, *tb; - int restore; PyGILState_STATE threadstate; @@ -709,7 +682,6 @@ void _pysqlite_final_callback(sqlite3_context* context) /* Keep the exception (if any) of the last call to step() */ PyErr_Fetch(&exception, &value, &tb); - restore = 1; function_result = _PyObject_CallMethodIdNoArgs(*aggregate_instance, &PyId_finalize); @@ -726,19 +698,12 @@ void _pysqlite_final_callback(sqlite3_context* context) } else { PyErr_Clear(); } - _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); -#if SQLITE_VERSION_NUMBER < 3003003 - /* with old SQLite versions, _sqlite3_result_error() sets a new Python - exception, so don't restore the previous exception */ - restore = 0; -#endif + sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); } - if (restore) { - /* Restore the exception (if any) of the last call to step(), - but clear also the current exception if finalize() failed */ - PyErr_Restore(exception, value, tb); - } + /* Restore the exception (if any) of the last call to step(), + but clear also the current exception if finalize() failed */ + PyErr_Restore(exception, value, tb); error: PyGILState_Release(threadstate); @@ -1110,7 +1075,7 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel Py_RETURN_NONE; } -#ifdef HAVE_LOAD_EXTENSION +#ifndef SQLITE_OMIT_LOAD_EXTENSION static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args) { int rc; @@ -1513,7 +1478,6 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) return retval; } -#ifdef HAVE_BACKUP_API static PyObject * pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds) { @@ -1664,7 +1628,6 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * return NULL; } } -#endif static PyObject * pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) @@ -1816,7 +1779,7 @@ static PyMethodDef connection_methods[] = { PyDoc_STR("Creates a new aggregate. Non-standard.")}, {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Sets authorizer callback. Non-standard.")}, - #ifdef HAVE_LOAD_EXTENSION + #ifndef SQLITE_OMIT_LOAD_EXTENSION {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")}, {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, @@ -1838,10 +1801,8 @@ static PyMethodDef connection_methods[] = { PyDoc_STR("Abort any pending database operation. Non-standard.")}, {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, - #ifdef HAVE_BACKUP_API {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Makes a backup of the database. Non-standard.")}, - #endif {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, PyDoc_STR("For context manager. Non-standard.")}, {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 71d951ee887e477..82f58eb24802616 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -29,8 +29,8 @@ #include "microprotocols.h" #include "row.h" -#if SQLITE_VERSION_NUMBER >= 3003003 -#define HAVE_SHARED_CACHE +#if SQLITE_VERSION_NUMBER < 3007003 +#error "SQLite 3.7.3 or higher required" #endif /* static objects at module-level */ @@ -131,7 +131,6 @@ PyDoc_STRVAR(module_complete_doc, \n\ Checks if a string contains a complete SQL statement. Non-standard."); -#ifdef HAVE_SHARED_CACHE static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* kwargs) { @@ -159,7 +158,6 @@ PyDoc_STRVAR(module_enable_shared_cache_doc, \n\ Enable or disable shared cache mode for the calling thread.\n\ Experimental/Non-standard."); -#endif /* HAVE_SHARED_CACHE */ static PyObject* module_register_adapter(PyObject* self, PyObject* args) { @@ -253,10 +251,8 @@ static PyMethodDef module_methods[] = { METH_VARARGS | METH_KEYWORDS, module_connect_doc}, {"complete_statement", (PyCFunction)(void(*)(void))module_complete, METH_VARARGS | METH_KEYWORDS, module_complete_doc}, -#ifdef HAVE_SHARED_CACHE {"enable_shared_cache", (PyCFunction)(void(*)(void))module_enable_shared_cache, METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, -#endif {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, module_register_adapter_doc}, {"register_converter", (PyCFunction)module_register_converter, @@ -307,29 +303,17 @@ static const IntConstantPair _int_constants[] = { {"SQLITE_UPDATE", SQLITE_UPDATE}, {"SQLITE_ATTACH", SQLITE_ATTACH}, {"SQLITE_DETACH", SQLITE_DETACH}, -#if SQLITE_VERSION_NUMBER >= 3002001 {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, {"SQLITE_REINDEX", SQLITE_REINDEX}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003000 {"SQLITE_ANALYZE", SQLITE_ANALYZE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003007 {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003008 {"SQLITE_FUNCTION", SQLITE_FUNCTION}, -#endif -#if SQLITE_VERSION_NUMBER >= 3006008 {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, -#endif #if SQLITE_VERSION_NUMBER >= 3008003 {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, #endif -#if SQLITE_VERSION_NUMBER >= 3006011 {"SQLITE_DONE", SQLITE_DONE}, -#endif {(char*)NULL, 0} }; @@ -360,6 +344,11 @@ PyMODINIT_FUNC PyInit__sqlite3(void) PyObject *tmp_obj; int i; + if (sqlite3_libversion_number() < 3007003) { + PyErr_SetString(PyExc_ImportError, MODULE_NAME ": SQLite 3.7.3 or higher required"); + return NULL; + } + module = PyModule_Create(&_sqlite3module); if (!module || diff --git a/setup.py b/setup.py index 21a5a58981fc153..04b1358bc916e11 100644 --- a/setup.py +++ b/setup.py @@ -1452,7 +1452,6 @@ def detect_sqlite(self): sqlite_setup_debug = False # verbose debug prints from this script? # We hunt for #define SQLITE_VERSION "n.n.n" - # We need to find >= sqlite version 3.3.9, for sqlite3_prepare_v2 sqlite_incdir = sqlite_libdir = None sqlite_inc_paths = [ '/usr/include', '/usr/include/sqlite', @@ -1463,7 +1462,8 @@ def detect_sqlite(self): ] if CROSS_COMPILING: sqlite_inc_paths = [] - MIN_SQLITE_VERSION_NUMBER = (3, 7, 2) + # We need to find >= sqlite version 3.7.3, for sqlite3_create_function_v2() + MIN_SQLITE_VERSION_NUMBER = (3, 7, 3) MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER]) From 3030f5636c1801bf8e7016d0227682a77c98ac9c Mon Sep 17 00:00:00 2001 From: dxflores Date: Tue, 8 Sep 2020 08:28:45 +0100 Subject: [PATCH 263/486] bpo-41732: add iterator to memoryview (GH-22119) --- .../2020-09-06-20-27-10.bpo-41732.1SKv26.rst | 1 + Objects/memoryobject.c | 108 +++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst b/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst new file mode 100644 index 000000000000000..caf237f37f4dee2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst @@ -0,0 +1 @@ +Added an :term:`iterator` to :class:`memoryview`. diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 13d883ae4d35d6c..d328f4d40b7a42c 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -3160,6 +3160,112 @@ static PyMethodDef memory_methods[] = { {NULL, NULL} }; +/**************************************************************************/ +/* Memoryview Iterator */ +/**************************************************************************/ + +static PyTypeObject PyMemoryIter_Type; + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyMemoryViewObject *it_seq; // Set to NULL when iterator is exhausted + Py_ssize_t it_length; + const char *it_fmt; +} memoryiterobject; + +static void +memoryiter_dealloc(memoryiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +memoryiter_traverse(memoryiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +memoryiter_next(memoryiterobject *it) +{ + PyMemoryViewObject *seq; + seq = it->it_seq; + if (seq == NULL) { + return NULL; + } + + if (it->it_index < it->it_length) { + CHECK_RELEASED(seq); + Py_buffer *view = &(seq->view); + char *ptr = (char *)seq->view.buf; + + ptr += view->strides[0] * it->it_index++; + ptr = ADJUST_PTR(ptr, view->suboffsets, 0); + if (ptr == NULL) { + return NULL; + } + return unpack_single(ptr, it->it_fmt); + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +memory_iter(PyObject *seq) +{ + if (!PyMemoryView_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + PyMemoryViewObject *obj = (PyMemoryViewObject *)seq; + int ndims = obj->view.ndim; + if (ndims == 0) { + PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory"); + return NULL; + } + if (ndims != 1) { + PyErr_SetString(PyExc_NotImplementedError, + "multi-dimensional sub-views are not implemented"); + return NULL; + } + + const char *fmt = adjust_fmt(&obj->view); + if (fmt == NULL) { + return NULL; + } + + memoryiterobject *it; + it = PyObject_GC_New(memoryiterobject, &PyMemoryIter_Type); + if (it == NULL) { + return NULL; + } + it->it_fmt = fmt; + it->it_length = memory_length(obj); + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = obj; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + +static PyTypeObject PyMemoryIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "memory_iterator", + .tp_basicsize = sizeof(memoryiterobject), + // methods + .tp_dealloc = (destructor)memoryiter_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)memoryiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)memoryiter_next, +}; PyTypeObject PyMemoryView_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -3187,7 +3293,7 @@ PyTypeObject PyMemoryView_Type = { (inquiry)memory_clear, /* tp_clear */ memory_richcompare, /* tp_richcompare */ offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */ - 0, /* tp_iter */ + memory_iter, /* tp_iter */ 0, /* tp_iternext */ memory_methods, /* tp_methods */ 0, /* tp_members */ From 37727200e9ae0d0748744135295b226c7e17970c Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 8 Sep 2020 03:59:15 -0500 Subject: [PATCH 264/486] bpo-1635741: Port the termios to multi-phase init (PEP 489) (GH-22139) --- ...2020-09-07-11-35-02.bpo-1635741.rvIexb.rst | 2 + Modules/termios.c | 182 ++++++++++-------- 2 files changed, 103 insertions(+), 81 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst new file mode 100644 index 000000000000000..1e19b34b372d895 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst @@ -0,0 +1,2 @@ +Port the :mod:`termios` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/termios.c b/Modules/termios.c index 178ae4ee6e41dd2..cc0d5853f85e352 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -51,8 +51,6 @@ get_termios_state(PyObject *module) return (termiosmodulestate *)state; } -#define modulestate_global get_termios_state(PyState_FindModule(&termiosmodule)) - static int fdconv(PyObject* obj, void* p) { int fd; @@ -79,31 +77,32 @@ indexing in the cc array must be done using the symbolic constants defined\n\ in this module."); static PyObject * -termios_tcgetattr(PyObject *self, PyObject *args) +termios_tcgetattr(PyObject *module, PyObject *args) { int fd; - struct termios mode; - PyObject *cc; - speed_t ispeed, ospeed; - PyObject *v; - int i; - char ch; - if (!PyArg_ParseTuple(args, "O&:tcgetattr", - fdconv, (void*)&fd)) + fdconv, (void*)&fd)) { return NULL; + } - if (tcgetattr(fd, &mode) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + termiosmodulestate *state = PyModule_GetState(module); + struct termios mode; + if (tcgetattr(fd, &mode) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } - ispeed = cfgetispeed(&mode); - ospeed = cfgetospeed(&mode); + speed_t ispeed = cfgetispeed(&mode); + speed_t ospeed = cfgetospeed(&mode); - cc = PyList_New(NCCS); - if (cc == NULL) + PyObject *cc = PyList_New(NCCS); + if (cc == NULL) { return NULL; + } + + PyObject *v; + int i; for (i = 0; i < NCCS; i++) { - ch = (char)mode.c_cc[i]; + char ch = (char)mode.c_cc[i]; v = PyBytes_FromStringAndSize(&ch, 1); if (v == NULL) goto err; @@ -156,17 +155,15 @@ queued output, or termios.TCSAFLUSH to change after transmitting all\n\ queued output and discarding all queued input. "); static PyObject * -termios_tcsetattr(PyObject *self, PyObject *args) +termios_tcsetattr(PyObject *module, PyObject *args) { int fd, when; - struct termios mode; - speed_t ispeed, ospeed; - PyObject *term, *cc, *v; - int i; - + PyObject *term; if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", - fdconv, &fd, &when, &term)) + fdconv, &fd, &when, &term)) { return NULL; + } + if (!PyList_Check(term) || PyList_Size(term) != 7) { PyErr_SetString(PyExc_TypeError, "tcsetattr, arg 3: must be 7 element list"); @@ -174,18 +171,22 @@ termios_tcsetattr(PyObject *self, PyObject *args) } /* Get the old mode, in case there are any hidden fields... */ - termiosmodulestate *state = modulestate_global; - if (tcgetattr(fd, &mode) == -1) + termiosmodulestate *state = PyModule_GetState(module); + struct termios mode; + if (tcgetattr(fd, &mode) == -1) { return PyErr_SetFromErrno(state->TermiosError); + } + mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); - ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); - ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); - cc = PyList_GetItem(term, 6); - if (PyErr_Occurred()) + speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); + speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); + PyObject *cc = PyList_GetItem(term, 6); + if (PyErr_Occurred()) { return NULL; + } if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { PyErr_Format(PyExc_TypeError, @@ -194,6 +195,8 @@ termios_tcsetattr(PyObject *self, PyObject *args) return NULL; } + int i; + PyObject *v; for (i = 0; i < NCCS; i++) { v = PyList_GetItem(cc, i); @@ -226,15 +229,18 @@ A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\ has a system dependent meaning."); static PyObject * -termios_tcsendbreak(PyObject *self, PyObject *args) +termios_tcsendbreak(PyObject *module, PyObject *args) { int fd, duration; - if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", - fdconv, &fd, &duration)) + fdconv, &fd, &duration)) { return NULL; - if (tcsendbreak(fd, duration) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + } + + termiosmodulestate *state = PyModule_GetState(module); + if (tcsendbreak(fd, duration) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } @@ -245,15 +251,18 @@ PyDoc_STRVAR(termios_tcdrain__doc__, Wait until all output written to file descriptor fd has been transmitted."); static PyObject * -termios_tcdrain(PyObject *self, PyObject *args) +termios_tcdrain(PyObject *module, PyObject *args) { int fd; - if (!PyArg_ParseTuple(args, "O&:tcdrain", - fdconv, &fd)) + fdconv, &fd)) { return NULL; - if (tcdrain(fd) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + } + + termiosmodulestate *state = PyModule_GetState(module); + if (tcdrain(fd) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } @@ -267,15 +276,18 @@ queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\ both queues. "); static PyObject * -termios_tcflush(PyObject *self, PyObject *args) +termios_tcflush(PyObject *module, PyObject *args) { int fd, queue; - if (!PyArg_ParseTuple(args, "O&i:tcflush", - fdconv, &fd, &queue)) + fdconv, &fd, &queue)) { return NULL; - if (tcflush(fd, queue) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + } + + termiosmodulestate *state = PyModule_GetState(module); + if (tcflush(fd, queue) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } @@ -289,15 +301,18 @@ termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\ or termios.TCION to restart input."); static PyObject * -termios_tcflow(PyObject *self, PyObject *args) +termios_tcflow(PyObject *module, PyObject *args) { int fd, action; - if (!PyArg_ParseTuple(args, "O&i:tcflow", - fdconv, &fd, &action)) + fdconv, &fd, &action)) { return NULL; - if (tcflow(fd, action) == -1) - return PyErr_SetFromErrno(modulestate_global->TermiosError); + } + + termiosmodulestate *state = PyModule_GetState(module); + if (tcflow(fd, action) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } Py_RETURN_NONE; } @@ -997,44 +1012,49 @@ static void termiosmodule_free(void *m) { termiosmodule_clear((PyObject *)m); } -static struct PyModuleDef termiosmodule = { - PyModuleDef_HEAD_INIT, - "termios", - termios__doc__, - sizeof(termiosmodulestate), - termios_methods, - NULL, - termiosmodule_traverse, - termiosmodule_clear, - termiosmodule_free, -}; - -PyMODINIT_FUNC -PyInit_termios(void) +static int +termios_exec(PyObject *mod) { - PyObject *m; struct constant *constant = termios_constants; - - if ((m = PyState_FindModule(&termiosmodule)) != NULL) { - Py_INCREF(m); - return m; - } - - if ((m = PyModule_Create(&termiosmodule)) == NULL) { - return NULL; - } - - termiosmodulestate *state = get_termios_state(m); + termiosmodulestate *state = get_termios_state(mod); state->TermiosError = PyErr_NewException("termios.error", NULL, NULL); if (state->TermiosError == NULL) { - return NULL; + return -1; } Py_INCREF(state->TermiosError); - PyModule_AddObject(m, "error", state->TermiosError); + if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) { + Py_DECREF(state->TermiosError); + return -1; + } while (constant->name != NULL) { - PyModule_AddIntConstant(m, constant->name, constant->value); + if (PyModule_AddIntConstant( + mod, constant->name, constant->value) < 0) { + return -1; + } ++constant; } - return m; + return 0; +} + +static PyModuleDef_Slot termios_slots[] = { + {Py_mod_exec, termios_exec}, + {0, NULL} +}; + +static struct PyModuleDef termiosmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "termios", + .m_doc = termios__doc__, + .m_size = sizeof(termiosmodulestate), + .m_methods = termios_methods, + .m_slots = termios_slots, + .m_traverse = termiosmodule_traverse, + .m_clear = termiosmodule_clear, + .m_free = termiosmodule_free, +}; + +PyMODINIT_FUNC PyInit_termios(void) +{ + return PyModuleDef_Init(&termiosmodule); } From 729a5f2e26bcd8ef3ee9e2a0d4affe49cfe0734b Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 8 Sep 2020 04:16:14 -0500 Subject: [PATCH 265/486] bpo-1635741: Convert _sha256 types to heap types (GH-22134) Convert the _sha256 extension module types to heap types. --- ...2020-09-07-09-45-47.bpo-1635741.QuDIut.rst | 1 + Modules/clinic/sha256module.c.h | 21 +- Modules/sha256module.c | 208 +++++++++--------- 3 files changed, 127 insertions(+), 103 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst new file mode 100644 index 000000000000000..90e56542d1e97a2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst @@ -0,0 +1 @@ +Convert the :mod:`_sha256` extension module types to heap types. diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index 2a788ea98499f39..89205c4f14f4e4e 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -9,15 +9,26 @@ PyDoc_STRVAR(SHA256Type_copy__doc__, "Return a copy of the hash object."); #define SHA256TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__}, + {"copy", (PyCFunction)(void(*)(void))SHA256Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, static PyObject * -SHA256Type_copy_impl(SHAobject *self); +SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * -SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +SHA256Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return SHA256Type_copy_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":copy", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = SHA256Type_copy_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(SHA256Type_digest__doc__, @@ -166,4 +177,4 @@ _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=c8cca8adbe72ec9a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7283f75c9d08f30 input=a9049054013a1b77]*/ diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 06e4430bd7c3336..edd4d010928f387 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -51,6 +51,19 @@ typedef struct { #include "clinic/sha256module.c.h" +typedef struct { + PyTypeObject* sha224_type; + PyTypeObject* sha256_type; +} _sha256_state; + +static inline _sha256_state* +_sha256_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_sha256_state *)state; +} + /* When run on a little-endian CPU we need to perform byte reversal on an array of longwords. */ @@ -365,20 +378,17 @@ sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA224type; -static PyTypeObject SHA256type; - static SHAobject * -newSHA224object(void) +newSHA224object(_sha256_state *state) { - return (SHAobject *)PyObject_New(SHAobject, &SHA224type); + return (SHAobject *)PyObject_New(SHAobject, state->sha224_type); } static SHAobject * -newSHA256object(void) +newSHA256object(_sha256_state *state) { - return (SHAobject *)PyObject_New(SHAobject, &SHA256type); + return (SHAobject *)PyObject_New(SHAobject, state->sha256_type); } /* Internal methods for a hash object */ @@ -386,7 +396,9 @@ newSHA256object(void) static void SHA_dealloc(PyObject *ptr) { + PyTypeObject *tp = Py_TYPE(ptr); PyObject_Del(ptr); + Py_DECREF(tp); } @@ -395,21 +407,25 @@ SHA_dealloc(PyObject *ptr) /*[clinic input] SHA256Type.copy + cls:defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -SHA256Type_copy_impl(SHAobject *self) -/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/ +SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=9273f92c382be12f input=3137146fcb88e212]*/ { SHAobject *newobj; - - if (Py_IS_TYPE(self, &SHA256type)) { - if ( (newobj = newSHA256object())==NULL) + _sha256_state *state = PyType_GetModuleState(cls); + if (Py_IS_TYPE(self, state->sha256_type)) { + if ( (newobj = newSHA256object(state)) == NULL) { return NULL; + } } else { - if ( (newobj = newSHA224object())==NULL) + if ( (newobj = newSHA224object(state))==NULL) { return NULL; + } } SHAcopy(self, newobj); @@ -517,74 +533,27 @@ static PyMemberDef SHA_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA224type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha224", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +static PyType_Slot sha256_types_slots[] = { + {Py_tp_dealloc, SHA_dealloc}, + {Py_tp_methods, SHA_methods}, + {Py_tp_members, SHA_members}, + {Py_tp_getset, SHA_getseters}, + {0,0} }; -static PyTypeObject SHA256type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha256", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ +static PyType_Spec sha224_type_spec = { + .name = "_sha256.sha224", + .basicsize = sizeof(SHAobject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha256_types_slots }; +static PyType_Spec sha256_type_spec = { + .name = "_sha256.sha256", + .basicsize = sizeof(SHAobject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha256_types_slots +}; /* The single module-level function: new() */ @@ -602,15 +571,19 @@ static PyObject * _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=a1de327e8e1185cf input=9be86301aeb14ea5]*/ { - SHAobject *new; Py_buffer buf; - if (string) + if (string) { GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } - if ((new = newSHA256object()) == NULL) { - if (string) + _sha256_state *state = PyModule_GetState(module); + + SHAobject *new; + if ((new = newSHA256object(state)) == NULL) { + if (string) { PyBuffer_Release(&buf); + } return NULL; } @@ -618,8 +591,9 @@ _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) if (PyErr_Occurred()) { Py_DECREF(new); - if (string) + if (string) { PyBuffer_Release(&buf); + } return NULL; } if (string) { @@ -644,15 +618,17 @@ static PyObject * _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=08be6b36569bc69c input=9fcfb46e460860ac]*/ { - SHAobject *new; Py_buffer buf; - - if (string) + if (string) { GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } - if ((new = newSHA224object()) == NULL) { - if (string) + _sha256_state *state = PyModule_GetState(module); + SHAobject *new; + if ((new = newSHA224object(state)) == NULL) { + if (string) { PyBuffer_Release(&buf); + } return NULL; } @@ -660,8 +636,9 @@ _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) if (PyErr_Occurred()) { Py_DECREF(new); - if (string) + if (string) { PyBuffer_Release(&buf); + } return NULL; } if (string) { @@ -681,25 +658,56 @@ static struct PyMethodDef SHA_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_sha256_traverse(PyObject *module, visitproc visit, void *arg) +{ + _sha256_state *state = _sha256_get_state(module); + Py_VISIT(state->sha224_type); + Py_VISIT(state->sha256_type); + return 0; +} + +static int +_sha256_clear(PyObject *module) +{ + _sha256_state *state = _sha256_get_state(module); + Py_CLEAR(state->sha224_type); + Py_CLEAR(state->sha256_type); + return 0; +} + +static void +_sha256_free(void *module) +{ + _sha256_clear((PyObject *)module); +} + static int sha256_exec(PyObject *module) { - Py_SET_TYPE(&SHA224type, &PyType_Type); - if (PyType_Ready(&SHA224type) < 0) { + _sha256_state *state = _sha256_get_state(module); + + state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha224_type_spec, NULL); + + if (state->sha224_type == NULL) { return -1; } - Py_SET_TYPE(&SHA256type, &PyType_Type); - if (PyType_Ready(&SHA256type) < 0) { + + state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha256_type_spec, NULL); + + if (state->sha256_type == NULL) { return -1; } - Py_INCREF((PyObject *)&SHA224type); - if (PyModule_AddObject(module, "SHA224Type", (PyObject *)&SHA224type) < 0) { - Py_DECREF((PyObject *)&SHA224type); + Py_INCREF((PyObject *)state->sha224_type); + if (PyModule_AddObject(module, "SHA224Type", (PyObject *)state->sha224_type) < 0) { + Py_DECREF((PyObject *)state->sha224_type); return -1; } - Py_INCREF((PyObject *)&SHA256type); - if (PyModule_AddObject(module, "SHA256Type", (PyObject *)&SHA256type) < 0) { - Py_DECREF((PyObject *)&SHA256type); + Py_INCREF((PyObject *)state->sha256_type); + if (PyModule_AddObject(module, "SHA256Type", (PyObject *)state->sha256_type) < 0) { + Py_DECREF((PyObject *)state->sha256_type); return -1; } return 0; @@ -713,8 +721,12 @@ static PyModuleDef_Slot _sha256_slots[] = { static struct PyModuleDef _sha256module = { PyModuleDef_HEAD_INIT, .m_name = "_sha256", + .m_size = sizeof(_sha256_state), .m_methods = SHA_functions, .m_slots = _sha256_slots, + .m_traverse = _sha256_traverse, + .m_clear = _sha256_clear, + .m_free = _sha256_free }; /* Initialize this module. */ From e428ebeb22e3d370ed0369f89af339a3c3261918 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 8 Sep 2020 15:33:08 +0200 Subject: [PATCH 266/486] bpo-1635741: Port _string module to multi-phase init (GH-22148) Port the _string extension module to the multi-phase initialization API (PEP 489). --- .../2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst | 2 ++ Objects/unicodeobject.c | 14 +++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst b/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst new file mode 100644 index 000000000000000..972d69b94b6ba6c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst @@ -0,0 +1,2 @@ +Port the ``_string`` extension module to the multi-phase initialization API +(:pep:`489`). diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 82e09ad05fcd13e..fd0e8e008adae4c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -16243,20 +16243,16 @@ static PyMethodDef _string_methods[] = { static struct PyModuleDef _string_module = { PyModuleDef_HEAD_INIT, - "_string", - PyDoc_STR("string helper module"), - 0, - _string_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_string", + .m_doc = PyDoc_STR("string helper module"), + .m_size = 0, + .m_methods = _string_methods, }; PyMODINIT_FUNC PyInit__string(void) { - return PyModule_Create(&_string_module); + return PyModuleDef_Init(&_string_module); } From 08225861663dde8ae1ccad068a1ff561d8bffa92 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 8 Sep 2020 15:33:52 +0200 Subject: [PATCH 267/486] bpo-1635741: Port mashal module to multi-phase init (#22149) Port the 'mashal' extension module to the multi-phase initialization API (PEP 489). --- ...2020-09-08-13-55-34.bpo-1635741.56MLP-.rst | 2 ++ Python/marshal.c | 34 ++++++++++--------- 2 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst b/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst new file mode 100644 index 000000000000000..8b5bd5efdc2c09e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst @@ -0,0 +1,2 @@ +Port the ``mashal`` extension module to the multi-phase initialization API +(:pep:`489`). diff --git a/Python/marshal.c b/Python/marshal.c index c4538bd373a82ef..91a0f8acb12487c 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1785,28 +1785,30 @@ dumps() -- marshal value as a bytes object\n\ loads() -- read value from a bytes-like object"); +static int +marshal_module_exec(PyObject *mod) +{ + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot marshalmodule_slots[] = { + {Py_mod_exec, marshal_module_exec}, + {0, NULL} +}; static struct PyModuleDef marshalmodule = { PyModuleDef_HEAD_INIT, - "marshal", - module_doc, - 0, - marshal_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "marshal", + .m_doc = module_doc, + .m_methods = marshal_methods, + .m_slots = marshalmodule_slots, }; PyMODINIT_FUNC PyMarshal_Init(void) { - PyObject *mod = PyModule_Create(&marshalmodule); - if (mod == NULL) - return NULL; - if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { - Py_DECREF(mod); - return NULL; - } - return mod; + return PyModuleDef_Init(&marshalmodule); } From 11b1d6236e22bf6d5cd77e1044655eefcd80235f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 8 Sep 2020 17:47:14 +0100 Subject: [PATCH 268/486] Fix incorrect bpo number in change notes. (GH-22151) --- Misc/NEWS.d/3.9.0a2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/3.9.0a2.rst b/Misc/NEWS.d/3.9.0a2.rst index 50478c08e90189a..1fd23b763e2a1ed 100644 --- a/Misc/NEWS.d/3.9.0a2.rst +++ b/Misc/NEWS.d/3.9.0a2.rst @@ -229,7 +229,7 @@ coroutine of an asynchronous generator. .. -.. bpo: 32949 +.. bpo: 33387 .. date: 2018-03-13-14-46-03 .. nonce: v821M7 .. section: Core and Builtins From 42888aa139f583ea516c3ad7a5eae1618c763125 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Tue, 8 Sep 2020 20:40:04 +0100 Subject: [PATCH 269/486] bpo-38762: Extend logging.test_multiprocessing to cover missing cases. (GH-22142) --- Lib/test/test_logging.py | 62 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 00a4825d6da88d4..d23fbfb4fe281b1 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4354,15 +4354,65 @@ def test_dict_arg(self): r.removeHandler(h) h.close() - def test_multiprocessing(self): - r = logging.makeLogRecord({}) - self.assertEqual(r.processName, 'MainProcess') + @staticmethod # pickled as target of child process in the following test + def _extract_logrecord_process_name(key, logMultiprocessing, conn=None): + prev_logMultiprocessing = logging.logMultiprocessing + logging.logMultiprocessing = logMultiprocessing try: import multiprocessing as mp + name = mp.current_process().name + + r1 = logging.makeLogRecord({'msg': f'msg1_{key}'}) + del sys.modules['multiprocessing'] + r2 = logging.makeLogRecord({'msg': f'msg2_{key}'}) + + results = {'processName' : name, + 'r1.processName': r1.processName, + 'r2.processName': r2.processName, + } + finally: + logging.logMultiprocessing = prev_logMultiprocessing + if conn: + conn.send(results) + else: + return results + + def test_multiprocessing(self): + multiprocessing_imported = 'multiprocessing' in sys.modules + try: + # logMultiprocessing is True by default + self.assertEqual(logging.logMultiprocessing, True) + + LOG_MULTI_PROCESSING = True + # When logMultiprocessing == True: + # In the main process processName = 'MainProcess' r = logging.makeLogRecord({}) - self.assertEqual(r.processName, mp.current_process().name) - except ImportError: - pass + self.assertEqual(r.processName, 'MainProcess') + + results = self._extract_logrecord_process_name(1, LOG_MULTI_PROCESSING) + self.assertEqual('MainProcess', results['processName']) + self.assertEqual('MainProcess', results['r1.processName']) + self.assertEqual('MainProcess', results['r2.processName']) + + # In other processes, processName is correct when multiprocessing in imported, + # but it is (incorrectly) defaulted to 'MainProcess' otherwise (bpo-38762). + import multiprocessing + parent_conn, child_conn = multiprocessing.Pipe() + p = multiprocessing.Process( + target=self._extract_logrecord_process_name, + args=(2, LOG_MULTI_PROCESSING, child_conn,) + ) + p.start() + results = parent_conn.recv() + self.assertNotEqual('MainProcess', results['processName']) + self.assertEqual(results['processName'], results['r1.processName']) + self.assertEqual('MainProcess', results['r2.processName']) + p.join() + + finally: + if multiprocessing_imported: + import multiprocessing + def test_optional(self): r = logging.makeLogRecord({}) From e7879bc68bca98cc34050a2db9ea8ad91d99f90d Mon Sep 17 00:00:00 2001 From: Graham Bleaney Date: Tue, 8 Sep 2020 18:41:10 -0400 Subject: [PATCH 270/486] Fix typo in typing.py (GH-22121) This is a trivial PR to fix a typo in a docstring in typing.py. From reverences -> references --- Lib/typing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/typing.py b/Lib/typing.py index fce8da4fe3cf05d..2899a0213d43407 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -245,7 +245,7 @@ def inner(*args, **kwds): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): - """Evaluate all forward reverences in the given type t. + """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). recursive_guard is used to prevent prevent infinite recursion with recursive ForwardRef. From c8e0c09a906781bd089b2ef9bafd90bbb5898bd0 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Tue, 8 Sep 2020 20:39:19 -0300 Subject: [PATCH 271/486] [doc] Fix padding in timeit (GH-22152) Compare -p and -u options help in rendered output to see the difference. --- Doc/library/timeit.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 46fa62c15fc2ef0..668fcb860cea87b 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -233,7 +233,7 @@ Where the following options are understood: .. cmdoption:: -u, --unit=U - specify a time unit for timer output; can select nsec, usec, msec, or sec + specify a time unit for timer output; can select nsec, usec, msec, or sec .. versionadded:: 3.5 From 671d847812e6dce0502db95270d493c34e5fda1c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 9 Sep 2020 03:28:02 +0300 Subject: [PATCH 272/486] bpo-41525: Make the Python program help ASCII-only (GH-21836) --- Lib/test/test_cmd_line.py | 6 +++++- .../2020-08-12-07-35-07.bpo-41525.d9q3XL.rst | 1 + Misc/python.man | 2 +- Python/initconfig.c | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 4794d446f08c794..fa3329efa28b827 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -46,7 +46,11 @@ def test_site_flag(self): def test_usage(self): rc, out, err = assert_python_ok('-h') - self.assertIn(b'usage', out) + lines = out.splitlines() + self.assertIn(b'usage', lines[0]) + # The first line contains the program name, + # but the rest should be ASCII-only + b''.join(lines[1:]).decode('ascii') def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst new file mode 100644 index 000000000000000..acc00f8b992c916 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst @@ -0,0 +1 @@ +The output of ``python --help`` contains now only ASCII characters. diff --git a/Misc/python.man b/Misc/python.man index 74b2d72939eeb45..225376574a26a96 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -291,7 +291,7 @@ Set implementation specific option. The following options are available: nested imports). Note that its output may be broken in multi-threaded application. Typical usage is python3 -X importtime -c 'import asyncio' - -X dev: enable CPython’s “development mode”, introducing additional runtime + -X dev: enable CPython's "development mode", introducing additional runtime checks which are too expensive to be enabled by default. It will not be more verbose than the default if the code is correct: new warnings are only emitted when an issue is detected. Effect of the developer mode: diff --git a/Python/initconfig.c b/Python/initconfig.c index 64286763b621edf..38d64b63afcc9c1 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -83,7 +83,7 @@ static const char usage_3[] = "\ cumulative time (including nested imports) and self time (excluding\n\ nested imports). Note that its output may be broken in multi-threaded\n\ application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ - -X dev: enable CPython’s “development mode”, introducing additional runtime\n\ + -X dev: enable CPython's \"development mode\", introducing additional runtime\n\ checks which are too expensive to be enabled by default. Effect of the\n\ developer mode:\n\ * Add default warning filter, as -W default\n\ From 77fa3a3c4cb2f71aac55a47d056fe159964a4a35 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 8 Sep 2020 22:28:48 -0500 Subject: [PATCH 273/486] bpo-1635741: port scproxy to multi-phase init (GH-22164) --- ...2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst | 2 ++ Modules/_scproxy.c | 22 ++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst new file mode 100644 index 000000000000000..17752b2ccd3fad9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst @@ -0,0 +1,2 @@ +Port the :mod:`_scproxy` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index dbee3f7367edeb0..4c1f1aa300c7172 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -231,21 +231,18 @@ static PyMethodDef mod_methods[] = { { 0, 0, 0, 0 } }; +static PyModuleDef_Slot _scproxy_slots[] = { + {0, NULL} +}; - -static struct PyModuleDef mod_module = { +static struct PyModuleDef _scproxy_module = { PyModuleDef_HEAD_INIT, - "_scproxy", - NULL, - -1, - mod_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_scproxy", + .m_size = 0, + .m_methods = mod_methods, + .m_slots = _scproxy_slots, }; - #ifdef __cplusplus extern "C" { #endif @@ -253,10 +250,9 @@ extern "C" { PyMODINIT_FUNC PyInit__scproxy(void) { - return PyModule_Create(&mod_module); + return PyModuleDef_Init(&_scproxy_module); } #ifdef __cplusplus } #endif - From c089604373bb0477cdfbe67937d51c5e5c6c389d Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Wed, 9 Sep 2020 17:48:44 +0800 Subject: [PATCH 274/486] bpo-41726: Update the refcounts info of PyType_FromModuleAndSpec in refcounts.dat (GH-22112) Update refcounts info of PyType_FromModuleAndSpec in refcounts.dat --- Doc/data/refcounts.dat | 5 +++++ .../Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst | 1 + 2 files changed, 6 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 882d7d6d62fc39d..355a4d6d3fa7ba1 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -2283,6 +2283,11 @@ PyType_CheckExact:PyObject*:o:0: PyType_FromSpec:PyObject*::+1: PyType_FromSpec:PyType_Spec*:spec:: +PyType_FromModuleAndSpec:PyObject*::+1: +PyType_FromModuleAndSpec:PyObject*:module:+1: +PyType_FromModuleAndSpec:PyType_Spec*:spec:: +PyType_FromModuleAndSpec:PyObject*:bases:0: + PyType_FromSpecWithBases:PyObject*::+1: PyType_FromSpecWithBases:PyType_Spec*:spec:: PyType_FromSpecWithBases:PyObject*:bases:0: diff --git a/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst b/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst new file mode 100644 index 000000000000000..1079a757c054ac9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst @@ -0,0 +1 @@ +Update the refcounts info of ``PyType_FromModuleAndSpec``. From 6710795ad9e2937e80b9db0321a7178907bd72f8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Sep 2020 12:07:17 +0200 Subject: [PATCH 275/486] Fix compiler warnings in init_dump_ascii_wstr() (GH-22150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix GCC 9.3 (using -O3) warnings on x86: initconfig.c: In function ‘init_dump_ascii_wstr’: initconfig.c:2679:34: warning: format ‘%lc’ expects argument of type ‘wint_t’, but argument 2 has type ‘wchar_t’ {aka ‘long int’} 2679 | PySys_WriteStderr("%lc", ch); initconfig.c:2682:38: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘wchar_t’ {aka ‘long int’} 2682 | PySys_WriteStderr("\\x%02x", ch); initconfig.c:2686:38: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘wchar_t’ {aka ‘long int’} 2686 | PySys_WriteStderr("\\U%08x", ch); initconfig.c:2690:38: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘wchar_t’ {aka ‘long int’} 2690 | PySys_WriteStderr("\\u%04x", ch); --- Python/initconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index 38d64b63afcc9c1..880e145ec031cd1 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2670,7 +2670,7 @@ init_dump_ascii_wstr(const wchar_t *str) PySys_WriteStderr("'"); for (; *str != L'\0'; str++) { - wchar_t ch = *str; + unsigned int ch = (unsigned int)*str; if (ch == L'\'') { PySys_WriteStderr("\\'"); } else if (0x20 <= ch && ch < 0x7f) { From 8d8aa8ca25cb0652a16807bd9f689999dafd274c Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Wed, 9 Sep 2020 11:21:22 +0100 Subject: [PATCH 276/486] Add minor clarification in logging documentation. (GH-22167) --- Doc/library/logging.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 19691d50937a71f..989016e649d6519 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -575,9 +575,9 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on pickled and sent across the wire, but you should be careful if you have more than one :class:`Formatter` subclass which customizes the formatting of exception information. In this case, you will have to clear the cached - value after a formatter has done its formatting, so that the next - formatter to handle the event doesn't use the cached value but - recalculates it afresh. + value (by setting the *exc_text* attribute to ``None``) after a formatter + has done its formatting, so that the next formatter to handle the event + doesn't use the cached value, but recalculates it afresh. If stack information is available, it's appended after the exception information, using :meth:`formatStack` to transform it if necessary. From bcbd616a2a1ddcb487fa154ebb1764635bc06f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= Date: Wed, 9 Sep 2020 21:29:42 +0200 Subject: [PATCH 277/486] bpo-41687: Fix error handling in Solaris sendfile implementation (GH-22128) I just realized that my recent PR with sendfile on Solaris ([PR 22040](https://github.com/python/cpython/pull/22040)) has broken error handling. Sorry for that, this simple followup fixes that. Automerge-Triggered-By: @1st1 --- Modules/posixmodule.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 00ba7580302bbab..7c496938ed4c5e5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9521,14 +9521,13 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, #if defined(__sun) && defined(__SVR4) // On Solaris, sendfile raises EINVAL rather than returning 0 // when the offset is equal or bigger than the in_fd size. - int res; struct stat st; do { Py_BEGIN_ALLOW_THREADS - res = fstat(in_fd, &st); + ret = fstat(in_fd, &st); Py_END_ALLOW_THREADS - } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) return (!async_err) ? posix_error() : NULL; From 293703dc67f5adb83f84dd1160f7d3e2c734ee38 Mon Sep 17 00:00:00 2001 From: Maggie Moss Date: Wed, 9 Sep 2020 13:23:24 -0700 Subject: [PATCH 278/486] bpo-41428: Implementation for PEP 604 (GH-21515) See https://www.python.org/dev/peps/pep-0604/ for more information. Co-authored-by: Pablo Galindo --- Include/internal/pycore_unionobject.h | 17 + Lib/test/test_isinstance.py | 32 ++ Lib/test/test_types.py | 114 +++++ Lib/test/test_typing.py | 6 - Lib/types.py | 1 + Lib/typing.py | 31 +- Makefile.pre.in | 2 + .../2020-07-28-22-43-27.bpo-41428.FM6xsI.rst | 1 + Objects/abstract.c | 15 +- Objects/typeobject.c | 19 +- Objects/unionobject.c | 464 ++++++++++++++++++ PCbuild/pythoncore.vcxproj | 2 + PCbuild/pythoncore.vcxproj.filters | 6 + 13 files changed, 693 insertions(+), 17 deletions(-) create mode 100644 Include/internal/pycore_unionobject.h create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst create mode 100644 Objects/unionobject.c diff --git a/Include/internal/pycore_unionobject.h b/Include/internal/pycore_unionobject.h new file mode 100644 index 000000000000000..fa8ba6ed944c1ab --- /dev/null +++ b/Include/internal/pycore_unionobject.h @@ -0,0 +1,17 @@ +#ifndef Py_INTERNAL_UNIONOBJECT_H +#define Py_INTERNAL_UNIONOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +PyAPI_FUNC(PyObject *) _Py_Union(PyObject *args); +PyAPI_DATA(PyTypeObject) _Py_UnionType; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UNIONOBJECT_H */ diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 53639e984e48a78..91e79c295481db8 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -4,6 +4,7 @@ import unittest import sys +import typing @@ -208,6 +209,25 @@ def test_isinstance_abstract(self): self.assertEqual(False, isinstance(AbstractChild(), Super)) self.assertEqual(False, isinstance(AbstractChild(), Child)) + def test_isinstance_with_or_union(self): + self.assertTrue(isinstance(Super(), Super | int)) + self.assertFalse(isinstance(None, str | int)) + self.assertTrue(isinstance(3, str | int)) + self.assertTrue(isinstance("", str | int)) + self.assertTrue(isinstance([], typing.List | typing.Tuple)) + self.assertTrue(isinstance(2, typing.List | int)) + self.assertFalse(isinstance(2, typing.List | typing.Tuple)) + self.assertTrue(isinstance(None, int | None)) + self.assertFalse(isinstance(3.14, int | str)) + with self.assertRaises(TypeError): + isinstance(2, list[int]) + with self.assertRaises(TypeError): + isinstance(2, list[int] | int) + with self.assertRaises(TypeError): + isinstance(2, int | str | list[int] | float) + + + def test_subclass_normal(self): # normal classes self.assertEqual(True, issubclass(Super, Super)) @@ -217,6 +237,8 @@ def test_subclass_normal(self): self.assertEqual(True, issubclass(Child, Child)) self.assertEqual(True, issubclass(Child, Super)) self.assertEqual(False, issubclass(Child, AbstractSuper)) + self.assertTrue(issubclass(typing.List, typing.List|typing.Tuple)) + self.assertFalse(issubclass(int, typing.List|typing.Tuple)) def test_subclass_abstract(self): # abstract classes @@ -251,6 +273,16 @@ def test_isinstance_recursion_limit(self): # blown self.assertRaises(RecursionError, blowstack, isinstance, '', str) + def test_subclass_with_union(self): + self.assertTrue(issubclass(int, int | float | int)) + self.assertTrue(issubclass(str, str | Child | str)) + self.assertFalse(issubclass(dict, float|str)) + self.assertFalse(issubclass(object, float|str)) + with self.assertRaises(TypeError): + issubclass(2, Child | Super) + with self.assertRaises(TypeError): + issubclass(int, list[int] | Child) + def test_issubclass_refcount_handling(self): # bpo-39382: abstract_issubclass() didn't hold item reference while # peeking in the bases tuple, in the single inheritance case. diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 49dc5bf40e3ed84..f499fb9c8c51a44 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -2,6 +2,7 @@ from test.support import run_with_locale import collections.abc +from collections import namedtuple import inspect import pickle import locale @@ -9,6 +10,12 @@ import types import unittest.mock import weakref +import typing + +class Example: + pass + +class Forward: ... class TypesTests(unittest.TestCase): @@ -598,6 +605,113 @@ def test_method_descriptor_types(self): self.assertIsInstance(int.from_bytes, types.BuiltinMethodType) self.assertIsInstance(int.__new__, types.BuiltinMethodType) + def test_or_types_operator(self): + self.assertEqual(int | str, typing.Union[int, str]) + self.assertNotEqual(int | list, typing.Union[int, str]) + self.assertEqual(str | int, typing.Union[int, str]) + self.assertEqual(int | None, typing.Union[int, None]) + self.assertEqual(None | int, typing.Union[int, None]) + self.assertEqual(int | str | list, typing.Union[int, str, list]) + self.assertEqual(int | (str | list), typing.Union[int, str, list]) + self.assertEqual(str | (int | list), typing.Union[int, str, list]) + self.assertEqual(typing.List | typing.Tuple, typing.Union[typing.List, typing.Tuple]) + self.assertEqual(typing.List[int] | typing.Tuple[int], typing.Union[typing.List[int], typing.Tuple[int]]) + self.assertEqual(typing.List[int] | None, typing.Union[typing.List[int], None]) + self.assertEqual(None | typing.List[int], typing.Union[None, typing.List[int]]) + self.assertEqual(str | float | int | complex | int, (int | str) | (float | complex)) + self.assertEqual(typing.Union[str, int, typing.List[int]], str | int | typing.List[int]) + self.assertEqual(int | int, int) + self.assertEqual( + BaseException | + bool | + bytes | + complex | + float | + int | + list | + map | + set, + typing.Union[ + BaseException, + bool, + bytes, + complex, + float, + int, + list, + map, + set, + ]) + with self.assertRaises(TypeError): + int | 3 + with self.assertRaises(TypeError): + 3 | int + with self.assertRaises(TypeError): + Example() | int + with self.assertRaises(TypeError): + (int | str) < typing.Union[str, int] + with self.assertRaises(TypeError): + (int | str) < (int | bool) + with self.assertRaises(TypeError): + (int | str) <= (int | str) + with self.assertRaises(TypeError): + # Check that we don't crash if typing.Union does not have a tuple in __args__ + x = typing.Union[str, int] + x.__args__ = [str, int] + (int | str ) == x + + def test_or_type_operator_with_TypeVar(self): + TV = typing.TypeVar('T') + assert TV | str == typing.Union[TV, str] + assert str | TV == typing.Union[str, TV] + + def test_or_type_operator_with_forward(self): + T = typing.TypeVar('T') + ForwardAfter = T | 'Forward' + ForwardBefore = 'Forward' | T + def forward_after(x: ForwardAfter[int]) -> None: ... + def forward_before(x: ForwardBefore[int]) -> None: ... + assert typing.get_args(typing.get_type_hints(forward_after)['x']) == (int, Forward) + assert typing.get_args(typing.get_type_hints(forward_before)['x']) == (int, Forward) + + def test_or_type_operator_with_Protocol(self): + class Proto(typing.Protocol): + def meth(self) -> int: + ... + assert Proto | str == typing.Union[Proto, str] + + def test_or_type_operator_with_Alias(self): + assert list | str == typing.Union[list, str] + assert typing.List | str == typing.Union[typing.List, str] + + def test_or_type_operator_with_NamedTuple(self): + NT=namedtuple('A', ['B', 'C', 'D']) + assert NT | str == typing.Union[NT,str] + + def test_or_type_operator_with_TypedDict(self): + class Point2D(typing.TypedDict): + x: int + y: int + label: str + assert Point2D | str == typing.Union[Point2D, str] + + def test_or_type_operator_with_NewType(self): + UserId = typing.NewType('UserId', int) + assert UserId | str == typing.Union[UserId, str] + + def test_or_type_operator_with_IO(self): + assert typing.IO | str == typing.Union[typing.IO, str] + + def test_or_type_operator_with_SpecialForm(self): + assert typing.Any | str == typing.Union[typing.Any, str] + assert typing.NoReturn | str == typing.Union[typing.NoReturn, str] + assert typing.Optional[int] | str == typing.Union[typing.Optional[int], str] + assert typing.Optional[int] | str == typing.Union[int, str, None] + assert typing.Union[int, bool] | str == typing.Union[int, bool, str] + + def test_or_type_repr(self): + assert repr(int | None) == "int | None" + assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]" class MappingProxyTests(unittest.TestCase): mappingproxy = types.MappingProxyType diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index b3be99141afca99..05140fc61b9bf5d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -244,8 +244,6 @@ def test_subclass_error(self): issubclass(int, Union) with self.assertRaises(TypeError): issubclass(Union, int) - with self.assertRaises(TypeError): - issubclass(int, Union[int, str]) with self.assertRaises(TypeError): issubclass(Union[int, str], int) @@ -347,10 +345,6 @@ def test_empty(self): with self.assertRaises(TypeError): Union[()] - def test_union_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, Union[int, str]) - def test_no_eval_union(self): u = Union[int, str] def f(x: u): ... diff --git a/Lib/types.py b/Lib/types.py index ad2020ec69b637f..9642e7212caac64 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -294,6 +294,7 @@ def wrapped(*args, **kwargs): GenericAlias = type(list[int]) +Union = type(int | str) __all__ = [n for n in globals() if n[:1] != '_'] diff --git a/Lib/typing.py b/Lib/typing.py index 2899a0213d43407..2aedbeb852a7126 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -117,7 +117,6 @@ # namespace, but excluded from __all__ because they might stomp on # legitimate imports of those modules. - def _type_check(arg, msg, is_argument=True): """Check that the argument is a type, and return it (internal helper). @@ -145,7 +144,7 @@ def _type_check(arg, msg, is_argument=True): return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef)): + if isinstance(arg, (type, TypeVar, ForwardRef, types.Union)): return arg if not callable(arg): raise TypeError(f"{msg} Got {arg!r:.100}.") @@ -205,7 +204,7 @@ def _remove_dups_flatten(parameters): # Flatten out Union[Union[...], ...]. params = [] for p in parameters: - if isinstance(p, _UnionGenericAlias): + if isinstance(p, (_UnionGenericAlias, types.Union)): params.extend(p.__args__) elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union: params.extend(p[1:]) @@ -586,6 +585,12 @@ def __init__(self, name, *constraints, bound=None, if def_mod != 'typing': self.__module__ = def_mod + def __or__(self, right): + return Union[self, right] + + def __ror__(self, right): + return Union[self, right] + def __repr__(self): if self.__covariant__: prefix = '+' @@ -693,6 +698,12 @@ def __eq__(self, other): def __hash__(self): return hash((self.__origin__, self.__args__)) + def __or__(self, right): + return Union[self, right] + + def __ror__(self, right): + return Union[self, right] + @_tp_cache def __getitem__(self, params): if self.__origin__ in (Generic, Protocol): @@ -792,6 +803,11 @@ def __subclasscheck__(self, cls): def __reduce__(self): return self._name + def __or__(self, right): + return Union[self, right] + + def __ror__(self, right): + return Union[self, right] class _CallableGenericAlias(_GenericAlias, _root=True): def __repr__(self): @@ -878,6 +894,15 @@ def __repr__(self): return f'typing.Optional[{_type_repr(args[0])}]' return super().__repr__() + def __instancecheck__(self, obj): + return self.__subclasscheck__(type(obj)) + + def __subclasscheck__(self, cls): + for arg in self.__args__: + if issubclass(cls, arg): + return True + + class Generic: """Abstract base class for generic types. diff --git a/Makefile.pre.in b/Makefile.pre.in index 5d3ac705a36253e..921bd08ea505d6c 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -432,6 +432,7 @@ OBJECT_OBJS= \ Objects/typeobject.o \ Objects/unicodeobject.o \ Objects/unicodectype.o \ + Objects/unionobject.o \ Objects/weakrefobject.o ########################################################################## @@ -1128,6 +1129,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_sysmodule.h \ $(srcdir)/Include/internal/pycore_traceback.h \ $(srcdir)/Include/internal/pycore_tuple.h \ + $(srcdir)/Include/internal/pycore_unionobject.h \ $(srcdir)/Include/internal/pycore_warnings.h \ $(DTRACE_HEADERS) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst new file mode 100644 index 000000000000000..a6652de92751177 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst @@ -0,0 +1 @@ +Implement PEP 604. This supports (int | str) etc. in place of Union[str, int]. \ No newline at end of file diff --git a/Objects/abstract.c b/Objects/abstract.c index 7bd72c9b5dcc269..c471f184f6c8487 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1,6 +1,7 @@ /* Abstract Object Interface (many thanks to Jim Fulton) */ #include "Python.h" +#include "pycore_unionobject.h" // _Py_UnionType && _Py_Union() #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_pyerrors.h" // _PyErr_Occurred() @@ -839,7 +840,6 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) Py_TYPE(w)->tp_name); return NULL; } - return binop_type_error(v, w, op_name); } return result; @@ -2412,7 +2412,6 @@ object_isinstance(PyObject *inst, PyObject *cls) PyObject *icls; int retval; _Py_IDENTIFIER(__class__); - if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); if (retval == 0) { @@ -2432,7 +2431,7 @@ object_isinstance(PyObject *inst, PyObject *cls) } else { if (!check_class(cls, - "isinstance() arg 2 must be a type or tuple of types")) + "isinstance() arg 2 must be a type, a tuple of types or a union")) return -1; retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); if (icls != NULL) { @@ -2525,10 +2524,14 @@ recursive_issubclass(PyObject *derived, PyObject *cls) if (!check_class(derived, "issubclass() arg 1 must be a class")) return -1; - if (!check_class(cls, - "issubclass() arg 2 must be a class" - " or tuple of classes")) + + PyTypeObject *type = Py_TYPE(cls); + int is_union = (PyType_Check(type) && type == &_Py_UnionType); + if (!is_union && !check_class(cls, + "issubclass() arg 2 must be a class," + " a tuple of classes, or a union.")) { return -1; + } return abstract_issubclass(derived, cls); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 74040757a07021b..3bb2c338fe0b530 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6,6 +6,7 @@ #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_unionobject.h" // _Py_Union() #include "frameobject.h" #include "structmember.h" // PyMemberDef @@ -3753,6 +3754,21 @@ type_is_gc(PyTypeObject *type) return type->tp_flags & Py_TPFLAGS_HEAPTYPE; } +static PyObject * +type_or(PyTypeObject* self, PyObject* param) { + PyObject *tuple = PyTuple_Pack(2, self, param); + if (tuple == NULL) { + return NULL; + } + PyObject *new_union = _Py_Union(tuple); + Py_DECREF(tuple); + return new_union; +} + +static PyNumberMethods type_as_number = { + .nb_or = (binaryfunc)type_or, // Add __or__ function +}; + PyTypeObject PyType_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "type", /* tp_name */ @@ -3764,7 +3780,7 @@ PyTypeObject PyType_Type = { 0, /* tp_setattr */ 0, /* tp_as_async */ (reprfunc)type_repr, /* tp_repr */ - 0, /* tp_as_number */ + &type_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ @@ -5598,7 +5614,6 @@ PyType_Ready(PyTypeObject *type) add_subclass((PyTypeObject *)b, type) < 0) goto error; } - /* All done -- set the ready flag */ type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; diff --git a/Objects/unionobject.c b/Objects/unionobject.c new file mode 100644 index 000000000000000..0ef7abb4c55c28e --- /dev/null +++ b/Objects/unionobject.c @@ -0,0 +1,464 @@ +// types.Union -- used to represent e.g. Union[int, str], int | str +#include "Python.h" +#include "pycore_unionobject.h" +#include "structmember.h" + + +typedef struct { + PyObject_HEAD + PyObject *args; +} unionobject; + +static void +unionobject_dealloc(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + + Py_XDECREF(alias->args); + self->ob_type->tp_free(self); +} + +static Py_hash_t +union_hash(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + Py_hash_t h1 = PyObject_Hash(alias->args); + if (h1 == -1) { + return -1; + } + return h1; +} + +static int +is_generic_alias_in_args(PyObject *args) { + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(args, iarg); + if (Py_TYPE(arg) == &Py_GenericAliasType) { + return 0; + } + } + return 1; +} + +static PyObject * +union_instancecheck(PyObject *self, PyObject *instance) +{ + unionobject *alias = (unionobject *) self; + Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); + if (!is_generic_alias_in_args(alias->args)) { + PyErr_SetString(PyExc_TypeError, + "isinstance() argument 2 cannot contain a parameterized generic"); + return NULL; + } + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); + if (arg == Py_None) { + arg = (PyObject *)&_PyNone_Type; + } + if (PyType_Check(arg) && PyObject_IsInstance(instance, arg) != 0) { + Py_RETURN_TRUE; + } + } + Py_RETURN_FALSE; +} + +static PyObject * +union_subclasscheck(PyObject *self, PyObject *instance) +{ + if (!PyType_Check(instance)) { + PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class"); + return NULL; + } + unionobject *alias = (unionobject *)self; + if (!is_generic_alias_in_args(alias->args)) { + PyErr_SetString(PyExc_TypeError, + "issubclass() argument 2 cannot contain a parameterized generic"); + return NULL; + } + Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); + if (PyType_Check(arg) && (PyType_IsSubtype((PyTypeObject *)instance, (PyTypeObject *)arg) != 0)) { + Py_RETURN_TRUE; + } + } + Py_RETURN_FALSE; +} + +static int +is_typing_module(PyObject *obj) { + PyObject *module = PyObject_GetAttrString(obj, "__module__"); + if (module == NULL) { + return -1; + } + int is_typing = PyUnicode_Check(module) && _PyUnicode_EqualToASCIIString(module, "typing"); + Py_DECREF(module); + return is_typing; +} + +static int +is_typing_name(PyObject *obj, char *name) +{ + PyTypeObject *type = Py_TYPE(obj); + if (strcmp(type->tp_name, name) != 0) { + return 0; + } + return is_typing_module(obj); +} + +static PyObject * +union_richcompare(PyObject *a, PyObject *b, int op) +{ + PyObject *result = NULL; + if (op != Py_EQ && op != Py_NE) { + result = Py_NotImplemented; + Py_INCREF(result); + return result; + } + + PyTypeObject *type = Py_TYPE(b); + + PyObject* a_set = PySet_New(((unionobject*)a)->args); + if (a_set == NULL) { + return NULL; + } + PyObject* b_set = PySet_New(NULL); + if (b_set == NULL) { + goto exit; + } + + // Populate b_set with the data from the right object + int is_typing_union = is_typing_name(b, "_UnionGenericAlias"); + if (is_typing_union < 0) { + goto exit; + } + if (is_typing_union) { + PyObject *b_args = PyObject_GetAttrString(b, "__args__"); + if (b_args == NULL) { + goto exit; + } + if (!PyTuple_CheckExact(b_args)) { + Py_DECREF(b_args); + PyErr_SetString(PyExc_TypeError, "__args__ argument of typing.Union object is not a tuple"); + goto exit; + } + Py_ssize_t b_arg_length = PyTuple_GET_SIZE(b_args); + for (Py_ssize_t i = 0; i < b_arg_length; i++) { + PyObject* arg = PyTuple_GET_ITEM(b_args, i); + if (arg == (PyObject *)&_PyNone_Type) { + arg = Py_None; + } + if (PySet_Add(b_set, arg) == -1) { + Py_DECREF(b_args); + goto exit; + } + } + Py_DECREF(b_args); + } else if (type == &_Py_UnionType) { + PyObject* args = ((unionobject*) b)->args; + Py_ssize_t arg_length = PyTuple_GET_SIZE(args); + for (Py_ssize_t i = 0; i < arg_length; i++) { + PyObject* arg = PyTuple_GET_ITEM(args, i); + if (PySet_Add(b_set, arg) == -1) { + goto exit; + } + } + } else { + if (PySet_Add(b_set, b) == -1) { + goto exit; + } + } + result = PyObject_RichCompare(a_set, b_set, op); +exit: + Py_XDECREF(a_set); + Py_XDECREF(b_set); + return result; +} + +static PyObject* +flatten_args(PyObject* args) +{ + int arg_length = PyTuple_GET_SIZE(args); + int total_args = 0; + // Get number of total args once it's flattened. + for (Py_ssize_t i = 0; i < arg_length; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + PyTypeObject* arg_type = Py_TYPE(arg); + if (arg_type == &_Py_UnionType) { + total_args += PyTuple_GET_SIZE(((unionobject*) arg)->args); + } else { + total_args++; + } + } + // Create new tuple of flattened args. + PyObject *flattened_args = PyTuple_New(total_args); + if (flattened_args == NULL) { + return NULL; + } + Py_ssize_t pos = 0; + for (Py_ssize_t i = 0; i < arg_length; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + PyTypeObject* arg_type = Py_TYPE(arg); + if (arg_type == &_Py_UnionType) { + PyObject* nested_args = ((unionobject*)arg)->args; + int nested_arg_length = PyTuple_GET_SIZE(nested_args); + for (int j = 0; j < nested_arg_length; j++) { + PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); + Py_INCREF(nested_arg); + PyTuple_SET_ITEM(flattened_args, pos, nested_arg); + pos++; + } + } else { + Py_INCREF(arg); + PyTuple_SET_ITEM(flattened_args, pos, arg); + pos++; + } + } + return flattened_args; +} + +static PyObject* +dedup_and_flatten_args(PyObject* args) +{ + args = flatten_args(args); + if (args == NULL) { + return NULL; + } + Py_ssize_t arg_length = PyTuple_GET_SIZE(args); + PyObject *new_args = PyTuple_New(arg_length); + if (new_args == NULL) { + return NULL; + } + // Add unique elements to an array. + int added_items = 0; + for (Py_ssize_t i = 0; i < arg_length; i++) { + int is_duplicate = 0; + PyObject* i_element = PyTuple_GET_ITEM(args, i); + for (Py_ssize_t j = i + 1; j < arg_length; j++) { + PyObject* j_element = PyTuple_GET_ITEM(args, j); + if (i_element == j_element) { + is_duplicate = 1; + } + } + if (!is_duplicate) { + Py_INCREF(i_element); + PyTuple_SET_ITEM(new_args, added_items, i_element); + added_items++; + } + } + Py_DECREF(args); + _PyTuple_Resize(&new_args, added_items); + return new_args; +} + +static int +is_typevar(PyObject *obj) +{ + return is_typing_name(obj, "TypeVar"); +} + +static int +is_special_form(PyObject *obj) +{ + return is_typing_name(obj, "_SpecialForm"); +} + +static int +is_new_type(PyObject *obj) +{ + PyTypeObject *type = Py_TYPE(obj); + if (type != &PyFunction_Type) { + return 0; + } + return is_typing_module(obj); +} + +static int +is_unionable(PyObject *obj) +{ + if (obj == Py_None) { + return 1; + } + PyTypeObject *type = Py_TYPE(obj); + return ( + is_typevar(obj) || + is_new_type(obj) || + is_special_form(obj) || + PyType_Check(obj) || + type == &Py_GenericAliasType || + type == &_Py_UnionType); +} + +static PyObject * +type_or(PyTypeObject* self, PyObject* param) +{ + PyObject *tuple = PyTuple_Pack(2, self, param); + if (tuple == NULL) { + return NULL; + } + PyObject *new_union = _Py_Union(tuple); + Py_DECREF(tuple); + return new_union; +} + +static int +union_repr_item(_PyUnicodeWriter *writer, PyObject *p) +{ + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(__qualname__); + _Py_IDENTIFIER(__origin__); + _Py_IDENTIFIER(__args__); + PyObject *qualname = NULL; + PyObject *module = NULL; + PyObject *r = NULL; + int err; + + int has_origin = _PyObject_HasAttrId(p, &PyId___origin__); + if (has_origin < 0) { + goto exit; + } + + if (has_origin) { + int has_args = _PyObject_HasAttrId(p, &PyId___args__); + if (has_args < 0) { + goto exit; + } + if (has_args) { + // It looks like a GenericAlias + goto use_repr; + } + } + + if (_PyObject_LookupAttrId(p, &PyId___qualname__, &qualname) < 0) { + goto exit; + } + if (qualname == NULL) { + goto use_repr; + } + if (_PyObject_LookupAttrId(p, &PyId___module__, &module) < 0) { + goto exit; + } + if (module == NULL || module == Py_None) { + goto use_repr; + } + + // Looks like a class + if (PyUnicode_Check(module) && + _PyUnicode_EqualToASCIIString(module, "builtins")) + { + // builtins don't need a module name + r = PyObject_Str(qualname); + goto exit; + } + else { + r = PyUnicode_FromFormat("%S.%S", module, qualname); + goto exit; + } + +use_repr: + r = PyObject_Repr(p); +exit: + Py_XDECREF(qualname); + Py_XDECREF(module); + if (r == NULL) { + return -1; + } + err = _PyUnicodeWriter_WriteStr(writer, r); + Py_DECREF(r); + return err; +} + +static PyObject * +union_repr(PyObject *self) +{ + unionobject *alias = (unionobject *)self; + Py_ssize_t len = PyTuple_GET_SIZE(alias->args); + + _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + for (Py_ssize_t i = 0; i < len; i++) { + if (i > 0 && _PyUnicodeWriter_WriteASCIIString(&writer, " | ", 3) < 0) { + goto error; + } + PyObject *p = PyTuple_GET_ITEM(alias->args, i); + if (union_repr_item(&writer, p) < 0) { + goto error; + } + } + return _PyUnicodeWriter_Finish(&writer); +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + +static PyMemberDef union_members[] = { + {"__args__", T_OBJECT, offsetof(unionobject, args), READONLY}, + {0} +}; + +static PyMethodDef union_methods[] = { + {"__instancecheck__", union_instancecheck, METH_O}, + {"__subclasscheck__", union_subclasscheck, METH_O}, + {0}}; + +static PyNumberMethods union_as_number = { + .nb_or = (binaryfunc)type_or, // Add __or__ function +}; + +PyTypeObject _Py_UnionType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "types.Union", + .tp_doc = "Represent a PEP 604 union type\n" + "\n" + "E.g. for int | str", + .tp_basicsize = sizeof(unionobject), + .tp_dealloc = unionobject_dealloc, + .tp_alloc = PyType_GenericAlloc, + .tp_free = PyObject_Del, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_hash = union_hash, + .tp_getattro = PyObject_GenericGetAttr, + .tp_members = union_members, + .tp_methods = union_methods, + .tp_richcompare = union_richcompare, + .tp_as_number = &union_as_number, + .tp_repr = union_repr, +}; + +PyObject * +_Py_Union(PyObject *args) +{ + assert(PyTuple_CheckExact(args)); + + unionobject* result = NULL; + + // Check arguments are unionable. + int nargs = PyTuple_GET_SIZE(args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(args, iarg); + if (arg == NULL) { + return NULL; + } + int is_arg_unionable = is_unionable(arg); + if (is_arg_unionable < 0) { + return NULL; + } + if (!is_arg_unionable) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + } + + result = PyObject_New(unionobject, &_Py_UnionType); + if (result == NULL) { + return NULL; + } + + result->args = dedup_and_flatten_args(args); + if (result->args == NULL) { + Py_DECREF(result); + return NULL; + } + return (PyObject*)result; +} diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 295b5e21eba5cef..266a193c1e86a33 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -196,6 +196,7 @@ + @@ -412,6 +413,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index ec82e42f61e8b08..22d9b7915769874 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -573,6 +573,9 @@ Include\internal + + Include\internal + Modules\zlib @@ -1175,6 +1178,9 @@ Objects + + Objects + From 7fc11f0404028c1775104b34a28e9defe9bfa4fb Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Wed, 9 Sep 2020 19:17:14 -0300 Subject: [PATCH 279/486] Add missing colon to IDLE doc markup (GH-22007) --- Doc/library/idle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 75b6fa3861b23d0..43096b014fed349 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -491,7 +491,7 @@ in the settings dialog. (To prevent auto popups, set the delay to a large number of milliseconds, such as 100000000.) For imported module names or class or function attributes, type '.'. For filenames in the root directory, type :data:`os.sep` or -data:`os.altsep` immediately after an opening quote. (On Windows, +:data:`os.altsep` immediately after an opening quote. (On Windows, one can specify a drive first.) Move into subdirectories by typing a directory name and a separator. From 1ef2fcf164e4fcce07dddbb36c806567490a1c5d Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 9 Sep 2020 18:53:18 -0400 Subject: [PATCH 280/486] Update idlelib/help.html to current IDLE doc (GH-22181) --- Lib/idlelib/help.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 81ce5100bb8ad5d..b2853cffe0c26d6 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -481,13 +481,13 @@

    Automatic indentationos.sep or -data:os.altsep immediately after an opening quote. (On Windows, +os.altsep immediately after an opening quote. (On Windows, one can specify a drive first.) Move into subdirectories by typing a directory name and a separator.

    -

    Instead of waiting, or after a box is closed. open a completion box +

    Instead of waiting, or after a box is closed, open a completion box immediately with Show Completions on the Edit menu. The default hot key is C-space. If one types a prefix for the desired name -before opening the box, the first match is displayed. +before opening the box, the first match or near miss is made visible. The result is the same as if one enters a prefix after the box is displayed. Show Completions after a quote completes filenames in the current directory instead of a root directory.

    @@ -975,7 +975,7 @@

    Navigation



    - Last updated on Jul 08, 2020. + Last updated on Sep 09, 2020. Found a bug?
    From 6553462fe71b1916739ba34a558ed2eee5d8423f Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Thu, 10 Sep 2020 03:33:13 -0300 Subject: [PATCH 281/486] [doc] Remove superfluous comment about equal in f-strings (GH-22006) Automerge-Triggered-By: @kushaldas --- Doc/reference/lexical_analysis.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 4c0f5688da4d750..19ba83a5513d8a7 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -702,7 +702,7 @@ defaults to the :func:`str` of the expression unless a conversion ``'!r'`` is declared. .. versionadded:: 3.8 - The equal sign ``'='`` was added in Python 3.8. + The equal sign ``'='``. If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on From 75523ba767ddec71e4adbdf76880f83cdcbe7b54 Mon Sep 17 00:00:00 2001 From: Bar Harel Date: Thu, 10 Sep 2020 13:50:23 +0300 Subject: [PATCH 282/486] Update logging documentation to tidy up formatting (GH-22173) --- Doc/library/logging.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 989016e649d6519..fb8ea705b0469f8 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -529,8 +529,7 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on :ref:`logrecord-attributes`. -.. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True, *, - defaults=None) +.. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None) Returns a new instance of the :class:`Formatter` class. The instance is initialized with a format string for the message as a whole, as well as a From 395142d0266acccf1f17f0a72a1857c19ebd0476 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 10 Sep 2020 09:09:04 -0500 Subject: [PATCH 283/486] bpo-1635741: Port cmath to multi-phase init (PEP 489) (GH-22165) --- ...2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst | 2 + Modules/cmathmodule.c | 78 ++++++++++++------- 2 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst new file mode 100644 index 000000000000000..bc1a6c888e33bd1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst @@ -0,0 +1,2 @@ +Port the :mod:`cmath` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 5eac4b4940bea4d..0f22049a170848e 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -1254,37 +1254,35 @@ static PyMethodDef cmath_methods[] = { {NULL, NULL} /* sentinel */ }; - -static struct PyModuleDef cmathmodule = { - PyModuleDef_HEAD_INIT, - "cmath", - module_doc, - -1, - cmath_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_cmath(void) +static int +cmath_exec(PyObject *mod) { - PyObject *m; - - m = PyModule_Create(&cmathmodule); - if (m == NULL) - return NULL; - - PyModule_AddObject(m, "pi", - PyFloat_FromDouble(Py_MATH_PI)); - PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); - PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ - PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); - PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); + if (PyModule_AddObject(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + return -1; + } + // 2pi + if (PyModule_AddObject(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "inf", PyFloat_FromDouble(m_inf())) < 0) { + return -1; + } + + if (PyModule_AddObject(mod, "infj", + PyComplex_FromCComplex(c_infj())) < 0) { + return -1; + } #if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) - PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); - PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); + if (PyModule_AddObject(mod, "nan", PyFloat_FromDouble(m_nan())) < 0) { + return -1; + } + if (PyModule_AddObject(mod, "nanj", + PyComplex_FromCComplex(c_nanj())) < 0) { + return -1; + } #endif /* initialize special value tables */ @@ -1401,5 +1399,25 @@ PyInit_cmath(void) C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) }) - return m; + return 0; } + +static PyModuleDef_Slot cmath_slots[] = { + {Py_mod_exec, cmath_exec}, + {0, NULL} +}; + +static struct PyModuleDef cmathmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "cmath", + .m_doc = module_doc, + .m_size = 0, + .m_methods = cmath_methods, + .m_slots = cmath_slots +}; + +PyMODINIT_FUNC +PyInit_cmath(void) +{ + return PyModuleDef_Init(&cmathmodule); +} \ No newline at end of file From 0ffd69337f6a4e71438048ccf4abf72d941df754 Mon Sep 17 00:00:00 2001 From: Mark Roseman Date: Thu, 10 Sep 2020 13:04:20 -0700 Subject: [PATCH 284/486] bpo-37149: Change Shipman tkinter link from archive.org to TkDocs (GH-22188) The new link responds much faster and begins with a short explanation of the status of the doc. --- Doc/library/tkinter.rst | 2 +- .../next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 9f954255c8b300f..7739f2f60a7980c 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -31,7 +31,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. `TKDocs `_ Extensive tutorial plus friendlier widget pages for some of the widgets. - `Tkinter 8.5 reference: a GUI for Python `_ + `Tkinter 8.5 reference: a GUI for Python `_ On-line reference material. `Tkinter docs from effbot `_ diff --git a/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst b/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst new file mode 100644 index 000000000000000..aeca652b4ed970b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst @@ -0,0 +1 @@ +Change Shipman tkinter doc link from archive.org to TkDocs. (The doc has been removed from the NMT server.) The new link responds much faster and includes a short explanatory note. From 635f59fd0bbe8dba5d6f44fd062cafeed0055415 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 10 Sep 2020 18:59:02 -0500 Subject: [PATCH 285/486] Doc: Fix alphabetical ordering of removeprefix/suffix. (GH-22194) --- Doc/library/stdtypes.rst | 55 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 5a10faa7bbd293b..0ffe7b7526fa768 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1568,33 +1568,6 @@ expression support in the :mod:`re` module). interpreted as in slice notation. -.. method:: str.removeprefix(prefix, /) - - If the string starts with the *prefix* string, return - ``string[len(prefix):]``. Otherwise, return a copy of the original - string:: - - >>> 'TestHook'.removeprefix('Test') - 'Hook' - >>> 'BaseTestCase'.removeprefix('Test') - 'BaseTestCase' - - .. versionadded:: 3.9 - -.. method:: str.removesuffix(suffix, /) - - If the string ends with the *suffix* string and that *suffix* is not empty, - return ``string[:-len(suffix)]``. Otherwise, return a copy of the - original string:: - - >>> 'MiscTests'.removesuffix('Tests') - 'Misc' - >>> 'TmpDirMixin'.removesuffix('Tests') - 'TmpDirMixin' - - .. versionadded:: 3.9 - - .. method:: str.encode(encoding="utf-8", errors="strict") Return an encoded version of the string as a bytes object. Default encoding @@ -1909,6 +1882,34 @@ expression support in the :mod:`re` module). the string itself, followed by two empty strings. +.. method:: str.removeprefix(prefix, /) + + If the string starts with the *prefix* string, return + ``string[len(prefix):]``. Otherwise, return a copy of the original + string:: + + >>> 'TestHook'.removeprefix('Test') + 'Hook' + >>> 'BaseTestCase'.removeprefix('Test') + 'BaseTestCase' + + .. versionadded:: 3.9 + + +.. method:: str.removesuffix(suffix, /) + + If the string ends with the *suffix* string and that *suffix* is not empty, + return ``string[:-len(suffix)]``. Otherwise, return a copy of the + original string:: + + >>> 'MiscTests'.removesuffix('Tests') + 'Misc' + >>> 'TmpDirMixin'.removesuffix('Tests') + 'TmpDirMixin' + + .. versionadded:: 3.9 + + .. method:: str.replace(old, new[, count]) Return a copy of the string with all occurrences of substring *old* replaced by From e53d96638fd1fb6530ea3f4ae700c699e9cc8496 Mon Sep 17 00:00:00 2001 From: Stargirl Flowers Date: Fri, 11 Sep 2020 08:20:12 -0700 Subject: [PATCH 286/486] [doc] struct: update note about network byte order form to be more helpful (GH-22201) Update the sentence to provide some context on why network byte order is defined as big endian. --- Doc/library/struct.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 856b6da8bb255d5..eccba20fb8fe7e9 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -159,8 +159,8 @@ the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. -The form ``'!'`` is available for those poor souls who claim they can't remember -whether network byte order is big-endian or little-endian. +The form ``'!'`` represents the network byte order which is always big-endian +as defined in `IETF RFC 1700 `_. There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. @@ -467,3 +467,5 @@ The :mod:`struct` module also defines the following type: .. _half precision format: https://en.wikipedia.org/wiki/Half-precision_floating-point_format .. _ieee 754 standard: https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008 + +.. _IETF RFC 1700: https://tools.ietf.org/html/rfc1700 From 116641f0b63c745245017d8e4a912fe5e5ae487e Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 12 Sep 2020 01:51:52 -0400 Subject: [PATCH 287/486] bpo-41729: Fix test_winconsole failures (3) and hang (GH-22146) The problems occured with a repository build on machine with freshly updated Windows 10 Pro. --- PC/_testconsole.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/_testconsole.c b/PC/_testconsole.c index f6fcfcf1964b8ad..b62f21c339aa410 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -63,7 +63,7 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file, for (DWORD i = 0; i < size; ++i, ++p, ++prec) { prec->EventType = KEY_EVENT; prec->Event.KeyEvent.bKeyDown = TRUE; - prec->Event.KeyEvent.wRepeatCount = 10; + prec->Event.KeyEvent.wRepeatCount = 1; prec->Event.KeyEvent.uChar.UnicodeChar = *p; } From baf264f894129ec3580a7cae15734cdb410c144a Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 12 Sep 2020 02:25:36 -0400 Subject: [PATCH 288/486] bpo-41731: Make test_cmd_line_script pass with -vv (GH-22206) Argument script_exec_args is usually an absolute file name, but twice has form ['-m', 'module_name']. --- Lib/test/test_cmd_line_script.py | 2 +- Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 6c8c28f40b564ba..f10ab40017a338b 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -145,7 +145,7 @@ def _check_import_error(self, script_exec_args, expected_msg, *run_args, __isolated=False, __cwd=cwd, **env_vars ) if verbose > 1: - print('Output from test script %r:' % script_exec_args) + print(f'Output from test script {script_exec_args!r:}') print(repr(err)) print('Expected output: %r' % expected_msg) self.assertIn(expected_msg.encode('utf-8'), err) diff --git a/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst b/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst new file mode 100644 index 000000000000000..e368a60f77b1ea7 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst @@ -0,0 +1 @@ +Make test_cmd_line_script pass with option '-vv'. From 62fbb550136eff8dfd0a5bc0f4bfc85aa823f3aa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 12 Sep 2020 08:50:18 +0200 Subject: [PATCH 289/486] bpo-39651: Fix asyncio proactor _write_to_self() (GH-22197) Fix a race condition in the call_soon_threadsafe() method of asyncio.ProactorEventLoop: do nothing if the self-pipe socket has been closed. --- Lib/asyncio/proactor_events.py | 11 ++++++++++- Lib/asyncio/selector_events.py | 18 ++++++++++-------- .../2020-09-11-12-38-55.bpo-39651.JMp9l2.rst | 3 +++ 3 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 4670bd683ab32cc..45c11ee4b487ecb 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -793,8 +793,17 @@ def _loop_self_reading(self, f=None): f.add_done_callback(self._loop_self_reading) def _write_to_self(self): + # This may be called from a different thread, possibly after + # _close_self_pipe() has been called or even while it is + # running. Guard for self._csock being None or closed. When + # a socket is closed, send() raises OSError (with errno set to + # EBADF, but let's not rely on the exact error code). + csock = self._csock + if csock is None: + return + try: - self._csock.send(b'\0') + csock.send(b'\0') except OSError: if self._debug: logger.debug("Fail to write a null byte into the " diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 8495a7901cd34c9..59cb6b1babec54d 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -133,14 +133,16 @@ def _write_to_self(self): # a socket is closed, send() raises OSError (with errno set to # EBADF, but let's not rely on the exact error code). csock = self._csock - if csock is not None: - try: - csock.send(b'\0') - except OSError: - if self._debug: - logger.debug("Fail to write a null byte into the " - "self-pipe socket", - exc_info=True) + if csock is None: + return + + try: + csock.send(b'\0') + except OSError: + if self._debug: + logger.debug("Fail to write a null byte into the " + "self-pipe socket", + exc_info=True) def _start_serving(self, protocol_factory, sock, sslcontext=None, server=None, backlog=100, diff --git a/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst b/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst new file mode 100644 index 000000000000000..78dcff137002927 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst @@ -0,0 +1,3 @@ +Fix a race condition in the ``call_soon_threadsafe()`` method of +``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has been +closed. From 3a021222c7a4d0c69645f20114822b6b5ecfc3a7 Mon Sep 17 00:00:00 2001 From: Norbert Cyran Date: Sat, 12 Sep 2020 09:58:56 +0200 Subject: [PATCH 290/486] bpo-41672: Fix type mismatches in imaplib docs (GH-22207) --- Doc/library/imaplib.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 7c5b07501615989..02ecfd95d43767f 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -143,7 +143,7 @@ The following utility functions are defined: .. function:: Int2AP(num) - Converts an integer into a string representation using characters from the set + Converts an integer into a bytes representation using characters from the set [``A`` .. ``P``]. @@ -197,7 +197,7 @@ you want to avoid having an argument string quoted (eg: the *flags* argument to Each command returns a tuple: ``(type, [data, ...])`` where *type* is usually ``'OK'`` or ``'NO'``, and *data* is either the text from the command response, -or mandated results from the command. Each *data* is either a string, or a +or mandated results from the command. Each *data* is either a ``bytes``, or a tuple. If a tuple, then the first part is the header of the response, and the second part contains the data (ie: 'literal' value). From ceaea4df5d85697de68c63b7890c30a63243bf18 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Sun, 13 Sep 2020 22:59:01 +0500 Subject: [PATCH 291/486] bpo-33239: Fix default value of 'buffering' parameter in docs of tempfile.* functions (GH-21763) `None` doesn't work: ```python >>> import tempfile >>> tempfile.TemporaryFile(buffering=None) Traceback (most recent call last): File "", line 1, in File "/home/sergey/tmp/cpython-dev/Lib/tempfile.py", line 607, in TemporaryFile return _io.open(fd, mode, buffering=buffering, TypeError: 'NoneType' object cannot be interpreted as an integer ``` Automerge-Triggered-By: @vsajip --- Doc/library/tempfile.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 3a2b88c0cb6a205..f9421da5fe7dfab 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -31,7 +31,7 @@ is recommended to use keyword arguments for clarity. The module defines the following user-callable items: -.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) +.. function:: TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) Return a :term:`file-like object` that can be used as a temporary storage area. The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon @@ -72,7 +72,7 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None) +.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None) This function operates exactly as :func:`TemporaryFile` does, except that the file is guaranteed to have a visible name in the file system (on @@ -93,7 +93,7 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) +.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) This function operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or From d20d0b8fc9b8928c99ae107dfbb13312a8709012 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 13 Sep 2020 14:27:51 -0600 Subject: [PATCH 292/486] bpo-38967: Improve the error msg for reserved _sunder_ names in enum (GH-18370) --- Lib/enum.py | 3 ++- Lib/test/test_enum.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Lib/enum.py b/Lib/enum.py index 49b552ba0ecf6cc..bc24f2ae2dfc012 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -76,7 +76,8 @@ def __setitem__(self, key, value): '_order_', '_create_pseudo_member_', '_generate_next_value_', '_missing_', '_ignore_', ): - raise ValueError('_names_ are reserved for future Enum use') + raise ValueError(f'_sunder_ names, such as "{key}", are ' + 'reserved for future Enum use') if key == '_generate_next_value_': # check if members already defined as auto() if self._auto_called: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index e7bad6240677317..b18f3b38a6619f6 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -419,6 +419,11 @@ def red(self): green = 2 blue = 3 + def test_reserved__sunder_(self): + with self.assertRaisesRegex(ValueError, '_sunder_ names, such as ' + '"_bad_", are reserved'): + class Bad(Enum): + _bad_ = 1 def test_enum_with_value_name(self): class Huh(Enum): From 8717d66e439dfa86e032c4c94648ac787f379bb4 Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Sun, 13 Sep 2020 18:05:44 -0300 Subject: [PATCH 293/486] bpo-41778: Change a punctuation on documentation. (GH-22229) On this paragrapah the clarification about IIS7 seems there's not connection beacuase is in other sentence. Move the punctuation to connect both the last sentence with the information in the parenthesis. I think the NEWS is not necessary here. Automerge-Triggered-By: @ericvsmith --- Doc/library/wsgiref.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 1e30aa4a898c13b..e92a689de0b9ba9 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -480,8 +480,8 @@ input, output, and error streams. rarely used and is not guaranteed by WSGI. On IIS<7, though, the setting can only be made on a vhost level, affecting all other script mappings, many of which break when exposed to the ``PATH_TRANSLATED`` bug. - For this reason IIS<7 is almost never deployed with the fix. (Even IIS7 - rarely uses it because there is still no UI for it.) + For this reason IIS<7 is almost never deployed with the fix (Even IIS7 + rarely uses it because there is still no UI for it.). There is no way for CGI code to tell whether the option was set, so a separate handler class is provided. It is used in the same way as From da6e17399e454485fe3823a2e9bde18802174f9b Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Mon, 14 Sep 2020 01:18:01 -0400 Subject: [PATCH 294/486] bpo-39883: Update macOS installer copy of LICENSE. (GH-22235) --- Mac/BuildScript/resources/License.rtf | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 25d53386da01a56..1dfdc1edc17fabe 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -1,9 +1,9 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2511 +{\rtf1\ansi\ansicpg1252\cocoartf2513 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT; \f3\fmodern\fcharset0 CourierNewPSMT;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} -\margl1440\margr1440\vieww14620\viewh13380\viewkind0 +\margl1440\margr1440\vieww18500\viewh13520\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 \f0\b\fs36 \cf0 \ul \ulc0 HISTORY AND LICENSE\ @@ -47,8 +47,17 @@ Thanks to the many outside volunteers who have worked under Guido's direction to \ \f0\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\f1\b0 \ulnone \ +\f1\b0 \cf0 \ulnone Python software and documentation are licensed under the Python Software Foundation License Version 2.\ +\ +Starting with Python 3.8.6, examples, recipes, and other code in the documentation are dual licensed under the PSF License Version 2 and the Zero-Clause BSD license.\ +\ +Some software incorporated into Python is under different licenses. The licenses are listed with code falling under that license.\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 +\cf0 \ \f0\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\ @@ -125,6 +134,18 @@ Permission to use, copy, modify, and distribute this software and its documentat STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\ \ \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 + +\f0\b \cf0 ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 \ +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.\ +\ +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 +\cf0 \ +\ \f0\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\ From 5e9f283dc5d3f92e4dbf18523fe6f5adb13563d2 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 13 Sep 2020 23:33:41 -0700 Subject: [PATCH 295/486] bpo-41513: Add docs and tests for hypot() (GH-22238) --- Doc/library/math.rst | 5 +++++ Lib/test/test_math.py | 51 +++++++++++++++++++++++++++++++++++++++++++ Modules/mathmodule.c | 14 ++++++------ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 6ec1feee35a6dc7..bbf64643ff59fc7 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -481,6 +481,11 @@ Trigonometric functions Added support for n-dimensional points. Formerly, only the two dimensional case was supported. + .. versionchanged:: 3.10 + Improved the algorithm's accuracy so that the maximum error is + under 1 ulp (unit in the last place). More typically, the result + is almost always correctly rounded to within 1/2 ulp. + .. function:: sin(x) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 4d62eb1b119930d..bbaa533c8489eb7 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -803,6 +803,57 @@ def testHypot(self): scale = FLOAT_MIN / 2.0 ** exp self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) + def testHypotAccuracy(self): + # Verify improved accuracy in cases that were known to be inaccurate. + + hypot = math.hypot + Decimal = decimal.Decimal + high_precision = decimal.Context(prec=500) + + for hx, hy in [ + # Cases with a 1 ulp error in Python 3.7 compiled with Clang + ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'), + ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'), + ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'), + ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'), + ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'), + ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'), + ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'), + ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'), + ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'), + ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'), + + # Cases with 2 ulp error in Python 3.8 + ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'), + ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'), + ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'), + ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'), + ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'), + ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'), + ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'), + ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'), + ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'), + ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'), + + # Cases with 1 ulp error in version fff3c28052e6b0750d6218e00acacd2fded4991a + ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'), + ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'), + ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'), + ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'), + ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'), + ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'), + ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'), + ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'), + ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'), + ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'), + ]: + with self.subTest(hx=hx, hy=hy): + x = float.fromhex(hx) + y = float.fromhex(hy) + with decimal.localcontext(high_precision): + z = float((Decimal(x)**2 + Decimal(y)**2).sqrt()) + self.assertEqual(hypot(x, y), z) + def testDist(self): from decimal import Decimal as D from fractions import Fraction as F diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 29137ae91a22ff5..ecd291ecd1b4b02 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2429,7 +2429,7 @@ magnitude. We avoid this cost by arranging the calculation so that fabs(csum) is always as large as fabs(x). To establish the invariant, *csum* is initialized to 1.0 which is -always larger than x**2 after scaling or division by *max*. +always larger than x**2 after scaling or after division by *max*. After the loop is finished, the initial 1.0 is subtracted out for a net zero effect on the final sum. Since *csum* will be greater than 1.0, the subtraction of 1.0 will not cause fractional digits to be @@ -2458,7 +2458,7 @@ Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. To minimize loss of information during the accumulation of fractional values, each term has a separate accumulator. This also breaks up sequential dependencies in the inner loop so the CPU can maximize -floating point throughput. [5] On a 2.6 GHz Haswell, adding one +floating point throughput. [4] On a 2.6 GHz Haswell, adding one dimension has an incremental cost of only 5ns -- for example when moving from hypot(x,y) to hypot(x,y,z). @@ -2470,7 +2470,7 @@ The differential correction starts with a value *x* that is the difference between the square of *h*, the possibly inaccurately rounded square root, and the accurately computed sum of squares. The correction is the first order term of the Maclaurin series -expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). [4] +expansion of sqrt(h**2 + x) == h + x/(2*h) + O(x**2). [5] Essentially, this differential correction is equivalent to one refinement step in Newton's divide-and-average square root @@ -2492,10 +2492,10 @@ exactly equal) was verified for 1 billion random inputs with n=5. [7] 1. Veltkamp-Dekker splitting: http://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf 2. Compensated summation: http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf 3. Square root differential correction: https://arxiv.org/pdf/1904.09481.pdf -4. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 -5. https://bugs.python.org/file49439/hypot.png -6. https://bugs.python.org/file49435/best_frac.py -7. https://bugs.python.org/file49448/test_hypot_commutativity.py +4. Data dependency graph: https://bugs.python.org/file49439/hypot.png +5. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 +6. Analysis of internal accuracy: https://bugs.python.org/file49435/best_frac.py +7. Commutativity test: https://bugs.python.org/file49448/test_hypot_commutativity.py */ From 3f1172798f9814c0faeab98a680269f2d16f7192 Mon Sep 17 00:00:00 2001 From: abdo Date: Mon, 14 Sep 2020 20:36:34 +0300 Subject: [PATCH 296/486] Fix a typo in locale Docs (#22233) --- Doc/library/locale.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index bf57a0835591682..678148a0dda2946 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -508,7 +508,7 @@ Background, details, hints, tips and caveats -------------------------------------------- The C standard defines the locale as a program-wide property that may be -relatively expensive to change. On top of that, some implementation are broken +relatively expensive to change. On top of that, some implementations are broken in such a way that frequent locale changes may cause core dumps. This makes the locale somewhat painful to use correctly. From 575a26dd4962dc4431a9226c627dfc0d2c53bc5d Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 14 Sep 2020 13:28:46 -0600 Subject: [PATCH 297/486] bpo-41646: Mention path-like objects support in the docs for shutil.copy() (GH-22208) --- Doc/library/shutil.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 1b094aeb9ca3d80..ecc3309ed5cc09e 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -158,9 +158,9 @@ Directory and files operations .. function:: copy(src, dst, *, follow_symlinks=True) Copies the file *src* to the file or directory *dst*. *src* and *dst* - should be strings. If *dst* specifies a directory, the file will be - copied into *dst* using the base filename from *src*. Returns the - path to the newly created file. + should be :term:`path-like objects ` or strings. If + *dst* specifies a directory, the file will be copied into *dst* using the + base filename from *src*. Returns the path to the newly created file. If *follow_symlinks* is false, and *src* is a symbolic link, *dst* will be created as a symbolic link. If *follow_symlinks* From 9741894dfa7dc5607923359f6b2343ba1b4da6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Mon, 14 Sep 2020 21:30:15 +0200 Subject: [PATCH 298/486] bpo-41744: Package python.props with correct name in NuGet package (GH-22154) NuGet automatically includes .props file from the build directory in the target using the package, but only if the .props file has the correct name: it must be $(id).props Rename python.props correspondingly in all the nuspec variants. Also keep python.props as it were for backward compatibility. --- .../next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst | 1 + Tools/nuget/python.nuspec | 2 +- Tools/nuget/pythonarm32.nuspec | 3 ++- Tools/nuget/pythondaily.nuspec | 3 ++- Tools/nuget/pythonx86.nuspec | 3 ++- 5 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst diff --git a/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst b/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst new file mode 100644 index 000000000000000..6106d6604c7dd58 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst @@ -0,0 +1 @@ +Fixes automatic import of props file when using the Nuget package. \ No newline at end of file diff --git a/Tools/nuget/python.nuspec b/Tools/nuget/python.nuspec index 8f98e808916a320..2da5f2037eb2342 100644 --- a/Tools/nuget/python.nuspec +++ b/Tools/nuget/python.nuspec @@ -13,6 +13,6 @@ - + diff --git a/Tools/nuget/pythonarm32.nuspec b/Tools/nuget/pythonarm32.nuspec index 273d79a0312bd94..2d197931edb32c3 100644 --- a/Tools/nuget/pythonarm32.nuspec +++ b/Tools/nuget/pythonarm32.nuspec @@ -14,6 +14,7 @@ - + + diff --git a/Tools/nuget/pythondaily.nuspec b/Tools/nuget/pythondaily.nuspec index 5cf55806ddfb39c..7df1983f42a6fe2 100644 --- a/Tools/nuget/pythondaily.nuspec +++ b/Tools/nuget/pythondaily.nuspec @@ -13,6 +13,7 @@ - + + diff --git a/Tools/nuget/pythonx86.nuspec b/Tools/nuget/pythonx86.nuspec index 27ef67e7f5d3637..ea878ba0bf390b6 100644 --- a/Tools/nuget/pythonx86.nuspec +++ b/Tools/nuget/pythonx86.nuspec @@ -13,6 +13,7 @@ - + + From eb6dbe538130ff6bd87a0174101a393e7c39b5e2 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Mon, 14 Sep 2020 13:32:44 -0700 Subject: [PATCH 299/486] bpo-40721: add note about enum member name case (GH-22231) * UPPER_CASE preferred as enum members are constants --- Doc/library/enum.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 00bfb260c020472..32e8bbf95092733 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -19,6 +19,12 @@ An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over. +.. note:: Case of Enum Members + + Because Enums are used to represent constants we recommend using + UPPER_CASE names for enum members, and will be using that style + in our examples. + Module Contents --------------- From bdc7a92e8ec04bc3d7003d13e6cfb587d32cd855 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 14 Sep 2020 17:13:49 -0700 Subject: [PATCH 300/486] bpo-41513: Remove broken tests that fail on Gentoo (GH-22249) --- Lib/test/test_math.py | 51 ------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index bbaa533c8489eb7..4d62eb1b119930d 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -803,57 +803,6 @@ def testHypot(self): scale = FLOAT_MIN / 2.0 ** exp self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) - def testHypotAccuracy(self): - # Verify improved accuracy in cases that were known to be inaccurate. - - hypot = math.hypot - Decimal = decimal.Decimal - high_precision = decimal.Context(prec=500) - - for hx, hy in [ - # Cases with a 1 ulp error in Python 3.7 compiled with Clang - ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'), - ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'), - ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'), - ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'), - ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'), - ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'), - ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'), - ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'), - ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'), - ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'), - - # Cases with 2 ulp error in Python 3.8 - ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'), - ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'), - ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'), - ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'), - ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'), - ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'), - ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'), - ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'), - ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'), - ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'), - - # Cases with 1 ulp error in version fff3c28052e6b0750d6218e00acacd2fded4991a - ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'), - ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'), - ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'), - ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'), - ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'), - ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'), - ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'), - ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'), - ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'), - ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'), - ]: - with self.subTest(hx=hx, hy=hy): - x = float.fromhex(hx) - y = float.fromhex(hy) - with decimal.localcontext(high_precision): - z = float((Decimal(x)**2 + Decimal(y)**2).sqrt()) - self.assertEqual(hypot(x, y), z) - def testDist(self): from decimal import Decimal as D from fractions import Fraction as F From 9f809a25953402f88fe6f40cf5d06826fa3152e0 Mon Sep 17 00:00:00 2001 From: Neeraj Samtani Date: Tue, 15 Sep 2020 17:39:29 +0400 Subject: [PATCH 301/486] bpo-41776: Revise example of "continue" in the tutorial documentation (GH-22234) Revise example of "continue" in the tutorial documentation --- Doc/tutorial/controlflow.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 5d24a19cfc07967..b8aec2b04f13fba 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -210,15 +210,15 @@ iteration of the loop:: ... if num % 2 == 0: ... print("Found an even number", num) ... continue - ... print("Found a number", num) + ... print("Found an odd number", num) Found an even number 2 - Found a number 3 + Found an odd number 3 Found an even number 4 - Found a number 5 + Found an odd number 5 Found an even number 6 - Found a number 7 + Found an odd number 7 Found an even number 8 - Found a number 9 + Found an odd number 9 .. _tut-pass: From 40a357df20a3cc58e3091ca1bb7ef5357aa43663 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2020 18:03:34 +0200 Subject: [PATCH 302/486] bpo-41631: _ast module uses again a global state (#21961) Partially revert commit ac46eb4ad6662cf6d771b20d8963658b2186c48c: "bpo-38113: Update the Python-ast.c generator to PEP384 (gh-15957)". Using a module state per module instance is causing subtle practical problems. For example, the Mercurial project replaces the __import__() function to implement lazy import, whereas Python expected that "import _ast" always return a fully initialized _ast module. Add _PyAST_Fini() to clear the state at exit. The _ast module has no state (set _astmodule.m_size to 0). Remove astmodule_traverse(), astmodule_clear() and astmodule_free() functions. --- Include/internal/pycore_pylifecycle.h | 1 + Lib/ast.py | 37 ++- Lib/test/test_ast.py | 84 ++++++ .../2020-08-26-11-23-31.bpo-41631.3jZcd9.rst | 5 + Parser/asdl_c.py | 61 ++-- Python/Python-ast.c | 275 ++---------------- Python/pylifecycle.c | 6 + 7 files changed, 160 insertions(+), 309 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 22def3dbc8b661e..6d84e37232b305e 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -84,6 +84,7 @@ extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern void _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); +extern void _PyAST_Fini(PyThreadState *tstate); extern PyStatus _PyGILState_Init(PyThreadState *tstate); extern void _PyGILState_Fini(PyThreadState *tstate); diff --git a/Lib/ast.py b/Lib/ast.py index 65ebd0100de0074..d860917f4d03ae3 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -497,18 +497,20 @@ def generic_visit(self, node): return node -# The following code is for backward compatibility. -# It will be removed in future. +# If the ast module is loaded more than once, only add deprecated methods once +if not hasattr(Constant, 'n'): + # The following code is for backward compatibility. + # It will be removed in future. -def _getter(self): - """Deprecated. Use value instead.""" - return self.value + def _getter(self): + """Deprecated. Use value instead.""" + return self.value -def _setter(self, value): - self.value = value + def _setter(self, value): + self.value = value -Constant.n = property(_getter, _setter) -Constant.s = property(_getter, _setter) + Constant.n = property(_getter, _setter) + Constant.s = property(_getter, _setter) class _ABC(type): @@ -600,14 +602,19 @@ class ExtSlice(slice): def __new__(cls, dims=(), **kwargs): return Tuple(list(dims), Load(), **kwargs) -def _dims_getter(self): - """Deprecated. Use elts instead.""" - return self.elts +# If the ast module is loaded more than once, only add deprecated methods once +if not hasattr(Tuple, 'dims'): + # The following code is for backward compatibility. + # It will be removed in future. -def _dims_setter(self, value): - self.elts = value + def _dims_getter(self): + """Deprecated. Use elts instead.""" + return self.elts -Tuple.dims = property(_dims_getter, _dims_setter) + def _dims_setter(self, value): + self.elts = value + + Tuple.dims = property(_dims_getter, _dims_setter) class Suite(mod): """Deprecated AST node class. Unused in Python 3.""" diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index f5aef61ec6f7c03..5f57ce8724482af 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1,7 +1,9 @@ import ast +import builtins import dis import os import sys +import types import unittest import warnings import weakref @@ -1945,6 +1947,88 @@ def visit_Ellipsis(self, node): ]) +@support.cpython_only +class ModuleStateTests(unittest.TestCase): + # bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. + + def check_ast_module(self): + # Check that the _ast module still works as expected + code = 'x + 1' + filename = '' + mode = 'eval' + + # Create _ast.AST subclasses instances + ast_tree = compile(code, filename, mode, flags=ast.PyCF_ONLY_AST) + + # Call PyAST_Check() + code = compile(ast_tree, filename, mode) + self.assertIsInstance(code, types.CodeType) + + def test_reload_module(self): + # bpo-41194: Importing the _ast module twice must not crash. + with support.swap_item(sys.modules, '_ast', None): + del sys.modules['_ast'] + import _ast as ast1 + + del sys.modules['_ast'] + import _ast as ast2 + + self.check_ast_module() + + # Unloading the two _ast module instances must not crash. + del ast1 + del ast2 + support.gc_collect() + + self.check_ast_module() + + def test_sys_modules(self): + # bpo-41631: Test reproducing a Mercurial crash when PyAST_Check() + # imported the _ast module internally. + lazy_mod = object() + + def my_import(name, *args, **kw): + sys.modules[name] = lazy_mod + return lazy_mod + + with support.swap_item(sys.modules, '_ast', None): + del sys.modules['_ast'] + + with support.swap_attr(builtins, '__import__', my_import): + # Test that compile() does not import the _ast module + self.check_ast_module() + self.assertNotIn('_ast', sys.modules) + + # Sanity check of the test itself + import _ast + self.assertIs(_ast, lazy_mod) + + def test_subinterpreter(self): + # bpo-41631: Importing and using the _ast module in a subinterpreter + # must not crash. + code = dedent(''' + import _ast + import ast + import gc + import sys + import types + + # Create _ast.AST subclasses instances and call PyAST_Check() + ast_tree = compile('x+1', '', 'eval', + flags=ast.PyCF_ONLY_AST) + code = compile(ast_tree, 'string', 'eval') + if not isinstance(code, types.CodeType): + raise AssertionError + + # Unloading the _ast module must not crash. + del ast, _ast + del sys.modules['ast'], sys.modules['_ast'] + gc.collect() + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + + def main(): if __name__ != '__main__': return diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst new file mode 100644 index 000000000000000..68bb51024d9e705 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst @@ -0,0 +1,5 @@ +The ``_ast`` module uses again a global state. Using a module state per module +instance is causing subtle practical problems. For example, the Mercurial +project replaces the ``__import__()`` function to implement lazy import, +whereas Python expected that ``import _ast`` always return a fully initialized +``_ast`` module. diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 6fe44b99f793bb4..0c053393d688b8d 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1089,11 +1089,9 @@ def visitModule(self, mod): static struct PyModuleDef _astmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ast", - .m_size = sizeof(astmodulestate), + // The _ast module uses a global state (global_ast_state). + .m_size = 0, .m_slots = astmodule_slots, - .m_traverse = astmodule_traverse, - .m_clear = astmodule_clear, - .m_free = astmodule_free, }; PyMODINIT_FUNC @@ -1374,59 +1372,40 @@ def generate_module_def(f, mod): f.write(' PyObject *' + s + ';\n') f.write('} astmodulestate;\n\n') f.write(""" -static astmodulestate* -get_ast_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (astmodulestate*)state; -} +// Forward declaration +static int init_types(astmodulestate *state); + +// bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. +static astmodulestate global_ast_state = {0}; static astmodulestate* get_global_ast_state(void) { - _Py_IDENTIFIER(_ast); - PyObject *name = _PyUnicode_FromId(&PyId__ast); // borrowed reference - if (name == NULL) { + astmodulestate* state = &global_ast_state; + if (!init_types(state)) { return NULL; } - PyObject *module = PyImport_GetModule(name); - if (module == NULL) { - if (PyErr_Occurred()) { - return NULL; - } - module = PyImport_Import(name); - if (module == NULL) { - return NULL; - } - } - astmodulestate *state = get_ast_state(module); - Py_DECREF(module); return state; } -static int astmodule_clear(PyObject *module) +static astmodulestate* +get_ast_state(PyObject* Py_UNUSED(module)) { - astmodulestate *state = get_ast_state(module); -""") - for s in module_state: - f.write(" Py_CLEAR(state->" + s + ');\n') - f.write(""" - return 0; + astmodulestate* state = get_global_ast_state(); + // get_ast_state() must only be called after _ast module is imported, + // and astmodule_exec() calls init_types() + assert(state != NULL); + return state; } -static int astmodule_traverse(PyObject *module, visitproc visit, void* arg) +void _PyAST_Fini(PyThreadState *tstate) { - astmodulestate *state = get_ast_state(module); + astmodulestate* state = &global_ast_state; """) for s in module_state: - f.write(" Py_VISIT(state->" + s + ');\n') + f.write(" Py_CLEAR(state->" + s + ');\n') f.write(""" - return 0; -} - -static void astmodule_free(void* module) { - astmodule_clear((PyObject*)module); + state->initialized = 0; } """) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 396a6832702b35e..094010e6c9ddce6 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -224,40 +224,35 @@ typedef struct { } astmodulestate; -static astmodulestate* -get_ast_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (astmodulestate*)state; -} +// Forward declaration +static int init_types(astmodulestate *state); + +// bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. +static astmodulestate global_ast_state = {0}; static astmodulestate* get_global_ast_state(void) { - _Py_IDENTIFIER(_ast); - PyObject *name = _PyUnicode_FromId(&PyId__ast); // borrowed reference - if (name == NULL) { + astmodulestate* state = &global_ast_state; + if (!init_types(state)) { return NULL; } - PyObject *module = PyImport_GetModule(name); - if (module == NULL) { - if (PyErr_Occurred()) { - return NULL; - } - module = PyImport_Import(name); - if (module == NULL) { - return NULL; - } - } - astmodulestate *state = get_ast_state(module); - Py_DECREF(module); return state; } -static int astmodule_clear(PyObject *module) +static astmodulestate* +get_ast_state(PyObject* Py_UNUSED(module)) { - astmodulestate *state = get_ast_state(module); + astmodulestate* state = get_global_ast_state(); + // get_ast_state() must only be called after _ast module is imported, + // and astmodule_exec() calls init_types() + assert(state != NULL); + return state; +} + +void _PyAST_Fini(PyThreadState *tstate) +{ + astmodulestate* state = &global_ast_state; Py_CLEAR(state->AST_type); Py_CLEAR(state->Add_singleton); Py_CLEAR(state->Add_type); @@ -472,231 +467,7 @@ static int astmodule_clear(PyObject *module) Py_CLEAR(state->vararg); Py_CLEAR(state->withitem_type); - return 0; -} - -static int astmodule_traverse(PyObject *module, visitproc visit, void* arg) -{ - astmodulestate *state = get_ast_state(module); - Py_VISIT(state->AST_type); - Py_VISIT(state->Add_singleton); - Py_VISIT(state->Add_type); - Py_VISIT(state->And_singleton); - Py_VISIT(state->And_type); - Py_VISIT(state->AnnAssign_type); - Py_VISIT(state->Assert_type); - Py_VISIT(state->Assign_type); - Py_VISIT(state->AsyncFor_type); - Py_VISIT(state->AsyncFunctionDef_type); - Py_VISIT(state->AsyncWith_type); - Py_VISIT(state->Attribute_type); - Py_VISIT(state->AugAssign_type); - Py_VISIT(state->Await_type); - Py_VISIT(state->BinOp_type); - Py_VISIT(state->BitAnd_singleton); - Py_VISIT(state->BitAnd_type); - Py_VISIT(state->BitOr_singleton); - Py_VISIT(state->BitOr_type); - Py_VISIT(state->BitXor_singleton); - Py_VISIT(state->BitXor_type); - Py_VISIT(state->BoolOp_type); - Py_VISIT(state->Break_type); - Py_VISIT(state->Call_type); - Py_VISIT(state->ClassDef_type); - Py_VISIT(state->Compare_type); - Py_VISIT(state->Constant_type); - Py_VISIT(state->Continue_type); - Py_VISIT(state->Del_singleton); - Py_VISIT(state->Del_type); - Py_VISIT(state->Delete_type); - Py_VISIT(state->DictComp_type); - Py_VISIT(state->Dict_type); - Py_VISIT(state->Div_singleton); - Py_VISIT(state->Div_type); - Py_VISIT(state->Eq_singleton); - Py_VISIT(state->Eq_type); - Py_VISIT(state->ExceptHandler_type); - Py_VISIT(state->Expr_type); - Py_VISIT(state->Expression_type); - Py_VISIT(state->FloorDiv_singleton); - Py_VISIT(state->FloorDiv_type); - Py_VISIT(state->For_type); - Py_VISIT(state->FormattedValue_type); - Py_VISIT(state->FunctionDef_type); - Py_VISIT(state->FunctionType_type); - Py_VISIT(state->GeneratorExp_type); - Py_VISIT(state->Global_type); - Py_VISIT(state->GtE_singleton); - Py_VISIT(state->GtE_type); - Py_VISIT(state->Gt_singleton); - Py_VISIT(state->Gt_type); - Py_VISIT(state->IfExp_type); - Py_VISIT(state->If_type); - Py_VISIT(state->ImportFrom_type); - Py_VISIT(state->Import_type); - Py_VISIT(state->In_singleton); - Py_VISIT(state->In_type); - Py_VISIT(state->Interactive_type); - Py_VISIT(state->Invert_singleton); - Py_VISIT(state->Invert_type); - Py_VISIT(state->IsNot_singleton); - Py_VISIT(state->IsNot_type); - Py_VISIT(state->Is_singleton); - Py_VISIT(state->Is_type); - Py_VISIT(state->JoinedStr_type); - Py_VISIT(state->LShift_singleton); - Py_VISIT(state->LShift_type); - Py_VISIT(state->Lambda_type); - Py_VISIT(state->ListComp_type); - Py_VISIT(state->List_type); - Py_VISIT(state->Load_singleton); - Py_VISIT(state->Load_type); - Py_VISIT(state->LtE_singleton); - Py_VISIT(state->LtE_type); - Py_VISIT(state->Lt_singleton); - Py_VISIT(state->Lt_type); - Py_VISIT(state->MatMult_singleton); - Py_VISIT(state->MatMult_type); - Py_VISIT(state->Mod_singleton); - Py_VISIT(state->Mod_type); - Py_VISIT(state->Module_type); - Py_VISIT(state->Mult_singleton); - Py_VISIT(state->Mult_type); - Py_VISIT(state->Name_type); - Py_VISIT(state->NamedExpr_type); - Py_VISIT(state->Nonlocal_type); - Py_VISIT(state->NotEq_singleton); - Py_VISIT(state->NotEq_type); - Py_VISIT(state->NotIn_singleton); - Py_VISIT(state->NotIn_type); - Py_VISIT(state->Not_singleton); - Py_VISIT(state->Not_type); - Py_VISIT(state->Or_singleton); - Py_VISIT(state->Or_type); - Py_VISIT(state->Pass_type); - Py_VISIT(state->Pow_singleton); - Py_VISIT(state->Pow_type); - Py_VISIT(state->RShift_singleton); - Py_VISIT(state->RShift_type); - Py_VISIT(state->Raise_type); - Py_VISIT(state->Return_type); - Py_VISIT(state->SetComp_type); - Py_VISIT(state->Set_type); - Py_VISIT(state->Slice_type); - Py_VISIT(state->Starred_type); - Py_VISIT(state->Store_singleton); - Py_VISIT(state->Store_type); - Py_VISIT(state->Sub_singleton); - Py_VISIT(state->Sub_type); - Py_VISIT(state->Subscript_type); - Py_VISIT(state->Try_type); - Py_VISIT(state->Tuple_type); - Py_VISIT(state->TypeIgnore_type); - Py_VISIT(state->UAdd_singleton); - Py_VISIT(state->UAdd_type); - Py_VISIT(state->USub_singleton); - Py_VISIT(state->USub_type); - Py_VISIT(state->UnaryOp_type); - Py_VISIT(state->While_type); - Py_VISIT(state->With_type); - Py_VISIT(state->YieldFrom_type); - Py_VISIT(state->Yield_type); - Py_VISIT(state->__dict__); - Py_VISIT(state->__doc__); - Py_VISIT(state->__module__); - Py_VISIT(state->_attributes); - Py_VISIT(state->_fields); - Py_VISIT(state->alias_type); - Py_VISIT(state->annotation); - Py_VISIT(state->arg); - Py_VISIT(state->arg_type); - Py_VISIT(state->args); - Py_VISIT(state->argtypes); - Py_VISIT(state->arguments_type); - Py_VISIT(state->asname); - Py_VISIT(state->ast); - Py_VISIT(state->attr); - Py_VISIT(state->bases); - Py_VISIT(state->body); - Py_VISIT(state->boolop_type); - Py_VISIT(state->cause); - Py_VISIT(state->cmpop_type); - Py_VISIT(state->col_offset); - Py_VISIT(state->comparators); - Py_VISIT(state->comprehension_type); - Py_VISIT(state->context_expr); - Py_VISIT(state->conversion); - Py_VISIT(state->ctx); - Py_VISIT(state->decorator_list); - Py_VISIT(state->defaults); - Py_VISIT(state->elt); - Py_VISIT(state->elts); - Py_VISIT(state->end_col_offset); - Py_VISIT(state->end_lineno); - Py_VISIT(state->exc); - Py_VISIT(state->excepthandler_type); - Py_VISIT(state->expr_context_type); - Py_VISIT(state->expr_type); - Py_VISIT(state->finalbody); - Py_VISIT(state->format_spec); - Py_VISIT(state->func); - Py_VISIT(state->generators); - Py_VISIT(state->handlers); - Py_VISIT(state->id); - Py_VISIT(state->ifs); - Py_VISIT(state->is_async); - Py_VISIT(state->items); - Py_VISIT(state->iter); - Py_VISIT(state->key); - Py_VISIT(state->keys); - Py_VISIT(state->keyword_type); - Py_VISIT(state->keywords); - Py_VISIT(state->kind); - Py_VISIT(state->kw_defaults); - Py_VISIT(state->kwarg); - Py_VISIT(state->kwonlyargs); - Py_VISIT(state->left); - Py_VISIT(state->level); - Py_VISIT(state->lineno); - Py_VISIT(state->lower); - Py_VISIT(state->mod_type); - Py_VISIT(state->module); - Py_VISIT(state->msg); - Py_VISIT(state->name); - Py_VISIT(state->names); - Py_VISIT(state->op); - Py_VISIT(state->operand); - Py_VISIT(state->operator_type); - Py_VISIT(state->ops); - Py_VISIT(state->optional_vars); - Py_VISIT(state->orelse); - Py_VISIT(state->posonlyargs); - Py_VISIT(state->returns); - Py_VISIT(state->right); - Py_VISIT(state->simple); - Py_VISIT(state->slice); - Py_VISIT(state->step); - Py_VISIT(state->stmt_type); - Py_VISIT(state->tag); - Py_VISIT(state->target); - Py_VISIT(state->targets); - Py_VISIT(state->test); - Py_VISIT(state->type); - Py_VISIT(state->type_comment); - Py_VISIT(state->type_ignore_type); - Py_VISIT(state->type_ignores); - Py_VISIT(state->unaryop_type); - Py_VISIT(state->upper); - Py_VISIT(state->value); - Py_VISIT(state->values); - Py_VISIT(state->vararg); - Py_VISIT(state->withitem_type); - - return 0; -} - -static void astmodule_free(void* module) { - astmodule_clear((PyObject*)module); + state->initialized = 0; } static int init_identifiers(astmodulestate *state) @@ -10316,11 +10087,9 @@ static PyModuleDef_Slot astmodule_slots[] = { static struct PyModuleDef _astmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ast", - .m_size = sizeof(astmodulestate), + // The _ast module uses a global state (global_ast_state). + .m_size = 0, .m_slots = astmodule_slots, - .m_traverse = astmodule_traverse, - .m_clear = astmodule_clear, - .m_free = astmodule_free, }; PyMODINIT_FUNC diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ab5a6767864dc59..75d57805c07b6af 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1259,6 +1259,12 @@ flush_std_files(void) static void finalize_interp_types(PyThreadState *tstate) { + // The _ast module state is shared by all interpreters. + // The state must only be cleared by the main interpreter. + if (_Py_IsMainInterpreter(tstate)) { + _PyAST_Fini(tstate); + } + _PyExc_Fini(tstate); _PyFrame_Fini(tstate); _PyAsyncGen_Fini(tstate); From 43c21dc69d7c6332ceb250dee52bb9cea67696de Mon Sep 17 00:00:00 2001 From: Mandeep Date: Tue, 15 Sep 2020 15:20:49 -0400 Subject: [PATCH 303/486] Improve the description of difflib in the documentation (GH-22253) From "can produce difference information in various formats ..." to " can produce information about file differences in various formats ..." Automerge-Triggered-By: @Mariatta --- Doc/library/difflib.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 25e3511d017858f..aa08988c8b36f71 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -18,8 +18,8 @@ -------------- This module provides classes and functions for comparing sequences. It -can be used for example, for comparing files, and can produce difference -information in various formats, including HTML and context and unified +can be used for example, for comparing files, and can produce information +about file differences in various formats, including HTML and context and unified diffs. For comparing directories and files, see also, the :mod:`filecmp` module. From 8b46bcc1727a1ae4052b2d404831b7a8ff641058 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 15 Sep 2020 12:27:06 -0700 Subject: [PATCH 304/486] minor reformat of enum tests (GH-22259) Automerge-Triggered-By: @ethanfurman --- Lib/test/test_enum.py | 70 +++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index b18f3b38a6619f6..138f572906a4784 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -420,8 +420,10 @@ def red(self): blue = 3 def test_reserved__sunder_(self): - with self.assertRaisesRegex(ValueError, '_sunder_ names, such as ' - '"_bad_", are reserved'): + with self.assertRaisesRegex( + ValueError, + '_sunder_ names, such as "_bad_", are reserved', + ): class Bad(Enum): _bad_ = 1 @@ -1136,9 +1138,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1153,7 +1157,8 @@ def __add__(self, other): if isinstance(self, NamedInt) and isinstance(other, NamedInt): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), - temp ) + temp, + ) else: return temp @@ -1193,9 +1198,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1210,7 +1217,8 @@ def __add__(self, other): if isinstance(self, NamedInt) and isinstance(other, NamedInt): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), - temp ) + temp, + ) else: return temp @@ -1250,9 +1258,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1267,7 +1277,8 @@ def __add__(self, other): if isinstance(self, NamedInt) and isinstance(other, NamedInt): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), - temp ) + temp, + ) else: return temp @@ -1307,9 +1318,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1324,7 +1337,8 @@ def __add__(self, other): if isinstance(self, NamedInt) and isinstance(other, NamedInt): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), - temp ) + temp, + ) else: return temp @@ -1333,7 +1347,6 @@ class NEI(NamedInt, Enum): x = ('the-x', 1) y = ('the-y', 2) - self.assertIs(NEI.__new__, Enum.__new__) self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") globals()['NamedInt'] = NamedInt @@ -1362,9 +1375,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1415,9 +1430,11 @@ def __name__(self): return self._intname def __repr__(self): # repr() is updated to include the name and type info - return "{}({!r}, {})".format(type(self).__name__, - self.__name__, - int.__repr__(self)) + return "{}({!r}, {})".format( + type(self).__name__, + self.__name__, + int.__repr__(self), + ) def __str__(self): # str() is unchanged, even if it relies on the repr() fallback base = int @@ -1432,7 +1449,8 @@ def __add__(self, other): if isinstance(self, NamedInt) and isinstance(other, NamedInt): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), - temp ) + temp, + ) else: return temp From bc8d99306afe33b9073702c59b0f38a60151c3fd Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Tue, 15 Sep 2020 17:13:26 -0300 Subject: [PATCH 305/486] Fix all Python Cookbook links (#22205) --- Doc/faq/programming.rst | 2 +- Doc/howto/urllib2.rst | 2 +- Doc/library/bisect.rst | 2 +- Doc/library/collections.abc.rst | 2 +- Doc/library/collections.rst | 4 ++-- Doc/library/difflib.rst | 2 +- Doc/library/math.rst | 2 +- Doc/library/random.rst | 2 +- Doc/library/shelve.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/tutorial/whatnow.rst | 2 +- Doc/whatsnew/3.2.rst | 4 ++-- Lib/collections/__init__.py | 2 +- Lib/heapq.py | 2 +- Lib/test/test_math.py | 2 +- Tools/peg_generator/pegen/sccutils.py | 4 ++-- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 66d210a55fac7e9..eecbbf4a5c4ff72 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1141,7 +1141,7 @@ How do you remove duplicates from a list? See the Python Cookbook for a long discussion of many ways to do this: - https://code.activestate.com/recipes/52560/ + https://github.com/ActiveState/code/tree/master/recipes/Python/52560_Remove_duplicates/recipe-52560.py If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 046a88af62f0b3e..38623371fbabff5 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -601,5 +601,5 @@ This document was reviewed and revised by John Lee. scripts with a localhost server, I have to prevent urllib from using the proxy. .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe - `_. + `_. diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 6bf7814b257f4ab..6666d55abe2e503 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -60,7 +60,7 @@ The following functions are provided: .. seealso:: `SortedCollection recipe - `_ that uses + `_ that uses bisect to build a full-featured collection class with straight-forward search methods and support for a key-function. The keys are precomputed to save unnecessary calls to the key function during searches. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index db0e25bb0772eb2..a6038098675da21 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -308,7 +308,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: .. seealso:: - * `OrderedSet recipe `_ for an + * `OrderedSet recipe `_ for an example built on :class:`MutableSet`. * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index f538da5e1c9faaf..a7d01b3f397a70f 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -135,12 +135,12 @@ The class can be used to simulate nested scopes and is useful in templating. :attr:`~collections.ChainMap.parents` property. * The `Nested Contexts recipe - `_ has options to control + `_ has options to control whether writes and other mutations apply only to the first mapping or to any mapping in the chain. * A `greatly simplified read-only version of Chainmap - `_. + `_. :class:`ChainMap` Examples and Recipes diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index aa08988c8b36f71..009b7976dff15fe 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -633,7 +633,7 @@ If you want to know how to change the first sequence into the second, use work. * `Simple version control recipe - `_ for a small application + `_ for a small application built with :class:`SequenceMatcher`. diff --git a/Doc/library/math.rst b/Doc/library/math.rst index bbf64643ff59fc7..f152c45a87aa378 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -123,7 +123,7 @@ Number-theoretic and representation functions For further discussion and two alternative approaches, see the `ASPN cookbook recipes for accurate floating point summation - `_\. + `_\. .. function:: gcd(*integers) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 0cdf0a6ac4a477e..4e97b1dbad85c1f 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -57,7 +57,7 @@ from sources provided by the operating system. `Complementary-Multiply-with-Carry recipe - `_ for a compatible alternative + `_ for a compatible alternative random number generator with a long period and comparatively simple update operations. diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index f08c58179a2f9f0..a94255bbf698e9e 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -75,7 +75,7 @@ Two additional methods are supported: .. seealso:: - `Persistent dictionary recipe `_ + `Persistent dictionary recipe `_ with widely supported storage formats and having the speed of native dictionaries. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 0ffe7b7526fa768..2eee22c79af7691 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1404,7 +1404,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe `_ + * The `linspace recipe `_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index d201d7061f98015..aa417ede4022863 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -679,7 +679,7 @@ always available. additional garbage collector overhead if the object is managed by the garbage collector. - See `recursive sizeof recipe `_ + See `recursive sizeof recipe `_ for an example of using :func:`getsizeof` recursively to find the size of containers and all their contents. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 3208201312b8710..38ce9f0a900c283 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -43,7 +43,7 @@ More Python resources: for download. Once you begin releasing code, you can register it here so that others can find it. -* https://code.activestate.com/recipes/langs/python/: The Python Cookbook is a +* https://github.com/ActiveState/code/tree/master/recipes/Python: The Python Cookbook is a sizable collection of code examples, larger modules, and useful scripts. Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 06bee9966c0be24..37bae34ce74adcb 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -781,8 +781,8 @@ functools (Contributed by Raymond Hettinger and incorporating design ideas from Jim Baker, Miki Tebeka, and Nick Coghlan; see `recipe 498245 - `_\, `recipe 577479 - `_\, :issue:`10586`, and + `_\, `recipe 577479 + `_\, :issue:`10586`, and :issue:`10593`.) * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 5d75501645fc4a7..f4da9d0cefd6bf6 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -574,7 +574,7 @@ class Counter(dict): # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm - # http://code.activestate.com/recipes/259174/ + # https://github.com/ActiveState/code/tree/master/recipes/Python/259174_bag_collection_class/recipe-259174.py # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): diff --git a/Lib/heapq.py b/Lib/heapq.py index fabefd87f8bf8c8..5895562db4142bc 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -456,7 +456,7 @@ def merge(*iterables, key=None, reverse=False): # 2) Made multiple passes over the data. # 3) Made more comparisons in common cases (small k, large n, semi-random input). # See the more detailed comparison of approach at: -# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest +# https://github.com/ActiveState/code/tree/master/recipes/Python/577573_Compare_algorithms/recipe-577573.py def nsmallest(n, iterable, key=None): """Find the n smallest elements in a dataset. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 4d62eb1b119930d..f5283c5e0dcb635 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -611,7 +611,7 @@ def testFsum(self): def msum(iterable): """Full precision summation. Compute sum(iterable) without any intermediate accumulation of error. Based on the 'lsum' function - at http://code.activestate.com/recipes/393090/ + at https://github.com/ActiveState/code/tree/master/recipes/Python/393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py """ tmant, texp = 0, 0 diff --git a/Tools/peg_generator/pegen/sccutils.py b/Tools/peg_generator/pegen/sccutils.py index 1f0586bb2f7d6db..0c295196607ec8b 100644 --- a/Tools/peg_generator/pegen/sccutils.py +++ b/Tools/peg_generator/pegen/sccutils.py @@ -18,7 +18,7 @@ def strongly_connected_components( exactly once; vertices not part of a SCC are returned as singleton sets. - From http://code.activestate.com/recipes/578507/. + From https://github.com/ActiveState/code/tree/master/recipes/Python/578507_Strongly_connected_components_directed/recipe-578507.py. """ identified: Set[str] = set() stack: List[str] = [] @@ -81,7 +81,7 @@ def topsort( {B, C} {A} - From http://code.activestate.com/recipes/577413/. + From https://github.com/ActiveState/code/tree/master/recipes/Python/577413_Topological_Sort/recipe-577413.py. """ # TODO: Use a faster algorithm? for k, v in data.items(): From a2ee379a23eefff3fde5514b3b2bd987ad873d4c Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 16 Sep 2020 00:58:32 +0300 Subject: [PATCH 306/486] bpo-41780: Fix __dir__ of types.GenericAlias (GH-22262) Automerge-Triggered-By: @gvanrossum --- Lib/test/test_genericalias.py | 5 +++ .../2020-09-15-23-29-49.bpo-41780.bOBUIH.rst | 2 + Objects/genericaliasobject.c | 39 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 1f24469471428af..643fffc073e82f3 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -287,6 +287,11 @@ def test_union_generic(self): self.assertEqual(a.__args__, (list[T], tuple[T, ...])) self.assertEqual(a.__parameters__, (T,)) + def test_dir(self): + dir_of_gen_alias = set(dir(list[int])) + self.assertTrue(dir_of_gen_alias.issuperset(dir(list))) + for generic_alias_property in ("__origin__", "__args__", "__parameters__"): + self.assertIn(generic_alias_property, dir_of_gen_alias) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst new file mode 100644 index 000000000000000..9a7594fc453381b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst @@ -0,0 +1,2 @@ +Fix :meth:`__dir__` of :class:`types.GenericAlias`. Patch by Batuhan +Taskaya. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 87bd1ae5c1430b5..ab56e1c4bf1a860 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -487,11 +487,50 @@ ga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) alias->origin, alias->args); } +static PyObject * +ga_dir(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + gaobject *alias = (gaobject *)self; + PyObject *dir = PyObject_Dir(alias->origin); + if (dir == NULL) { + return NULL; + } + + PyObject *dir_entry = NULL; + for (const char * const *p = attr_exceptions; ; p++) { + if (*p == NULL) { + break; + } + else { + dir_entry = PyUnicode_FromString(*p); + if (dir_entry == NULL) { + goto error; + } + int contains = PySequence_Contains(dir, dir_entry); + if (contains < 0) { + goto error; + } + if (contains == 0 && PyList_Append(dir, dir_entry) < 0) { + goto error; + } + + Py_CLEAR(dir_entry); + } + } + return dir; + +error: + Py_DECREF(dir); + Py_XDECREF(dir_entry); + return NULL; +} + static PyMethodDef ga_methods[] = { {"__mro_entries__", ga_mro_entries, METH_O}, {"__instancecheck__", ga_instancecheck, METH_O}, {"__subclasscheck__", ga_subclasscheck, METH_O}, {"__reduce__", ga_reduce, METH_NOARGS}, + {"__dir__", ga_dir, METH_NOARGS}, {0} }; From 3f4c334a20d7ae9c848f0586e5d3007e667e7635 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 15 Sep 2020 15:56:26 -0700 Subject: [PATCH 307/486] bpo-39587: Enum - use correct mixed-in data type (GH-22263) --- Lib/enum.py | 13 +++++- Lib/test/test_enum.py | 43 +++++++++++++++++++ .../2020-09-15-14-56-13.bpo-39587.69xzuh.rst | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst diff --git a/Lib/enum.py b/Lib/enum.py index bc24f2ae2dfc012..5e0088ee89fee3b 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -482,14 +482,25 @@ def _get_mixins_(bases): return object, Enum def _find_data_type(bases): + data_types = [] for chain in bases: + candidate = None for base in chain.__mro__: if base is object: continue elif '__new__' in base.__dict__: if issubclass(base, Enum): continue - return base + data_types.append(candidate or base) + break + elif not issubclass(base, Enum): + candidate = base + if len(data_types) > 1: + raise TypeError('too many data types: %r' % data_types) + elif data_types: + return data_types[0] + else: + return None # ensure final parent class is an Enum derivative, find any concrete # data type, and check that Enum has no members diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 138f572906a4784..a909c108833fc08 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -560,6 +560,49 @@ def test_format_enum_str(self): self.assertFormatIsValue('{:>20}', Directional.WEST) self.assertFormatIsValue('{:<20}', Directional.WEST) + def test_enum_str_override(self): + class MyStrEnum(Enum): + def __str__(self): + return 'MyStr' + class MyMethodEnum(Enum): + def hello(self): + return 'Hello! My name is %s' % self.name + class Test1Enum(MyMethodEnum, int, MyStrEnum): + One = 1 + Two = 2 + self.assertEqual(str(Test1Enum.One), 'MyStr') + # + class Test2Enum(MyStrEnum, MyMethodEnum): + One = 1 + Two = 2 + self.assertEqual(str(Test2Enum.One), 'MyStr') + + def test_inherited_data_type(self): + class HexInt(int): + def __repr__(self): + return hex(self) + class MyEnum(HexInt, enum.Enum): + A = 1 + B = 2 + C = 3 + self.assertEqual(repr(MyEnum.A), '') + + def test_too_many_data_types(self): + with self.assertRaisesRegex(TypeError, 'too many data types'): + class Huh(str, int, Enum): + One = 1 + + class MyStr(str): + def hello(self): + return 'hello, %s' % self + class MyInt(int): + def repr(self): + return hex(self) + with self.assertRaisesRegex(TypeError, 'too many data types'): + class Huh(MyStr, MyInt, Enum): + One = 1 + + def test_hash(self): Season = self.Season dates = {} diff --git a/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst b/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst new file mode 100644 index 000000000000000..e2f2b64867bedbf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst @@ -0,0 +1 @@ +use the correct mix-in data type when constructing Enums From aab4e79a1b27da6e07b4723046726e28335289a1 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 15 Sep 2020 16:26:06 -0700 Subject: [PATCH 308/486] Doc: Fix broken manpage link (GH-21937) sigprocmask is in section 2, not 3. --- Doc/library/signal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 05b285ed110ec4c..00a730b6b9ca6ae 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -416,7 +416,7 @@ The :mod:`signal` module defines the following functions: :data:`SIGKILL` and :data:`SIGSTOP` cannot be blocked. - .. availability:: Unix. See the man page :manpage:`sigprocmask(3)` and + .. availability:: Unix. See the man page :manpage:`sigprocmask(2)` and :manpage:`pthread_sigmask(3)` for further information. See also :func:`pause`, :func:`sigpending` and :func:`sigwait`. From d579c6c5cabf9ad1658d0d848e9800cd356218ff Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 15 Sep 2020 16:28:25 -0700 Subject: [PATCH 309/486] bpo-41789: honor object overrides in Enum classes (GH-22250) EnumMeta double-checks that `__repr__`, `__str__`, `__format__`, and `__reduce_ex__` are not the same as `object`'s, and replaces them if they are -- even if that replacement was intentionally done in the Enum being constructed. This patch fixes that. Automerge-Triggered-By: @ethanfurman --- Lib/enum.py | 4 ++++ Lib/test/test_enum.py | 9 ++++++++- .../Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst diff --git a/Lib/enum.py b/Lib/enum.py index 5e0088ee89fee3b..e72d30626746184 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -250,7 +250,11 @@ def __new__(metacls, cls, bases, classdict): # double check that repr and friends are not the mixin's or various # things break (such as pickle) + # however, if the method is defined in the Enum itself, don't replace + # it for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): + if name in classdict: + continue class_method = getattr(enum_class, name) obj_method = getattr(member_type, name, None) enum_method = getattr(first_enum, name, None) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index a909c108833fc08..865edf1d9cfc67b 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -560,6 +560,14 @@ def test_format_enum_str(self): self.assertFormatIsValue('{:>20}', Directional.WEST) self.assertFormatIsValue('{:<20}', Directional.WEST) + def test_object_str_override(self): + class Colors(Enum): + RED, GREEN, BLUE = 1, 2, 3 + def __repr__(self): + return "test.%s" % (self._name_, ) + __str__ = object.__str__ + self.assertEqual(str(Colors.RED), 'test.RED') + def test_enum_str_override(self): class MyStrEnum(Enum): def __str__(self): @@ -602,7 +610,6 @@ def repr(self): class Huh(MyStr, MyInt, Enum): One = 1 - def test_hash(self): Season = self.Season dates = {} diff --git a/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst b/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst new file mode 100644 index 000000000000000..5ce7a3ca67b7250 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst @@ -0,0 +1,2 @@ +Honor `object` overrides in `Enum` class creation (specifically, `__str__`, +`__repr__`, `__format__`, and `__reduce_ex__`). From 29ef8f223b20fc0579d2005c180183139111f2b4 Mon Sep 17 00:00:00 2001 From: Patrick Reader Date: Wed, 16 Sep 2020 05:58:32 +0100 Subject: [PATCH 310/486] bpo-41792: Add is_typeddict function to typing.py (GH-22254) Closes issue41792. Also closes https://github.com/python/typing/issues/751. --- Doc/library/typing.rst | 14 ++++++++++++++ Lib/test/test_typing.py | 7 +++++++ Lib/typing.py | 15 +++++++++++++++ .../2020-09-15-07-55-35.bpo-41792.qMpSlU.rst | 6 ++++++ 4 files changed, 42 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 3125ae97808a9e5..bfff81e26760f52 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1658,6 +1658,20 @@ Introspection helpers .. versionadded:: 3.8 +.. function:: is_typeddict(tp) + + Check if an annotation is a TypedDict class. + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + + .. versionadded:: 3.10 + .. class:: ForwardRef A class used for internal typing representation of string forward references. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 05140fc61b9bf5d..42aa430c5e107e6 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -16,6 +16,7 @@ from typing import cast, runtime_checkable from typing import get_type_hints from typing import get_origin, get_args +from typing import is_typeddict from typing import no_type_check, no_type_check_decorator from typing import Type from typing import NewType @@ -3900,6 +3901,12 @@ class Cat(Animal): 'voice': str, } + def test_is_typeddict(self): + assert is_typeddict(Point2D) is True + assert is_typeddict(Union[str, int]) is False + # classes, not instances + assert is_typeddict(Point2D()) is False + class IOTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 2aedbeb852a7126..8c61bd8e084a850 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -103,6 +103,7 @@ 'get_args', 'get_origin', 'get_type_hints', + 'is_typeddict', 'NewType', 'no_type_check', 'no_type_check_decorator', @@ -1479,6 +1480,20 @@ def get_args(tp): return () +def is_typeddict(tp): + """Check if an annotation is a TypedDict class + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + """ + return isinstance(tp, _TypedDictMeta) + + def no_type_check(arg): """Decorator to indicate that annotations are not type hints. diff --git a/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst b/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst new file mode 100644 index 000000000000000..fbbc6724ba51ec6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst @@ -0,0 +1,6 @@ +Add is_typeddict function to typing.py to check if a type is a TypedDict +class + +Previously there was no way to check that without using private API. See the +`relevant issue in python/typing +` From d5399ff3382e881aa99ce914c62ee64420f31a5a Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 16 Sep 2020 07:11:57 -0700 Subject: [PATCH 311/486] bpo-41517: do not allow Enums to be extended (#22271) fix bug that let Enums be extended via multiple inheritance --- Lib/enum.py | 19 ++++++++++++++----- Lib/test/test_enum.py | 3 +++ .../2020-09-15-22-43-30.bpo-41517.sLBH7g.rst | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst diff --git a/Lib/enum.py b/Lib/enum.py index e72d30626746184..0c2cf569fac88d9 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -124,10 +124,12 @@ class EnumMeta(type): """Metaclass for Enum""" @classmethod def __prepare__(metacls, cls, bases): + # check that previous enum members do not exist + metacls._check_for_existing_members(cls, bases) # create the namespace dict enum_dict = _EnumDict() # inherit previous flags and _generate_next_value_ function - member_type, first_enum = metacls._get_mixins_(bases) + member_type, first_enum = metacls._get_mixins_(cls, bases) if first_enum is not None: enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None) return enum_dict @@ -143,7 +145,7 @@ def __new__(metacls, cls, bases, classdict): ignore = classdict['_ignore_'] for key in ignore: classdict.pop(key, None) - member_type, first_enum = metacls._get_mixins_(bases) + member_type, first_enum = metacls._get_mixins_(cls, bases) __new__, save_new, use_args = metacls._find_new_(classdict, member_type, first_enum) @@ -402,7 +404,7 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s """ metacls = cls.__class__ bases = (cls, ) if type is None else (type, cls) - _, first_enum = cls._get_mixins_(bases) + _, first_enum = cls._get_mixins_(cls, bases) classdict = metacls.__prepare__(class_name, bases) # special processing needed for names? @@ -475,7 +477,14 @@ def _convert_(cls, name, module, filter, source=None): return cls @staticmethod - def _get_mixins_(bases): + def _check_for_existing_members(class_name, bases): + for chain in bases: + for base in chain.__mro__: + if issubclass(base, Enum) and base._member_names_: + raise TypeError("%s: cannot extend enumeration %r" % (class_name, base.__name__)) + + @staticmethod + def _get_mixins_(class_name, bases): """Returns the type for creating enum members, and the first inherited enum class. @@ -500,7 +509,7 @@ def _find_data_type(bases): elif not issubclass(base, Enum): candidate = base if len(data_types) > 1: - raise TypeError('too many data types: %r' % data_types) + raise TypeError('%r: too many data types: %r' % (class_name, data_types)) elif data_types: return data_types[0] else: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 865edf1d9cfc67b..2fcd047989afb20 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1009,6 +1009,9 @@ class MoreColor(Color): cyan = 4 magenta = 5 yellow = 6 + with self.assertRaisesRegex(TypeError, "EvenMoreColor: cannot extend enumeration 'Color'"): + class EvenMoreColor(Color, IntEnum): + chartruese = 7 def test_exclude_methods(self): class whatever(Enum): diff --git a/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst b/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst new file mode 100644 index 000000000000000..e7654711062cef9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst @@ -0,0 +1 @@ +fix bug allowing Enums to be extended via multiple inheritance From 33d6ce6aefd66fb9d19e87b45824797ef35da22d Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Wed, 16 Sep 2020 12:06:23 -0300 Subject: [PATCH 312/486] [doc] Minor improvements to is_typeddict (GH-22280) 1. The check is on the type 2. Add link to TypeDict --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index bfff81e26760f52..d31c65d38e1abbb 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1660,7 +1660,7 @@ Introspection helpers .. function:: is_typeddict(tp) - Check if an annotation is a TypedDict class. + Check if a type is a :class:`TypedDict`. For example:: class Film(TypedDict): From 8182687dd3aac54a45cc15827f36fe6c7f92c162 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 16 Sep 2020 10:26:50 -0700 Subject: [PATCH 313/486] bpo-39728: Enum: fix duplicate `ValueError` (GH-22277) fix default `_missing_` to return `None` instead of raising a `ValueError` Co-authored-by: Andrey Darascheka --- Lib/enum.py | 2 +- Lib/test/test_enum.py | 19 ++++++++++++++++++- Misc/ACKS | 1 + .../2020-02-24-10-58-34.bpo-39728.kOOaHn.rst | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst diff --git a/Lib/enum.py b/Lib/enum.py index 0c2cf569fac88d9..060b2a0dadf4576 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -629,7 +629,7 @@ def _generate_next_value_(name, start, count, last_values): @classmethod def _missing_(cls, value): - raise ValueError("%r is not a valid %s" % (value, cls.__qualname__)) + return None def __repr__(self): return "<%s.%s: %r>" % ( diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 2fcd047989afb20..5d72d82cec27ffe 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1845,6 +1845,18 @@ class Dupes(Enum): third = auto() self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) + def test_default_missing(self): + class Color(Enum): + RED = 1 + GREEN = 2 + BLUE = 3 + try: + Color(7) + except ValueError as exc: + self.assertTrue(exc.__context__ is None) + else: + raise Exception('Exception not raised.') + def test_missing(self): class Color(Enum): red = 1 @@ -1863,7 +1875,12 @@ def _missing_(cls, item): # trigger not found return None self.assertIs(Color('three'), Color.blue) - self.assertRaises(ValueError, Color, 7) + try: + Color(7) + except ValueError as exc: + self.assertTrue(exc.__context__ is None) + else: + raise Exception('Exception not raised.') try: Color('bad return') except TypeError as exc: diff --git a/Misc/ACKS b/Misc/ACKS index 8b0d7a45da16953..2628d6b690d1cbe 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -433,6 +433,7 @@ Marcos Donolo Dima Dorfman Yves Dorfsman Michael Dorman +Andrey Doroschenko Steve Dower Allen Downey Cesar Douady diff --git a/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst b/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst new file mode 100644 index 000000000000000..beb2016a85ba682 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst @@ -0,0 +1 @@ +fix default `_missing_` so a duplicate `ValueError` is not set as the `__context__` of the original `ValueError` From 66f34edc845e364984d5875713e6988e0ad86742 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 16 Sep 2020 11:37:24 -0700 Subject: [PATCH 314/486] acknowledge Weipeng Hong's contributions (GH-22284) --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 2628d6b690d1cbe..d5bdb084a1e1edb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -736,6 +736,7 @@ Thomas Holmes Craig Holmquist Philip Homburg Naofumi Honda +Weipeng Hong Jeffrey Honig Rob Hooft Michiel de Hoon From 99a576ed14029e74067c41a7ffbbdcef91a46cfa Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 16 Sep 2020 19:42:00 +0100 Subject: [PATCH 315/486] bpo-41746: Add type information to asdl_seq objects (GH-22223) * Add new capability to the PEG parser to type variable assignments. For instance: ``` | a[asdl_stmt_seq*]=';'.small_stmt+ [';'] NEWLINE { a } ``` * Add new sequence types from the asdl definition (automatically generated) * Make `asdl_seq` type a generic aliasing pointer type. * Create a new `asdl_generic_seq` for the generic case using `void*`. * The old `asdl_seq_GET`/`ast_seq_SET` macros now are typed. * New `asdl_seq_GET_UNTYPED`/`ast_seq_SET_UNTYPED` macros for dealing with generic sequences. * Changes all possible `asdl_seq` types to use specific versions everywhere. --- Doc/tools/extensions/peg_highlight.py | 2 +- Grammar/python.gram | 122 ++-- Include/Python-ast.h | 356 ++++++---- Include/asdl.h | 71 +- Include/ast.h | 2 +- Parser/asdl_c.py | 61 +- Parser/parser.c | 713 ++++++++++---------- Parser/pegen.c | 187 ++--- Parser/pegen.h | 30 +- Parser/string_parser.c | 8 +- Python/Python-ast.c | 507 +++++++------- Python/asdl.c | 64 +- Python/ast.c | 25 +- Python/ast_opt.c | 106 +-- Python/ast_unparse.c | 8 +- Python/compile.c | 77 +-- Python/future.c | 3 +- Python/symtable.c | 22 +- Tools/peg_generator/pegen/c_generator.py | 15 +- Tools/peg_generator/pegen/grammar.py | 3 +- Tools/peg_generator/pegen/grammar_parser.py | 42 +- Tools/peg_generator/pegen/metagrammar.gram | 2 + 22 files changed, 1339 insertions(+), 1087 deletions(-) diff --git a/Doc/tools/extensions/peg_highlight.py b/Doc/tools/extensions/peg_highlight.py index 8bc24670fbe0abe..9a2acb7f320ba6e 100644 --- a/Doc/tools/extensions/peg_highlight.py +++ b/Doc/tools/extensions/peg_highlight.py @@ -43,7 +43,7 @@ class PEGLexer(RegexLexer): (r"'\W+?'", Text), (r'"\W+?"', Text), ], - "variables": [(_name + _text_ws + "(=)", bygroups(None, None, None),),], + "variables": [(_name + _text_ws + r"(\[.*\])?" + _text_ws + "(=)", bygroups(None, None, None, None, None),),], "invalids": [ (r"^(\s+\|\s+invalid_\w+\s*\n)", bygroups(None)), (r"^(\s+\|\s+incorrect_\w+\s*\n)", bygroups(None)), diff --git a/Grammar/python.gram b/Grammar/python.gram index 524e88eb389968e..e4533b1a1b87971 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -34,27 +34,27 @@ func_type[mod_ty]: '(' a=[type_expressions] ')' '->' b=expression NEWLINE* ENDMA fstring[expr_ty]: star_expressions # type_expressions allow */** but ignore them -type_expressions[asdl_seq*]: +type_expressions[asdl_expr_seq*]: | a=','.expression+ ',' '*' b=expression ',' '**' c=expression { - _PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) } - | a=','.expression+ ',' '*' b=expression { _PyPegen_seq_append_to_end(p, a, b) } - | a=','.expression+ ',' '**' b=expression { _PyPegen_seq_append_to_end(p, a, b) } + (asdl_expr_seq*)_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) } + | a=','.expression+ ',' '*' b=expression { (asdl_expr_seq*)_PyPegen_seq_append_to_end(p, a, b) } + | a=','.expression+ ',' '**' b=expression { (asdl_expr_seq*)_PyPegen_seq_append_to_end(p, a, b) } | '*' a=expression ',' '**' b=expression { - _PyPegen_seq_append_to_end(p, CHECK(_PyPegen_singleton_seq(p, a)), b) } - | '*' a=expression { _PyPegen_singleton_seq(p, a) } - | '**' a=expression { _PyPegen_singleton_seq(p, a) } - | ','.expression+ - -statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) } -statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } | simple_stmt -statement_newline[asdl_seq*]: - | a=compound_stmt NEWLINE { _PyPegen_singleton_seq(p, a) } + (asdl_expr_seq*)_PyPegen_seq_append_to_end(p, CHECK(_PyPegen_singleton_seq(p, a)), b) } + | '*' a=expression { (asdl_expr_seq*)_PyPegen_singleton_seq(p, a) } + | '**' a=expression { (asdl_expr_seq*)_PyPegen_singleton_seq(p, a) } + | a[asdl_expr_seq*]=','.expression+ {a} + +statements[asdl_stmt_seq*]: a=statement+ { (asdl_stmt_seq*)_PyPegen_seq_flatten(p, a) } +statement[asdl_stmt_seq*]: a=compound_stmt { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } | a[asdl_stmt_seq*]=simple_stmt { a } +statement_newline[asdl_stmt_seq*]: + | a=compound_stmt NEWLINE { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } | simple_stmt - | NEWLINE { _PyPegen_singleton_seq(p, CHECK(_Py_Pass(EXTRA))) } + | NEWLINE { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, CHECK(_Py_Pass(EXTRA))) } | ENDMARKER { _PyPegen_interactive_exit(p) } -simple_stmt[asdl_seq*]: - | a=small_stmt !';' NEWLINE { _PyPegen_singleton_seq(p, a) } # Not needed, there for speedup - | a=';'.small_stmt+ [';'] NEWLINE { a } +simple_stmt[asdl_stmt_seq*]: + | a=small_stmt !';' NEWLINE { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } # Not needed, there for speedup + | a[asdl_stmt_seq*]=';'.small_stmt+ [';'] NEWLINE { a } # NOTE: assignment MUST precede expression, else parsing a simple assignment # will throw a SyntaxError. small_stmt[stmt_ty] (memo): @@ -91,7 +91,7 @@ assignment[stmt_ty]: | a=('(' b=single_target ')' { b } | single_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] { CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) } - | a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) !'=' tc=[TYPE_COMMENT] { + | a[asdl_expr_seq*]=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) !'=' tc=[TYPE_COMMENT] { _Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } | a=single_target b=augassign ~ c=(yield_expr | star_expressions) { _Py_AugAssign(a, b->kind, c, EXTRA) } @@ -112,9 +112,9 @@ augassign[AugOperator*]: | '**=' { _PyPegen_augoperator(p, Pow) } | '//=' { _PyPegen_augoperator(p, FloorDiv) } -global_stmt[stmt_ty]: 'global' a=','.NAME+ { +global_stmt[stmt_ty]: 'global' a[asdl_expr_seq*]=','.NAME+ { _Py_Global(CHECK(_PyPegen_map_names_to_ids(p, a)), EXTRA) } -nonlocal_stmt[stmt_ty]: 'nonlocal' a=','.NAME+ { +nonlocal_stmt[stmt_ty]: 'nonlocal' a[asdl_expr_seq*]=','.NAME+ { _Py_Nonlocal(CHECK(_PyPegen_map_names_to_ids(p, a)), EXTRA) } yield_stmt[stmt_ty]: y=yield_expr { _Py_Expr(y, EXTRA) } @@ -133,19 +133,19 @@ import_from[stmt_ty]: _Py_ImportFrom(b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) } | 'from' a=('.' | '...')+ 'import' b=import_from_targets { _Py_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) } -import_from_targets[asdl_seq*]: +import_from_targets[asdl_alias_seq*]: | '(' a=import_from_as_names [','] ')' { a } | import_from_as_names !',' - | '*' { _PyPegen_singleton_seq(p, CHECK(_PyPegen_alias_for_star(p))) } + | '*' { (asdl_alias_seq*)_PyPegen_singleton_seq(p, CHECK(_PyPegen_alias_for_star(p))) } | invalid_import_from_targets -import_from_as_names[asdl_seq*]: - | a=','.import_from_as_name+ { a } +import_from_as_names[asdl_alias_seq*]: + | a[asdl_alias_seq*]=','.import_from_as_name+ { a } import_from_as_name[alias_ty]: | a=NAME b=['as' z=NAME { z }] { _Py_alias(a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, p->arena) } -dotted_as_names[asdl_seq*]: - | a=','.dotted_as_name+ { a } +dotted_as_names[asdl_alias_seq*]: + | a[asdl_alias_seq*]=','.dotted_as_name+ { a } dotted_as_name[alias_ty]: | a=dotted_name b=['as' z=NAME { z }] { _Py_alias(a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, @@ -155,12 +155,12 @@ dotted_name[expr_ty]: | NAME if_stmt[stmt_ty]: - | 'if' a=named_expression ':' b=block c=elif_stmt { _Py_If(a, b, CHECK(_PyPegen_singleton_seq(p, c)), EXTRA) } + | 'if' a=named_expression ':' b=block c=elif_stmt { _Py_If(a, b, CHECK((asdl_stmt_seq*)_PyPegen_singleton_seq(p, c)), EXTRA) } | 'if' a=named_expression ':' b=block c=[else_block] { _Py_If(a, b, c, EXTRA) } elif_stmt[stmt_ty]: | 'elif' a=named_expression ':' b=block c=elif_stmt { _Py_If(a, b, CHECK(_PyPegen_singleton_seq(p, c)), EXTRA) } | 'elif' a=named_expression ':' b=block c=[else_block] { _Py_If(a, b, c, EXTRA) } -else_block[asdl_seq*]: 'else' ':' b=block { b } +else_block[asdl_stmt_seq*]: 'else' ':' b=block { b } while_stmt[stmt_ty]: | 'while' a=named_expression ':' b=block c=[else_block] { _Py_While(a, b, c, EXTRA) } @@ -173,13 +173,13 @@ for_stmt[stmt_ty]: | invalid_for_target with_stmt[stmt_ty]: - | 'with' '(' a=','.with_item+ ','? ')' ':' b=block { + | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { _Py_With(a, b, NULL, EXTRA) } - | 'with' a=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { + | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { _Py_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } - | ASYNC 'with' '(' a=','.with_item+ ','? ')' ':' b=block { + | ASYNC 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NULL, EXTRA)) } - | ASYNC 'with' a=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { + | ASYNC 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) } with_item[withitem_ty]: | e=expression 'as' t=target &(',' | ')' | ':') { _Py_withitem(e, t, p->arena) } @@ -188,12 +188,12 @@ with_item[withitem_ty]: try_stmt[stmt_ty]: | 'try' ':' b=block f=finally_block { _Py_Try(b, NULL, NULL, f, EXTRA) } - | 'try' ':' b=block ex=except_block+ el=[else_block] f=[finally_block] { _Py_Try(b, ex, el, f, EXTRA) } + | 'try' ':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _Py_Try(b, ex, el, f, EXTRA) } except_block[excepthandler_ty]: | 'except' e=expression t=['as' z=NAME { z }] ':' b=block { _Py_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } | 'except' ':' b=block { _Py_ExceptHandler(NULL, NULL, b, EXTRA) } -finally_block[asdl_seq*]: 'finally' ':' a=block { a } +finally_block[asdl_stmt_seq*]: 'finally' ':' a=block { a } return_stmt[stmt_ty]: | 'return' a=[star_expressions] { _Py_Return(a, EXTRA) } @@ -229,11 +229,11 @@ params[arguments_ty]: | parameters parameters[arguments_ty]: - | a=slash_no_default b=param_no_default* c=param_with_default* d=[star_etc] { + | a=slash_no_default b[asdl_arg_seq*]=param_no_default* c=param_with_default* d=[star_etc] { _PyPegen_make_arguments(p, a, NULL, b, c, d) } | a=slash_with_default b=param_with_default* c=[star_etc] { _PyPegen_make_arguments(p, NULL, a, NULL, b, c) } - | a=param_no_default+ b=param_with_default* c=[star_etc] { + | a[asdl_arg_seq*]=param_no_default+ b=param_with_default* c=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, a, b, c) } | a=param_with_default+ b=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)} | a=star_etc { _PyPegen_make_arguments(p, NULL, NULL, NULL, NULL, a) } @@ -241,12 +241,12 @@ parameters[arguments_ty]: # Some duplication here because we can't write (',' | &')'), # which is because we don't support empty alternatives (yet). # -slash_no_default[asdl_seq*]: - | a=param_no_default+ '/' ',' { a } - | a=param_no_default+ '/' &')' { a } +slash_no_default[asdl_arg_seq*]: + | a[asdl_arg_seq*]=param_no_default+ '/' ',' { a } + | a[asdl_arg_seq*]=param_no_default+ '/' &')' { a } slash_with_default[SlashWithDefault*]: - | a=param_no_default* b=param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, a, b) } - | a=param_no_default* b=param_with_default+ '/' &')' { _PyPegen_slash_with_default(p, a, b) } + | a=param_no_default* b=param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } + | a=param_no_default* b=param_with_default+ '/' &')' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } star_etc[StarEtc*]: | '*' a=param_no_default b=param_maybe_default* c=[kwds] { @@ -284,7 +284,7 @@ param[arg_ty]: a=NAME b=annotation? { _Py_arg(a->v.Name.id, b, NULL, EXTRA) } annotation[expr_ty]: ':' a=expression { a } default[expr_ty]: '=' a=expression { a } -decorators[asdl_seq*]: a=('@' f=named_expression NEWLINE { f })+ { a } +decorators[asdl_expr_seq*]: a[asdl_expr_seq*]=('@' f=named_expression NEWLINE { f })+ { a } class_def[stmt_ty]: | a=decorators b=class_def_raw { _PyPegen_class_def_decorators(p, a, b) } @@ -296,12 +296,12 @@ class_def_raw[stmt_ty]: (b) ? ((expr_ty) b)->v.Call.keywords : NULL, c, NULL, EXTRA) } -block[asdl_seq*] (memo): +block[asdl_stmt_seq*] (memo): | NEWLINE INDENT a=statements DEDENT { a } | simple_stmt | invalid_block -expressions_list[asdl_seq*]: a=','.star_expression+ [','] { a } +expressions_list[asdl_expr_seq*]: a[asdl_expr_seq*]=','.star_expression+ [','] { a } star_expressions[expr_ty]: | a=star_expression b=(',' c=star_expression { c })+ [','] { _Py_Tuple(CHECK(_PyPegen_seq_insert_in_front(p, a, b)), Load, EXTRA) } @@ -311,7 +311,7 @@ star_expression[expr_ty] (memo): | '*' a=bitwise_or { _Py_Starred(a, Load, EXTRA) } | expression -star_named_expressions[asdl_seq*]: a=','.star_named_expression+ [','] { a } +star_named_expressions[asdl_expr_seq*]: a[asdl_expr_seq*]=','.star_named_expression+ [','] { a } star_named_expression[expr_ty]: | '*' a=bitwise_or { _Py_Starred(a, Load, EXTRA) } | named_expression @@ -344,21 +344,21 @@ lambda_params[arguments_ty]: # a colon, not a close parenthesis. (For more, see parameters above.) # lambda_parameters[arguments_ty]: - | a=lambda_slash_no_default b=lambda_param_no_default* c=lambda_param_with_default* d=[lambda_star_etc] { + | a=lambda_slash_no_default b[asdl_arg_seq*]=lambda_param_no_default* c=lambda_param_with_default* d=[lambda_star_etc] { _PyPegen_make_arguments(p, a, NULL, b, c, d) } | a=lambda_slash_with_default b=lambda_param_with_default* c=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, a, NULL, b, c) } - | a=lambda_param_no_default+ b=lambda_param_with_default* c=[lambda_star_etc] { + | a[asdl_arg_seq*]=lambda_param_no_default+ b=lambda_param_with_default* c=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, a, b, c) } | a=lambda_param_with_default+ b=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)} | a=lambda_star_etc { _PyPegen_make_arguments(p, NULL, NULL, NULL, NULL, a) } -lambda_slash_no_default[asdl_seq*]: - | a=lambda_param_no_default+ '/' ',' { a } - | a=lambda_param_no_default+ '/' &':' { a } +lambda_slash_no_default[asdl_arg_seq*]: + | a[asdl_arg_seq*]=lambda_param_no_default+ '/' ',' { a } + | a[asdl_arg_seq*]=lambda_param_no_default+ '/' &':' { a } lambda_slash_with_default[SlashWithDefault*]: - | a=lambda_param_no_default* b=lambda_param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, a, b) } - | a=lambda_param_no_default* b=lambda_param_with_default+ '/' &':' { _PyPegen_slash_with_default(p, a, b) } + | a=lambda_param_no_default* b=lambda_param_with_default+ '/' ',' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } + | a=lambda_param_no_default* b=lambda_param_with_default+ '/' &':' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } lambda_star_etc[StarEtc*]: | '*' a=lambda_param_no_default b=lambda_param_maybe_default* c=[lambda_kwds] { @@ -472,7 +472,7 @@ primary[expr_ty]: slices[expr_ty]: | a=slice !',' { a } - | a=','.slice+ [','] { _Py_Tuple(a, Load, EXTRA) } + | a[asdl_expr_seq*]=','.slice+ [','] { _Py_Tuple(a, Load, EXTRA) } slice[expr_ty]: | a=[expression] ':' b=[expression] c=[':' d=[expression] { d }] { _Py_Slice(a, b, c, EXTRA) } | a=expression { a } @@ -518,12 +518,12 @@ double_starred_kvpair[KeyValuePair*]: | '**' a=bitwise_or { _PyPegen_key_value_pair(p, NULL, a) } | kvpair kvpair[KeyValuePair*]: a=expression ':' b=expression { _PyPegen_key_value_pair(p, a, b) } -for_if_clauses[asdl_seq*]: - | for_if_clause+ +for_if_clauses[asdl_comprehension_seq*]: + | a[asdl_comprehension_seq*]=for_if_clause+ { a } for_if_clause[comprehension_ty]: - | ASYNC 'for' a=star_targets 'in' ~ b=disjunction c=('if' z=disjunction { z })* { + | ASYNC 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* { CHECK_VERSION(6, "Async comprehensions are", _Py_comprehension(a, b, c, 1, p->arena)) } - | 'for' a=star_targets 'in' ~ b=disjunction c=('if' z=disjunction { z })* { + | 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* { _Py_comprehension(a, b, c, 0, p->arena) } | invalid_for_target @@ -535,7 +535,7 @@ arguments[expr_ty] (memo): | a=args [','] &')' { a } | incorrect_arguments args[expr_ty]: - | a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) } + | a[asdl_expr_seq*]=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b, EXTRA) } | a=kwargs { _Py_Call(_PyPegen_dummy_name(p), CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)), CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)), @@ -562,7 +562,7 @@ star_targets[expr_ty]: | a=star_target !',' { a } | a=star_target b=(',' c=star_target { c })* [','] { _Py_Tuple(CHECK(_PyPegen_seq_insert_in_front(p, a, b)), Store, EXTRA) } -star_targets_seq[asdl_seq*]: a=','.star_target+ [','] { a } +star_targets_seq[asdl_expr_seq*]: a[asdl_expr_seq*]=','.star_target+ [','] { a } star_target[expr_ty] (memo): | '*' a=(!'*' star_target) { _Py_Starred(CHECK(_PyPegen_set_expr_context(p, a, Store)), Store, EXTRA) } @@ -583,7 +583,7 @@ single_subscript_attribute_target[expr_ty]: | a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) } | a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) } -del_targets[asdl_seq*]: a=','.del_target+ [','] { a } +del_targets[asdl_expr_seq*]: a[asdl_expr_seq*]=','.del_target+ [','] { a } del_target[expr_ty] (memo): | a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Del, EXTRA) } | a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Del, EXTRA) } @@ -594,7 +594,7 @@ del_t_atom[expr_ty]: | '(' a=[del_targets] ')' { _Py_Tuple(a, Del, EXTRA) } | '[' a=[del_targets] ']' { _Py_List(a, Del, EXTRA) } -targets[asdl_seq*]: a=','.target+ [','] { a } +targets[asdl_expr_seq*]: a[asdl_expr_seq*]=','.target+ [','] { a } target[expr_ty] (memo): | a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) } | a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) } diff --git a/Include/Python-ast.h b/Include/Python-ast.h index e7afa1e6579e8d4..e14bab566fb5a2a 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -47,18 +47,99 @@ typedef struct _withitem *withitem_ty; typedef struct _type_ignore *type_ignore_ty; +typedef struct { + _ASDL_SEQ_HEAD + mod_ty typed_elements[1]; +} asdl_mod_seq; + +asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + stmt_ty typed_elements[1]; +} asdl_stmt_seq; + +asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + expr_ty typed_elements[1]; +} asdl_expr_seq; + +asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + comprehension_ty typed_elements[1]; +} asdl_comprehension_seq; + +asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + excepthandler_ty typed_elements[1]; +} asdl_excepthandler_seq; + +asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arguments_ty typed_elements[1]; +} asdl_arguments_seq; + +asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arg_ty typed_elements[1]; +} asdl_arg_seq; + +asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + keyword_ty typed_elements[1]; +} asdl_keyword_seq; + +asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + alias_ty typed_elements[1]; +} asdl_alias_seq; + +asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + withitem_ty typed_elements[1]; +} asdl_withitem_seq; + +asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + type_ignore_ty typed_elements[1]; +} asdl_type_ignore_seq; + +asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena + *arena); + + enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, FunctionType_kind=4}; struct _mod { enum _mod_kind kind; union { struct { - asdl_seq *body; - asdl_seq *type_ignores; + asdl_stmt_seq *body; + asdl_type_ignore_seq *type_ignores; } Module; struct { - asdl_seq *body; + asdl_stmt_seq *body; } Interactive; struct { @@ -66,7 +147,7 @@ struct _mod { } Expression; struct { - asdl_seq *argtypes; + asdl_expr_seq *argtypes; expr_ty returns; } FunctionType; @@ -87,8 +168,8 @@ struct _stmt { struct { identifier name; arguments_ty args; - asdl_seq *body; - asdl_seq *decorator_list; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; expr_ty returns; string type_comment; } FunctionDef; @@ -96,18 +177,18 @@ struct _stmt { struct { identifier name; arguments_ty args; - asdl_seq *body; - asdl_seq *decorator_list; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; expr_ty returns; string type_comment; } AsyncFunctionDef; struct { identifier name; - asdl_seq *bases; - asdl_seq *keywords; - asdl_seq *body; - asdl_seq *decorator_list; + asdl_expr_seq *bases; + asdl_keyword_seq *keywords; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; } ClassDef; struct { @@ -115,11 +196,11 @@ struct _stmt { } Return; struct { - asdl_seq *targets; + asdl_expr_seq *targets; } Delete; struct { - asdl_seq *targets; + asdl_expr_seq *targets; expr_ty value; string type_comment; } Assign; @@ -140,40 +221,40 @@ struct _stmt { struct { expr_ty target; expr_ty iter; - asdl_seq *body; - asdl_seq *orelse; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; string type_comment; } For; struct { expr_ty target; expr_ty iter; - asdl_seq *body; - asdl_seq *orelse; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; string type_comment; } AsyncFor; struct { expr_ty test; - asdl_seq *body; - asdl_seq *orelse; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; } While; struct { expr_ty test; - asdl_seq *body; - asdl_seq *orelse; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; } If; struct { - asdl_seq *items; - asdl_seq *body; + asdl_withitem_seq *items; + asdl_stmt_seq *body; string type_comment; } With; struct { - asdl_seq *items; - asdl_seq *body; + asdl_withitem_seq *items; + asdl_stmt_seq *body; string type_comment; } AsyncWith; @@ -183,10 +264,10 @@ struct _stmt { } Raise; struct { - asdl_seq *body; - asdl_seq *handlers; - asdl_seq *orelse; - asdl_seq *finalbody; + asdl_stmt_seq *body; + asdl_excepthandler_seq *handlers; + asdl_stmt_seq *orelse; + asdl_stmt_seq *finalbody; } Try; struct { @@ -195,21 +276,21 @@ struct _stmt { } Assert; struct { - asdl_seq *names; + asdl_alias_seq *names; } Import; struct { identifier module; - asdl_seq *names; + asdl_alias_seq *names; int level; } ImportFrom; struct { - asdl_seq *names; + asdl_identifier_seq *names; } Global; struct { - asdl_seq *names; + asdl_identifier_seq *names; } Nonlocal; struct { @@ -236,7 +317,7 @@ struct _expr { union { struct { boolop_ty op; - asdl_seq *values; + asdl_expr_seq *values; } BoolOp; struct { @@ -267,33 +348,33 @@ struct _expr { } IfExp; struct { - asdl_seq *keys; - asdl_seq *values; + asdl_expr_seq *keys; + asdl_expr_seq *values; } Dict; struct { - asdl_seq *elts; + asdl_expr_seq *elts; } Set; struct { expr_ty elt; - asdl_seq *generators; + asdl_comprehension_seq *generators; } ListComp; struct { expr_ty elt; - asdl_seq *generators; + asdl_comprehension_seq *generators; } SetComp; struct { expr_ty key; expr_ty value; - asdl_seq *generators; + asdl_comprehension_seq *generators; } DictComp; struct { expr_ty elt; - asdl_seq *generators; + asdl_comprehension_seq *generators; } GeneratorExp; struct { @@ -311,13 +392,13 @@ struct _expr { struct { expr_ty left; asdl_int_seq *ops; - asdl_seq *comparators; + asdl_expr_seq *comparators; } Compare; struct { expr_ty func; - asdl_seq *args; - asdl_seq *keywords; + asdl_expr_seq *args; + asdl_keyword_seq *keywords; } Call; struct { @@ -327,7 +408,7 @@ struct _expr { } FormattedValue; struct { - asdl_seq *values; + asdl_expr_seq *values; } JoinedStr; struct { @@ -358,12 +439,12 @@ struct _expr { } Name; struct { - asdl_seq *elts; + asdl_expr_seq *elts; expr_context_ty ctx; } List; struct { - asdl_seq *elts; + asdl_expr_seq *elts; expr_context_ty ctx; } Tuple; @@ -383,7 +464,7 @@ struct _expr { struct _comprehension { expr_ty target; expr_ty iter; - asdl_seq *ifs; + asdl_expr_seq *ifs; int is_async; }; @@ -394,7 +475,7 @@ struct _excepthandler { struct { expr_ty type; identifier name; - asdl_seq *body; + asdl_stmt_seq *body; } ExceptHandler; } v; @@ -405,13 +486,13 @@ struct _excepthandler { }; struct _arguments { - asdl_seq *posonlyargs; - asdl_seq *args; + asdl_arg_seq *posonlyargs; + asdl_arg_seq *args; arg_ty vararg; - asdl_seq *kwonlyargs; - asdl_seq *kw_defaults; + asdl_arg_seq *kwonlyargs; + asdl_expr_seq *kw_defaults; arg_ty kwarg; - asdl_seq *defaults; + asdl_expr_seq *defaults; }; struct _arg { @@ -458,39 +539,41 @@ struct _type_ignore { // Note: these macros affect function definitions, not only call sites. #define Module(a0, a1, a2) _Py_Module(a0, a1, a2) -mod_ty _Py_Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena); +mod_ty _Py_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, + PyArena *arena); #define Interactive(a0, a1) _Py_Interactive(a0, a1) -mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +mod_ty _Py_Interactive(asdl_stmt_seq * body, PyArena *arena); #define Expression(a0, a1) _Py_Expression(a0, a1) mod_ty _Py_Expression(expr_ty body, PyArena *arena); #define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2) -mod_ty _Py_FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena); +mod_ty _Py_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena + *arena); #define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, - asdl_seq * decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * + body, asdl_expr_seq * decorator_list, expr_ty returns, + string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * - body, asdl_seq * decorator_list, expr_ty returns, - string type_comment, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena - *arena); +stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq + * body, asdl_expr_seq * decorator_list, expr_ty + returns, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); #define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, - asdl_seq * body, asdl_seq * decorator_list, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); +stmt_ty _Py_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * + keywords, asdl_stmt_seq * body, asdl_expr_seq * + decorator_list, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); #define Return(a0, a1, a2, a3, a4, a5) _Py_Return(a0, a1, a2, a3, a4, a5) stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, int +stmt_ty _Py_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); +stmt_ty _Py_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int col_offset, int end_lineno, int @@ -500,52 +583,54 @@ stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * - orelse, string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * - orelse, string type_comment, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); #define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); +stmt_ty _Py_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define If(a0, a1, a2, a3, a4, a5, a6, a7) _Py_If(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); +stmt_ty _Py_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); #define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); +stmt_ty _Py_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); +stmt_ty _Py_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); #define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) -stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, - asdl_seq * finalbody, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _Py_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena); #define Assert(a0, a1, a2, a3, a4, a5, a6) _Py_Assert(a0, a1, a2, a3, a4, a5, a6) stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Import(a0, a1, a2, a3, a4, a5) _Py_Import(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, int +stmt_ty _Py_Import(asdl_alias_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int - lineno, int col_offset, int end_lineno, int +stmt_ty _Py_ImportFrom(identifier module, asdl_alias_seq * names, int level, + int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Global(a0, a1, a2, a3, a4, a5) _Py_Global(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, int +stmt_ty _Py_Global(asdl_identifier_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Nonlocal(a0, a1, a2, a3, a4, a5) _Py_Nonlocal(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Nonlocal(asdl_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _Py_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); #define Expr(a0, a1, a2, a3, a4, a5) _Py_Expr(a0, a1, a2, a3, a4, a5) stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); @@ -559,8 +644,9 @@ stmt_ty _Py_Break(int lineno, int col_offset, int end_lineno, int stmt_ty _Py_Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define BoolOp(a0, a1, a2, a3, a4, a5, a6) _Py_BoolOp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); +expr_ty _Py_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); #define NamedExpr(a0, a1, a2, a3, a4, a5, a6) _Py_NamedExpr(a0, a1, a2, a3, a4, a5, a6) expr_ty _Py_NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena @@ -580,28 +666,28 @@ expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Dict(a0, a1, a2, a3, a4, a5, a6) _Py_Dict(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int +expr_ty _Py_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Set(a0, a1, a2, a3, a4, a5) _Py_Set(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); +expr_ty _Py_Set(asdl_expr_seq * elts, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); #define ListComp(a0, a1, a2, a3, a4, a5, a6) _Py_ListComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int +expr_ty _Py_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); +#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * + generators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); #define GeneratorExp(a0, a1, a2, a3, a4, a5, a6) _Py_GeneratorExp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define Await(a0, a1, a2, a3, a4, a5) _Py_Await(a0, a1, a2, a3, a4, a5) expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); @@ -612,19 +698,19 @@ expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Compare(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Compare(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * + comparators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); #define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); +expr_ty _Py_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * + keywords, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) -expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int +expr_ty _Py_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6) expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset, @@ -646,11 +732,11 @@ expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define List(a0, a1, a2, a3, a4, a5, a6) _Py_List(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int +expr_ty _Py_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Tuple(a0, a1, a2, a3, a4, a5, a6) _Py_Tuple(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int +expr_ty _Py_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define Slice(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Slice(a0, a1, a2, a3, a4, a5, a6, a7) @@ -658,18 +744,18 @@ expr_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) -comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * - ifs, int is_async, PyArena *arena); +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq + * ifs, int is_async, PyArena *arena); #define ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) -excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq * - body, int lineno, int col_offset, int +excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq + * body, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); #define arguments(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) -arguments_ty _Py_arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty - vararg, asdl_seq * kwonlyargs, asdl_seq * - kw_defaults, arg_ty kwarg, asdl_seq * defaults, - PyArena *arena); +arguments_ty _Py_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, + arg_ty vararg, asdl_arg_seq * kwonlyargs, + asdl_expr_seq * kw_defaults, arg_ty kwarg, + asdl_expr_seq * defaults, PyArena *arena); #define arg(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arg(a0, a1, a2, a3, a4, a5, a6, a7) arg_ty _Py_arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, diff --git a/Include/asdl.h b/Include/asdl.h index e962560bcd4cbef..8b61e16c329ea90 100644 --- a/Include/asdl.h +++ b/Include/asdl.h @@ -13,25 +13,80 @@ typedef PyObject * constant; interned Python strings. */ -/* XXX A sequence should be typed so that its use can be typechecked. */ +#define _ASDL_SEQ_HEAD \ + Py_ssize_t size; \ + void **elements; typedef struct { - Py_ssize_t size; - void *elements[1]; + _ASDL_SEQ_HEAD } asdl_seq; typedef struct { - Py_ssize_t size; - int elements[1]; + _ASDL_SEQ_HEAD + void *typed_elements[1]; +} asdl_generic_seq; + +typedef struct { + _ASDL_SEQ_HEAD + PyObject *typed_elements[1]; +} asdl_identifier_seq; + +typedef struct { + _ASDL_SEQ_HEAD + int typed_elements[1]; } asdl_int_seq; -asdl_seq *_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena); +asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena); +asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena); asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); -#define asdl_seq_GET(S, I) (S)->elements[(I)] + +#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \ +asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \ +{ \ + asdl_ ## NAME ## _seq *seq = NULL; \ + size_t n; \ + /* check size is sane */ \ + if (size < 0 || \ + (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \ + /* check if size can be added safely */ \ + if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + n += sizeof(asdl_ ## NAME ## _seq); \ + seq = (asdl_ ## NAME ## _seq *)PyArena_Malloc(arena, n); \ + if (!seq) { \ + PyErr_NoMemory(); \ + return NULL; \ + } \ + memset(seq, 0, n); \ + seq->size = size; \ + seq->elements = (void**)seq->typed_elements; \ + return seq; \ +} + +#define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)] +#define asdl_seq_GET(S, I) (S)->typed_elements[(I)] #define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) #ifdef Py_DEBUG #define asdl_seq_SET(S, I, V) \ + do { \ + Py_ssize_t _asdl_i = (I); \ + assert((S) != NULL); \ + assert(0 <= _asdl_i && _asdl_i < (S)->size); \ + (S)->typed_elements[_asdl_i] = (V); \ + } while (0) +#else +#define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V) +#endif + +#ifdef Py_DEBUG +#define asdl_seq_SET_UNTYPED(S, I, V) \ do { \ Py_ssize_t _asdl_i = (I); \ assert((S) != NULL); \ @@ -39,7 +94,7 @@ asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); (S)->elements[_asdl_i] = (V); \ } while (0) #else -#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) +#define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V) #endif #endif /* !Py_ASDL_H */ diff --git a/Include/ast.h b/Include/ast.h index de42a3b5e6f91a1..434ee18dd91b2a7 100644 --- a/Include/ast.h +++ b/Include/ast.h @@ -15,7 +15,7 @@ PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty); /* Return the borrowed reference to the first literal string in the sequence of statements or NULL if it doesn't start from a literal string. Doesn't set exception. */ -PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_seq *); +PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_stmt_seq *); #ifdef __cplusplus } diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 0c053393d688b8d..242eccf3d37d783 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -163,6 +163,32 @@ def visitProduct(self, product, name, depth): self.emit(s, depth) self.emit("", depth) +class SequenceDefVisitor(EmitVisitor): + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type, depth=0): + self.visit(type.value, type.name, depth) + + def visitSum(self, sum, name, depth): + if is_simple(sum): + return + self.emit_sequence_constructor(name, depth) + + def emit_sequence_constructor(self, name,depth): + ctype = get_c_type(name) + self.emit("""\ +typedef struct { + _ASDL_SEQ_HEAD + %(ctype)s typed_elements[1]; +} asdl_%(name)s_seq;""" % locals(), reflow=False, depth=depth) + self.emit("", depth) + self.emit("asdl_%(name)s_seq *_Py_asdl_%(name)s_seq_new(Py_ssize_t size, PyArena *arena);" % locals(), depth) + self.emit("", depth) + + def visitProduct(self, product, name, depth): + self.emit_sequence_constructor(name, depth) class StructVisitor(EmitVisitor): """Visitor to generate typedefs for AST.""" @@ -219,7 +245,8 @@ def visitField(self, field, depth): if field.type == 'cmpop': self.emit("asdl_int_seq *%(name)s;" % locals(), depth) else: - self.emit("asdl_seq *%(name)s;" % locals(), depth) + _type = field.type + self.emit("asdl_%(_type)s_seq *%(name)s;" % locals(), depth) else: self.emit("%(ctype)s %(name)s;" % locals(), depth) @@ -274,7 +301,7 @@ def get_args(self, fields): if f.type == 'cmpop': ctype = "asdl_int_seq *" else: - ctype = "asdl_seq *" + ctype = f"asdl_{f.type}_seq *" else: ctype = get_c_type(f.type) args.append((ctype, name, f.opt or f.seq)) @@ -507,7 +534,8 @@ def visitFieldDeclaration(self, field, name, sum=None, prod=None, depth=0): if self.isSimpleType(field): self.emit("asdl_int_seq* %s;" % field.name, depth) else: - self.emit("asdl_seq* %s;" % field.name, depth) + _type = field.type + self.emit(f"asdl_{field.type}_seq* {field.name};", depth) else: ctype = get_c_type(field.type) self.emit("%s %s;" % (ctype, field.name), depth) @@ -562,7 +590,7 @@ def visitField(self, field, name, sum=None, prod=None, depth=0): if self.isSimpleType(field): self.emit("%s = _Py_asdl_int_seq_new(len, arena);" % field.name, depth+1) else: - self.emit("%s = _Py_asdl_seq_new(len, arena);" % field.name, depth+1) + self.emit("%s = _Py_asdl_%s_seq_new(len, arena);" % (field.name, field.type), depth+1) self.emit("if (%s == NULL) goto failed;" % field.name, depth+1) self.emit("for (i = 0; i < len; i++) {", depth+1) self.emit("%s val;" % ctype, depth+2) @@ -600,6 +628,24 @@ def prototype(self, sum, name): visitProduct = visitSum = prototype +class SequenceConstructorVisitor(EmitVisitor): + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value, type.name) + + def visitProduct(self, prod, name): + self.emit_sequence_constructor(name, get_c_type(name)) + + def visitSum(self, sum, name): + if not is_simple(sum): + self.emit_sequence_constructor(name, get_c_type(name)) + + def emit_sequence_constructor(self, name, type): + self.emit(f"GENERATE_ASDL_SEQ_CONSTRUCTOR({name}, {type})", depth=0) + class PyTypesDeclareVisitor(PickleVisitor): def visitProduct(self, prod, name): @@ -647,6 +693,7 @@ def visitConstructor(self, cons, name): self.emit('"%s",' % t.name, 1) self.emit("};",0) + class PyTypesVisitor(PickleVisitor): def visitModule(self, mod): @@ -874,7 +921,7 @@ def visitModule(self, mod): if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, asdl_seq_GET(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -1264,7 +1311,7 @@ def set(self, field, value, depth): depth+2, reflow=False) self.emit("}", depth) else: - self.emit("value = ast2obj_list(state, %s, ast2obj_%s);" % (value, field.type), depth) + self.emit("value = ast2obj_list(state, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) else: ctype = get_c_type(field.type) self.emit("value = ast2obj_%s(state, %s);" % (field.type, value), depth, reflow=False) @@ -1431,6 +1478,7 @@ def write_header(f, mod): f.write('#undef Yield /* undefine macro conflicting with */\n') f.write('\n') c = ChainOfVisitors(TypeDefVisitor(f), + SequenceDefVisitor(f), StructVisitor(f)) c.visit(mod) f.write("// Note: these macros affect function definitions, not only call sites.\n") @@ -1457,6 +1505,7 @@ def write_source(f, mod): generate_module_def(f, mod) v = ChainOfVisitors( + SequenceConstructorVisitor(f), PyTypesDeclareVisitor(f), PyTypesVisitor(f), Obj2ModPrototypeVisitor(f), diff --git a/Parser/parser.c b/Parser/parser.c index 8a7cb62fd7cf8dd..1bd74a38fbc2bae 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -389,11 +389,11 @@ static mod_ty interactive_rule(Parser *p); static mod_ty eval_rule(Parser *p); static mod_ty func_type_rule(Parser *p); static expr_ty fstring_rule(Parser *p); -static asdl_seq* type_expressions_rule(Parser *p); -static asdl_seq* statements_rule(Parser *p); -static asdl_seq* statement_rule(Parser *p); -static asdl_seq* statement_newline_rule(Parser *p); -static asdl_seq* simple_stmt_rule(Parser *p); +static asdl_expr_seq* type_expressions_rule(Parser *p); +static asdl_stmt_seq* statements_rule(Parser *p); +static asdl_stmt_seq* statement_rule(Parser *p); +static asdl_stmt_seq* statement_newline_rule(Parser *p); +static asdl_stmt_seq* simple_stmt_rule(Parser *p); static stmt_ty small_stmt_rule(Parser *p); static stmt_ty compound_stmt_rule(Parser *p); static stmt_ty assignment_rule(Parser *p); @@ -406,22 +406,22 @@ static stmt_ty del_stmt_rule(Parser *p); static stmt_ty import_stmt_rule(Parser *p); static stmt_ty import_name_rule(Parser *p); static stmt_ty import_from_rule(Parser *p); -static asdl_seq* import_from_targets_rule(Parser *p); -static asdl_seq* import_from_as_names_rule(Parser *p); +static asdl_alias_seq* import_from_targets_rule(Parser *p); +static asdl_alias_seq* import_from_as_names_rule(Parser *p); static alias_ty import_from_as_name_rule(Parser *p); -static asdl_seq* dotted_as_names_rule(Parser *p); +static asdl_alias_seq* dotted_as_names_rule(Parser *p); static alias_ty dotted_as_name_rule(Parser *p); static expr_ty dotted_name_rule(Parser *p); static stmt_ty if_stmt_rule(Parser *p); static stmt_ty elif_stmt_rule(Parser *p); -static asdl_seq* else_block_rule(Parser *p); +static asdl_stmt_seq* else_block_rule(Parser *p); static stmt_ty while_stmt_rule(Parser *p); static stmt_ty for_stmt_rule(Parser *p); static stmt_ty with_stmt_rule(Parser *p); static withitem_ty with_item_rule(Parser *p); static stmt_ty try_stmt_rule(Parser *p); static excepthandler_ty except_block_rule(Parser *p); -static asdl_seq* finally_block_rule(Parser *p); +static asdl_stmt_seq* finally_block_rule(Parser *p); static stmt_ty return_stmt_rule(Parser *p); static stmt_ty raise_stmt_rule(Parser *p); static stmt_ty function_def_rule(Parser *p); @@ -429,7 +429,7 @@ static stmt_ty function_def_raw_rule(Parser *p); static Token* func_type_comment_rule(Parser *p); static arguments_ty params_rule(Parser *p); static arguments_ty parameters_rule(Parser *p); -static asdl_seq* slash_no_default_rule(Parser *p); +static asdl_arg_seq* slash_no_default_rule(Parser *p); static SlashWithDefault* slash_with_default_rule(Parser *p); static StarEtc* star_etc_rule(Parser *p); static arg_ty kwds_rule(Parser *p); @@ -439,14 +439,14 @@ static NameDefaultPair* param_maybe_default_rule(Parser *p); static arg_ty param_rule(Parser *p); static expr_ty annotation_rule(Parser *p); static expr_ty default_rule(Parser *p); -static asdl_seq* decorators_rule(Parser *p); +static asdl_expr_seq* decorators_rule(Parser *p); static stmt_ty class_def_rule(Parser *p); static stmt_ty class_def_raw_rule(Parser *p); -static asdl_seq* block_rule(Parser *p); -static asdl_seq* expressions_list_rule(Parser *p); +static asdl_stmt_seq* block_rule(Parser *p); +static asdl_expr_seq* expressions_list_rule(Parser *p); static expr_ty star_expressions_rule(Parser *p); static expr_ty star_expression_rule(Parser *p); -static asdl_seq* star_named_expressions_rule(Parser *p); +static asdl_expr_seq* star_named_expressions_rule(Parser *p); static expr_ty star_named_expression_rule(Parser *p); static expr_ty named_expression_rule(Parser *p); static expr_ty annotated_rhs_rule(Parser *p); @@ -455,7 +455,7 @@ static expr_ty expression_rule(Parser *p); static expr_ty lambdef_rule(Parser *p); static arguments_ty lambda_params_rule(Parser *p); static arguments_ty lambda_parameters_rule(Parser *p); -static asdl_seq* lambda_slash_no_default_rule(Parser *p); +static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p); static SlashWithDefault* lambda_slash_with_default_rule(Parser *p); static StarEtc* lambda_star_etc_rule(Parser *p); static arg_ty lambda_kwds_rule(Parser *p); @@ -504,7 +504,7 @@ static expr_ty dictcomp_rule(Parser *p); static asdl_seq* double_starred_kvpairs_rule(Parser *p); static KeyValuePair* double_starred_kvpair_rule(Parser *p); static KeyValuePair* kvpair_rule(Parser *p); -static asdl_seq* for_if_clauses_rule(Parser *p); +static asdl_comprehension_seq* for_if_clauses_rule(Parser *p); static comprehension_ty for_if_clause_rule(Parser *p); static expr_ty yield_expr_rule(Parser *p); static expr_ty arguments_rule(Parser *p); @@ -514,15 +514,15 @@ static expr_ty starred_expression_rule(Parser *p); static KeywordOrStarred* kwarg_or_starred_rule(Parser *p); static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p); static expr_ty star_targets_rule(Parser *p); -static asdl_seq* star_targets_seq_rule(Parser *p); +static asdl_expr_seq* star_targets_seq_rule(Parser *p); static expr_ty star_target_rule(Parser *p); static expr_ty star_atom_rule(Parser *p); static expr_ty single_target_rule(Parser *p); static expr_ty single_subscript_attribute_target_rule(Parser *p); -static asdl_seq* del_targets_rule(Parser *p); +static asdl_expr_seq* del_targets_rule(Parser *p); static expr_ty del_target_rule(Parser *p); static expr_ty del_t_atom_rule(Parser *p); -static asdl_seq* targets_rule(Parser *p); +static asdl_expr_seq* targets_rule(Parser *p); static expr_ty target_rule(Parser *p); static expr_ty t_primary_rule(Parser *p); static void *t_lookahead_rule(Parser *p); @@ -764,7 +764,7 @@ interactive_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> interactive[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement_newline")); - asdl_seq* a; + asdl_stmt_seq* a; if ( (a = statement_newline_rule(p)) // statement_newline ) @@ -938,7 +938,7 @@ fstring_rule(Parser *p) // | '*' expression // | '**' expression // | ','.expression+ -static asdl_seq* +static asdl_expr_seq* type_expressions_rule(Parser *p) { D(p->level++); @@ -946,7 +946,7 @@ type_expressions_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.expression+ ',' '*' expression ',' '**' expression if (p->error_indicator) { @@ -978,7 +978,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_seq_append_to_end ( p , a , b ) ) , c ); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_seq_append_to_end ( p , a , b ) ) , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1011,7 +1011,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); - _res = _PyPegen_seq_append_to_end ( p , a , b ); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1044,7 +1044,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , a , b ); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1080,7 +1080,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); - _res = _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b ); + _res = ( asdl_expr_seq * ) _PyPegen_seq_append_to_end ( p , CHECK ( _PyPegen_singleton_seq ( p , a ) ) , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1107,7 +1107,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression")); - _res = _PyPegen_singleton_seq ( p , a ); + _res = ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1134,7 +1134,7 @@ type_expressions_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression")); - _res = _PyPegen_singleton_seq ( p , a ); + _res = ( asdl_expr_seq * ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1152,13 +1152,18 @@ type_expressions_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+")); - asdl_seq * _gather_9_var; + asdl_expr_seq* a; if ( - (_gather_9_var = _gather_9_rule(p)) // ','.expression+ + (a = (asdl_expr_seq*)_gather_9_rule(p)) // ','.expression+ ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); - _res = _gather_9_var; + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } goto done; } p->mark = _mark; @@ -1172,7 +1177,7 @@ type_expressions_rule(Parser *p) } // statements: statement+ -static asdl_seq* +static asdl_stmt_seq* statements_rule(Parser *p) { D(p->level++); @@ -1180,7 +1185,7 @@ statements_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // statement+ if (p->error_indicator) { @@ -1194,7 +1199,7 @@ statements_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); - _res = _PyPegen_seq_flatten ( p , a ); + _res = ( asdl_stmt_seq * ) _PyPegen_seq_flatten ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1213,7 +1218,7 @@ statements_rule(Parser *p) } // statement: compound_stmt | simple_stmt -static asdl_seq* +static asdl_stmt_seq* statement_rule(Parser *p) { D(p->level++); @@ -1221,7 +1226,7 @@ statement_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // compound_stmt if (p->error_indicator) { @@ -1235,7 +1240,7 @@ statement_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt")); - _res = _PyPegen_singleton_seq ( p , a ); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1253,13 +1258,18 @@ statement_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; + asdl_stmt_seq* a; if ( - (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt + (a = (asdl_stmt_seq*)simple_stmt_rule(p)) // simple_stmt ) { D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - _res = simple_stmt_var; + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } goto done; } p->mark = _mark; @@ -1273,7 +1283,7 @@ statement_rule(Parser *p) } // statement_newline: compound_stmt NEWLINE | simple_stmt | NEWLINE | $ -static asdl_seq* +static asdl_stmt_seq* statement_newline_rule(Parser *p) { D(p->level++); @@ -1281,7 +1291,7 @@ statement_newline_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; @@ -1307,7 +1317,7 @@ statement_newline_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); - _res = _PyPegen_singleton_seq ( p , a ); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1325,7 +1335,7 @@ statement_newline_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; + asdl_stmt_seq* simple_stmt_var; if ( (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt ) @@ -1359,7 +1369,7 @@ statement_newline_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyPegen_singleton_seq ( p , CHECK ( _Py_Pass ( EXTRA ) ) ); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , CHECK ( _Py_Pass ( EXTRA ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1402,7 +1412,7 @@ statement_newline_rule(Parser *p) } // simple_stmt: small_stmt !';' NEWLINE | ';'.small_stmt+ ';'? NEWLINE -static asdl_seq* +static asdl_stmt_seq* simple_stmt_rule(Parser *p) { D(p->level++); @@ -1410,7 +1420,7 @@ simple_stmt_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // small_stmt !';' NEWLINE if (p->error_indicator) { @@ -1429,7 +1439,7 @@ simple_stmt_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "small_stmt !';' NEWLINE")); - _res = _PyPegen_singleton_seq ( p , a ); + _res = ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -1449,10 +1459,10 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'.small_stmt+ ';'? NEWLINE")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_stmt_seq* a; Token * newline_var; if ( - (a = _gather_12_rule(p)) // ';'.small_stmt+ + (a = (asdl_stmt_seq*)_gather_12_rule(p)) // ';'.small_stmt+ && (_opt_var = _PyPegen_expect_token(p, 13), 1) // ';'? && @@ -2127,11 +2137,11 @@ assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); - asdl_seq * a; + asdl_expr_seq* a; void *b; void *tc; if ( - (a = _loop1_22_rule(p)) // ((star_targets '='))+ + (a = (asdl_expr_seq*)_loop1_22_rule(p)) // ((star_targets '='))+ && (b = _tmp_23_rule(p)) // yield_expr | star_expressions && @@ -2602,11 +2612,11 @@ global_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> global_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); Token * _keyword; - asdl_seq * a; + asdl_expr_seq* a; if ( (_keyword = _PyPegen_expect_token(p, 508)) // token='global' && - (a = _gather_25_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_25_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); @@ -2664,11 +2674,11 @@ nonlocal_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> nonlocal_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); Token * _keyword; - asdl_seq * a; + asdl_expr_seq* a; if ( (_keyword = _PyPegen_expect_token(p, 509)) // token='nonlocal' && - (a = _gather_27_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_27_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); @@ -2850,7 +2860,7 @@ del_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); Token * _keyword; - asdl_seq* a; + asdl_expr_seq* a; if ( (_keyword = _PyPegen_expect_token(p, 503)) // token='del' && @@ -2988,7 +2998,7 @@ import_name_rule(Parser *p) } D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); Token * _keyword; - asdl_seq* a; + asdl_alias_seq* a; if ( (_keyword = _PyPegen_expect_token(p, 513)) // token='import' && @@ -3055,7 +3065,7 @@ import_from_rule(Parser *p) Token * _keyword_1; asdl_seq * a; expr_ty b; - asdl_seq* c; + asdl_alias_seq* c; if ( (_keyword = _PyPegen_expect_token(p, 514)) // token='from' && @@ -3099,7 +3109,7 @@ import_from_rule(Parser *p) Token * _keyword; Token * _keyword_1; asdl_seq * a; - asdl_seq* b; + asdl_alias_seq* b; if ( (_keyword = _PyPegen_expect_token(p, 514)) // token='from' && @@ -3143,7 +3153,7 @@ import_from_rule(Parser *p) // | import_from_as_names !',' // | '*' // | invalid_import_from_targets -static asdl_seq* +static asdl_alias_seq* import_from_targets_rule(Parser *p) { D(p->level++); @@ -3151,7 +3161,7 @@ import_from_targets_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_alias_seq* _res = NULL; int _mark = p->mark; { // '(' import_from_as_names ','? ')' if (p->error_indicator) { @@ -3163,7 +3173,7 @@ import_from_targets_rule(Parser *p) Token * _literal_1; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq* a; + asdl_alias_seq* a; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -3193,7 +3203,7 @@ import_from_targets_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); - asdl_seq* import_from_as_names_var; + asdl_alias_seq* import_from_as_names_var; if ( (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names && @@ -3220,7 +3230,7 @@ import_from_targets_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); - _res = _PyPegen_singleton_seq ( p , CHECK ( _PyPegen_alias_for_star ( p ) ) ); + _res = ( asdl_alias_seq * ) _PyPegen_singleton_seq ( p , CHECK ( _PyPegen_alias_for_star ( p ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -3258,7 +3268,7 @@ import_from_targets_rule(Parser *p) } // import_from_as_names: ','.import_from_as_name+ -static asdl_seq* +static asdl_alias_seq* import_from_as_names_rule(Parser *p) { D(p->level++); @@ -3266,7 +3276,7 @@ import_from_as_names_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_alias_seq* _res = NULL; int _mark = p->mark; { // ','.import_from_as_name+ if (p->error_indicator) { @@ -3274,9 +3284,9 @@ import_from_as_names_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); - asdl_seq * a; + asdl_alias_seq* a; if ( - (a = _gather_33_rule(p)) // ','.import_from_as_name+ + (a = (asdl_alias_seq*)_gather_33_rule(p)) // ','.import_from_as_name+ ) { D(fprintf(stderr, "%*c+ import_from_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); @@ -3343,7 +3353,7 @@ import_from_as_name_rule(Parser *p) } // dotted_as_names: ','.dotted_as_name+ -static asdl_seq* +static asdl_alias_seq* dotted_as_names_rule(Parser *p) { D(p->level++); @@ -3351,7 +3361,7 @@ dotted_as_names_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_alias_seq* _res = NULL; int _mark = p->mark; { // ','.dotted_as_name+ if (p->error_indicator) { @@ -3359,9 +3369,9 @@ dotted_as_names_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); - asdl_seq * a; + asdl_alias_seq* a; if ( - (a = _gather_36_rule(p)) // ','.dotted_as_name+ + (a = (asdl_alias_seq*)_gather_36_rule(p)) // ','.dotted_as_name+ ) { D(fprintf(stderr, "%*c+ dotted_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); @@ -3554,7 +3564,7 @@ if_stmt_rule(Parser *p) Token * _keyword; Token * _literal; expr_ty a; - asdl_seq* b; + asdl_stmt_seq* b; stmt_ty c; if ( (_keyword = _PyPegen_expect_token(p, 510)) // token='if' @@ -3578,7 +3588,7 @@ if_stmt_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _Py_If ( a , b , CHECK ( _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); + _res = _Py_If ( a , b , CHECK ( ( asdl_stmt_seq * ) _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -3599,7 +3609,7 @@ if_stmt_rule(Parser *p) Token * _keyword; Token * _literal; expr_ty a; - asdl_seq* b; + asdl_stmt_seq* b; void *c; if ( (_keyword = _PyPegen_expect_token(p, 510)) // token='if' @@ -3672,7 +3682,7 @@ elif_stmt_rule(Parser *p) Token * _keyword; Token * _literal; expr_ty a; - asdl_seq* b; + asdl_stmt_seq* b; stmt_ty c; if ( (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' @@ -3717,7 +3727,7 @@ elif_stmt_rule(Parser *p) Token * _keyword; Token * _literal; expr_ty a; - asdl_seq* b; + asdl_stmt_seq* b; void *c; if ( (_keyword = _PyPegen_expect_token(p, 515)) // token='elif' @@ -3760,7 +3770,7 @@ elif_stmt_rule(Parser *p) } // else_block: 'else' ':' block -static asdl_seq* +static asdl_stmt_seq* else_block_rule(Parser *p) { D(p->level++); @@ -3768,7 +3778,7 @@ else_block_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // 'else' ':' block if (p->error_indicator) { @@ -3778,7 +3788,7 @@ else_block_rule(Parser *p) D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':' block")); Token * _keyword; Token * _literal; - asdl_seq* b; + asdl_stmt_seq* b; if ( (_keyword = _PyPegen_expect_token(p, 516)) // token='else' && @@ -3835,7 +3845,7 @@ while_stmt_rule(Parser *p) Token * _keyword; Token * _literal; expr_ty a; - asdl_seq* b; + asdl_stmt_seq* b; void *c; if ( (_keyword = _PyPegen_expect_token(p, 512)) // token='while' @@ -3910,7 +3920,7 @@ for_stmt_rule(Parser *p) Token * _keyword; Token * _keyword_1; Token * _literal; - asdl_seq* b; + asdl_stmt_seq* b; void *el; expr_ty ex; expr_ty t; @@ -3972,7 +3982,7 @@ for_stmt_rule(Parser *p) Token * _keyword_1; Token * _literal; Token * async_var; - asdl_seq* b; + asdl_stmt_seq* b; void *el; expr_ty ex; expr_ty t; @@ -4086,14 +4096,14 @@ with_stmt_rule(Parser *p) Token * _literal_2; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; - asdl_seq* b; + asdl_withitem_seq* a; + asdl_stmt_seq* b; if ( (_keyword = _PyPegen_expect_token(p, 519)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _gather_39_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_39_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? && @@ -4134,13 +4144,13 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token * _keyword; Token * _literal; - asdl_seq * a; - asdl_seq* b; + asdl_withitem_seq* a; + asdl_stmt_seq* b; void *tc; if ( (_keyword = _PyPegen_expect_token(p, 519)) // token='with' && - (a = _gather_41_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_41_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -4183,9 +4193,9 @@ with_stmt_rule(Parser *p) Token * _literal_2; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_withitem_seq* a; Token * async_var; - asdl_seq* b; + asdl_stmt_seq* b; if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && @@ -4193,7 +4203,7 @@ with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _gather_43_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_43_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? && @@ -4234,16 +4244,16 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token * _keyword; Token * _literal; - asdl_seq * a; + asdl_withitem_seq* a; Token * async_var; - asdl_seq* b; + asdl_stmt_seq* b; void *tc; if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && (_keyword = _PyPegen_expect_token(p, 519)) // token='with' && - (a = _gather_45_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_45_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -4402,8 +4412,8 @@ try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block finally_block")); Token * _keyword; Token * _literal; - asdl_seq* b; - asdl_seq* f; + asdl_stmt_seq* b; + asdl_stmt_seq* f; if ( (_keyword = _PyPegen_expect_token(p, 511)) // token='try' && @@ -4444,9 +4454,9 @@ try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block except_block+ else_block? finally_block?")); Token * _keyword; Token * _literal; - asdl_seq* b; + asdl_stmt_seq* b; void *el; - asdl_seq * ex; + asdl_excepthandler_seq* ex; void *f; if ( (_keyword = _PyPegen_expect_token(p, 511)) // token='try' @@ -4455,7 +4465,7 @@ try_stmt_rule(Parser *p) && (b = block_rule(p)) // block && - (ex = _loop1_48_rule(p)) // except_block+ + (ex = (asdl_excepthandler_seq*)_loop1_48_rule(p)) // except_block+ && (el = else_block_rule(p), 1) // else_block? && @@ -4518,7 +4528,7 @@ except_block_rule(Parser *p) D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); Token * _keyword; Token * _literal; - asdl_seq* b; + asdl_stmt_seq* b; expr_ty e; void *t; if ( @@ -4563,7 +4573,7 @@ except_block_rule(Parser *p) D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); Token * _keyword; Token * _literal; - asdl_seq* b; + asdl_stmt_seq* b; if ( (_keyword = _PyPegen_expect_token(p, 521)) // token='except' && @@ -4601,7 +4611,7 @@ except_block_rule(Parser *p) } // finally_block: 'finally' ':' block -static asdl_seq* +static asdl_stmt_seq* finally_block_rule(Parser *p) { D(p->level++); @@ -4609,7 +4619,7 @@ finally_block_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // 'finally' ':' block if (p->error_indicator) { @@ -4619,7 +4629,7 @@ finally_block_rule(Parser *p) D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' ':' block")); Token * _keyword; Token * _literal; - asdl_seq* a; + asdl_stmt_seq* a; if ( (_keyword = _PyPegen_expect_token(p, 522)) // token='finally' && @@ -4824,7 +4834,7 @@ function_def_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); - asdl_seq* d; + asdl_expr_seq* d; stmt_ty f; if ( (d = decorators_rule(p)) // decorators @@ -4903,7 +4913,7 @@ function_def_raw_rule(Parser *p) Token * _literal_1; Token * _literal_2; void *a; - asdl_seq* b; + asdl_stmt_seq* b; expr_ty n; void *params; void *tc; @@ -4961,7 +4971,7 @@ function_def_raw_rule(Parser *p) Token * _literal_2; void *a; Token * async_var; - asdl_seq* b; + asdl_stmt_seq* b; expr_ty n; void *params; void *tc; @@ -5179,14 +5189,14 @@ parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - asdl_seq* a; - asdl_seq * b; + asdl_arg_seq* a; + asdl_arg_seq* b; asdl_seq * c; void *d; if ( (a = slash_no_default_rule(p)) // slash_no_default && - (b = _loop0_54_rule(p)) // param_no_default* + (b = (asdl_arg_seq*)_loop0_54_rule(p)) // param_no_default* && (c = _loop0_55_rule(p)) // param_with_default* && @@ -5242,11 +5252,11 @@ parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); - asdl_seq * a; + asdl_arg_seq* a; asdl_seq * b; void *c; if ( - (a = _loop1_57_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_57_rule(p)) // param_no_default+ && (b = _loop0_58_rule(p)) // param_with_default* && @@ -5324,7 +5334,7 @@ parameters_rule(Parser *p) } // slash_no_default: param_no_default+ '/' ',' | param_no_default+ '/' &')' -static asdl_seq* +static asdl_arg_seq* slash_no_default_rule(Parser *p) { D(p->level++); @@ -5332,7 +5342,7 @@ slash_no_default_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_arg_seq* _res = NULL; int _mark = p->mark; { // param_no_default+ '/' ',' if (p->error_indicator) { @@ -5342,9 +5352,9 @@ slash_no_default_rule(Parser *p) D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); Token * _literal; Token * _literal_1; - asdl_seq * a; + asdl_arg_seq* a; if ( - (a = _loop1_60_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_60_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -5371,9 +5381,9 @@ slash_no_default_rule(Parser *p) } D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); Token * _literal; - asdl_seq * a; + asdl_arg_seq* a; if ( - (a = _loop1_61_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_61_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -5433,7 +5443,7 @@ slash_with_default_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); - _res = _PyPegen_slash_with_default ( p , a , b ); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -5465,7 +5475,7 @@ slash_with_default_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); - _res = _PyPegen_slash_with_default ( p , a , b ); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -6050,7 +6060,7 @@ default_rule(Parser *p) } // decorators: (('@' named_expression NEWLINE))+ -static asdl_seq* +static asdl_expr_seq* decorators_rule(Parser *p) { D(p->level++); @@ -6058,7 +6068,7 @@ decorators_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // (('@' named_expression NEWLINE))+ if (p->error_indicator) { @@ -6066,9 +6076,9 @@ decorators_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _loop1_68_rule(p)) // (('@' named_expression NEWLINE))+ + (a = (asdl_expr_seq*)_loop1_68_rule(p)) // (('@' named_expression NEWLINE))+ ) { D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); @@ -6107,7 +6117,7 @@ class_def_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); - asdl_seq* a; + asdl_expr_seq* a; stmt_ty b; if ( (a = decorators_rule(p)) // decorators @@ -6183,7 +6193,7 @@ class_def_raw_rule(Parser *p) Token * _literal; expr_ty a; void *b; - asdl_seq* c; + asdl_stmt_seq* c; if ( (_keyword = _PyPegen_expect_token(p, 524)) // token='class' && @@ -6225,7 +6235,7 @@ class_def_raw_rule(Parser *p) } // block: NEWLINE INDENT statements DEDENT | simple_stmt | invalid_block -static asdl_seq* +static asdl_stmt_seq* block_rule(Parser *p) { D(p->level++); @@ -6233,7 +6243,7 @@ block_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_stmt_seq* _res = NULL; if (_PyPegen_is_memoized(p, block_type, &_res)) { D(p->level--); return _res; @@ -6245,7 +6255,7 @@ block_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); - asdl_seq* a; + asdl_stmt_seq* a; Token * dedent_var; Token * indent_var; Token * newline_var; @@ -6278,7 +6288,7 @@ block_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt")); - asdl_seq* simple_stmt_var; + asdl_stmt_seq* simple_stmt_var; if ( (simple_stmt_var = simple_stmt_rule(p)) // simple_stmt ) @@ -6318,7 +6328,7 @@ block_rule(Parser *p) } // expressions_list: ','.star_expression+ ','? -static asdl_seq* +static asdl_expr_seq* expressions_list_rule(Parser *p) { D(p->level++); @@ -6326,7 +6336,7 @@ expressions_list_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.star_expression+ ','? if (p->error_indicator) { @@ -6336,9 +6346,9 @@ expressions_list_rule(Parser *p) D(fprintf(stderr, "%*c> expressions_list[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_expression+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_70_rule(p)) // ','.star_expression+ + (a = (asdl_expr_seq*)_gather_70_rule(p)) // ','.star_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -6573,7 +6583,7 @@ star_expression_rule(Parser *p) } // star_named_expressions: ','.star_named_expression+ ','? -static asdl_seq* +static asdl_expr_seq* star_named_expressions_rule(Parser *p) { D(p->level++); @@ -6581,7 +6591,7 @@ star_named_expressions_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.star_named_expression+ ','? if (p->error_indicator) { @@ -6591,9 +6601,9 @@ star_named_expressions_rule(Parser *p) D(fprintf(stderr, "%*c> star_named_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_73_rule(p)) // ','.star_named_expression+ + (a = (asdl_expr_seq*)_gather_73_rule(p)) // ','.star_named_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -7245,14 +7255,14 @@ lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - asdl_seq* a; - asdl_seq * b; + asdl_arg_seq* a; + asdl_arg_seq* b; asdl_seq * c; void *d; if ( (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default && - (b = _loop0_76_rule(p)) // lambda_param_no_default* + (b = (asdl_arg_seq*)_loop0_76_rule(p)) // lambda_param_no_default* && (c = _loop0_77_rule(p)) // lambda_param_with_default* && @@ -7308,11 +7318,11 @@ lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); - asdl_seq * a; + asdl_arg_seq* a; asdl_seq * b; void *c; if ( - (a = _loop1_79_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_79_rule(p)) // lambda_param_no_default+ && (b = _loop0_80_rule(p)) // lambda_param_with_default* && @@ -7392,7 +7402,7 @@ lambda_parameters_rule(Parser *p) // lambda_slash_no_default: // | lambda_param_no_default+ '/' ',' // | lambda_param_no_default+ '/' &':' -static asdl_seq* +static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { D(p->level++); @@ -7400,7 +7410,7 @@ lambda_slash_no_default_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_arg_seq* _res = NULL; int _mark = p->mark; { // lambda_param_no_default+ '/' ',' if (p->error_indicator) { @@ -7410,9 +7420,9 @@ lambda_slash_no_default_rule(Parser *p) D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); Token * _literal; Token * _literal_1; - asdl_seq * a; + asdl_arg_seq* a; if ( - (a = _loop1_82_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_82_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -7439,9 +7449,9 @@ lambda_slash_no_default_rule(Parser *p) } D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); Token * _literal; - asdl_seq * a; + asdl_arg_seq* a; if ( - (a = _loop1_83_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_83_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -7501,7 +7511,7 @@ lambda_slash_with_default_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); - _res = _PyPegen_slash_with_default ( p , a , b ); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -7533,7 +7543,7 @@ lambda_slash_with_default_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); - _res = _PyPegen_slash_with_default ( p , a , b ); + _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq * ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; D(p->level--); @@ -10553,9 +10563,9 @@ slices_rule(Parser *p) D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_94_rule(p)) // ','.slice+ + (a = (asdl_expr_seq*)_gather_94_rule(p)) // ','.slice+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -11111,7 +11121,7 @@ listcomp_rule(Parser *p) Token * _literal; Token * _literal_1; expr_ty a; - asdl_seq* b; + asdl_comprehension_seq* b; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' && @@ -11336,7 +11346,7 @@ genexp_rule(Parser *p) Token * _literal; Token * _literal_1; expr_ty a; - asdl_seq* b; + asdl_comprehension_seq* b; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -11428,7 +11438,7 @@ set_rule(Parser *p) D(fprintf(stderr, "%*c> set[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' expressions_list '}'")); Token * _literal; Token * _literal_1; - asdl_seq* a; + asdl_expr_seq* a; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && @@ -11495,7 +11505,7 @@ setcomp_rule(Parser *p) Token * _literal; Token * _literal_1; expr_ty a; - asdl_seq* b; + asdl_comprehension_seq* b; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && @@ -11653,7 +11663,7 @@ dictcomp_rule(Parser *p) Token * _literal; Token * _literal_1; KeyValuePair* a; - asdl_seq* b; + asdl_comprehension_seq* b; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && @@ -11867,7 +11877,7 @@ kvpair_rule(Parser *p) } // for_if_clauses: for_if_clause+ -static asdl_seq* +static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { D(p->level++); @@ -11875,7 +11885,7 @@ for_if_clauses_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_comprehension_seq* _res = NULL; int _mark = p->mark; { // for_if_clause+ if (p->error_indicator) { @@ -11883,13 +11893,18 @@ for_if_clauses_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); - asdl_seq * _loop1_105_var; + asdl_comprehension_seq* a; if ( - (_loop1_105_var = _loop1_105_rule(p)) // for_if_clause+ + (a = (asdl_comprehension_seq*)_loop1_105_rule(p)) // for_if_clause+ ) { D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); - _res = _loop1_105_var; + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } goto done; } p->mark = _mark; @@ -11928,7 +11943,7 @@ for_if_clause_rule(Parser *p) expr_ty a; Token * async_var; expr_ty b; - asdl_seq * c; + asdl_expr_seq* c; if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && @@ -11942,7 +11957,7 @@ for_if_clause_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - (c = _loop0_106_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_106_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -11973,7 +11988,7 @@ for_if_clause_rule(Parser *p) Token * _keyword_1; expr_ty a; expr_ty b; - asdl_seq * c; + asdl_expr_seq* c; if ( (_keyword = _PyPegen_expect_token(p, 517)) // token='for' && @@ -11985,7 +12000,7 @@ for_if_clause_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - (c = _loop0_107_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_107_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -12228,10 +12243,10 @@ args_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | named_expression !'=')+ [',' kwargs]")); - asdl_seq * a; + asdl_expr_seq* a; void *b; if ( - (a = _gather_108_rule(p)) // ','.(starred_expression | named_expression !'=')+ + (a = (asdl_expr_seq*)_gather_108_rule(p)) // ','.(starred_expression | named_expression !'=')+ && (b = _tmp_110_rule(p), 1) // [',' kwargs] ) @@ -12768,7 +12783,7 @@ star_targets_rule(Parser *p) } // star_targets_seq: ','.star_target+ ','? -static asdl_seq* +static asdl_expr_seq* star_targets_seq_rule(Parser *p) { D(p->level++); @@ -12776,7 +12791,7 @@ star_targets_seq_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.star_target+ ','? if (p->error_indicator) { @@ -12786,9 +12801,9 @@ star_targets_seq_rule(Parser *p) D(fprintf(stderr, "%*c> star_targets_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_120_rule(p)) // ','.star_target+ + (a = (asdl_expr_seq*)_gather_120_rule(p)) // ','.star_target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -13353,7 +13368,7 @@ single_subscript_attribute_target_rule(Parser *p) } // del_targets: ','.del_target+ ','? -static asdl_seq* +static asdl_expr_seq* del_targets_rule(Parser *p) { D(p->level++); @@ -13361,7 +13376,7 @@ del_targets_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.del_target+ ','? if (p->error_indicator) { @@ -13371,9 +13386,9 @@ del_targets_rule(Parser *p) D(fprintf(stderr, "%*c> del_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_123_rule(p)) // ','.del_target+ + (a = (asdl_expr_seq*)_gather_123_rule(p)) // ','.del_target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -13694,7 +13709,7 @@ del_t_atom_rule(Parser *p) } // targets: ','.target+ ','? -static asdl_seq* +static asdl_expr_seq* targets_rule(Parser *p) { D(p->level++); @@ -13702,7 +13717,7 @@ targets_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq* _res = NULL; + asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.target+ ','? if (p->error_indicator) { @@ -13712,9 +13727,9 @@ targets_rule(Parser *p) D(fprintf(stderr, "%*c> targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.target+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - asdl_seq * a; + asdl_expr_seq* a; if ( - (a = _gather_125_rule(p)) // ','.target+ + (a = (asdl_expr_seq*)_gather_125_rule(p)) // ','.target+ && (_opt_var = _PyPegen_expect_token(p, 12), 1) // ','? ) @@ -14418,7 +14433,7 @@ incorrect_arguments_rule(Parser *p) void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty a; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (a = expression_rule(p)) // expression && @@ -14449,7 +14464,7 @@ incorrect_arguments_rule(Parser *p) } D(fprintf(stderr, "%*c> incorrect_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); expr_ty a; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (a = args_rule(p)) // args && @@ -14478,7 +14493,7 @@ incorrect_arguments_rule(Parser *p) Token * _literal; expr_ty a; expr_ty args_var; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (args_var = args_rule(p)) // args && @@ -15029,7 +15044,7 @@ invalid_comprehension_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); void *_tmp_132_var; expr_ty a; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (_tmp_132_var = _tmp_132_rule(p)) // '[' | '(' | '{' && @@ -15078,7 +15093,7 @@ invalid_dict_comprehension_rule(Parser *p) Token * _literal_1; Token * a; expr_ty bitwise_or_var; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && @@ -15537,7 +15552,7 @@ invalid_import_from_targets_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names ','")); Token * _literal; - asdl_seq* import_from_as_names_var; + asdl_alias_seq* import_from_as_names_var; if ( (import_from_as_names_var = import_from_as_names_rule(p)) // import_from_as_names && @@ -15614,7 +15629,7 @@ _loop0_1_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_1[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -15622,7 +15637,7 @@ _loop0_1_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_1_type, _seq); D(p->level--); @@ -15680,7 +15695,7 @@ _loop0_2_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_2[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -15688,7 +15703,7 @@ _loop0_2_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_2_type, _seq); D(p->level--); @@ -15755,7 +15770,7 @@ _loop0_4_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_4[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -15763,7 +15778,7 @@ _loop0_4_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_4_type, _seq); D(p->level--); @@ -15869,7 +15884,7 @@ _loop0_6_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_6[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -15877,7 +15892,7 @@ _loop0_6_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_6_type, _seq); D(p->level--); @@ -15983,7 +15998,7 @@ _loop0_8_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_8[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -15991,7 +16006,7 @@ _loop0_8_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_8_type, _seq); D(p->level--); @@ -16097,7 +16112,7 @@ _loop0_10_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_10[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -16105,7 +16120,7 @@ _loop0_10_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_10_type, _seq); D(p->level--); @@ -16178,7 +16193,7 @@ _loop1_11_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); - asdl_seq* statement_var; + asdl_stmt_seq* statement_var; while ( (statement_var = statement_rule(p)) // statement ) @@ -16207,7 +16222,7 @@ _loop1_11_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -16215,7 +16230,7 @@ _loop1_11_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_11_type, _seq); D(p->level--); @@ -16282,7 +16297,7 @@ _loop0_13_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_13[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';' small_stmt")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -16290,7 +16305,7 @@ _loop0_13_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_13_type, _seq); D(p->level--); @@ -16840,7 +16855,7 @@ _loop1_22_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -16848,7 +16863,7 @@ _loop1_22_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_22_type, _seq); D(p->level--); @@ -17025,7 +17040,7 @@ _loop0_26_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_26[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17033,7 +17048,7 @@ _loop0_26_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_26_type, _seq); D(p->level--); @@ -17139,7 +17154,7 @@ _loop0_28_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_28[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17147,7 +17162,7 @@ _loop0_28_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_28_type, _seq); D(p->level--); @@ -17343,7 +17358,7 @@ _loop0_31_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_31[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17351,7 +17366,7 @@ _loop0_31_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_31_type, _seq); D(p->level--); @@ -17414,7 +17429,7 @@ _loop1_32_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17422,7 +17437,7 @@ _loop1_32_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq); D(p->level--); @@ -17489,7 +17504,7 @@ _loop0_34_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_34[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' import_from_as_name")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17497,7 +17512,7 @@ _loop0_34_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_34_type, _seq); D(p->level--); @@ -17647,7 +17662,7 @@ _loop0_37_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_37[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_as_name")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17655,7 +17670,7 @@ _loop0_37_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_37_type, _seq); D(p->level--); @@ -17805,7 +17820,7 @@ _loop0_40_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_40[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17813,7 +17828,7 @@ _loop0_40_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_40_type, _seq); D(p->level--); @@ -17919,7 +17934,7 @@ _loop0_42_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_42[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -17927,7 +17942,7 @@ _loop0_42_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_42_type, _seq); D(p->level--); @@ -18033,7 +18048,7 @@ _loop0_44_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_44[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18041,7 +18056,7 @@ _loop0_44_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_44_type, _seq); D(p->level--); @@ -18147,7 +18162,7 @@ _loop0_46_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_46[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18155,7 +18170,7 @@ _loop0_46_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_46_type, _seq); D(p->level--); @@ -18331,7 +18346,7 @@ _loop1_48_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18339,7 +18354,7 @@ _loop1_48_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_48_type, _seq); D(p->level--); @@ -18612,7 +18627,7 @@ _loop0_54_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_54[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18620,7 +18635,7 @@ _loop0_54_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq); D(p->level--); @@ -18678,7 +18693,7 @@ _loop0_55_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_55[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18686,7 +18701,7 @@ _loop0_55_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_55_type, _seq); D(p->level--); @@ -18744,7 +18759,7 @@ _loop0_56_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_56[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18752,7 +18767,7 @@ _loop0_56_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq); D(p->level--); @@ -18815,7 +18830,7 @@ _loop1_57_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18823,7 +18838,7 @@ _loop1_57_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_57_type, _seq); D(p->level--); @@ -18881,7 +18896,7 @@ _loop0_58_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_58[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18889,7 +18904,7 @@ _loop0_58_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq); D(p->level--); @@ -18952,7 +18967,7 @@ _loop1_59_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -18960,7 +18975,7 @@ _loop1_59_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_59_type, _seq); D(p->level--); @@ -19023,7 +19038,7 @@ _loop1_60_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19031,7 +19046,7 @@ _loop1_60_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); D(p->level--); @@ -19094,7 +19109,7 @@ _loop1_61_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19102,7 +19117,7 @@ _loop1_61_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); D(p->level--); @@ -19160,7 +19175,7 @@ _loop0_62_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_62[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19168,7 +19183,7 @@ _loop0_62_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_62_type, _seq); D(p->level--); @@ -19231,7 +19246,7 @@ _loop1_63_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19239,7 +19254,7 @@ _loop1_63_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_63_type, _seq); D(p->level--); @@ -19297,7 +19312,7 @@ _loop0_64_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_64[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19305,7 +19320,7 @@ _loop0_64_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_64_type, _seq); D(p->level--); @@ -19368,7 +19383,7 @@ _loop1_65_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19376,7 +19391,7 @@ _loop1_65_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_65_type, _seq); D(p->level--); @@ -19434,7 +19449,7 @@ _loop0_66_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_66[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19442,7 +19457,7 @@ _loop0_66_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq); D(p->level--); @@ -19505,7 +19520,7 @@ _loop1_67_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19513,7 +19528,7 @@ _loop1_67_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_67_type, _seq); D(p->level--); @@ -19576,7 +19591,7 @@ _loop1_68_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19584,7 +19599,7 @@ _loop1_68_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_68_type, _seq); D(p->level--); @@ -19698,7 +19713,7 @@ _loop0_71_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_71[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19706,7 +19721,7 @@ _loop0_71_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_71_type, _seq); D(p->level--); @@ -19808,7 +19823,7 @@ _loop1_72_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19816,7 +19831,7 @@ _loop1_72_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_72_type, _seq); D(p->level--); @@ -19883,7 +19898,7 @@ _loop0_74_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_74[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -19891,7 +19906,7 @@ _loop0_74_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); D(p->level--); @@ -19993,7 +20008,7 @@ _loop1_75_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20001,7 +20016,7 @@ _loop1_75_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_75_type, _seq); D(p->level--); @@ -20059,7 +20074,7 @@ _loop0_76_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_76[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20067,7 +20082,7 @@ _loop0_76_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_76_type, _seq); D(p->level--); @@ -20125,7 +20140,7 @@ _loop0_77_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_77[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20133,7 +20148,7 @@ _loop0_77_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_77_type, _seq); D(p->level--); @@ -20191,7 +20206,7 @@ _loop0_78_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20199,7 +20214,7 @@ _loop0_78_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_78_type, _seq); D(p->level--); @@ -20262,7 +20277,7 @@ _loop1_79_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20270,7 +20285,7 @@ _loop1_79_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_79_type, _seq); D(p->level--); @@ -20328,7 +20343,7 @@ _loop0_80_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20336,7 +20351,7 @@ _loop0_80_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_80_type, _seq); D(p->level--); @@ -20399,7 +20414,7 @@ _loop1_81_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20407,7 +20422,7 @@ _loop1_81_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq); D(p->level--); @@ -20470,7 +20485,7 @@ _loop1_82_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20478,7 +20493,7 @@ _loop1_82_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_82_type, _seq); D(p->level--); @@ -20541,7 +20556,7 @@ _loop1_83_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20549,7 +20564,7 @@ _loop1_83_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_83_type, _seq); D(p->level--); @@ -20607,7 +20622,7 @@ _loop0_84_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_84[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20615,7 +20630,7 @@ _loop0_84_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_84_type, _seq); D(p->level--); @@ -20678,7 +20693,7 @@ _loop1_85_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20686,7 +20701,7 @@ _loop1_85_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); D(p->level--); @@ -20744,7 +20759,7 @@ _loop0_86_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_86[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20752,7 +20767,7 @@ _loop0_86_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_86_type, _seq); D(p->level--); @@ -20815,7 +20830,7 @@ _loop1_87_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20823,7 +20838,7 @@ _loop1_87_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_87_type, _seq); D(p->level--); @@ -20881,7 +20896,7 @@ _loop0_88_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_88[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20889,7 +20904,7 @@ _loop0_88_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_88_type, _seq); D(p->level--); @@ -20952,7 +20967,7 @@ _loop1_89_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -20960,7 +20975,7 @@ _loop1_89_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_89_type, _seq); D(p->level--); @@ -21023,7 +21038,7 @@ _loop1_90_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21031,7 +21046,7 @@ _loop1_90_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_90_type, _seq); D(p->level--); @@ -21094,7 +21109,7 @@ _loop1_91_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21102,7 +21117,7 @@ _loop1_91_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_91_type, _seq); D(p->level--); @@ -21165,7 +21180,7 @@ _loop1_92_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21173,7 +21188,7 @@ _loop1_92_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_92_type, _seq); D(p->level--); @@ -21281,7 +21296,7 @@ _loop0_95_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' slice")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21289,7 +21304,7 @@ _loop0_95_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_95_type, _seq); D(p->level--); @@ -21657,7 +21672,7 @@ _loop1_100_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21665,7 +21680,7 @@ _loop1_100_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_100_type, _seq); D(p->level--); @@ -21834,7 +21849,7 @@ _loop0_104_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_104[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21842,7 +21857,7 @@ _loop0_104_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_104_type, _seq); D(p->level--); @@ -21944,7 +21959,7 @@ _loop1_105_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -21952,7 +21967,7 @@ _loop1_105_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_105_type, _seq); D(p->level--); @@ -22010,7 +22025,7 @@ _loop0_106_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_106[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22018,7 +22033,7 @@ _loop0_106_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_106_type, _seq); D(p->level--); @@ -22076,7 +22091,7 @@ _loop0_107_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22084,7 +22099,7 @@ _loop0_107_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq); D(p->level--); @@ -22151,7 +22166,7 @@ _loop0_109_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | named_expression !'=')")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22159,7 +22174,7 @@ _loop0_109_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_109_type, _seq); D(p->level--); @@ -22309,7 +22324,7 @@ _loop0_112_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22317,7 +22332,7 @@ _loop0_112_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); D(p->level--); @@ -22423,7 +22438,7 @@ _loop0_114_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22431,7 +22446,7 @@ _loop0_114_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); D(p->level--); @@ -22537,7 +22552,7 @@ _loop0_116_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_116[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22545,7 +22560,7 @@ _loop0_116_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_116_type, _seq); D(p->level--); @@ -22651,7 +22666,7 @@ _loop0_118_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22659,7 +22674,7 @@ _loop0_118_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); D(p->level--); @@ -22756,7 +22771,7 @@ _loop0_119_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_119[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22764,7 +22779,7 @@ _loop0_119_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_119_type, _seq); D(p->level--); @@ -22831,7 +22846,7 @@ _loop0_121_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22839,7 +22854,7 @@ _loop0_121_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_121_type, _seq); D(p->level--); @@ -22983,7 +22998,7 @@ _loop0_124_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -22991,7 +23006,7 @@ _loop0_124_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_124_type, _seq); D(p->level--); @@ -23097,7 +23112,7 @@ _loop0_126_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_126[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' target")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23105,7 +23120,7 @@ _loop0_126_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq); D(p->level--); @@ -23188,7 +23203,7 @@ _tmp_127_rule(Parser *p) } D(fprintf(stderr, "%*c> _tmp_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; - asdl_seq* for_if_clauses_var; + asdl_comprehension_seq* for_if_clauses_var; if ( (expression_var = expression_rule(p)) // expression && @@ -23236,7 +23251,7 @@ _loop0_128_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); - asdl_seq* star_named_expressions_var; + asdl_expr_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions ) @@ -23260,7 +23275,7 @@ _loop0_128_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23268,7 +23283,7 @@ _loop0_128_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); D(p->level--); @@ -23326,7 +23341,7 @@ _loop0_129_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23334,7 +23349,7 @@ _loop0_129_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq); D(p->level--); @@ -23392,7 +23407,7 @@ _loop0_130_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23400,7 +23415,7 @@ _loop0_130_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_130_type, _seq); D(p->level--); @@ -23587,7 +23602,7 @@ _loop0_133_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23595,7 +23610,7 @@ _loop0_133_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq); D(p->level--); @@ -23708,7 +23723,7 @@ _loop0_135_rule(Parser *p) D(fprintf(stderr, "%*c%s _loop0_135[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -23716,7 +23731,7 @@ _loop0_135_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_135_type, _seq); D(p->level--); @@ -24594,7 +24609,7 @@ _loop1_153_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -24602,7 +24617,7 @@ _loop1_153_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_153_type, _seq); D(p->level--); @@ -24665,7 +24680,7 @@ _loop1_154_rule(Parser *p) D(p->level--); return NULL; } - asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; @@ -24673,7 +24688,7 @@ _loop1_154_rule(Parser *p) D(p->level--); return NULL; } - for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_154_type, _seq); D(p->level--); diff --git a/Parser/pegen.c b/Parser/pegen.c index 4beb2abdd296aae..1de495eaf398e84 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -1243,7 +1243,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen return result; } -void * +asdl_stmt_seq* _PyPegen_interactive_exit(Parser *p) { if (p->errcode) { @@ -1257,11 +1257,11 @@ asdl_seq * _PyPegen_singleton_seq(Parser *p, void *a) { assert(a != NULL); - asdl_seq *seq = _Py_asdl_seq_new(1, p->arena); + asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena); if (!seq) { return NULL; } - asdl_seq_SET(seq, 0, a); + asdl_seq_SET_UNTYPED(seq, 0, a); return seq; } @@ -1274,14 +1274,14 @@ _PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq) return _PyPegen_singleton_seq(p, a); } - asdl_seq *new_seq = _Py_asdl_seq_new(asdl_seq_LEN(seq) + 1, p->arena); + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); if (!new_seq) { return NULL; } - asdl_seq_SET(new_seq, 0, a); + asdl_seq_SET_UNTYPED(new_seq, 0, a); for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) { - asdl_seq_SET(new_seq, i, asdl_seq_GET(seq, i - 1)); + asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1)); } return new_seq; } @@ -1295,15 +1295,15 @@ _PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a) return _PyPegen_singleton_seq(p, a); } - asdl_seq *new_seq = _Py_asdl_seq_new(asdl_seq_LEN(seq) + 1, p->arena); + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); if (!new_seq) { return NULL; } for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) { - asdl_seq_SET(new_seq, i, asdl_seq_GET(seq, i)); + asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i)); } - asdl_seq_SET(new_seq, asdl_seq_LEN(new_seq) - 1, a); + asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a); return new_seq; } @@ -1312,7 +1312,7 @@ _get_flattened_seq_size(asdl_seq *seqs) { Py_ssize_t size = 0; for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { - asdl_seq *inner_seq = asdl_seq_GET(seqs, i); + asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); size += asdl_seq_LEN(inner_seq); } return size; @@ -1325,16 +1325,16 @@ _PyPegen_seq_flatten(Parser *p, asdl_seq *seqs) Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs); assert(flattened_seq_size > 0); - asdl_seq *flattened_seq = _Py_asdl_seq_new(flattened_seq_size, p->arena); + asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena); if (!flattened_seq) { return NULL; } int flattened_seq_idx = 0; for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) { - asdl_seq *inner_seq = asdl_seq_GET(seqs, i); + asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) { - asdl_seq_SET(flattened_seq, flattened_seq_idx++, asdl_seq_GET(inner_seq, j)); + asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j)); } } assert(flattened_seq_idx == flattened_seq_size); @@ -1403,7 +1403,7 @@ _PyPegen_seq_count_dots(asdl_seq *seq) { int number_of_dots = 0; for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { - Token *current_expr = asdl_seq_GET(seq, i); + Token *current_expr = asdl_seq_GET_UNTYPED(seq, i); switch (current_expr->type) { case ELLIPSIS: number_of_dots += 3; @@ -1435,13 +1435,13 @@ _PyPegen_alias_for_star(Parser *p) } /* Creates a new asdl_seq* with the identifiers of all the names in seq */ -asdl_seq * -_PyPegen_map_names_to_ids(Parser *p, asdl_seq *seq) +asdl_identifier_seq * +_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq) { Py_ssize_t len = asdl_seq_LEN(seq); assert(len > 0); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); + asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena); if (!new_seq) { return NULL; } @@ -1477,39 +1477,39 @@ _PyPegen_get_cmpops(Parser *p, asdl_seq *seq) return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - CmpopExprPair *pair = asdl_seq_GET(seq, i); + CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); asdl_seq_SET(new_seq, i, pair->cmpop); } return new_seq; } -asdl_seq * +asdl_expr_seq * _PyPegen_get_exprs(Parser *p, asdl_seq *seq) { Py_ssize_t len = asdl_seq_LEN(seq); assert(len > 0); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); if (!new_seq) { return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - CmpopExprPair *pair = asdl_seq_GET(seq, i); + CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); asdl_seq_SET(new_seq, i, pair->expr); } return new_seq; } /* Creates an asdl_seq* where all the elements have been changed to have ctx as context */ -static asdl_seq * -_set_seq_context(Parser *p, asdl_seq *seq, expr_context_ty ctx) +static asdl_expr_seq * +_set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx) { Py_ssize_t len = asdl_seq_LEN(seq); if (len == 0) { return NULL; } - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); if (!new_seq) { return NULL; } @@ -1529,13 +1529,19 @@ _set_name_context(Parser *p, expr_ty e, expr_context_ty ctx) static expr_ty _set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx) { - return _Py_Tuple(_set_seq_context(p, e->v.Tuple.elts, ctx), ctx, EXTRA_EXPR(e, e)); + return _Py_Tuple( + _set_seq_context(p, e->v.Tuple.elts, ctx), + ctx, + EXTRA_EXPR(e, e)); } static expr_ty _set_list_context(Parser *p, expr_ty e, expr_context_ty ctx) { - return _Py_List(_set_seq_context(p, e->v.List.elts, ctx), ctx, EXTRA_EXPR(e, e)); + return _Py_List( + _set_seq_context(p, e->v.List.elts, ctx), + ctx, + EXTRA_EXPR(e, e)); } static expr_ty @@ -1602,32 +1608,32 @@ _PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value) } /* Extracts all keys from an asdl_seq* of KeyValuePair*'s */ -asdl_seq * +asdl_expr_seq * _PyPegen_get_keys(Parser *p, asdl_seq *seq) { Py_ssize_t len = asdl_seq_LEN(seq); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); if (!new_seq) { return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - KeyValuePair *pair = asdl_seq_GET(seq, i); + KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); asdl_seq_SET(new_seq, i, pair->key); } return new_seq; } /* Extracts all values from an asdl_seq* of KeyValuePair*'s */ -asdl_seq * +asdl_expr_seq * _PyPegen_get_values(Parser *p, asdl_seq *seq) { Py_ssize_t len = asdl_seq_LEN(seq); - asdl_seq *new_seq = _Py_asdl_seq_new(len, p->arena); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); if (!new_seq) { return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - KeyValuePair *pair = asdl_seq_GET(seq, i); + KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); asdl_seq_SET(new_seq, i, pair->value); } return new_seq; @@ -1648,7 +1654,7 @@ _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) /* Constructs a SlashWithDefault */ SlashWithDefault * -_PyPegen_slash_with_default(Parser *p, asdl_seq *plain_names, asdl_seq *names_with_defaults) +_PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults) { SlashWithDefault *a = PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); if (!a) { @@ -1678,47 +1684,47 @@ _PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b) { Py_ssize_t first_len = asdl_seq_LEN(a); Py_ssize_t second_len = asdl_seq_LEN(b); - asdl_seq *new_seq = _Py_asdl_seq_new(first_len + second_len, p->arena); + asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena); if (!new_seq) { return NULL; } int k = 0; for (Py_ssize_t i = 0; i < first_len; i++) { - asdl_seq_SET(new_seq, k++, asdl_seq_GET(a, i)); + asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i)); } for (Py_ssize_t i = 0; i < second_len; i++) { - asdl_seq_SET(new_seq, k++, asdl_seq_GET(b, i)); + asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i)); } return new_seq; } -static asdl_seq * +static asdl_arg_seq* _get_names(Parser *p, asdl_seq *names_with_defaults) { Py_ssize_t len = asdl_seq_LEN(names_with_defaults); - asdl_seq *seq = _Py_asdl_seq_new(len, p->arena); + asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena); if (!seq) { return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - NameDefaultPair *pair = asdl_seq_GET(names_with_defaults, i); + NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); asdl_seq_SET(seq, i, pair->arg); } return seq; } -static asdl_seq * +static asdl_expr_seq * _get_defaults(Parser *p, asdl_seq *names_with_defaults) { Py_ssize_t len = asdl_seq_LEN(names_with_defaults); - asdl_seq *seq = _Py_asdl_seq_new(len, p->arena); + asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena); if (!seq) { return NULL; } for (Py_ssize_t i = 0; i < len; i++) { - NameDefaultPair *pair = asdl_seq_GET(names_with_defaults, i); + NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); asdl_seq_SET(seq, i, pair->value); } return seq; @@ -1726,39 +1732,45 @@ _get_defaults(Parser *p, asdl_seq *names_with_defaults) /* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */ arguments_ty -_PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, - SlashWithDefault *slash_with_default, asdl_seq *plain_names, +_PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default, + SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names, asdl_seq *names_with_default, StarEtc *star_etc) { - asdl_seq *posonlyargs; + asdl_arg_seq *posonlyargs; if (slash_without_default != NULL) { posonlyargs = slash_without_default; } else if (slash_with_default != NULL) { - asdl_seq *slash_with_default_names = + asdl_arg_seq *slash_with_default_names = _get_names(p, slash_with_default->names_with_defaults); if (!slash_with_default_names) { return NULL; } - posonlyargs = _PyPegen_join_sequences(p, slash_with_default->plain_names, slash_with_default_names); + posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences( + p, + (asdl_seq*)slash_with_default->plain_names, + (asdl_seq*)slash_with_default_names); if (!posonlyargs) { return NULL; } } else { - posonlyargs = _Py_asdl_seq_new(0, p->arena); + posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); if (!posonlyargs) { return NULL; } } - asdl_seq *posargs; + asdl_arg_seq *posargs; if (plain_names != NULL && names_with_default != NULL) { - asdl_seq *names_with_default_names = _get_names(p, names_with_default); + asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default); if (!names_with_default_names) { return NULL; } - posargs = _PyPegen_join_sequences(p, plain_names, names_with_default_names); + posargs = (asdl_arg_seq*)_PyPegen_join_sequences( + p, + (asdl_seq*)plain_names, + (asdl_seq*)names_with_default_names); if (!posargs) { return NULL; } @@ -1773,24 +1785,27 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, posargs = plain_names; } else { - posargs = _Py_asdl_seq_new(0, p->arena); + posargs = _Py_asdl_arg_seq_new(0, p->arena); if (!posargs) { return NULL; } } - asdl_seq *posdefaults; + asdl_expr_seq *posdefaults; if (slash_with_default != NULL && names_with_default != NULL) { - asdl_seq *slash_with_default_values = + asdl_expr_seq *slash_with_default_values = _get_defaults(p, slash_with_default->names_with_defaults); if (!slash_with_default_values) { return NULL; } - asdl_seq *names_with_default_values = _get_defaults(p, names_with_default); + asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default); if (!names_with_default_values) { return NULL; } - posdefaults = _PyPegen_join_sequences(p, slash_with_default_values, names_with_default_values); + posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences( + p, + (asdl_seq*)slash_with_default_values, + (asdl_seq*)names_with_default_values); if (!posdefaults) { return NULL; } @@ -1808,7 +1823,7 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, } } else { - posdefaults = _Py_asdl_seq_new(0, p->arena); + posdefaults = _Py_asdl_expr_seq_new(0, p->arena); if (!posdefaults) { return NULL; } @@ -1819,7 +1834,7 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, vararg = star_etc->vararg; } - asdl_seq *kwonlyargs; + asdl_arg_seq *kwonlyargs; if (star_etc != NULL && star_etc->kwonlyargs != NULL) { kwonlyargs = _get_names(p, star_etc->kwonlyargs); if (!kwonlyargs) { @@ -1827,13 +1842,13 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, } } else { - kwonlyargs = _Py_asdl_seq_new(0, p->arena); + kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); if (!kwonlyargs) { return NULL; } } - asdl_seq *kwdefaults; + asdl_expr_seq *kwdefaults; if (star_etc != NULL && star_etc->kwonlyargs != NULL) { kwdefaults = _get_defaults(p, star_etc->kwonlyargs); if (!kwdefaults) { @@ -1841,7 +1856,7 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, } } else { - kwdefaults = _Py_asdl_seq_new(0, p->arena); + kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); if (!kwdefaults) { return NULL; } @@ -1861,23 +1876,23 @@ _PyPegen_make_arguments(Parser *p, asdl_seq *slash_without_default, arguments_ty _PyPegen_empty_arguments(Parser *p) { - asdl_seq *posonlyargs = _Py_asdl_seq_new(0, p->arena); + asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); if (!posonlyargs) { return NULL; } - asdl_seq *posargs = _Py_asdl_seq_new(0, p->arena); + asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena); if (!posargs) { return NULL; } - asdl_seq *posdefaults = _Py_asdl_seq_new(0, p->arena); + asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena); if (!posdefaults) { return NULL; } - asdl_seq *kwonlyargs = _Py_asdl_seq_new(0, p->arena); + asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); if (!kwonlyargs) { return NULL; } - asdl_seq *kwdefaults = _Py_asdl_seq_new(0, p->arena); + asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); if (!kwdefaults) { return NULL; } @@ -1900,7 +1915,7 @@ _PyPegen_augoperator(Parser *p, operator_ty kind) /* Construct a FunctionDef equivalent to function_def, but with decorators */ stmt_ty -_PyPegen_function_def_decorators(Parser *p, asdl_seq *decorators, stmt_ty function_def) +_PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def) { assert(function_def != NULL); if (function_def->kind == AsyncFunctionDef_kind) { @@ -1922,7 +1937,7 @@ _PyPegen_function_def_decorators(Parser *p, asdl_seq *decorators, stmt_ty functi /* Construct a ClassDef equivalent to class_def, but with decorators */ stmt_ty -_PyPegen_class_def_decorators(Parser *p, asdl_seq *decorators, stmt_ty class_def) +_PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def) { assert(class_def != NULL); return _Py_ClassDef(class_def->v.ClassDef.name, class_def->v.ClassDef.bases, @@ -1950,7 +1965,7 @@ _seq_number_of_starred_exprs(asdl_seq *seq) { int n = 0; for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) { - KeywordOrStarred *k = asdl_seq_GET(seq, i); + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i); if (!k->is_keyword) { n++; } @@ -1959,21 +1974,21 @@ _seq_number_of_starred_exprs(asdl_seq *seq) } /* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */ -asdl_seq * +asdl_expr_seq * _PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs) { int new_len = _seq_number_of_starred_exprs(kwargs); if (new_len == 0) { return NULL; } - asdl_seq *new_seq = _Py_asdl_seq_new(new_len, p->arena); + asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena); if (!new_seq) { return NULL; } int idx = 0; for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) { - KeywordOrStarred *k = asdl_seq_GET(kwargs, i); + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); if (!k->is_keyword) { asdl_seq_SET(new_seq, idx++, k->element); } @@ -1982,7 +1997,7 @@ _PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs) } /* Return a new asdl_seq* with only the keywords in kwargs */ -asdl_seq * +asdl_keyword_seq* _PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) { Py_ssize_t len = asdl_seq_LEN(kwargs); @@ -1990,14 +2005,14 @@ _PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) if (new_len == 0) { return NULL; } - asdl_seq *new_seq = _Py_asdl_seq_new(new_len, p->arena); + asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena); if (!new_seq) { return NULL; } int idx = 0; for (Py_ssize_t i = 0; i < len; i++) { - KeywordOrStarred *k = asdl_seq_GET(kwargs, i); + KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); if (k->is_keyword) { asdl_seq_SET(new_seq, idx++, k->element); } @@ -2011,8 +2026,8 @@ _PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) Py_ssize_t len = asdl_seq_LEN(strings); assert(len > 0); - Token *first = asdl_seq_GET(strings, 0); - Token *last = asdl_seq_GET(strings, len - 1); + Token *first = asdl_seq_GET_UNTYPED(strings, 0); + Token *last = asdl_seq_GET_UNTYPED(strings, len - 1); int bytesmode = 0; PyObject *bytes_str = NULL; @@ -2021,7 +2036,7 @@ _PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) _PyPegen_FstringParser_Init(&state); for (Py_ssize_t i = 0; i < len; i++) { - Token *t = asdl_seq_GET(strings, i); + Token *t = asdl_seq_GET_UNTYPED(strings, i); int this_bytesmode; int this_rawmode; @@ -2095,12 +2110,12 @@ _PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) } mod_ty -_PyPegen_make_module(Parser *p, asdl_seq *a) { - asdl_seq *type_ignores = NULL; +_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) { + asdl_type_ignore_seq *type_ignores = NULL; Py_ssize_t num = p->type_ignore_comments.num_items; if (num > 0) { // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena - type_ignores = _Py_asdl_seq_new(num, p->arena); + type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena); if (type_ignores == NULL) { return NULL; } @@ -2219,7 +2234,7 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args) } -expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b, +expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { Py_ssize_t args_len = asdl_seq_LEN(a); @@ -2231,14 +2246,14 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b, } - asdl_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); - asdl_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); + asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); + asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); if (starreds) { total_len += asdl_seq_LEN(starreds); } - asdl_seq *args = _Py_asdl_seq_new(total_len, arena); + asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena); Py_ssize_t i = 0; for (i = 0; i < args_len; i++) { @@ -2250,6 +2265,4 @@ expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_seq *a, asdl_seq *b, return _Py_Call(_PyPegen_dummy_name(p), args, keywords, lineno, col_offset, end_lineno, end_col_offset, arena); - - } diff --git a/Parser/pegen.h b/Parser/pegen.h index c81681efad20807..000dc8c462b85ce 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -91,7 +91,7 @@ typedef struct { } NameDefaultPair; typedef struct { - asdl_seq *plain_names; + asdl_arg_seq *plain_names; asdl_seq *names_with_defaults; // asdl_seq* of NameDefaultsPair's } SlashWithDefault; @@ -229,7 +229,7 @@ mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char void *_PyPegen_run_parser(Parser *); mod_ty _PyPegen_run_parser_from_file(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); -void *_PyPegen_interactive_exit(Parser *); +asdl_stmt_seq *_PyPegen_interactive_exit(Parser *); asdl_seq *_PyPegen_singleton_seq(Parser *, void *); asdl_seq *_PyPegen_seq_insert_in_front(Parser *, void *, asdl_seq *); asdl_seq *_PyPegen_seq_append_to_end(Parser *, asdl_seq *, void *); @@ -237,33 +237,33 @@ asdl_seq *_PyPegen_seq_flatten(Parser *, asdl_seq *); expr_ty _PyPegen_join_names_with_dot(Parser *, expr_ty, expr_ty); int _PyPegen_seq_count_dots(asdl_seq *); alias_ty _PyPegen_alias_for_star(Parser *); -asdl_seq *_PyPegen_map_names_to_ids(Parser *, asdl_seq *); +asdl_identifier_seq *_PyPegen_map_names_to_ids(Parser *, asdl_expr_seq *); CmpopExprPair *_PyPegen_cmpop_expr_pair(Parser *, cmpop_ty, expr_ty); asdl_int_seq *_PyPegen_get_cmpops(Parser *p, asdl_seq *); -asdl_seq *_PyPegen_get_exprs(Parser *, asdl_seq *); +asdl_expr_seq *_PyPegen_get_exprs(Parser *, asdl_seq *); expr_ty _PyPegen_set_expr_context(Parser *, expr_ty, expr_context_ty); KeyValuePair *_PyPegen_key_value_pair(Parser *, expr_ty, expr_ty); -asdl_seq *_PyPegen_get_keys(Parser *, asdl_seq *); -asdl_seq *_PyPegen_get_values(Parser *, asdl_seq *); +asdl_expr_seq *_PyPegen_get_keys(Parser *, asdl_seq *); +asdl_expr_seq *_PyPegen_get_values(Parser *, asdl_seq *); NameDefaultPair *_PyPegen_name_default_pair(Parser *, arg_ty, expr_ty, Token *); -SlashWithDefault *_PyPegen_slash_with_default(Parser *, asdl_seq *, asdl_seq *); +SlashWithDefault *_PyPegen_slash_with_default(Parser *, asdl_arg_seq *, asdl_seq *); StarEtc *_PyPegen_star_etc(Parser *, arg_ty, asdl_seq *, arg_ty); -arguments_ty _PyPegen_make_arguments(Parser *, asdl_seq *, SlashWithDefault *, - asdl_seq *, asdl_seq *, StarEtc *); +arguments_ty _PyPegen_make_arguments(Parser *, asdl_arg_seq *, SlashWithDefault *, + asdl_arg_seq *, asdl_seq *, StarEtc *); arguments_ty _PyPegen_empty_arguments(Parser *); AugOperator *_PyPegen_augoperator(Parser*, operator_ty type); -stmt_ty _PyPegen_function_def_decorators(Parser *, asdl_seq *, stmt_ty); -stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_seq *, stmt_ty); +stmt_ty _PyPegen_function_def_decorators(Parser *, asdl_expr_seq *, stmt_ty); +stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_expr_seq *, stmt_ty); KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int); -asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); -asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); -expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *, +asdl_expr_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *); +asdl_keyword_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); +expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_expr_seq *, asdl_seq *, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *); asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *); int _PyPegen_check_barry_as_flufl(Parser *); -mod_ty _PyPegen_make_module(Parser *, asdl_seq *); +mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *); // Error reporting helpers typedef enum { diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 2c35da590defbbc..1285968b3191773 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -970,15 +970,15 @@ ExprList_Dealloc(ExprList *l) l->size = -1; } -static asdl_seq * +static asdl_expr_seq * ExprList_Finish(ExprList *l, PyArena *arena) { - asdl_seq *seq; + asdl_expr_seq *seq; ExprList_check_invariants(l); /* Allocate the asdl_seq and copy the expressions in to it. */ - seq = _Py_asdl_seq_new(l->size, arena); + seq = _Py_asdl_expr_seq_new(l->size, arena); if (seq) { Py_ssize_t i; for (i = 0; i < l->size; i++) { @@ -1167,7 +1167,7 @@ expr_ty _PyPegen_FstringParser_Finish(Parser *p, FstringParser *state, Token* first_token, Token *last_token) { - asdl_seq *seq; + asdl_expr_seq *seq; FstringParser_check_invariants(state); diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 094010e6c9ddce6..13657a672756674 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -549,6 +549,18 @@ static int init_identifiers(astmodulestate *state) return 1; }; +GENERATE_ASDL_SEQ_CONSTRUCTOR(mod, mod_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(stmt, stmt_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(expr, expr_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(comprehension, comprehension_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(excepthandler, excepthandler_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(arguments, arguments_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(arg, arg_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(keyword, keyword_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(alias, alias_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(withitem, withitem_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty) + static PyObject* ast2obj_mod(astmodulestate *state, void*); static const char * const Module_fields[]={ "body", @@ -1097,7 +1109,7 @@ static PyObject* ast2obj_list(astmodulestate *state, asdl_seq *seq, PyObject* (* if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, asdl_seq_GET(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -1912,7 +1924,8 @@ static int obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out, PyArena* arena); mod_ty -Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena) +Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, PyArena + *arena) { mod_ty p; p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -1925,7 +1938,7 @@ Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena) } mod_ty -Interactive(asdl_seq * body, PyArena *arena) +Interactive(asdl_stmt_seq * body, PyArena *arena) { mod_ty p; p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -1954,7 +1967,7 @@ Expression(expr_ty body, PyArena *arena) } mod_ty -FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) +FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena) { mod_ty p; if (!returns) { @@ -1972,9 +1985,10 @@ FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) } stmt_ty -FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * - decorator_list, expr_ty returns, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, + asdl_expr_seq * decorator_list, expr_ty returns, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; if (!name) { @@ -2005,10 +2019,10 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * } stmt_ty -AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq - * decorator_list, expr_ty returns, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) +AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, + asdl_expr_seq * decorator_list, expr_ty returns, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; if (!name) { @@ -2039,9 +2053,9 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq } stmt_ty -ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * - body, asdl_seq * decorator_list, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * keywords, + asdl_stmt_seq * body, asdl_expr_seq * decorator_list, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!name) { @@ -2083,7 +2097,7 @@ Return(expr_ty value, int lineno, int col_offset, int end_lineno, int } stmt_ty -Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int +Delete(asdl_expr_seq * targets, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; @@ -2100,8 +2114,8 @@ Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int } stmt_ty -Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!value) { @@ -2189,8 +2203,8 @@ AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int } stmt_ty -For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string - type_comment, int lineno, int col_offset, int end_lineno, int +For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * orelse, + string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; @@ -2221,9 +2235,9 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string } stmt_ty -AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, - string type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * + orelse, string type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!target) { @@ -2253,8 +2267,8 @@ AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, } stmt_ty -While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!test) { @@ -2277,7 +2291,7 @@ While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int } stmt_ty -If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int +If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; @@ -2301,8 +2315,8 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int } stmt_ty -With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +With(asdl_withitem_seq * items, asdl_stmt_seq * body, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2320,8 +2334,9 @@ With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int } stmt_ty -AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string type_comment, + int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2357,9 +2372,9 @@ Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, } stmt_ty -Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq * - finalbody, int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) +Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, asdl_stmt_seq * + orelse, asdl_stmt_seq * finalbody, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2401,7 +2416,7 @@ Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, } stmt_ty -Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int +Import(asdl_alias_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; @@ -2418,8 +2433,8 @@ Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int } stmt_ty -ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +ImportFrom(identifier module, asdl_alias_seq * names, int level, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2437,8 +2452,8 @@ ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int } stmt_ty -Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +Global(asdl_identifier_seq * names, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2454,8 +2469,8 @@ Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int } stmt_ty -Nonlocal(asdl_seq * names, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2541,7 +2556,7 @@ Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, } expr_ty -BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int +BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; @@ -2716,8 +2731,8 @@ IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, } expr_ty -Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -2734,7 +2749,7 @@ Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int } expr_ty -Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int +Set(asdl_expr_seq * elts, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; @@ -2751,8 +2766,8 @@ Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int } expr_ty -ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!elt) { @@ -2774,8 +2789,8 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int } expr_ty -SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +SetComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!elt) { @@ -2797,8 +2812,9 @@ SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int } expr_ty -DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!key) { @@ -2826,8 +2842,8 @@ DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int } expr_ty -GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) +GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!elt) { @@ -2910,8 +2926,9 @@ YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int } expr_ty -Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * comparators, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!left) { @@ -2934,8 +2951,8 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, } expr_ty -Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * keywords, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!func) { @@ -2983,8 +3000,8 @@ FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, } expr_ty -JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) { expr_ty p; p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -3147,7 +3164,7 @@ Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int +List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; @@ -3170,8 +3187,8 @@ List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int } expr_ty -Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; if (!ctx) { @@ -3212,7 +3229,7 @@ Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, } comprehension_ty -comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, +comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int is_async, PyArena *arena) { comprehension_ty p; @@ -3237,8 +3254,9 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, } excepthandler_ty -ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) +ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq * body, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { excepthandler_ty p; p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -3256,9 +3274,9 @@ ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int } arguments_ty -arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq * - kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * - defaults, PyArena *arena) +arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, arg_ty vararg, + asdl_arg_seq * kwonlyargs, asdl_expr_seq * kw_defaults, arg_ty kwarg, + asdl_expr_seq * defaults, PyArena *arena) { arguments_ty p; p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); @@ -3386,12 +3404,12 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Module_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Module.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Module.type_ignores, + value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores, ast2obj_type_ignore); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_ignores, value) == -1) @@ -3402,7 +3420,8 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Interactive_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Interactive.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3422,7 +3441,8 @@ ast2obj_mod(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->FunctionType_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.FunctionType.argtypes, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->argtypes, value) == -1) goto failed; @@ -3465,12 +3485,13 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.FunctionDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.FunctionDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) @@ -3501,12 +3522,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFunctionDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFunctionDef.decorator_list, + value = ast2obj_list(state, + (asdl_seq*)o->v.AsyncFunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) @@ -3532,22 +3555,26 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.bases, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->bases, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.keywords, ast2obj_keyword); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords, + ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ClassDef.decorator_list, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; @@ -3567,7 +3594,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Delete_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Delete.targets, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; @@ -3577,7 +3605,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Assign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Assign.targets, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; @@ -3652,12 +3681,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.For.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.For.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3682,12 +3711,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFor.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncFor.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3707,12 +3738,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.While.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.While.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3727,12 +3758,12 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.If.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.If.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -3742,12 +3773,13 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->With_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.With.items, ast2obj_withitem); + value = ast2obj_list(state, (asdl_seq*)o->v.With.items, + ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.With.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3762,12 +3794,14 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->AsyncWith_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.AsyncWith.items, ast2obj_withitem); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items, + ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.AsyncWith.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -3797,22 +3831,24 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Try_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Try.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.handlers, ast2obj_excepthandler); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers, + ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.orelse, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Try.finalbody, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) goto failed; @@ -3837,7 +3873,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Import_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Import.names, ast2obj_alias); + value = ast2obj_list(state, (asdl_seq*)o->v.Import.names, + ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3852,7 +3889,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->module, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ImportFrom.names, ast2obj_alias); + value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names, + ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3867,7 +3905,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Global_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Global.names, ast2obj_identifier); + value = ast2obj_list(state, (asdl_seq*)o->v.Global.names, + ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3877,7 +3916,8 @@ ast2obj_stmt(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Nonlocal_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Nonlocal.names, ast2obj_identifier); + value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names, + ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; @@ -3955,7 +3995,8 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.BoolOp.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4050,12 +4091,12 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Dict_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Dict.keys, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Dict.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4065,7 +4106,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Set_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Set.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4080,7 +4121,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ListComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4096,7 +4137,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.SetComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4117,7 +4158,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.DictComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4133,7 +4174,7 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.GeneratorExp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -4190,7 +4231,8 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->ops, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Compare.comparators, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->comparators, value) == -1) goto failed; @@ -4205,12 +4247,13 @@ ast2obj_expr(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->func, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Call.args, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.Call.keywords, ast2obj_keyword); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords, + ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; @@ -4240,7 +4283,8 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->JoinedStr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.JoinedStr.values, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -4335,7 +4379,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->List_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.List.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4350,7 +4394,7 @@ ast2obj_expr(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->Tuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, o->v.Tuple.elts, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -4557,7 +4601,7 @@ ast2obj_comprehension(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->ifs, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->ifs, value) == -1) goto failed; @@ -4598,7 +4642,8 @@ ast2obj_excepthandler(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->v.ExceptHandler.body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body, + ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -4644,12 +4689,12 @@ ast2obj_arguments(astmodulestate *state, void* _o) tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_list(state, o->posonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->posonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->args, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; @@ -4659,12 +4704,12 @@ ast2obj_arguments(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->vararg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->kwonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->kw_defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->kw_defaults, value) == -1) goto failed; @@ -4674,7 +4719,7 @@ ast2obj_arguments(astmodulestate *state, void* _o) if (PyObject_SetAttr(result, state->kwarg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, o->defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->defaults, value) == -1) goto failed; @@ -4899,8 +4944,8 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; - asdl_seq* type_ignores; + asdl_stmt_seq* body; + asdl_type_ignore_seq* type_ignores; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -4918,7 +4963,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -4951,7 +4996,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - type_ignores = _Py_asdl_seq_new(len, arena); + type_ignores = _Py_asdl_type_ignore_seq_new(len, arena); if (type_ignores == NULL) goto failed; for (i = 0; i < len; i++) { type_ignore_ty val; @@ -4978,7 +5023,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; + asdl_stmt_seq* body; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -4996,7 +5041,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5048,7 +5093,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* argtypes; + asdl_expr_seq* argtypes; expr_ty returns; if (_PyObject_LookupAttr(obj, state->argtypes, &tmp) < 0) { @@ -5067,7 +5112,7 @@ obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - argtypes = _Py_asdl_seq_new(len, arena); + argtypes = _Py_asdl_expr_seq_new(len, arena); if (argtypes == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5184,8 +5229,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { identifier name; arguments_ty args; - asdl_seq* body; - asdl_seq* decorator_list; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; @@ -5231,7 +5276,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5264,7 +5309,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5321,8 +5366,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { identifier name; arguments_ty args; - asdl_seq* body; - asdl_seq* decorator_list; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; @@ -5368,7 +5413,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5401,7 +5446,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5457,10 +5502,10 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { identifier name; - asdl_seq* bases; - asdl_seq* keywords; - asdl_seq* body; - asdl_seq* decorator_list; + asdl_expr_seq* bases; + asdl_keyword_seq* keywords; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { return 1; @@ -5491,7 +5536,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - bases = _Py_asdl_seq_new(len, arena); + bases = _Py_asdl_expr_seq_new(len, arena); if (bases == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5524,7 +5569,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_seq_new(len, arena); + keywords = _Py_asdl_keyword_seq_new(len, arena); if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; @@ -5557,7 +5602,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5590,7 +5635,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_seq_new(len, arena); + decorator_list = _Py_asdl_expr_seq_new(len, arena); if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5644,7 +5689,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* targets; + asdl_expr_seq* targets; if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) { return 1; @@ -5662,7 +5707,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_seq_new(len, arena); + targets = _Py_asdl_expr_seq_new(len, arena); if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5690,7 +5735,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* targets; + asdl_expr_seq* targets; expr_ty value; string type_comment; @@ -5710,7 +5755,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_seq_new(len, arena); + targets = _Py_asdl_expr_seq_new(len, arena); if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -5888,8 +5933,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { expr_ty target; expr_ty iter; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; string type_comment; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -5934,7 +5979,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -5967,7 +6012,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6010,8 +6055,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) if (isinstance) { expr_ty target; expr_ty iter; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; string type_comment; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -6056,7 +6101,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6089,7 +6134,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6131,8 +6176,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { expr_ty test; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { return 1; @@ -6163,7 +6208,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6196,7 +6241,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6225,8 +6270,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { expr_ty test; - asdl_seq* body; - asdl_seq* orelse; + asdl_stmt_seq* body; + asdl_stmt_seq* orelse; if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { return 1; @@ -6257,7 +6302,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6290,7 +6335,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6318,8 +6363,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* items; - asdl_seq* body; + asdl_withitem_seq* items; + asdl_stmt_seq* body; string type_comment; if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { @@ -6338,7 +6383,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - items = _Py_asdl_seq_new(len, arena); + items = _Py_asdl_withitem_seq_new(len, arena); if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; @@ -6371,7 +6416,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6412,8 +6457,8 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* items; - asdl_seq* body; + asdl_withitem_seq* items; + asdl_stmt_seq* body; string type_comment; if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { @@ -6432,7 +6477,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - items = _Py_asdl_seq_new(len, arena); + items = _Py_asdl_withitem_seq_new(len, arena); if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; @@ -6465,7 +6510,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6546,10 +6591,10 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* body; - asdl_seq* handlers; - asdl_seq* orelse; - asdl_seq* finalbody; + asdl_stmt_seq* body; + asdl_excepthandler_seq* handlers; + asdl_stmt_seq* orelse; + asdl_stmt_seq* finalbody; if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { return 1; @@ -6567,7 +6612,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6600,7 +6645,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - handlers = _Py_asdl_seq_new(len, arena); + handlers = _Py_asdl_excepthandler_seq_new(len, arena); if (handlers == NULL) goto failed; for (i = 0; i < len; i++) { excepthandler_ty val; @@ -6633,7 +6678,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_seq_new(len, arena); + orelse = _Py_asdl_stmt_seq_new(len, arena); if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6666,7 +6711,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - finalbody = _Py_asdl_seq_new(len, arena); + finalbody = _Py_asdl_stmt_seq_new(len, arena); if (finalbody == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -6734,7 +6779,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_alias_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -6752,7 +6797,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_alias_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; @@ -6781,7 +6826,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) } if (isinstance) { identifier module; - asdl_seq* names; + asdl_alias_seq* names; int level; if (_PyObject_LookupAttr(obj, state->module, &tmp) < 0) { @@ -6813,7 +6858,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_alias_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; @@ -6854,7 +6899,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_identifier_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -6872,7 +6917,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_identifier_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; @@ -6900,7 +6945,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* names; + asdl_identifier_seq* names; if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { return 1; @@ -6918,7 +6963,7 @@ obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - names = _Py_asdl_seq_new(len, arena); + names = _Py_asdl_identifier_seq_new(len, arena); if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; @@ -7081,7 +7126,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { boolop_ty op; - asdl_seq* values; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { return 1; @@ -7112,7 +7157,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7368,8 +7413,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* keys; - asdl_seq* values; + asdl_expr_seq* keys; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) { return 1; @@ -7387,7 +7432,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keys = _Py_asdl_seq_new(len, arena); + keys = _Py_asdl_expr_seq_new(len, arena); if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7420,7 +7465,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7448,7 +7493,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { return 1; @@ -7466,7 +7511,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7494,7 +7539,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -7525,7 +7570,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -7554,7 +7599,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -7585,7 +7630,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -7615,7 +7660,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (isinstance) { expr_ty key; expr_ty value; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->key, &tmp) < 0) { return 1; @@ -7659,7 +7704,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -7688,7 +7733,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty elt; - asdl_seq* generators; + asdl_comprehension_seq* generators; if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { return 1; @@ -7719,7 +7764,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_seq_new(len, arena); + generators = _Py_asdl_comprehension_seq_new(len, arena); if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; @@ -7827,7 +7872,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) if (isinstance) { expr_ty left; asdl_int_seq* ops; - asdl_seq* comparators; + asdl_expr_seq* comparators; if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) { return 1; @@ -7891,7 +7936,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - comparators = _Py_asdl_seq_new(len, arena); + comparators = _Py_asdl_expr_seq_new(len, arena); if (comparators == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7920,8 +7965,8 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) } if (isinstance) { expr_ty func; - asdl_seq* args; - asdl_seq* keywords; + asdl_expr_seq* args; + asdl_keyword_seq* keywords; if (_PyObject_LookupAttr(obj, state->func, &tmp) < 0) { return 1; @@ -7952,7 +7997,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - args = _Py_asdl_seq_new(len, arena); + args = _Py_asdl_expr_seq_new(len, arena); if (args == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -7985,7 +8030,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_seq_new(len, arena); + keywords = _Py_asdl_keyword_seq_new(len, arena); if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; @@ -8067,7 +8112,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* values; + asdl_expr_seq* values; if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) { return 1; @@ -8085,7 +8130,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - values = _Py_asdl_seq_new(len, arena); + values = _Py_asdl_expr_seq_new(len, arena); if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8341,7 +8386,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; expr_context_ty ctx; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { @@ -8360,7 +8405,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8401,7 +8446,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) return 1; } if (isinstance) { - asdl_seq* elts; + asdl_expr_seq* elts; expr_context_ty ctx; if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { @@ -8420,7 +8465,7 @@ obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena) goto failed; } len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_seq_new(len, arena); + elts = _Py_asdl_expr_seq_new(len, arena); if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8834,7 +8879,7 @@ obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty* PyObject* tmp = NULL; expr_ty target; expr_ty iter; - asdl_seq* ifs; + asdl_expr_seq* ifs; int is_async; if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { @@ -8879,7 +8924,7 @@ obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty* goto failed; } len = PyList_GET_SIZE(tmp); - ifs = _Py_asdl_seq_new(len, arena); + ifs = _Py_asdl_expr_seq_new(len, arena); if (ifs == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -8993,7 +9038,7 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* if (isinstance) { expr_ty type; identifier name; - asdl_seq* body; + asdl_stmt_seq* body; if (_PyObject_LookupAttr(obj, state->type, &tmp) < 0) { return 1; @@ -9037,7 +9082,7 @@ obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty* goto failed; } len = PyList_GET_SIZE(tmp); - body = _Py_asdl_seq_new(len, arena); + body = _Py_asdl_stmt_seq_new(len, arena); if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; @@ -9071,13 +9116,13 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, PyArena* arena) { PyObject* tmp = NULL; - asdl_seq* posonlyargs; - asdl_seq* args; + asdl_arg_seq* posonlyargs; + asdl_arg_seq* args; arg_ty vararg; - asdl_seq* kwonlyargs; - asdl_seq* kw_defaults; + asdl_arg_seq* kwonlyargs; + asdl_expr_seq* kw_defaults; arg_ty kwarg; - asdl_seq* defaults; + asdl_expr_seq* defaults; if (_PyObject_LookupAttr(obj, state->posonlyargs, &tmp) < 0) { return 1; @@ -9095,7 +9140,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - posonlyargs = _Py_asdl_seq_new(len, arena); + posonlyargs = _Py_asdl_arg_seq_new(len, arena); if (posonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9128,7 +9173,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - args = _Py_asdl_seq_new(len, arena); + args = _Py_asdl_arg_seq_new(len, arena); if (args == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9174,7 +9219,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - kwonlyargs = _Py_asdl_seq_new(len, arena); + kwonlyargs = _Py_asdl_arg_seq_new(len, arena); if (kwonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; @@ -9207,7 +9252,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - kw_defaults = _Py_asdl_seq_new(len, arena); + kw_defaults = _Py_asdl_expr_seq_new(len, arena); if (kw_defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; @@ -9253,7 +9298,7 @@ obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out, goto failed; } len = PyList_GET_SIZE(tmp); - defaults = _Py_asdl_seq_new(len, arena); + defaults = _Py_asdl_expr_seq_new(len, arena); if (defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; diff --git a/Python/asdl.c b/Python/asdl.c index c21107811813af9..4ff07e4377b18e7 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -1,64 +1,6 @@ #include "Python.h" #include "asdl.h" -asdl_seq * -_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena) -{ - asdl_seq *seq = NULL; - size_t n; - - /* check size is sane */ - if (size < 0 || - (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { - PyErr_NoMemory(); - return NULL; - } - n = (size ? (sizeof(void *) * (size - 1)) : 0); - - /* check if size can be added safely */ - if (n > SIZE_MAX - sizeof(asdl_seq)) { - PyErr_NoMemory(); - return NULL; - } - n += sizeof(asdl_seq); - - seq = (asdl_seq *)PyArena_Malloc(arena, n); - if (!seq) { - PyErr_NoMemory(); - return NULL; - } - memset(seq, 0, n); - seq->size = size; - return seq; -} - -asdl_int_seq * -_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena) -{ - asdl_int_seq *seq = NULL; - size_t n; - - /* check size is sane */ - if (size < 0 || - (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { - PyErr_NoMemory(); - return NULL; - } - n = (size ? (sizeof(void *) * (size - 1)) : 0); - - /* check if size can be added safely */ - if (n > SIZE_MAX - sizeof(asdl_seq)) { - PyErr_NoMemory(); - return NULL; - } - n += sizeof(asdl_seq); - - seq = (asdl_int_seq *)PyArena_Malloc(arena, n); - if (!seq) { - PyErr_NoMemory(); - return NULL; - } - memset(seq, 0, n); - seq->size = size; - return seq; -} +GENERATE_ASDL_SEQ_CONSTRUCTOR(generic, void*); +GENERATE_ASDL_SEQ_CONSTRUCTOR(identifier, PyObject*); +GENERATE_ASDL_SEQ_CONSTRUCTOR(int, int); diff --git a/Python/ast.c b/Python/ast.c index 7bf66e50aa14d94..4b7bbd229c99b25 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -14,9 +14,9 @@ #define MAXLEVEL 200 /* Max parentheses level */ -static int validate_stmts(asdl_seq *); -static int validate_exprs(asdl_seq *, expr_context_ty, int); -static int validate_nonempty_seq(asdl_seq *, const char *, const char *); +static int validate_stmts(asdl_stmt_seq *); +static int validate_exprs(asdl_expr_seq*, expr_context_ty, int); +static int _validate_nonempty_seq(asdl_seq *, const char *, const char *); static int validate_stmt(stmt_ty); static int validate_expr(expr_ty, expr_context_ty); @@ -40,7 +40,7 @@ validate_name(PyObject *name) } static int -validate_comprehension(asdl_seq *gens) +validate_comprehension(asdl_comprehension_seq *gens) { Py_ssize_t i; if (!asdl_seq_LEN(gens)) { @@ -58,7 +58,7 @@ validate_comprehension(asdl_seq *gens) } static int -validate_keywords(asdl_seq *keywords) +validate_keywords(asdl_keyword_seq *keywords) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(keywords); i++) @@ -68,7 +68,7 @@ validate_keywords(asdl_seq *keywords) } static int -validate_args(asdl_seq *args) +validate_args(asdl_arg_seq *args) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(args); i++) { @@ -324,23 +324,24 @@ validate_expr(expr_ty exp, expr_context_ty ctx) } static int -validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) +_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) { if (asdl_seq_LEN(seq)) return 1; PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner); return 0; } +#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner) static int -validate_assignlist(asdl_seq *targets, expr_context_ty ctx) +validate_assignlist(asdl_expr_seq *targets, expr_context_ty ctx) { return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && validate_exprs(targets, ctx, 0); } static int -validate_body(asdl_seq *body, const char *owner) +validate_body(asdl_stmt_seq *body, const char *owner) { return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); } @@ -488,7 +489,7 @@ validate_stmt(stmt_ty stmt) } static int -validate_stmts(asdl_seq *seq) +validate_stmts(asdl_stmt_seq *seq) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(seq); i++) { @@ -507,7 +508,7 @@ validate_stmts(asdl_seq *seq) } static int -validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) +validate_exprs(asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(exprs); i++) { @@ -550,7 +551,7 @@ PyAST_Validate(mod_ty mod) } PyObject * -_PyAST_GetDocString(asdl_seq *body) +_PyAST_GetDocString(asdl_stmt_seq *body) { if (!asdl_seq_LEN(body)) { return NULL; diff --git a/Python/ast_opt.c b/Python/ast_opt.c index ff786d6f8d63ef1..5efaac4c8925a98 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -271,7 +271,7 @@ fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) } static PyObject* -make_const_tuple(asdl_seq *elts) +make_const_tuple(asdl_expr_seq *elts) { for (int i = 0; i < asdl_seq_LEN(elts); i++) { expr_ty e = (expr_ty)asdl_seq_GET(elts, i); @@ -337,7 +337,7 @@ fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state) PyObject *newval; if (arg->kind == List_kind) { /* First change a list into tuple. */ - asdl_seq *elts = arg->v.List.elts; + asdl_expr_seq *elts = arg->v.List.elts; Py_ssize_t n = asdl_seq_LEN(elts); for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(elts, i); @@ -368,7 +368,7 @@ static int fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) { asdl_int_seq *ops; - asdl_seq *args; + asdl_expr_seq *args; Py_ssize_t i; ops = node->v.Compare.ops; @@ -405,9 +405,9 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOp #define CALL_SEQ(FUNC, TYPE, ARG) { \ int i; \ - asdl_seq *seq = (ARG); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (elt != NULL && !FUNC(elt, ctx_, state)) \ return 0; \ } \ @@ -424,13 +424,13 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOp } static int -astfold_body(asdl_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) +astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) { int docstring = _PyAST_GetDocString(stmts) != NULL; - CALL_SEQ(astfold_stmt, stmt_ty, stmts); + CALL_SEQ(astfold_stmt, stmt, stmts); if (!docstring && _PyAST_GetDocString(stmts) != NULL) { stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); - asdl_seq *values = _Py_asdl_seq_new(1, ctx_); + asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_); if (!values) { return 0; } @@ -453,7 +453,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL(astfold_body, asdl_seq, node_->v.Module.body); break; case Interactive_kind: - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body); break; case Expression_kind: CALL(astfold_expr, expr_ty, node_->v.Expression.body); @@ -469,7 +469,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { switch (node_->kind) { case BoolOp_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.BoolOp.values); + CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); break; case BinOp_kind: CALL(astfold_expr, expr_ty, node_->v.BinOp.left); @@ -490,28 +490,28 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse); break; case Dict_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.keys); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.values); + CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys); + CALL_SEQ(astfold_expr, expr, node_->v.Dict.values); break; case Set_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Set.elts); + CALL_SEQ(astfold_expr, expr, node_->v.Set.elts); break; case ListComp_kind: CALL(astfold_expr, expr_ty, node_->v.ListComp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.ListComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators); break; case SetComp_kind: CALL(astfold_expr, expr_ty, node_->v.SetComp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.SetComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators); break; case DictComp_kind: CALL(astfold_expr, expr_ty, node_->v.DictComp.key); CALL(astfold_expr, expr_ty, node_->v.DictComp.value); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.DictComp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators); break; case GeneratorExp_kind: CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt); - CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.GeneratorExp.generators); + CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators); break; case Await_kind: CALL(astfold_expr, expr_ty, node_->v.Await.value); @@ -524,20 +524,20 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) break; case Compare_kind: CALL(astfold_expr, expr_ty, node_->v.Compare.left); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Compare.comparators); + CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators); CALL(fold_compare, expr_ty, node_); break; case Call_kind: CALL(astfold_expr, expr_ty, node_->v.Call.func); - CALL_SEQ(astfold_expr, expr_ty, node_->v.Call.args); - CALL_SEQ(astfold_keyword, keyword_ty, node_->v.Call.keywords); + CALL_SEQ(astfold_expr, expr, node_->v.Call.args); + CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords); break; case FormattedValue_kind: CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value); CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec); break; case JoinedStr_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.JoinedStr.values); + CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values); break; case Attribute_kind: CALL(astfold_expr, expr_ty, node_->v.Attribute.value); @@ -556,10 +556,10 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step); break; case List_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts); + CALL_SEQ(astfold_expr, expr, node_->v.List.elts); break; case Tuple_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Tuple.elts); + CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts); CALL(fold_tuple, expr_ty, node_); break; case Name_kind: @@ -586,7 +586,7 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState { CALL(astfold_expr, expr_ty, node_->target); CALL(astfold_expr, expr_ty, node_->iter); - CALL_SEQ(astfold_expr, expr_ty, node_->ifs); + CALL_SEQ(astfold_expr, expr, node_->ifs); CALL(fold_iter, expr_ty, node_->iter); return 1; @@ -595,13 +595,13 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - CALL_SEQ(astfold_arg, arg_ty, node_->posonlyargs); - CALL_SEQ(astfold_arg, arg_ty, node_->args); + CALL_SEQ(astfold_arg, arg, node_->posonlyargs); + CALL_SEQ(astfold_arg, arg, node_->args); CALL_OPT(astfold_arg, arg_ty, node_->vararg); - CALL_SEQ(astfold_arg, arg_ty, node_->kwonlyargs); - CALL_SEQ(astfold_expr, expr_ty, node_->kw_defaults); + CALL_SEQ(astfold_arg, arg, node_->kwonlyargs); + CALL_SEQ(astfold_expr, expr, node_->kw_defaults); CALL_OPT(astfold_arg, arg_ty, node_->kwarg); - CALL_SEQ(astfold_expr, expr_ty, node_->defaults); + CALL_SEQ(astfold_expr, expr, node_->defaults); return 1; } @@ -621,7 +621,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case FunctionDef_kind: CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); - CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); } @@ -629,25 +629,25 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case AsyncFunctionDef_kind: CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); - CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); } break; case ClassDef_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases); - CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords); + CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases); + CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords); CALL(astfold_body, asdl_seq, node_->v.ClassDef.body); - CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list); + CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list); break; case Return_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value); break; case Delete_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Delete.targets); + CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets); break; case Assign_kind: - CALL_SEQ(astfold_expr, expr_ty, node_->v.Assign.targets); + CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets); CALL(astfold_expr, expr_ty, node_->v.Assign.value); break; case AugAssign_kind: @@ -664,44 +664,44 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case For_kind: CALL(astfold_expr, expr_ty, node_->v.For.target); CALL(astfold_expr, expr_ty, node_->v.For.iter); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.For.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse); CALL(fold_iter, expr_ty, node_->v.For.iter); break; case AsyncFor_kind: CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target); CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse); break; case While_kind: CALL(astfold_expr, expr_ty, node_->v.While.test); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.While.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse); break; case If_kind: CALL(astfold_expr, expr_ty, node_->v.If.test); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.body); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.If.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse); break; case With_kind: - CALL_SEQ(astfold_withitem, withitem_ty, node_->v.With.items); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.With.body); + CALL_SEQ(astfold_withitem, withitem, node_->v.With.items); + CALL_SEQ(astfold_stmt, stmt, node_->v.With.body); break; case AsyncWith_kind: - CALL_SEQ(astfold_withitem, withitem_ty, node_->v.AsyncWith.items); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncWith.body); + CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items); + CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body); break; case Raise_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc); CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause); break; case Try_kind: - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.body); - CALL_SEQ(astfold_excepthandler, excepthandler_ty, node_->v.Try.handlers); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.orelse); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.finalbody); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body); + CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody); break; case Assert_kind: CALL(astfold_expr, expr_ty, node_->v.Assert.test); @@ -722,7 +722,7 @@ astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState switch (node_->kind) { case ExceptHandler_kind: CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type); - CALL_SEQ(astfold_stmt, stmt_ty, node_->v.ExceptHandler.body); + CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body); break; default: break; diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index e699751a05a0559..a04ff93e9d9d902 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -117,7 +117,7 @@ static int append_ast_boolop(_PyUnicodeWriter *writer, expr_ty e, int level) { Py_ssize_t i, value_count; - asdl_seq *values; + asdl_expr_seq *values; const char *op = (e->v.BoolOp.op == And) ? " and " : " or "; int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR; @@ -398,7 +398,7 @@ append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen) } static int -append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_seq *comprehensions) +append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_comprehension_seq *comprehensions) { Py_ssize_t i, gen_count; gen_count = asdl_seq_LEN(comprehensions); @@ -453,7 +453,7 @@ append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, int level) { const char *op; Py_ssize_t i, comparator_count; - asdl_seq *comparators; + asdl_expr_seq *comparators; asdl_int_seq *ops; APPEND_STR_IF(level > PR_CMP, "("); @@ -612,7 +612,7 @@ append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) /* Build body separately to enable wrapping the entire stream of Strs, Constants and FormattedValues in one opening and one closing quote. */ static PyObject * -build_fstring_body(asdl_seq *values, bool is_format_spec) +build_fstring_body(asdl_expr_seq *values, bool is_format_spec) { Py_ssize_t i, value_count; _PyUnicodeWriter body_writer; diff --git a/Python/compile.c b/Python/compile.c index 2c5326686f8663c..3ebf221cf02b716 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -222,27 +222,27 @@ static int compiler_subscript(struct compiler *, expr_ty); static int compiler_slice(struct compiler *, expr_ty); static int inplace_binop(operator_ty); -static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t); +static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); static int expr_constant(expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_async_with(struct compiler *, stmt_ty, int); static int compiler_async_for(struct compiler *, stmt_ty); static int compiler_call_helper(struct compiler *c, int n, - asdl_seq *args, - asdl_seq *keywords); + asdl_expr_seq *args, + asdl_keyword_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); static int compiler_sync_comprehension_generator( struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); static int compiler_async_comprehension_generator( struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); @@ -1525,7 +1525,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b) #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) \ @@ -1535,7 +1535,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b) #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ int _i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ if (!compiler_visit_ ## TYPE((C), elt)) { \ @@ -1559,7 +1559,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b) /* Search if variable annotations are present statically in a block. */ static int -find_ann(asdl_seq *stmts) +find_ann(asdl_stmt_seq *stmts) { int i, j, res = 0; stmt_ty st; @@ -1778,7 +1778,7 @@ compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblock and for annotations. */ static int -compiler_body(struct compiler *c, asdl_seq *stmts) +compiler_body(struct compiler *c, asdl_stmt_seq *stmts) { int i = 0; stmt_ty st; @@ -1841,8 +1841,7 @@ compiler_mod(struct compiler *c, mod_ty mod) ADDOP(c, SETUP_ANNOTATIONS); } c->c_interactive = 1; - VISIT_SEQ_IN_SCOPE(c, stmt, - mod->v.Interactive.body); + VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); @@ -1945,7 +1944,7 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py } static int -compiler_decorators(struct compiler *c, asdl_seq* decos) +compiler_decorators(struct compiler *c, asdl_expr_seq* decos) { int i; @@ -1959,8 +1958,8 @@ compiler_decorators(struct compiler *c, asdl_seq* decos) } static int -compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, - asdl_seq *kw_defaults) +compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, + asdl_expr_seq *kw_defaults) { /* Push a dict of keyword-only default values. @@ -2047,7 +2046,7 @@ compiler_visit_argannotation(struct compiler *c, identifier id, } static int -compiler_visit_argannotations(struct compiler *c, asdl_seq* args, +compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args, PyObject *names) { int i; @@ -2173,7 +2172,7 @@ compiler_check_debug_one_arg(struct compiler *c, arg_ty arg) } static int -compiler_check_debug_args_seq(struct compiler *c, asdl_seq *args) +compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args) { if (args != NULL) { for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) { @@ -2208,8 +2207,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) arguments_ty args; expr_ty returns; identifier name; - asdl_seq* decos; - asdl_seq *body; + asdl_expr_seq* decos; + asdl_stmt_seq *body; Py_ssize_t i, funcflags; int annotations; int scope_type; @@ -2306,7 +2305,7 @@ compiler_class(struct compiler *c, stmt_ty s) PyCodeObject *co; PyObject *str; int i, firstlineno; - asdl_seq* decos = s->v.ClassDef.decorator_list; + asdl_expr_seq *decos = s->v.ClassDef.decorator_list; if (!compiler_decorators(c, decos)) return 0; @@ -2418,9 +2417,7 @@ compiler_class(struct compiler *c, stmt_ty s) ADDOP_LOAD_CONST(c, s->v.ClassDef.name); /* 5. generate the rest of the code for the call */ - if (!compiler_call_helper(c, 2, - s->v.ClassDef.bases, - s->v.ClassDef.keywords)) + if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) return 0; /* 6. apply decorators */ @@ -2528,7 +2525,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* fallback to general implementation */ break; case BoolOp_kind: { - asdl_seq *s = e->v.BoolOp.values; + asdl_expr_seq *s = e->v.BoolOp.values; Py_ssize_t i, n = asdl_seq_LEN(s) - 1; assert(n >= 0); int cond2 = e->v.BoolOp.op == Or; @@ -3645,7 +3642,7 @@ compiler_boolop(struct compiler *c, expr_ty e) basicblock *end; int jumpi; Py_ssize_t i, n; - asdl_seq *s; + asdl_expr_seq *s; assert(e->kind == BoolOp_kind); if (e->v.BoolOp.op == And) @@ -3673,7 +3670,7 @@ compiler_boolop(struct compiler *c, expr_ty e) } static int -starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed, +starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, int build, int add, int extend, int tuple) { Py_ssize_t n = asdl_seq_LEN(elts); @@ -3750,7 +3747,7 @@ starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed, } static int -assignment_helper(struct compiler *c, asdl_seq *elts) +assignment_helper(struct compiler *c, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); Py_ssize_t i; @@ -3784,7 +3781,7 @@ assignment_helper(struct compiler *c, asdl_seq *elts) static int compiler_list(struct compiler *c, expr_ty e) { - asdl_seq *elts = e->v.List.elts; + asdl_expr_seq *elts = e->v.List.elts; if (e->v.List.ctx == Store) { return assignment_helper(c, elts); } @@ -3800,7 +3797,7 @@ compiler_list(struct compiler *c, expr_ty e) static int compiler_tuple(struct compiler *c, expr_ty e) { - asdl_seq *elts = e->v.Tuple.elts; + asdl_expr_seq *elts = e->v.Tuple.elts; if (e->v.Tuple.ctx == Store) { return assignment_helper(c, elts); } @@ -3821,7 +3818,7 @@ compiler_set(struct compiler *c, expr_ty e) } static int -are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end) +are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end) { Py_ssize_t i; for (i = begin; i < end; i++) { @@ -4084,7 +4081,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) { Py_ssize_t argsl, i; expr_ty meth = e->v.Call.func; - asdl_seq *args = e->v.Call.args; + asdl_expr_seq *args = e->v.Call.args; /* Check that the call node is an attribute access, and that the call doesn't have keyword parameters. */ @@ -4110,7 +4107,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) } static int -validate_keywords(struct compiler *c, asdl_seq *keywords) +validate_keywords(struct compiler *c, asdl_keyword_seq *keywords) { Py_ssize_t nkeywords = asdl_seq_LEN(keywords); for (Py_ssize_t i = 0; i < nkeywords; i++) { @@ -4210,7 +4207,7 @@ compiler_formatted_value(struct compiler *c, expr_ty e) } static int -compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end) { Py_ssize_t i, n = end - begin; keyword_ty kw; @@ -4249,8 +4246,8 @@ compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ static int compiler_call_helper(struct compiler *c, int n, /* Args already pushed */ - asdl_seq *args, - asdl_seq *keywords) + asdl_expr_seq *args, + asdl_keyword_seq *keywords) { Py_ssize_t i, nseen, nelts, nkwelts; @@ -4375,7 +4372,7 @@ compiler_call_helper(struct compiler *c, static int compiler_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4392,7 +4389,7 @@ compiler_comprehension_generator(struct compiler *c, static int compiler_sync_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4424,7 +4421,7 @@ compiler_sync_comprehension_generator(struct compiler *c, /* Fast path for the temporary variable assignment idiom: for y in [f(x)] */ - asdl_seq *elts; + asdl_expr_seq *elts; switch (gen->iter->kind) { case List_kind: elts = gen->iter->v.List.elts; @@ -4511,7 +4508,7 @@ compiler_sync_comprehension_generator(struct compiler *c, static int compiler_async_comprehension_generator(struct compiler *c, - asdl_seq *generators, int gen_index, + asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) { @@ -4602,7 +4599,7 @@ compiler_async_comprehension_generator(struct compiler *c, static int compiler_comprehension(struct compiler *c, expr_ty e, int type, - identifier name, asdl_seq *generators, expr_ty elt, + identifier name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty val) { PyCodeObject *co = NULL; @@ -5226,7 +5223,7 @@ check_ann_subscr(struct compiler *c, expr_ty e) return 1; case Tuple_kind: { /* extended slice */ - asdl_seq *elts = e->v.Tuple.elts; + asdl_expr_seq *elts = e->v.Tuple.elts; Py_ssize_t i, n = asdl_seq_LEN(elts); for (i = 0; i < n; i++) { if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) { diff --git a/Python/future.c b/Python/future.c index 56da4d8c798b867..3cea4fee78085c7 100644 --- a/Python/future.c +++ b/Python/future.c @@ -13,11 +13,10 @@ static int future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) { int i; - asdl_seq *names; assert(s->kind == ImportFrom_kind); - names = s->v.ImportFrom.names; + asdl_alias_seq *names = s->v.ImportFrom.names; for (i = 0; i < asdl_seq_LEN(names); i++) { alias_ty name = (alias_ty)asdl_seq_GET(names, i); const char *feature = PyUnicode_AsUTF8(name->name); diff --git a/Python/symtable.c b/Python/symtable.c index d192f31deefb77a..4a98e79e74a250c 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -202,8 +202,8 @@ static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty); static int symtable_visit_alias(struct symtable *st, alias_ty); static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); static int symtable_visit_keyword(struct symtable *st, keyword_ty); -static int symtable_visit_params(struct symtable *st, asdl_seq *args); -static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args); +static int symtable_visit_params(struct symtable *st, asdl_arg_seq *args); +static int symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args); static int symtable_implicit_arg(struct symtable *st, int pos); static int symtable_visit_annotations(struct symtable *st, arguments_ty, expr_ty); static int symtable_visit_withitem(struct symtable *st, withitem_ty item); @@ -261,7 +261,7 @@ struct symtable * PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) { struct symtable *st = symtable_new(); - asdl_seq *seq; + asdl_stmt_seq *seq; int i; PyThreadState *tstate; int recursion_limit = Py_GetRecursionLimit(); @@ -1116,7 +1116,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ(ST, TYPE, SEQ) { \ int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (!symtable_visit_ ## TYPE((ST), elt)) \ @@ -1126,7 +1126,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \ int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (i = (START); i < asdl_seq_LEN(seq); i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (!symtable_visit_ ## TYPE((ST), elt)) \ @@ -1136,7 +1136,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { #define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \ int i = 0; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (!elt) continue; /* can be NULL */ \ @@ -1318,7 +1318,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case Global_kind: { int i; - asdl_seq *seq = s->v.Global.names; + asdl_identifier_seq *seq = s->v.Global.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); long cur = symtable_lookup(st, name); @@ -1351,7 +1351,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } case Nonlocal_kind: { int i; - asdl_seq *seq = s->v.Nonlocal.names; + asdl_identifier_seq *seq = s->v.Nonlocal.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); long cur = symtable_lookup(st, name); @@ -1683,7 +1683,7 @@ symtable_implicit_arg(struct symtable *st, int pos) } static int -symtable_visit_params(struct symtable *st, asdl_seq *args) +symtable_visit_params(struct symtable *st, asdl_arg_seq *args) { int i; @@ -1700,7 +1700,7 @@ symtable_visit_params(struct symtable *st, asdl_seq *args) } static int -symtable_visit_argannotations(struct symtable *st, asdl_seq *args) +symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args) { int i; @@ -1850,7 +1850,7 @@ symtable_visit_keyword(struct symtable *st, keyword_ty k) static int symtable_handle_comprehension(struct symtable *st, expr_ty e, - identifier scope_name, asdl_seq *generators, + identifier scope_name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty value) { int is_generator = (e->kind == GeneratorExp_kind); diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index aee668c3f329aba..1a814aad11cccdf 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -74,6 +74,7 @@ class FunctionCall: function: str arguments: List[Any] = field(default_factory=list) assigned_variable: Optional[str] = None + assigned_variable_type: Optional[str] = None return_type: Optional[str] = None nodetype: Optional[NodeTypes] = None force_true: bool = False @@ -87,7 +88,10 @@ def __str__(self) -> str: if self.force_true: parts.append(", 1") if self.assigned_variable: - parts = ["(", self.assigned_variable, " = ", *parts, ")"] + if self.assigned_variable_type: + parts = ["(", self.assigned_variable, " = ", '(', self.assigned_variable_type, ')', *parts, ")"] + else: + parts = ["(", self.assigned_variable, " = ", *parts, ")"] if self.comment: parts.append(f" // {self.comment}") return "".join(parts) @@ -210,6 +214,8 @@ def visit_NamedItem(self, node: NamedItem) -> FunctionCall: call = self.generate_call(node.item) if node.name: call.assigned_variable = node.name + if node.type: + call.assigned_variable_type = node.type return call def lookahead_call_helper(self, node: Lookahead, positive: int) -> FunctionCall: @@ -568,9 +574,9 @@ def _handle_loop_rule_body(self, node: Rule, rhs: Rhs) -> None: self.print("PyMem_Free(_children);") self.add_return("NULL") self.print("}") - self.print("asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena);") + self.print("asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);") self.out_of_memory_return(f"!_seq", cleanup_code="PyMem_Free(_children);") - self.print("for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]);") + self.print("for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);") self.print("PyMem_Free(_children);") if node.name: self.print(f"_PyPegen_insert_memo(p, _start_mark, {node.name}_type, _seq);") @@ -782,4 +788,5 @@ def add_var(self, node: NamedItem) -> Tuple[Optional[str], Optional[str]]: name = node.name if node.name else call.assigned_variable if name is not None: name = self.dedupe(name) - return name, call.return_type + return_type = call.return_type if node.type is None else node.type + return name, return_type diff --git a/Tools/peg_generator/pegen/grammar.py b/Tools/peg_generator/pegen/grammar.py index 78edf412ea6e473..332ee3c3eec5e23 100644 --- a/Tools/peg_generator/pegen/grammar.py +++ b/Tools/peg_generator/pegen/grammar.py @@ -259,9 +259,10 @@ def collect_todo(self, gen: ParserGenerator) -> None: class NamedItem: - def __init__(self, name: Optional[str], item: Item): + def __init__(self, name: Optional[str], item: Item, type: Optional[str] = None): self.name = name self.item = item + self.type = type self.nullable = False def __str__(self) -> str: diff --git a/Tools/peg_generator/pegen/grammar_parser.py b/Tools/peg_generator/pegen/grammar_parser.py index c784cfdf3b26673..6e3bc5068f5a763 100644 --- a/Tools/peg_generator/pegen/grammar_parser.py +++ b/Tools/peg_generator/pegen/grammar_parser.py @@ -402,9 +402,49 @@ def items(self) -> Optional[NamedItemList]: @memoize def named_item(self) -> Optional[NamedItem]: - # named_item: NAME '=' ~ item | item | lookahead + # named_item: NAME '[' NAME '*' ']' '=' ~ item | NAME '[' NAME ']' '=' ~ item | NAME '=' ~ item | item | lookahead mark = self.mark() cut = False + if ( + (name := self.name()) + and + (literal := self.expect('[')) + and + (type := self.name()) + and + (literal_1 := self.expect('*')) + and + (literal_2 := self.expect(']')) + and + (literal_3 := self.expect('=')) + and + (cut := True) + and + (item := self.item()) + ): + return NamedItem ( name . string , item , f"{type.string}*" ) + self.reset(mark) + if cut: return None + cut = False + if ( + (name := self.name()) + and + (literal := self.expect('[')) + and + (type := self.name()) + and + (literal_1 := self.expect(']')) + and + (literal_2 := self.expect('=')) + and + (cut := True) + and + (item := self.item()) + ): + return NamedItem ( name . string , item , type . string ) + self.reset(mark) + if cut: return None + cut = False if ( (name := self.name()) and diff --git a/Tools/peg_generator/pegen/metagrammar.gram b/Tools/peg_generator/pegen/metagrammar.gram index f0c5ac3ab390fb8..4802f56b68f7b6d 100644 --- a/Tools/peg_generator/pegen/metagrammar.gram +++ b/Tools/peg_generator/pegen/metagrammar.gram @@ -83,6 +83,8 @@ items[NamedItemList]: | named_item { [named_item] } named_item[NamedItem]: + | NAME '[' type=NAME '*' ']' '=' ~ item {NamedItem(name.string, item, f"{type.string}*")} + | NAME '[' type=NAME ']' '=' ~ item {NamedItem(name.string, item, type.string)} | NAME '=' ~ item {NamedItem(name.string, item)} | item {NamedItem(None, item)} | it=lookahead {NamedItem(None, it)} From 30a7ad0ea871c40cd2d2a58da8e67fad8f453414 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 16 Sep 2020 12:37:54 -0700 Subject: [PATCH 316/486] _auto_called cleanup (GH-22285) --- Lib/enum.py | 2 +- Lib/test/test_enum.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/enum.py b/Lib/enum.py index 060b2a0dadf4576..21a94caaee33f34 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -105,9 +105,9 @@ def __setitem__(self, key, value): # enum overwriting a descriptor? raise TypeError('%r already defined as: %r' % (key, self[key])) if isinstance(value, auto): - self._auto_called = True if value.value == _auto_null: value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:]) + self._auto_called = True value = value.value self._member_names.append(key) self._last_values.append(value) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 5d72d82cec27ffe..ebf76047972dc0b 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1837,6 +1837,17 @@ class Color(Enum): def _generate_next_value_(name, start, count, last): return name + def test_auto_order_wierd(self): + weird_auto = auto() + weird_auto.value = 'pathological case' + class Color(Enum): + red = weird_auto + def _generate_next_value_(name, start, count, last): + return name + blue = auto() + self.assertEqual(list(Color), [Color.red, Color.blue]) + self.assertEqual(Color.red.value, 'pathological case') + self.assertEqual(Color.blue.value, 'blue') def test_duplicate_auto(self): class Dupes(Enum): From a940338a4cbe59aae5519c8afced7aa691961e18 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Wed, 16 Sep 2020 13:01:00 -0700 Subject: [PATCH 317/486] Enum: make `Flag` and `IntFlag` members iterable (GH-22221) --- Doc/library/enum.rst | 15 +++++++++++++++ Lib/enum.py | 4 ++++ Lib/test/test_enum.py | 12 ++++++++++++ .../2020-09-12-16-18-42.bpo-32218.IpYkEe.rst | 1 + 4 files changed, 32 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 32e8bbf95092733..2f84be229bc4da6 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -656,6 +656,13 @@ be combined with them:: >>> Perm.X | 8 +:class:`IntFlag` members can also be iterated over:: + + >>> list(RW) + [, ] + +.. versionadded:: 3.10 + Flag ^^^^ @@ -709,6 +716,14 @@ value:: >>> bool(Color.BLACK) False +:class:`Flag` members can also be iterated over:: + + >>> purple = Color.RED | Color.BLUE + >>> list(purple) + [, ] + +.. versionadded:: 3.10 + .. note:: For the majority of new code, :class:`Enum` and :class:`Flag` are strongly diff --git a/Lib/enum.py b/Lib/enum.py index 21a94caaee33f34..3c459ea4113d0b5 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -753,6 +753,10 @@ def __contains__(self, other): type(other).__qualname__, self.__class__.__qualname__)) return other._value_ & self._value_ == other._value_ + def __iter__(self): + members, extra_flags = _decompose(self.__class__, self.value) + return (m for m in members if m._value_ != 0) + def __repr__(self): cls = self.__class__ if self._name_ is not None: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index ebf76047972dc0b..59789fb7bcc5fde 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2350,6 +2350,12 @@ def test_member_contains(self): self.assertFalse(W in RX) self.assertFalse(X in RW) + def test_member_iter(self): + Color = self.Color + self.assertEqual(list(Color.PURPLE), [Color.BLUE, Color.RED]) + self.assertEqual(list(Color.BLUE), [Color.BLUE]) + self.assertEqual(list(Color.GREEN), [Color.GREEN]) + def test_auto_number(self): class Color(Flag): red = auto() @@ -2805,6 +2811,12 @@ def test_member_contains(self): with self.assertRaises(TypeError): self.assertFalse('test' in RW) + def test_member_iter(self): + Color = self.Color + self.assertEqual(list(Color.PURPLE), [Color.BLUE, Color.RED]) + self.assertEqual(list(Color.BLUE), [Color.BLUE]) + self.assertEqual(list(Color.GREEN), [Color.GREEN]) + def test_bool(self): Perm = self.Perm for f in Perm: diff --git a/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst b/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst new file mode 100644 index 000000000000000..d5832b9767b7041 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst @@ -0,0 +1 @@ +`enum.Flag` and `enum.IntFlag` members are now iterable From a9e409158d9ad4e16997ad9ebbdc958d374fd462 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 17 Sep 2020 10:34:20 +0300 Subject: [PATCH 318/486] bpo-41715: Fix potential catastrofic backtracking in c_analyzer. (GH-22091) --- Tools/c-analyzer/c_analyzer/common/info.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tools/c-analyzer/c_analyzer/common/info.py b/Tools/c-analyzer/c_analyzer/common/info.py index 3f3f8c5b05de594..1a853a42ff2a2cf 100644 --- a/Tools/c-analyzer/c_analyzer/common/info.py +++ b/Tools/c-analyzer/c_analyzer/common/info.py @@ -9,7 +9,8 @@ UNKNOWN = '???' -NAME_RE = re.compile(r'^([a-zA-Z]|_\w*[a-zA-Z]\w*|[a-zA-Z]\w*)$') +# Does not start with digit and contains at least one letter. +NAME_RE = re.compile(r'(?!\d)(?=.*?[A-Za-z])\w+', re.ASCII) class ID(_NTBase, namedtuple('ID', 'filename funcname name')): @@ -50,17 +51,16 @@ def validate(self): """Fail if the object is invalid (i.e. init with bad data).""" if not self.name: raise TypeError('missing name') - else: - if not NAME_RE.match(self.name): - raise ValueError( - f'name must be an identifier, got {self.name!r}') + if not NAME_RE.fullmatch(self.name): + raise ValueError( + f'name must be an identifier, got {self.name!r}') # Symbols from a binary might not have filename/funcname info. if self.funcname: if not self.filename: raise TypeError('missing filename') - if not NAME_RE.match(self.funcname) and self.funcname != UNKNOWN: + if not NAME_RE.fullmatch(self.funcname) and self.funcname != UNKNOWN: raise ValueError( f'name must be an identifier, got {self.funcname!r}') From ca503b47eb534e8c178b3f97f9c0786d66dad365 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 17 Sep 2020 10:35:44 +0300 Subject: [PATCH 319/486] bpo-41662: Fix bugs in binding parameters in sqlite3 (GH-21998) * When the parameters argument is a list, correctly handle the case of changing it during iteration. * When the parameters argument is a custom sequence, no longer override an exception raised in ``__len__()``. --- Lib/sqlite3/test/dbapi.py | 14 +++++++++++++- Lib/sqlite3/test/regression.py | 13 +++++++++++++ .../2020-08-29-16-07-36.bpo-41662.Mn79zh.rst | 1 + .../2020-08-30-21-38-57.bpo-41662.6e9iZn.rst | 2 ++ Modules/_sqlite/statement.c | 7 +++++-- 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst create mode 100644 Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index a8dfeb9b2d69330..7867bf361e5ac6f 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -270,7 +270,7 @@ def CheckExecuteParamList(self): self.assertEqual(row[0], "foo") def CheckExecuteParamSequence(self): - class L(object): + class L: def __len__(self): return 1 def __getitem__(self, x): @@ -282,6 +282,18 @@ def __getitem__(self, x): row = self.cu.fetchone() self.assertEqual(row[0], "foo") + def CheckExecuteParamSequenceBadLen(self): + # Issue41662: Error in __len__() was overridden with ProgrammingError. + class L: + def __len__(self): + 1/0 + def __getitem__(slf, x): + raise AssertionError + + self.cu.execute("insert into test(name) values ('foo')") + with self.assertRaises(ZeroDivisionError): + self.cu.execute("select name from test where name=?", L()) + def CheckExecuteDictMapping(self): self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("select name from test where name=:name", {"name": "foo"}) diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 0735a5c129226d9..67557e19c796bb5 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -132,6 +132,19 @@ def CheckTypeMapUsage(self): con.execute("insert into foo(bar) values (5)") con.execute(SELECT) + def CheckBindMutatingList(self): + # Issue41662: Crash when mutate a list of parameters during iteration. + class X: + def __conform__(self, protocol): + parameters.clear() + return "..." + parameters = [X(), 0] + con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) + con.execute("create table foo(bar X, baz integer)") + # Should not crash + with self.assertRaises(IndexError): + con.execute("insert into foo(bar, baz) values (?, ?)", parameters) + def CheckErrorMsgDecodeError(self): # When porting the module to Python 3.0, the error message about # decoding errors disappeared. This verifies they're back again. diff --git a/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst b/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst new file mode 100644 index 000000000000000..0571c2d110beebf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst @@ -0,0 +1 @@ +Fixed crash when mutate list of parameters during iteration in :mod:`sqlite3`. diff --git a/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst b/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst new file mode 100644 index 000000000000000..aecb0a1ea4d08f8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst @@ -0,0 +1,2 @@ +No longer override exceptions raised in ``__len__()`` of a sequence of +parameters in :mod:`sqlite3` with :exc:`~sqlite3.ProgrammingError`. diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 26599b423eb8b91..02e47a02b718ccc 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -227,6 +227,9 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para num_params = PyList_GET_SIZE(parameters); } else { num_params = PySequence_Size(parameters); + if (num_params == -1) { + return; + } } if (num_params != num_params_needed) { PyErr_Format(pysqlite_ProgrammingError, @@ -238,9 +241,9 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para for (i = 0; i < num_params; i++) { if (PyTuple_CheckExact(parameters)) { current_param = PyTuple_GET_ITEM(parameters, i); - Py_XINCREF(current_param); + Py_INCREF(current_param); } else if (PyList_CheckExact(parameters)) { - current_param = PyList_GET_ITEM(parameters, i); + current_param = PyList_GetItem(parameters, i); Py_XINCREF(current_param); } else { current_param = PySequence_GetItem(parameters, i); From fac27867286b060bce9e7a96d55a4c5c54e7fb8b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 17 Sep 2020 11:49:01 +0300 Subject: [PATCH 320/486] bpo-27032, bpo-37328: Document removing HTMLParser.unescape(). (GH-22288) --- Doc/whatsnew/3.9.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index be7406e13c2cd44..e1ea799b76296da 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -887,6 +887,12 @@ Removed :func:`asyncio.current_task` and :func:`asyncio.all_tasks` instead. (Contributed by Rémi Lapeyre in :issue:`40967`) +* The ``unescape()`` method in the :class:`html.parser.HTMLParser` class + has been removed (it was deprecated since Python 3.4). :func:`html.unescape` + should be used for converting character references to the corresponding + unicode characters. + + Porting to Python 3.9 ===================== From 9bc2dd5466f0a47b1425d7211fe16478d38add98 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 17 Sep 2020 21:56:58 -0400 Subject: [PATCH 321/486] bpo-41808: Add What's New 3.9 entry missing from master (#22294) Entry was added by bpo-40939, #21012 and #21039. --- Doc/whatsnew/3.9.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e1ea799b76296da..b3cc84d07f38d5a 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -708,6 +708,11 @@ Deprecated users can leverage the Abstract Syntax Tree (AST) generation and compilation stage, using the :mod:`ast` module. +* The Public C API functions :c:func:`PyParser_SimpleParseStringFlags`, + :c:func:`PyParser_SimpleParseStringFlagsFilename`, + :c:func:`PyParser_SimpleParseFileFlags` and :c:func:`PyNode_Compile` + are deprecated and will be removed in Python 3.10 together with the old parser. + * Using :data:`NotImplemented` in a boolean context has been deprecated, as it is almost exclusively the result of incorrect rich comparator implementations. It will be made a :exc:`TypeError` in a future version From eec03d1b42dfdacc28afc92261a43db0cc6bb2e6 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 18 Sep 2020 09:54:42 +0300 Subject: [PATCH 322/486] Remove duplicated words words (GH-22298) --- Doc/library/tkinter.font.rst | 4 ++-- Doc/whatsnew/3.9.rst | 2 +- .../next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst | 2 +- .../next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/tkinter.font.rst b/Doc/library/tkinter.font.rst index 30c1e7b5f9eb434..b0f4505e9e3c692 100644 --- a/Doc/library/tkinter.font.rst +++ b/Doc/library/tkinter.font.rst @@ -38,8 +38,8 @@ The different font weights and slants are: | *family* - font family i.e. Courier, Times | *size* - font size | If *size* is positive it is interpreted as size in points. - | If *size* is a negative number its absolute value is treated as - as size in pixels. + | If *size* is a negative number its absolute value is treated + | as size in pixels. | *weight* - font emphasis (NORMAL, BOLD) | *slant* - ROMAN, ITALIC | *underline* - font underlining (0 - none, 1 - underline) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index b3cc84d07f38d5a..e9fc496e47e24e2 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -887,7 +887,7 @@ Removed deprecated since 2006, and only returning ``False`` when it's called. (Contributed by Batuhan Taskaya in :issue:`40208`) -* The :meth:`asyncio.Task.current_task` and :meth:`asyncio.Task.all_tasks` have +* The :meth:`asyncio.Task.current_task` and :meth:`asyncio.Task.all_tasks` have been removed. They were deprecated since Python 3.7 and you can use :func:`asyncio.current_task` and :func:`asyncio.all_tasks` instead. (Contributed by Rémi Lapeyre in :issue:`40967`) diff --git a/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst b/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst index 6375276602e4a3c..af284b06eaed6e3 100644 --- a/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst +++ b/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst @@ -1,2 +1,2 @@ -Fix reference leak in the :mod:`select` module when the the module is +Fix reference leak in the :mod:`select` module when the module is imported in a subinterpreter. diff --git a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst index 532b809b77eed3d..c64a86295d7700e 100644 --- a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst +++ b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst @@ -1,2 +1,2 @@ Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). -from from emitting each warning three times. +from emitting each warning three times. From 7324b092a1479d49a74e04a00a2b6af2b5d837e1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 18 Sep 2020 09:10:15 +0200 Subject: [PATCH 323/486] bpo-41762: Fix usage of productionlist markup in the doc (GH-22281) Use an unique identifier for the different grammars documented using the Sphinx productionlist markup. productionlist markups of the same grammar, like "expressions" or "compound statements", use the same identifier "python-grammar". --- Doc/library/functions.rst | 2 +- Doc/library/string.rst | 4 +- Doc/reference/compound_stmts.rst | 23 ++++++------ Doc/reference/expressions.rst | 54 +++++++++++++-------------- Doc/reference/introduction.rst | 2 +- Doc/reference/lexical_analysis.rst | 14 +++---- Doc/reference/simple_stmts.rst | 34 ++++++++--------- Doc/reference/toplevel_components.rst | 6 +-- 8 files changed, 70 insertions(+), 69 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d381d43d8e99c35..7543fc4b10d4666 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -596,7 +596,7 @@ are always available. They are listed here in alphabetical order. input must conform to the following grammar after leading and trailing whitespace characters are removed: - .. productionlist:: + .. productionlist:: float sign: "+" | "-" infinity: "Infinity" | "inf" nan: "nan" diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 62e86d6dd97066c..91f43e9353d915c 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -205,7 +205,7 @@ literal text, it can be escaped by doubling: ``{{`` and ``}}``. The grammar for a replacement field is as follows: - .. productionlist:: sf + .. productionlist:: format-string replacement_field: "{" [`field_name`] ["!" `conversion`] [":" `format_spec`] "}" field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")* arg_name: [`identifier` | `digit`+] @@ -308,7 +308,7 @@ non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: -.. productionlist:: +.. productionlist:: format-spec format_spec: [[`fill`]`align`][`sign`][#][0][`width`][`grouping_option`][.`precision`][`type`] fill: align: "<" | ">" | "=" | "^" diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index df720f6cc32380c..158d6a8f164e23c 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -44,7 +44,8 @@ executed:: Summarizing: -.. productionlist:: + +.. productionlist:: python-grammar compound_stmt: `if_stmt` : | `while_stmt` : | `for_stmt` @@ -89,7 +90,7 @@ The :keyword:`!if` statement The :keyword:`if` statement is used for conditional execution: -.. productionlist:: +.. productionlist:: python-grammar if_stmt: "if" `assignment_expression` ":" `suite` : ("elif" `assignment_expression` ":" `suite`)* : ["else" ":" `suite`] @@ -115,7 +116,7 @@ The :keyword:`!while` statement The :keyword:`while` statement is used for repeated execution as long as an expression is true: -.. productionlist:: +.. productionlist:: python-grammar while_stmt: "while" `assignment_expression` ":" `suite` : ["else" ":" `suite`] @@ -151,7 +152,7 @@ The :keyword:`!for` statement The :keyword:`for` statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object: -.. productionlist:: +.. productionlist:: python-grammar for_stmt: "for" `target_list` "in" `expression_list` ":" `suite` : ["else" ":" `suite`] @@ -234,7 +235,7 @@ The :keyword:`!try` statement The :keyword:`try` statement specifies exception handlers and/or cleanup code for a group of statements: -.. productionlist:: +.. productionlist:: python-grammar try_stmt: `try1_stmt` | `try2_stmt` try1_stmt: "try" ":" `suite` : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ @@ -390,7 +391,7 @@ methods defined by a context manager (see section :ref:`context-managers`). This allows common :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` usage patterns to be encapsulated for convenient reuse. -.. productionlist:: +.. productionlist:: python-grammar with_stmt: "with" `with_item` ("," `with_item`)* ":" `suite` with_item: `expression` ["as" `target`] @@ -503,7 +504,7 @@ Function definitions A function definition defines a user-defined function object (see section :ref:`types`): -.. productionlist:: +.. productionlist:: python-grammar funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")" : ["->" `expression`] ":" `suite` decorators: `decorator`+ @@ -670,7 +671,7 @@ Class definitions A class definition defines a class object (see section :ref:`types`): -.. productionlist:: +.. productionlist:: python-grammar classdef: [`decorators`] "class" `classname` [`inheritance`] ":" `suite` inheritance: "(" [`argument_list`] ")" classname: `identifier` @@ -762,7 +763,7 @@ Coroutines Coroutine function definition ----------------------------- -.. productionlist:: +.. productionlist:: python-grammar async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" : ["->" `expression`] ":" `suite` @@ -795,7 +796,7 @@ An example of a coroutine function:: The :keyword:`!async for` statement ----------------------------------- -.. productionlist:: +.. productionlist:: python-grammar async_for_stmt: "async" `for_stmt` An :term:`asynchronous iterable` is able to call asynchronous code in its @@ -840,7 +841,7 @@ body of a coroutine function. The :keyword:`!async with` statement ------------------------------------ -.. productionlist:: +.. productionlist:: python-grammar async_with_stmt: "async" `with_stmt` An :term:`asynchronous context manager` is a :term:`context manager` that is diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 18abce3c510bdb8..b68c29860cf3329 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -13,7 +13,7 @@ This chapter explains the meaning of the elements of expressions in Python. be used to describe syntax, not lexical analysis. When (one alternative of) a syntax rule has the form -.. productionlist:: * +.. productionlist:: python-grammar name: `othername` and no semantics are given, the semantics of this form of ``name`` are the same @@ -54,7 +54,7 @@ Atoms are the most basic elements of expressions. The simplest atoms are identifiers or literals. Forms enclosed in parentheses, brackets or braces are also categorized syntactically as atoms. The syntax for atoms is: -.. productionlist:: +.. productionlist:: python-grammar atom: `identifier` | `literal` | `enclosure` enclosure: `parenth_form` | `list_display` | `dict_display` | `set_display` : | `generator_expression` | `yield_atom` @@ -103,7 +103,7 @@ Literals Python supports string and bytes literals and various numeric literals: -.. productionlist:: +.. productionlist:: python-grammar literal: `stringliteral` | `bytesliteral` : | `integer` | `floatnumber` | `imagnumber` @@ -134,7 +134,7 @@ Parenthesized forms A parenthesized form is an optional expression list enclosed in parentheses: -.. productionlist:: +.. productionlist:: python-grammar parenth_form: "(" [`starred_expression`] ")" A parenthesized expression list yields whatever that expression list yields: if @@ -177,7 +177,7 @@ called "displays", each of them in two flavors: Common syntax elements for comprehensions are: -.. productionlist:: +.. productionlist:: python-grammar comprehension: `assignment_expression` `comp_for` comp_for: ["async"] "for" `target_list` "in" `or_test` [`comp_iter`] comp_iter: `comp_for` | `comp_if` @@ -243,7 +243,7 @@ List displays A list display is a possibly empty series of expressions enclosed in square brackets: -.. productionlist:: +.. productionlist:: python-grammar list_display: "[" [`starred_list` | `comprehension`] "]" A list display yields a new list object, the contents being specified by either @@ -267,7 +267,7 @@ Set displays A set display is denoted by curly braces and distinguishable from dictionary displays by the lack of colons separating keys and values: -.. productionlist:: +.. productionlist:: python-grammar set_display: "{" (`starred_list` | `comprehension`) "}" A set display yields a new mutable set object, the contents being specified by @@ -296,7 +296,7 @@ Dictionary displays A dictionary display is a possibly empty series of key/datum pairs enclosed in curly braces: -.. productionlist:: +.. productionlist:: python-grammar dict_display: "{" [`key_datum_list` | `dict_comprehension`] "}" key_datum_list: `key_datum` ("," `key_datum`)* [","] key_datum: `expression` ":" `expression` | "**" `or_expr` @@ -355,7 +355,7 @@ Generator expressions A generator expression is a compact generator notation in parentheses: -.. productionlist:: +.. productionlist:: python-grammar generator_expression: "(" `expression` `comp_for` ")" A generator expression yields a new generator object. Its syntax is the same as @@ -409,7 +409,7 @@ Yield expressions pair: yield; expression pair: generator; function -.. productionlist:: +.. productionlist:: python-grammar yield_atom: "(" `yield_expression` ")" yield_expression: "yield" [`expression_list` | "from" `expression`] @@ -746,7 +746,7 @@ Primaries Primaries represent the most tightly bound operations of the language. Their syntax is: -.. productionlist:: +.. productionlist:: python-grammar primary: `atom` | `attributeref` | `subscription` | `slicing` | `call` @@ -761,7 +761,7 @@ Attribute references An attribute reference is a primary followed by a period and a name: -.. productionlist:: +.. productionlist:: python-grammar attributeref: `primary` "." `identifier` .. index:: @@ -799,7 +799,7 @@ Subscriptions A subscription selects an item of a sequence (string, tuple or list) or mapping (dictionary) object: -.. productionlist:: +.. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" The primary must evaluate to an object that supports subscription (lists or @@ -855,7 +855,7 @@ A slicing selects a range of items in a sequence object (e.g., a string, tuple or list). Slicings may be used as expressions or as targets in assignment or :keyword:`del` statements. The syntax for a slicing: -.. productionlist:: +.. productionlist:: python-grammar slicing: `primary` "[" `slice_list` "]" slice_list: `slice_item` ("," `slice_item`)* [","] slice_item: `expression` | `proper_slice` @@ -905,7 +905,7 @@ Calls A call calls a callable object (e.g., a :term:`function`) with a possibly empty series of :term:`arguments `: -.. productionlist:: +.. productionlist:: python-grammar call: `primary` "(" [`argument_list` [","] | `comprehension`] ")" argument_list: `positional_arguments` ["," `starred_and_keywords`] : ["," `keywords_arguments`] @@ -1088,7 +1088,7 @@ Await expression Suspend the execution of :term:`coroutine` on an :term:`awaitable` object. Can only be used inside a :term:`coroutine function`. -.. productionlist:: +.. productionlist:: python-grammar await_expr: "await" `primary` .. versionadded:: 3.5 @@ -1106,7 +1106,7 @@ The power operator The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is: -.. productionlist:: +.. productionlist:: python-grammar power: (`await_expr` | `primary`) ["**" `u_expr`] Thus, in an unparenthesized sequence of power and unary operators, the operators @@ -1139,7 +1139,7 @@ Unary arithmetic and bitwise operations All unary arithmetic and bitwise operations have the same priority: -.. productionlist:: +.. productionlist:: python-grammar u_expr: `power` | "-" `u_expr` | "+" `u_expr` | "~" `u_expr` .. index:: @@ -1183,7 +1183,7 @@ that some of these operations also apply to certain non-numeric types. Apart from the power operator, there are only two levels, one for multiplicative operators and one for additive operators: -.. productionlist:: +.. productionlist:: python-grammar m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` | : `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr` | : `m_expr` "%" `u_expr` @@ -1279,7 +1279,7 @@ Shifting operations The shifting operations have lower priority than the arithmetic operations: -.. productionlist:: +.. productionlist:: python-grammar shift_expr: `a_expr` | `shift_expr` ("<<" | ">>") `a_expr` These operators accept integers as arguments. They shift the first argument to @@ -1300,7 +1300,7 @@ Binary bitwise operations Each of the three bitwise operations has a different priority level: -.. productionlist:: +.. productionlist:: python-grammar and_expr: `shift_expr` | `and_expr` "&" `shift_expr` xor_expr: `and_expr` | `xor_expr` "^" `and_expr` or_expr: `xor_expr` | `or_expr` "|" `xor_expr` @@ -1349,7 +1349,7 @@ lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like ``a < b < c`` have the interpretation that is conventional in mathematics: -.. productionlist:: +.. productionlist:: python-grammar comparison: `or_expr` (`comp_operator` `or_expr`)* comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" : | "is" ["not"] | ["not"] "in" @@ -1608,7 +1608,7 @@ Boolean operations pair: Conditional; expression pair: Boolean; operation -.. productionlist:: +.. productionlist:: python-grammar or_test: `and_test` | `or_test` "or" `and_test` and_test: `not_test` | `and_test` "and" `not_test` not_test: `comparison` | "not" `not_test` @@ -1647,7 +1647,7 @@ returns a boolean value regardless of the type of its argument Assignment expressions ====================== -.. productionlist:: +.. productionlist:: python-grammar assignment_expression: [`identifier` ":="] `expression` An assignment expression (sometimes also called a "named expression" or @@ -1683,7 +1683,7 @@ Conditional expressions single: if; conditional expression single: else; conditional expression -.. productionlist:: +.. productionlist:: python-grammar conditional_expression: `or_test` ["if" `or_test` "else" `expression`] expression: `conditional_expression` | `lambda_expr` expression_nocond: `or_test` | `lambda_expr_nocond` @@ -1710,7 +1710,7 @@ Lambdas pair: anonymous; function single: : (colon); lambda expression -.. productionlist:: +.. productionlist:: python-grammar lambda_expr: "lambda" [`parameter_list`] ":" `expression` lambda_expr_nocond: "lambda" [`parameter_list`] ":" `expression_nocond` @@ -1737,7 +1737,7 @@ Expression lists pair: expression; list single: , (comma); expression list -.. productionlist:: +.. productionlist:: python-grammar expression_list: `expression` ("," `expression`)* [","] starred_list: `starred_item` ("," `starred_item`)* [","] starred_expression: `expression` | (`starred_item` ",")* [`starred_item`] diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 62480bd7dd9a614..72e874ee98e4660 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -93,7 +93,7 @@ Notation The descriptions of lexical analysis and syntax use a modified BNF grammar notation. This uses the following style of definition: -.. productionlist:: +.. productionlist:: notation name: `lc_letter` (`lc_letter` | "_")* lc_letter: "a"..."z" diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 19ba83a5513d8a7..77e0578f5d89b65 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -296,7 +296,7 @@ Unicode Character Database as included in the :mod:`unicodedata` module. Identifiers are unlimited in length. Case is significant. -.. productionlist:: +.. productionlist:: python-grammar identifier: `xid_start` `xid_continue`* id_start: id_continue: @@ -412,7 +412,7 @@ String and Bytes literals String literals are described by the following lexical definitions: -.. productionlist:: +.. productionlist:: python-grammar stringliteral: [`stringprefix`](`shortstring` | `longstring`) stringprefix: "r" | "u" | "R" | "U" | "f" | "F" : | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF" @@ -424,7 +424,7 @@ String literals are described by the following lexical definitions: longstringchar: stringescapeseq: "\" -.. productionlist:: +.. productionlist:: python-grammar bytesliteral: `bytesprefix`(`shortbytes` | `longbytes`) bytesprefix: "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB" shortbytes: "'" `shortbytesitem`* "'" | '"' `shortbytesitem`* '"' @@ -659,7 +659,7 @@ Escape sequences are decoded like in ordinary string literals (except when a literal is also marked as a raw string). After decoding, the grammar for the contents of the string is: -.. productionlist:: +.. productionlist:: python-grammar f_string: (`literal_char` | "{{" | "}}" | `replacement_field`)* replacement_field: "{" `f_expression` ["="] ["!" `conversion`] [":" `format_spec`] "}" f_expression: (`conditional_expression` | "*" `or_expr`) @@ -820,7 +820,7 @@ Integer literals Integer literals are described by the following lexical definitions: -.. productionlist:: +.. productionlist:: python-grammar integer: `decinteger` | `bininteger` | `octinteger` | `hexinteger` decinteger: `nonzerodigit` (["_"] `digit`)* | "0"+ (["_"] "0")* bininteger: "0" ("b" | "B") (["_"] `bindigit`)+ @@ -864,7 +864,7 @@ Floating point literals Floating point literals are described by the following lexical definitions: -.. productionlist:: +.. productionlist:: python-grammar floatnumber: `pointfloat` | `exponentfloat` pointfloat: [`digitpart`] `fraction` | `digitpart` "." exponentfloat: (`digitpart` | `pointfloat`) `exponent` @@ -894,7 +894,7 @@ Imaginary literals Imaginary literals are described by the following lexical definitions: -.. productionlist:: +.. productionlist:: python-grammar imagnumber: (`floatnumber` | `digitpart`) ("j" | "J") An imaginary literal yields a complex number with a real part of 0.0. Complex diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index a8ec0fbe8b732cd..93be32713ff32a2 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -11,7 +11,7 @@ A simple statement is comprised within a single logical line. Several simple statements may occur on a single line separated by semicolons. The syntax for simple statements is: -.. productionlist:: +.. productionlist:: python-grammar simple_stmt: `expression_stmt` : | `assert_stmt` : | `assignment_stmt` @@ -46,7 +46,7 @@ result; in Python, procedures return the value ``None``). Other uses of expression statements are allowed and occasionally useful. The syntax for an expression statement is: -.. productionlist:: +.. productionlist:: python-grammar expression_stmt: `starred_expression` An expression statement evaluates the expression list (which may be a single @@ -82,7 +82,7 @@ Assignment statements Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects: -.. productionlist:: +.. productionlist:: python-grammar assignment_stmt: (`target_list` "=")+ (`starred_expression` | `yield_expression`) target_list: `target` ("," `target`)* [","] target: `identifier` @@ -280,7 +280,7 @@ Augmented assignment statements Augmented assignment is the combination, in a single statement, of a binary operation and an assignment statement: -.. productionlist:: +.. productionlist:: python-grammar augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`) augtarget: `identifier` | `attributeref` | `subscription` | `slicing` augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" @@ -328,7 +328,7 @@ Annotated assignment statements :term:`Annotation ` assignment is the combination, in a single statement, of a variable or attribute annotation and an optional assignment statement: -.. productionlist:: +.. productionlist:: python-grammar annotated_assignment_stmt: `augtarget` ":" `expression` : ["=" (`starred_expression` | `yield_expression`)] @@ -385,7 +385,7 @@ The :keyword:`!assert` statement Assert statements are a convenient way to insert debugging assertions into a program: -.. productionlist:: +.. productionlist:: python-grammar assert_stmt: "assert" `expression` ["," `expression`] The simple form, ``assert expression``, is equivalent to :: @@ -425,7 +425,7 @@ The :keyword:`!pass` statement pair: null; operation pair: null; operation -.. productionlist:: +.. productionlist:: python-grammar pass_stmt: "pass" :keyword:`pass` is a null operation --- when it is executed, nothing happens. @@ -447,7 +447,7 @@ The :keyword:`!del` statement pair: deletion; target triple: deletion; target; list -.. productionlist:: +.. productionlist:: python-grammar del_stmt: "del" `target_list` Deletion is recursively defined very similar to the way assignment is defined. @@ -486,7 +486,7 @@ The :keyword:`!return` statement pair: function; definition pair: class; definition -.. productionlist:: +.. productionlist:: python-grammar return_stmt: "return" [`expression_list`] :keyword:`return` may only occur syntactically nested in a function definition, @@ -525,7 +525,7 @@ The :keyword:`!yield` statement single: function; generator exception: StopIteration -.. productionlist:: +.. productionlist:: python-grammar yield_stmt: `yield_expression` A :keyword:`yield` statement is semantically equivalent to a :ref:`yield @@ -560,7 +560,7 @@ The :keyword:`!raise` statement pair: raising; exception single: __traceback__ (exception attribute) -.. productionlist:: +.. productionlist:: python-grammar raise_stmt: "raise" [`expression` ["from" `expression`]] If no expressions are present, :keyword:`raise` re-raises the last exception @@ -663,7 +663,7 @@ The :keyword:`!break` statement statement: while pair: loop; statement -.. productionlist:: +.. productionlist:: python-grammar break_stmt: "break" :keyword:`break` may only occur syntactically nested in a :keyword:`for` or @@ -698,7 +698,7 @@ The :keyword:`!continue` statement pair: loop; statement keyword: finally -.. productionlist:: +.. productionlist:: python-grammar continue_stmt: "continue" :keyword:`continue` may only occur syntactically nested in a :keyword:`for` or @@ -725,7 +725,7 @@ The :keyword:`!import` statement exception: ImportError single: , (comma); import statement -.. productionlist:: +.. productionlist:: python-grammar import_stmt: "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])* : | "from" `relative_module` "import" `identifier` ["as" `identifier`] : ("," `identifier` ["as" `identifier`])* @@ -859,7 +859,7 @@ that introduce incompatible changes to the language. It allows use of the new features on a per-module basis before the release in which the feature becomes standard. -.. productionlist:: * +.. productionlist:: python-grammar future_stmt: "from" "__future__" "import" `feature` ["as" `identifier`] : ("," `feature` ["as" `identifier`])* : | "from" "__future__" "import" "(" `feature` ["as" `identifier`] @@ -937,7 +937,7 @@ The :keyword:`!global` statement triple: global; name; binding single: , (comma); identifier list -.. productionlist:: +.. productionlist:: python-grammar global_stmt: "global" `identifier` ("," `identifier`)* The :keyword:`global` statement is a declaration which holds for the entire @@ -982,7 +982,7 @@ The :keyword:`!nonlocal` statement .. index:: statement: nonlocal single: , (comma); identifier list -.. productionlist:: +.. productionlist:: python-grammar nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)* .. XXX add when implemented diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index d5ffb37b2e58cde..319c9de484241e2 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -66,7 +66,7 @@ File input All input read from non-interactive files has the same form: -.. productionlist:: +.. productionlist:: python-grammar file_input: (NEWLINE | `statement`)* This syntax is used in the following situations: @@ -85,7 +85,7 @@ Interactive input Input in interactive mode is parsed using the following grammar: -.. productionlist:: +.. productionlist:: python-grammar interactive_input: [`stmt_list`] NEWLINE | `compound_stmt` NEWLINE Note that a (top-level) compound statement must be followed by a blank line in @@ -103,5 +103,5 @@ Expression input :func:`eval` is used for expression input. It ignores leading whitespace. The string argument to :func:`eval` must have the following form: -.. productionlist:: +.. productionlist:: python-grammar eval_input: `expression_list` NEWLINE* From 0d6293238ccf0865b5601ac8212397b1ebbca341 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 18 Sep 2020 18:22:36 +0900 Subject: [PATCH 324/486] bpo-35293: Remove RemovedInSphinx40Warning (GH-22198) * bpo-35293: Remove RemovedInSphinx40Warning * Update Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst Co-authored-by: Victor Stinner * bpo-35293: Apply Victor's review Co-authored-by: Victor Stinner --- Doc/tools/extensions/pyspecific.py | 36 +++++++++++-------- .../2020-09-12-17-37-13.bpo-35293._cOwPD.rst | 1 + 2 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 008dd8a6f7c8cdf..80fbd96d56fdc0a 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -31,7 +31,12 @@ from sphinx.util.nodes import split_explicit_title from sphinx.writers.text import TextWriter, TextTranslator from sphinx.writers.latex import LaTeXTranslator -from sphinx.domains.python import PyModulelevel, PyClassmember + +try: + from sphinx.domains.python import PyFunction, PyMethod +except ImportError: + from sphinx.domains.python import PyClassmember as PyMethod + from sphinx.domains.python import PyModulelevel as PyFunction # Support for checking for suspicious markup @@ -271,17 +276,18 @@ def needs_arglist(self): return False -class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel): +class PyDecoratorFunction(PyDecoratorMixin, PyFunction): def run(self): # a decorator function is a function after all self.name = 'py:function' - return PyModulelevel.run(self) + return PyFunction.run(self) -class PyDecoratorMethod(PyDecoratorMixin, PyClassmember): +# TODO: Use sphinx.domains.python.PyDecoratorMethod when possible +class PyDecoratorMethod(PyDecoratorMixin, PyMethod): def run(self): self.name = 'py:method' - return PyClassmember.run(self) + return PyMethod.run(self) class PyCoroutineMixin(object): @@ -298,31 +304,31 @@ def handle_signature(self, sig, signode): return ret -class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel): +class PyCoroutineFunction(PyCoroutineMixin, PyFunction): def run(self): self.name = 'py:function' - return PyModulelevel.run(self) + return PyFunction.run(self) -class PyCoroutineMethod(PyCoroutineMixin, PyClassmember): +class PyCoroutineMethod(PyCoroutineMixin, PyMethod): def run(self): self.name = 'py:method' - return PyClassmember.run(self) + return PyMethod.run(self) -class PyAwaitableFunction(PyAwaitableMixin, PyClassmember): +class PyAwaitableFunction(PyAwaitableMixin, PyFunction): def run(self): self.name = 'py:function' - return PyClassmember.run(self) + return PyFunction.run(self) -class PyAwaitableMethod(PyAwaitableMixin, PyClassmember): +class PyAwaitableMethod(PyAwaitableMixin, PyMethod): def run(self): self.name = 'py:method' - return PyClassmember.run(self) + return PyMethod.run(self) -class PyAbstractMethod(PyClassmember): +class PyAbstractMethod(PyMethod): def handle_signature(self, sig, signode): ret = super(PyAbstractMethod, self).handle_signature(sig, signode) @@ -332,7 +338,7 @@ def handle_signature(self, sig, signode): def run(self): self.name = 'py:method' - return PyClassmember.run(self) + return PyMethod.run(self) # Support for documenting version of removal in deprecations diff --git a/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst b/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst new file mode 100644 index 000000000000000..089d44e35d2baa5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst @@ -0,0 +1 @@ +Fix RemovedInSphinx40Warning when building the documentation. Patch by Dong-hee Na. From 6f3d14bd69031da064f57195c559980c8a18f831 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 18 Sep 2020 16:23:18 +0200 Subject: [PATCH 325/486] bpo-35293: Travis CI uses "make venv" for the doc (GH-22307) Doc/requirements.txt becomes the reference for packages and package versions needed to build the Python documentation. * Doc/Makefile now uses Doc/requirements.txt * .travis.yml now uses "make env" of Doc/Makefile --- .travis.yml | 5 +---- Doc/Makefile | 2 +- Doc/requirements.txt | 13 ++++++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index a915f7a46ec3d50..254a4ea35ab944b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,10 +51,7 @@ matrix: env: TESTING=docs before_script: - cd Doc - # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures. - # (Updating the version is fine as long as no warnings are raised by doing so.) - # The theme used by the docs is stored separately, so we need to install that as well. - - python -m pip install sphinx==2.2.0 blurb python-docs-theme + - make venv PYTHON=python script: - make check suspicious html SPHINXOPTS="-q -W -j4" - name: "Documentation tests" diff --git a/Doc/Makefile b/Doc/Makefile index c11a7ca5c1bcb70..f653d70674eb1c6 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -143,7 +143,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) $(VENVDIR)/bin/python3 -m pip install -U pip setuptools - $(VENVDIR)/bin/python3 -m pip install -U Sphinx==3.2.1 blurb python-docs-theme + $(VENVDIR)/bin/python3 -m pip install -r requirements.txt @echo "The venv has been created in the $(VENVDIR) directory" dist: diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 198446b350ff2d3..2b70af3a4fc6b9d 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -1,5 +1,12 @@ -# Requirements for docs build on netlify -# Pin sphinx to version specified in .travis.yml -sphinx==2.2.0 +# Requirements to build the Python documentation + +# Sphinx version is pinned so that new versions that introduce new warnings +# won't suddenly cause build failures. Updating the version is fine as long +# as no warnings are raised by doing so. +sphinx==3.2.1 + blurb + +# The theme used by the documentation is stored separately, so we need +# to install that as well. python-docs-theme From 677e9d5c95d1107133df50f7e48616eebb5b7227 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 18 Sep 2020 17:57:28 -0700 Subject: [PATCH 326/486] Make fractional value accumulation consistent inside and outside the loop. (GH-22315) --- Modules/mathmodule.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index ecd291ecd1b4b02..935759ec671ca52 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2550,8 +2550,7 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(csum + lo * lo == csum); frac_lo += lo * lo; } - frac += frac_lo + frac_mid; - h = sqrt(csum - 1.0 + frac); + h = sqrt(csum - 1.0 + (frac_lo + frac_mid + frac)); x = h; t = x * T27; @@ -2569,15 +2568,15 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac_mid += (oldcsum - csum) + x; x = -lo * lo; assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac_lo += (oldcsum - csum) + x; - x = csum - 1.0 + frac; + x = csum - 1.0 + (frac_lo + frac_mid + frac); return (h + x / (2.0 * h)) / scale; } /* When max_e < -1023, ldexp(1.0, -max_e) overflows. From b5a91057acb31d3244f537b9b4d31ac368a285ba Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 18 Sep 2020 18:38:38 -0700 Subject: [PATCH 327/486] bpo-41756: Introduce PyGen_Send C API (GH-22196) The new API allows to efficiently send values into native generators and coroutines avoiding use of StopIteration exceptions to signal returns. ceval loop now uses this method instead of the old "private" _PyGen_Send C API. This translates to 1.6x increased performance of 'await' calls in micro-benchmarks. Aside from CPython core improvements, this new API will also allow Cython to generate more efficient code, benefiting high-performance IO libraries like uvloop. --- Doc/c-api/gen.rst | 15 +++++ Doc/data/refcounts.dat | 5 ++ Include/genobject.h | 15 +++++ .../2020-09-12-12-55-45.bpo-41756.1h0tbV.rst | 2 + Modules/_asynciomodule.c | 27 ++++++-- Objects/genobject.c | 65 ++++++++++++++----- Python/ceval.c | 58 ++++++++++++----- 7 files changed, 148 insertions(+), 39 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst index 74410927bfde107..e098425e6364d9e 100644 --- a/Doc/c-api/gen.rst +++ b/Doc/c-api/gen.rst @@ -15,6 +15,11 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. The C structure used for generator objects. +.. c:type:: PySendResult + + The enum value used to represent different results of :c:func:`PyGen_Send`. + + .. c:var:: PyTypeObject PyGen_Type The type object corresponding to generator objects. @@ -42,3 +47,13 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. A reference to *frame* is stolen by this function. The *frame* argument must not be ``NULL``. + +.. c:function:: PySendResult PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **presult) + + Sends the *arg* value into the generator *gen*. Coroutine objects + are also allowed to be as the *gen* argument but they need to be + explicitly casted to PyGenObject*. Returns: + + - ``PYGEN_RETURN`` if generator returns. Return value is returned via *presult*. + - ``PYGEN_NEXT`` if generator yields. Yielded value is returned via *presult*. + - ``PYGEN_ERROR`` if generator has raised and exception. *presult* is set to ``NULL``. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 355a4d6d3fa7ba1..6b1bde37967ae93 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -959,6 +959,11 @@ PyGen_NewWithQualName:PyFrameObject*:frame:0: PyGen_NewWithQualName:PyObject*:name:0: PyGen_NewWithQualName:PyObject*:qualname:0: +PyGen_Send:int::: +PyGen_Send:PyGenObject*:gen:0: +PyGen_Send:PyObject*:arg:0: +PyGen_Send:PyObject**:presult:+1: + PyCoro_CheckExact:int::: PyCoro_CheckExact:PyObject*:ob:0: diff --git a/Include/genobject.h b/Include/genobject.h index a76dc92e811c42b..7488054c68fcd8b 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -45,6 +45,21 @@ PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *); PyObject *_PyGen_yf(PyGenObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); +typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, +} PySendResult; + +/* Sends the value into the generator or the coroutine. Returns: + - PYGEN_RETURN (0) if generator has returned. + 'result' parameter is filled with return value + - PYGEN_ERROR (-1) if exception was raised. + 'result' parameter is NULL + - PYGEN_NEXT (1) if generator has yielded. + 'result' parameter is filled with yielded value. */ +PyAPI_FUNC(PySendResult) PyGen_Send(PyGenObject *, PyObject *, PyObject **); + #ifndef Py_LIMITED_API typedef struct { _PyGenObject_HEAD(cr) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst new file mode 100644 index 000000000000000..b387cfd94033c9b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst @@ -0,0 +1,2 @@ +Add PyGen_Send function to allow sending value into generator/coroutine +without raising StopIteration exception to signal return diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 4a1c91e9eddd67f..2151f20281a31bc 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2621,6 +2621,20 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) Py_RETURN_NONE; } +static inline int +gen_status_from_result(PyObject **result) +{ + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + + assert(PyErr_Occurred()); + return PYGEN_ERROR; +} + static PyObject * task_step_impl(TaskObj *task, PyObject *exc) { @@ -2679,26 +2693,29 @@ task_step_impl(TaskObj *task, PyObject *exc) return NULL; } + int gen_status = PYGEN_ERROR; if (exc == NULL) { if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { - result = _PyGen_Send((PyGenObject*)coro, Py_None); + gen_status = PyGen_Send((PyGenObject*)coro, Py_None, &result); } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); + gen_status = gen_status_from_result(&result); } } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); + gen_status = gen_status_from_result(&result); if (clear_exc) { /* We created 'exc' during this call */ Py_DECREF(exc); } } - if (result == NULL) { + if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) { PyObject *et, *ev, *tb; - if (_PyGen_FetchStopIterationValue(&o) == 0) { + if (result != NULL) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ @@ -2709,10 +2726,10 @@ task_step_impl(TaskObj *task, PyObject *exc) res = future_cancel((FutureObj*)task, task->task_cancel_msg); } else { - res = future_set_result((FutureObj*)task, o); + res = future_set_result((FutureObj*)task, result); } - Py_DECREF(o); + Py_DECREF(result); if (res == NULL) { return NULL; diff --git a/Objects/genobject.c b/Objects/genobject.c index 809838a4cd2f3b5..24aca988354c5ae 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -137,7 +137,7 @@ gen_dealloc(PyGenObject *gen) } static PyObject * -gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_return_value) { PyThreadState *tstate = _PyThreadState_GET(); PyFrameObject *f = gen->gi_frame; @@ -170,6 +170,10 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) PyErr_SetNone(PyExc_StopAsyncIteration); } else { + if (is_return_value != NULL) { + *is_return_value = 1; + Py_RETURN_NONE; + } PyErr_SetNone(PyExc_StopIteration); } } @@ -230,18 +234,33 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) /* Delay exception instantiation if we can */ if (PyAsyncGen_CheckExact(gen)) { PyErr_SetNone(PyExc_StopAsyncIteration); + Py_CLEAR(result); } else if (arg) { - /* Set exception if not called by gen_iternext() */ - PyErr_SetNone(PyExc_StopIteration); + if (is_return_value != NULL) { + *is_return_value = 1; + } + else { + /* Set exception if not called by gen_iternext() */ + PyErr_SetNone(PyExc_StopIteration); + Py_CLEAR(result); + } + } + else { + Py_CLEAR(result); } } else { /* Async generators cannot return anything but None */ assert(!PyAsyncGen_CheckExact(gen)); - _PyGen_SetStopIterationValue(result); + if (is_return_value != NULL) { + *is_return_value = 1; + } + else { + _PyGen_SetStopIterationValue(result); + Py_CLEAR(result); + } } - Py_CLEAR(result); } else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { const char *msg = "generator raised StopIteration"; @@ -264,7 +283,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); } - if (!result || _PyFrameHasCompleted(f)) { + if ((is_return_value && *is_return_value) || !result || _PyFrameHasCompleted(f)) { /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); @@ -283,7 +302,19 @@ return next yielded value or raise StopIteration."); PyObject * _PyGen_Send(PyGenObject *gen, PyObject *arg) { - return gen_send_ex(gen, arg, 0, 0); + return gen_send_ex(gen, arg, 0, 0, NULL); +} + +PySendResult +PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **result) +{ + assert(result != NULL); + + int is_return_value = 0; + if ((*result = gen_send_ex(gen, arg, 0, 0, &is_return_value)) == NULL) { + return PYGEN_ERROR; + } + return is_return_value ? PYGEN_RETURN : PYGEN_NEXT; } PyDoc_STRVAR(close_doc, @@ -365,7 +396,7 @@ gen_close(PyGenObject *gen, PyObject *args) } if (err == 0) PyErr_SetNone(PyExc_GeneratorExit); - retval = gen_send_ex(gen, Py_None, 1, 1); + retval = gen_send_ex(gen, Py_None, 1, 1, NULL); if (retval) { const char *msg = "generator ignored GeneratorExit"; if (PyCoro_CheckExact(gen)) { @@ -413,7 +444,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, gen->gi_frame->f_state = state; Py_DECREF(yf); if (err < 0) - return gen_send_ex(gen, Py_None, 1, 0); + return gen_send_ex(gen, Py_None, 1, 0, NULL); goto throw_here; } if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { @@ -465,10 +496,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, assert(gen->gi_frame->f_lasti >= 0); gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send_ex(gen, val, 0, 0); + ret = gen_send_ex(gen, val, 0, 0, NULL); Py_DECREF(val); } else { - ret = gen_send_ex(gen, Py_None, 1, 0); + ret = gen_send_ex(gen, Py_None, 1, 0, NULL); } } return ret; @@ -522,7 +553,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } PyErr_Restore(typ, val, tb); - return gen_send_ex(gen, Py_None, 1, 0); + return gen_send_ex(gen, Py_None, 1, 0, NULL); failed_throw: /* Didn't use our arguments, so restore their original refcounts */ @@ -551,7 +582,7 @@ gen_throw(PyGenObject *gen, PyObject *args) static PyObject * gen_iternext(PyGenObject *gen) { - return gen_send_ex(gen, NULL, 0, 0); + return gen_send_ex(gen, NULL, 0, 0, NULL); } /* @@ -1051,13 +1082,13 @@ coro_wrapper_dealloc(PyCoroWrapper *cw) static PyObject * coro_wrapper_iternext(PyCoroWrapper *cw) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0); + return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0, NULL); } static PyObject * coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0); + return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0, NULL); } static PyObject * @@ -1570,7 +1601,7 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg) } o->ags_gen->ag_running_async = 1; - result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0); + result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0, NULL); result = async_gen_unwrap_value(o->ags_gen, result); if (result == NULL) { @@ -1926,7 +1957,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) assert(o->agt_state == AWAITABLE_STATE_ITER); - retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0); + retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0, NULL); if (o->agt_args) { return async_gen_unwrap_value(o->agt_gen, retval); } else { diff --git a/Python/ceval.c b/Python/ceval.c index f747faaebf024a3..3de372f45a25170 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2223,29 +2223,53 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) case TARGET(YIELD_FROM): { PyObject *v = POP(); PyObject *receiver = TOP(); - int err; - if (PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver)) { - retval = _PyGen_Send((PyGenObject *)receiver, v); + int is_gen_or_coro = PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver); + int gen_status; + if (tstate->c_tracefunc == NULL && is_gen_or_coro) { + gen_status = PyGen_Send((PyGenObject *)receiver, v, &retval); } else { - _Py_IDENTIFIER(send); - if (v == Py_None) - retval = Py_TYPE(receiver)->tp_iternext(receiver); - else - retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); + if (is_gen_or_coro) { + retval = _PyGen_Send((PyGenObject *)receiver, v); + } + else { + _Py_IDENTIFIER(send); + if (v == Py_None) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); + } + else { + retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); + } + } + + if (retval == NULL) { + if (tstate->c_tracefunc != NULL + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + gen_status = PYGEN_RETURN; + } + else { + gen_status = PYGEN_ERROR; + } + } + else { + gen_status = PYGEN_NEXT; + } } Py_DECREF(v); - if (retval == NULL) { - PyObject *val; - if (tstate->c_tracefunc != NULL - && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); - err = _PyGen_FetchStopIterationValue(&val); - if (err < 0) - goto error; + if (gen_status == PYGEN_ERROR) { + assert (retval == NULL); + goto error; + } + if (gen_status == PYGEN_RETURN) { + assert (retval != NULL); + Py_DECREF(receiver); - SET_TOP(val); + SET_TOP(retval); + retval = NULL; DISPATCH(); } + assert (gen_status == PYGEN_NEXT); /* receiver remains on stack, retval is value to be yielded */ /* and repeat... */ assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); From 3fc82c418ef073e9bea3e46c57f63625e455e963 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Sat, 19 Sep 2020 11:12:57 -0700 Subject: [PATCH 328/486] bpo-41811: create SortKey members using first given value (GH-22316) --- Lib/pstats.py | 6 +++--- Lib/test/test_pstats.py | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Lib/pstats.py b/Lib/pstats.py index e781b91c6052cfd..0f93ae02c95074d 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -45,9 +45,9 @@ class SortKey(str, Enum): TIME = 'time', 'tottime' def __new__(cls, *values): - obj = str.__new__(cls) - - obj._value_ = values[0] + value = values[0] + obj = str.__new__(cls, value) + obj._value_ = value for other_value in values[1:]: cls._value2member_map_[other_value] = obj obj._all_values = values diff --git a/Lib/test/test_pstats.py b/Lib/test/test_pstats.py index 10559deb6bcb23a..4f78b99fd1cae79 100644 --- a/Lib/test/test_pstats.py +++ b/Lib/test/test_pstats.py @@ -95,5 +95,9 @@ def pass3(): pass self.assertIn('pass2', funcs_called) self.assertIn('pass3', funcs_called) + def test_SortKey_enum(self): + self.assertEqual(SortKey.FILENAME, 'filename') + self.assertNotEqual(SortKey.FILENAME, SortKey.CALLS) + if __name__ == "__main__": unittest.main() From 84dfcefc4cb910c4ad2896c9d23f4b238f43e9e1 Mon Sep 17 00:00:00 2001 From: idomic Date: Sat, 19 Sep 2020 15:13:29 -0400 Subject: [PATCH 329/486] bpo-33689: Blank lines in .pth file cause a duplicate sys.path entry (GH-20679) --- Lib/site.py | 2 ++ Lib/test/test_site.py | 7 ++++++- .../next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst diff --git a/Lib/site.py b/Lib/site.py index 4c095774729c5e6..4d3b869fff77a0e 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -170,6 +170,8 @@ def addpackage(sitedir, name, known_paths): for n, line in enumerate(f): if line.startswith("#"): continue + if line.strip() == "": + continue try: if line.startswith(("import ", "import\t")): exec(line) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 97b5c5de95bbc24..d3ee68facdbc3de 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -161,6 +161,12 @@ def test_addpackage_import_bad_exec(self): self.assertRegex(err_out.getvalue(), 'Traceback') self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError') + def test_addpackage_empty_lines(self): + # Issue 33689 + pth_dir, pth_fn = self.make_pth("\n\n \n\n") + known_paths = site.addpackage(pth_dir, pth_fn, set()) + self.assertEqual(known_paths, set()) + def test_addpackage_import_bad_pth_file(self): # Issue 5258 pth_dir, pth_fn = self.make_pth("abc\x00def\n") @@ -595,7 +601,6 @@ def test_startup_interactivehook_isolated_explicit(self): 'import site, sys; site.enablerlcompleter(); sys.exit(hasattr(sys, "__interactivehook__"))']).wait() self.assertTrue(r, "'__interactivehook__' not added by enablerlcompleter()") - @unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") class _pthFileTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst b/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst new file mode 100644 index 000000000000000..bc0756d02ddc9e8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst @@ -0,0 +1,4 @@ +Ignore empty or whitespace-only lines in .pth files. This matches the +documentated behavior. Before, empty lines caused the site-packages +dir to appear multiple times in sys.path. +By Ido Michael, contributors Malcolm Smith and Tal Einat. From d863c2d4b57b568dbd4b9c1651227667f6763109 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 19 Sep 2020 21:38:11 +0100 Subject: [PATCH 330/486] Add missing whatsnew entry for TestCase.assertNoLogs (GH-22317) --- Doc/whatsnew/3.10.rst | 7 +++++++ Misc/ACKS | 1 + 2 files changed, 8 insertions(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index f6f276a8bfa4955..ce888fec1d8c972 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -145,6 +145,13 @@ Add :data:`sys.orig_argv` attribute: the list of the original command line arguments passed to the Python executable. (Contributed by Victor Stinner in :issue:`23427`.) +unittest +-------- + +Add new method :meth:`~unittest.TestCase.assertNoLogs` to complement the +existing :meth:`~unittest.TestCase.assertLogs`. (Contributed by Kit Yan Choi +in :issue:`39385`.) + xml --- diff --git a/Misc/ACKS b/Misc/ACKS index d5bdb084a1e1edb..d23797a2f55574a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -306,6 +306,7 @@ Albert Chin-A-Young Adal Chiriliuc Matt Chisholm Lita Cho +Kit Yan Choi Sayan Chowdhury Yuan-Chao Chou Anders Chrigström From 04a0d2f29f2da4d16ff9449e2e771c51877d881c Mon Sep 17 00:00:00 2001 From: Peter McCormick Date: Sat, 19 Sep 2020 23:40:46 -0400 Subject: [PATCH 331/486] bpo-41815: SQLite: segfault if backup called on closed database (GH-22322) # [bpo-41815](): SQLite: fix segfault if backup called on closed database Attempting to backup a closed database will trigger segfault: ```python import sqlite3 target = sqlite3.connect(':memory:') source = sqlite3.connect(':memory:') source.close() source.backup(target) ``` --- Lib/sqlite3/test/backup.py | 7 +++++++ .../next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst | 2 ++ Modules/_sqlite/connection.c | 4 ++++ 3 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst diff --git a/Lib/sqlite3/test/backup.py b/Lib/sqlite3/test/backup.py index 2752a4db337ddd8..3637c4bb21b6db6 100644 --- a/Lib/sqlite3/test/backup.py +++ b/Lib/sqlite3/test/backup.py @@ -35,6 +35,13 @@ def test_bad_target_closed_connection(self): with self.assertRaises(sqlite.ProgrammingError): self.cx.backup(bck) + def test_bad_source_closed_connection(self): + bck = sqlite.connect(':memory:') + source = sqlite.connect(":memory:") + source.close() + with self.assertRaises(sqlite.ProgrammingError): + source.backup(bck) + def test_bad_target_in_transaction(self): bck = sqlite.connect(':memory:') bck.execute('CREATE TABLE bar (key INTEGER)') diff --git a/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst b/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst new file mode 100644 index 000000000000000..3560db9bc5d355b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst @@ -0,0 +1,2 @@ +Fix SQLite3 segfault when backing up closed database. Patch contributed by +Peter David McCormick. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index f765ba1df246694..81fc1335371a6fc 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1514,6 +1514,10 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * sleep_ms = (int)ms; } + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { return NULL; } From d311098d838f4d1ce4642fd5555f747ee8b6a949 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 20 Sep 2020 09:38:07 +0300 Subject: [PATCH 332/486] bpo-12178: Fix escaping of escapechar in csv.writer() (GH-13710) Co-authored-by: Itay Elbirt --- Lib/test/test_csv.py | 14 ++++++++++++++ .../2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst | 3 +++ Modules/_csv.c | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 38160220853ea83..a98707ce3caed77 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -202,6 +202,20 @@ def test_write_escape(self): escapechar='\\', quoting = csv.QUOTE_NONE) self._write_test(['a',1,'p,q'], 'a,1,p\\,q', escapechar='\\', quoting = csv.QUOTE_NONE) + self._write_test(['\\', 'a'], '\\\\,a', + escapechar='\\', quoting=csv.QUOTE_NONE) + self._write_test(['\\', 'a'], '\\\\,a', + escapechar='\\', quoting=csv.QUOTE_MINIMAL) + self._write_test(['\\', 'a'], '"\\\\","a"', + escapechar='\\', quoting=csv.QUOTE_ALL) + self._write_test(['\\ ', 'a'], '\\\\ ,a', + escapechar='\\', quoting=csv.QUOTE_MINIMAL) + self._write_test(['\\,', 'a'], '\\\\\\,,a', + escapechar='\\', quoting=csv.QUOTE_NONE) + self._write_test([',\\', 'a'], '",\\\\",a', + escapechar='\\', quoting=csv.QUOTE_MINIMAL) + self._write_test(['C\\', '6', '7', 'X"'], 'C\\\\,6,7,"X"""', + escapechar='\\', quoting=csv.QUOTE_MINIMAL) def test_write_iterable(self): self._write_test(iter(['a', 1, 'p,q']), 'a,1,"p,q"') diff --git a/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst b/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst new file mode 100644 index 000000000000000..80e2a7b5fbb2c08 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst @@ -0,0 +1,3 @@ +:func:`csv.writer` now correctly escapes *escapechar* when input +contains *escapechar*. Patch by Catalin Iacob, Berker Peksag, +and Itay Elbirt. diff --git a/Modules/_csv.c b/Modules/_csv.c index da61db9377f94d1..594f6c147272627 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -1040,6 +1040,9 @@ join_append_data(WriterObj *self, unsigned int field_kind, const void *field_dat else want_escape = 1; } + else if (c == dialect->escapechar) { + want_escape = 1; + } if (!want_escape) *quoted = 1; } From 9c1175b0107751ad26368300559f68328ca98eb5 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sun, 20 Sep 2020 14:09:50 -0300 Subject: [PATCH 333/486] [doc] Teach 0-args form of super in Programming FAQ (GH-22176) --- Doc/faq/programming.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index eecbbf4a5c4ff72..fd0adc378bfa6f7 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1504,20 +1504,19 @@ Most :meth:`__setattr__` implementations must modify ``self.__dict__`` to store local state for self without causing an infinite recursion. -How do I call a method defined in a base class from a derived class that overrides it? --------------------------------------------------------------------------------------- +How do I call a method defined in a base class from a derived class that extends it? +------------------------------------------------------------------------------------ Use the built-in :func:`super` function:: class Derived(Base): def meth(self): - super(Derived, self).meth() + super().meth() # calls Base.meth -For version prior to 3.0, you may be using classic classes: For a class -definition such as ``class Derived(Base): ...`` you can call method ``meth()`` -defined in ``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self, -arguments...)``. Here, ``Base.meth`` is an unbound method, so you need to -provide the ``self`` argument. +In the example, :func:`super` will automatically determine the instance from +which it was called (the ``self`` value), look up the :term:`method resolution +order` (MRO) with ``type(self).__mro__``, and return the next in line after +``Derived`` in the MRO: ``Base``. How can I organize my code to make it easier to change the base class? From 9d72f793d91ea5a5efd30576d4cb4767f8c3c1a2 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 20 Sep 2020 21:47:56 -0700 Subject: [PATCH 334/486] bpo-41513: Add accuracy tests for math.hypot() (GH-22327) --- Lib/test/test_math.py | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index f5283c5e0dcb635..2abe5b028b355dd 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -803,6 +803,69 @@ def testHypot(self): scale = FLOAT_MIN / 2.0 ** exp self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "hypot() loses accuracy on machines with double rounding") + def testHypotAccuracy(self): + # Verify improved accuracy in cases that were known to be inaccurate. + # + # The new algorithm's accuracy depends on IEEE 754 arithmetic + # guarantees, on having the usual ROUND HALF EVEN rounding mode, on + # the system not having double rounding due to extended precision, + # and on the compiler maintaining the specified order of operations. + # + # This test is known to succeed on most of our builds. If it fails + # some build, we either need to add another skipIf if the cause is + # identifiable; otherwise, we can remove this test entirely. + + hypot = math.hypot + Decimal = decimal.Decimal + high_precision = decimal.Context(prec=500) + + for hx, hy in [ + # Cases with a 1 ulp error in Python 3.7 compiled with Clang + ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'), + ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'), + ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'), + ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'), + ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'), + ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'), + ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'), + ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'), + ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'), + ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'), + + # Cases with 2 ulp error in Python 3.8 + ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'), + ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'), + ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'), + ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'), + ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'), + ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'), + ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'), + ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'), + ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'), + ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'), + + # Cases with 1 ulp error in version fff3c28052e6b0 + ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'), + ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'), + ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'), + ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'), + ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'), + ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'), + ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'), + ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'), + ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'), + ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'), + ]: + x = float.fromhex(hx) + y = float.fromhex(hy) + with self.subTest(hx=hx, hy=hy, x=x, y=y): + with decimal.localcontext(high_precision): + z = float((Decimal(x)**2 + Decimal(y)**2).sqrt()) + self.assertEqual(hypot(x, y), z) + def testDist(self): from decimal import Decimal as D from fractions import Fraction as F From 632fe6de498cc5bc1d4ec0e95beaffa1b539b639 Mon Sep 17 00:00:00 2001 From: Samuel Marks <807580+SamuelMarks@users.noreply.github.com> Date: Mon, 21 Sep 2020 18:35:17 +1000 Subject: [PATCH 335/486] bpo-41819: Fix compiler warning in init_dump_ascii_wstr() (GH-22332) Fix the compiler warning: format specifies type `wint_t` (aka `int`) but the argument has type `unsigned int` --- Python/initconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index 880e145ec031cd1..6a13dc52ed776ce 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2674,7 +2674,7 @@ init_dump_ascii_wstr(const wchar_t *str) if (ch == L'\'') { PySys_WriteStderr("\\'"); } else if (0x20 <= ch && ch < 0x7f) { - PySys_WriteStderr("%lc", ch); + PySys_WriteStderr("%c", ch); } else if (ch <= 0xff) { PySys_WriteStderr("\\x%02x", ch); From edd5dee0790d60f8ef953a6dd211740f1cc7ffd6 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 21 Sep 2020 07:40:42 -0500 Subject: [PATCH 336/486] bpo-1635741: Convert an _lsprof method to argument clinic (GH-22240) --- Modules/_lsprof.c | 73 ++++++++++++++++++++++---------------- Modules/clinic/_lsprof.c.h | 44 +++++++++++++++++++++++ 2 files changed, 86 insertions(+), 31 deletions(-) create mode 100644 Modules/clinic/_lsprof.c.h diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 5e53d839640d994..a4ba7d523003381 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -50,8 +50,15 @@ typedef struct { #define POF_BUILTINS 0x004 #define POF_NOMEMORY 0x100 +/*[clinic input] +module _lsprof +class _lsprof.Profiler "ProfilerObject *" "&ProfilerType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e349ac952152f336]*/ static PyTypeObject PyProfiler_Type; +#include "clinic/_lsprof.c.h" + #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) #define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type) @@ -556,49 +563,54 @@ static int statsForEntry(rotating_node_t *node, void *arg) return err; } -PyDoc_STRVAR(getstats_doc, "\ -getstats() -> list of profiler_entry objects\n\ -\n\ -Return all information collected by the profiler.\n\ -Each profiler_entry is a tuple-like object with the\n\ -following attributes:\n\ -\n\ - code code object\n\ - callcount how many times this was called\n\ - reccallcount how many times called recursively\n\ - totaltime total time in this entry\n\ - inlinetime inline time in this entry (not in subcalls)\n\ - calls details of the calls\n\ -\n\ -The calls attribute is either None or a list of\n\ -profiler_subentry objects:\n\ -\n\ - code called code object\n\ - callcount how many times this is called\n\ - reccallcount how many times this is called recursively\n\ - totaltime total time spent in this call\n\ - inlinetime inline time (not in further subcalls)\n\ -"); +/*[clinic input] +_lsprof.Profiler.getstats -static PyObject* -profiler_getstats(ProfilerObject *pObj, PyObject* noarg) +list of profiler_entry objects. + +getstats() -> list of profiler_entry objects + +Return all information collected by the profiler. +Each profiler_entry is a tuple-like object with the +following attributes: + + code code object + callcount how many times this was called + reccallcount how many times called recursively + totaltime total time in this entry + inlinetime inline time in this entry (not in subcalls) + calls details of the calls + +The calls attribute is either None or a list of +profiler_subentry objects: + + code called code object + callcount how many times this is called + reccallcount how many times this is called recursively + totaltime total time spent in this call + inlinetime inline time (not in further subcalls) +[clinic start generated code]*/ + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self) +/*[clinic end generated code: output=9461b451e9ef0f24 input=ade04fa384ce450a]*/ { statscollector_t collect; - if (pending_exception(pObj)) { + if (pending_exception(self)) { return NULL; } - if (!pObj->externalTimer || pObj->externalTimerUnit == 0.0) { + if (!self->externalTimer || self->externalTimerUnit == 0.0) { _PyTime_t onesec = _PyTime_FromSeconds(1); collect.factor = (double)1 / onesec; } else { - collect.factor = pObj->externalTimerUnit; + collect.factor = self->externalTimerUnit; } collect.list = PyList_New(0); if (collect.list == NULL) return NULL; - if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) + if (RotatingTree_Enum(self->profilerEntries, statsForEntry, &collect) != 0) { Py_DECREF(collect.list); return NULL; @@ -750,8 +762,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) } static PyMethodDef profiler_methods[] = { - {"getstats", (PyCFunction)profiler_getstats, - METH_NOARGS, getstats_doc}, + _LSPROF_PROFILER_GETSTATS_METHODDEF {"enable", (PyCFunction)(void(*)(void))profiler_enable, METH_VARARGS | METH_KEYWORDS, enable_doc}, {"disable", (PyCFunction)profiler_disable, diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h new file mode 100644 index 000000000000000..50762e3ff35960e --- /dev/null +++ b/Modules/clinic/_lsprof.c.h @@ -0,0 +1,44 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, +"getstats($self, /)\n" +"--\n" +"\n" +"list of profiler_entry objects.\n" +"\n" +"getstats() -> list of profiler_entry objects\n" +"\n" +"Return all information collected by the profiler.\n" +"Each profiler_entry is a tuple-like object with the\n" +"following attributes:\n" +"\n" +" code code object\n" +" callcount how many times this was called\n" +" reccallcount how many times called recursively\n" +" totaltime total time in this entry\n" +" inlinetime inline time in this entry (not in subcalls)\n" +" calls details of the calls\n" +"\n" +"The calls attribute is either None or a list of\n" +"profiler_subentry objects:\n" +"\n" +" code called code object\n" +" callcount how many times this is called\n" +" reccallcount how many times this is called recursively\n" +" totaltime total time spent in this call\n" +" inlinetime inline time (not in further subcalls)"); + +#define _LSPROF_PROFILER_GETSTATS_METHODDEF \ + {"getstats", (PyCFunction)_lsprof_Profiler_getstats, METH_NOARGS, _lsprof_Profiler_getstats__doc__}, + +static PyObject * +_lsprof_Profiler_getstats_impl(ProfilerObject *self); + +static PyObject * +_lsprof_Profiler_getstats(ProfilerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _lsprof_Profiler_getstats_impl(self); +} +/*[clinic end generated code: output=24c525812713e00f input=a9049054013a1b77]*/ From b7dafa26795f54070f4b843c192a2ead68c85ed6 Mon Sep 17 00:00:00 2001 From: Angelin BOOZ <9497359+lem2clide@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:11:06 +0200 Subject: [PATCH 337/486] bpo-40084: Enum - dir() includes member attributes (GH-19219) --- Lib/enum.py | 2 +- Lib/test/test_enum.py | 12 ++++++++++++ Lib/test/test_httplib.py | 6 +++++- Misc/ACKS | 1 + .../Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst | 1 + 5 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst diff --git a/Lib/enum.py b/Lib/enum.py index 3c459ea4113d0b5..e8603a43420b0eb 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -644,7 +644,7 @@ def __dir__(self): for cls in self.__class__.mro() for m in cls.__dict__ if m[0] != '_' and m not in self._member_map_ - ] + ] + [m for m in self.__dict__ if m[0] != '_'] return (['__class__', '__doc__', '__module__'] + added_behavior) def __format__(self, format_spec): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 59789fb7bcc5fde..3f39073f5d564ed 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -216,6 +216,18 @@ class SubEnum(SuperEnum): set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']), ) + def test_dir_on_sub_with_behavior_including_instance_dict_on_super(self): + # see issue40084 + class SuperEnum(IntEnum): + def __new__(cls, value, description=""): + obj = int.__new__(cls, value) + obj._value_ = value + obj.description = description + return obj + class SubEnum(SuperEnum): + sample = 5 + self.assertTrue({'description'} <= set(dir(SubEnum.sample))) + def test_enum_in_enum_out(self): Season = self.Season self.assertIs(Season(Season.WINTER), Season.WINTER) diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index a3f268be97921c3..4abff60230b5462 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -1,5 +1,5 @@ import errno -from http import client +from http import client, HTTPStatus import io import itertools import os @@ -519,6 +519,10 @@ def _parse_chunked(self, data): class BasicTest(TestCase): + def test_dir_with_added_behavior_on_status(self): + # see issue40084 + self.assertTrue({'description', 'name', 'phrase', 'value'} <= set(dir(HTTPStatus(404)))) + def test_status_lines(self): # Test HTTP status lines diff --git a/Misc/ACKS b/Misc/ACKS index d23797a2f55574a..01ee1cb42d39d0d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -191,6 +191,7 @@ Gawain Bolton Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond +Angelin Booz Médéric Boquien Matias Bordese Jonas Borgström diff --git a/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst b/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst new file mode 100644 index 000000000000000..65ff4ce36e82eab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst @@ -0,0 +1 @@ +Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes as well as methods. From b071310206cbabe4fbbdd86f76d7323b9c94301e Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Mon, 21 Sep 2020 17:23:13 -0700 Subject: [PATCH 338/486] bpo-41816: add `StrEnum` (GH-22337) `StrEnum` ensures that its members were already strings, or intended to be strings. --- Doc/library/enum.rst | 38 +++++++++++++ Lib/enum.py | 32 ++++++++++- Lib/test/test_enum.py | 54 ++++++++++++------- .../2020-09-19-12-22-08.bpo-41816.ynynXJ.rst | 2 + 4 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 2f84be229bc4da6..843d961afc4f723 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -44,6 +44,11 @@ helper, :class:`auto`. Base class for creating enumerated constants that are also subclasses of :class:`int`. +.. class:: StrEnum + + Base class for creating enumerated constants that are also + subclasses of :class:`str`. + .. class:: IntFlag Base class for creating enumerated constants that can be combined using @@ -601,6 +606,25 @@ However, they still can't be compared to standard :class:`Enum` enumerations:: [0, 1] +StrEnum +^^^^^^^ + +The second variation of :class:`Enum` that is provided is also a subclass of +:class:`str`. Members of a :class:`StrEnum` can be compared to strings; +by extension, string enumerations of different types can also be compared +to each other. :class:`StrEnum` exists to help avoid the problem of getting +an incorrect member:: + + >>> class Directions(StrEnum): + ... NORTH = 'north', # notice the trailing comma + ... SOUTH = 'south' + +Before :class:`StrEnum`, ``Directions.NORTH`` would have been the :class:`tuple` +``('north',)``. + +.. versionadded:: 3.10 + + IntFlag ^^^^^^^ @@ -1132,6 +1156,20 @@ all-uppercase names for members):: .. versionchanged:: 3.5 +Creating members that are mixed with other data types +""""""""""""""""""""""""""""""""""""""""""""""""""""" + +When subclassing other data types, such as :class:`int` or :class:`str`, with +an :class:`Enum`, all values after the `=` are passed to that data type's +constructor. For example:: + + >>> class MyEnum(IntEnum): + ... example = '11', 16 # '11' will be interpreted as a hexadecimal + ... # number + >>> MyEnum.example + + + Boolean value of ``Enum`` classes and members """"""""""""""""""""""""""""""""""""""""""""" diff --git a/Lib/enum.py b/Lib/enum.py index e8603a43420b0eb..589b17fd6977754 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -4,7 +4,7 @@ __all__ = [ 'EnumMeta', - 'Enum', 'IntEnum', 'Flag', 'IntFlag', + 'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'auto', 'unique', ] @@ -688,7 +688,35 @@ def value(self): class IntEnum(int, Enum): - """Enum where members are also (and must be) ints""" + """ + Enum where members are also (and must be) ints + """ + + +class StrEnum(str, Enum): + """ + Enum where members are also (and must be) strings + """ + + def __new__(cls, *values): + if len(values) > 3: + raise TypeError('too many arguments for str(): %r' % (values, )) + if len(values) == 1: + # it must be a string + if not isinstance(values[0], str): + raise TypeError('%r is not a string' % (values[0], )) + if len(values) > 1: + # check that encoding argument is a string + if not isinstance(values[1], str): + raise TypeError('encoding must be a string, not %r' % (values[1], )) + if len(values) > 2: + # check that errors argument is a string + if not isinstance(values[2], str): + raise TypeError('errors must be a string, not %r' % (values[2], )) + value = str(*values) + member = str.__new__(cls, value) + member._value_ = value + return member def _reduce_ex_by_name(self, proto): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 3f39073f5d564ed..8e84d929429ebf0 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -5,7 +5,7 @@ import unittest import threading from collections import OrderedDict -from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto +from enum import Enum, IntEnum, StrEnum, EnumMeta, Flag, IntFlag, unique, auto from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support @@ -48,14 +48,9 @@ class FlagStooges(Flag): FlagStooges = exc # for pickle test and subclass tests -try: - class StrEnum(str, Enum): - 'accepts only string values' - class Name(StrEnum): - BDFL = 'Guido van Rossum' - FLUFL = 'Barry Warsaw' -except Exception as exc: - Name = exc +class Name(StrEnum): + BDFL = 'Guido van Rossum' + FLUFL = 'Barry Warsaw' try: Question = Enum('Question', 'who what when where why', module=__name__) @@ -665,14 +660,13 @@ class phy(str, Enum): tau = 'Tau' self.assertTrue(phy.pi < phy.tau) - def test_strenum_inherited(self): - class StrEnum(str, Enum): - pass + def test_strenum_inherited_methods(self): class phy(StrEnum): pi = 'Pi' tau = 'Tau' self.assertTrue(phy.pi < phy.tau) - + self.assertEqual(phy.pi.upper(), 'PI') + self.assertEqual(phy.tau.count('a'), 1) def test_intenum(self): class WeekDay(IntEnum): @@ -2014,13 +2008,6 @@ class ReformedColor(StrMixin, IntEnum, SomeEnum, AnotherEnum): self.assertTrue(issubclass(ReformedColor, int)) def test_multiple_inherited_mixin(self): - class StrEnum(str, Enum): - def __new__(cls, *args, **kwargs): - for a in args: - if not isinstance(a, str): - raise TypeError("Enumeration '%s' (%s) is not" - " a string" % (a, type(a).__name__)) - return str.__new__(cls, *args, **kwargs) @unique class Decision1(StrEnum): REVERT = "REVERT" @@ -2043,6 +2030,33 @@ def test_empty_globals(self): local_ls = {} exec(code, global_ns, local_ls) + def test_strenum(self): + class GoodStrEnum(StrEnum): + one = '1' + two = '2' + three = b'3', 'ascii' + four = b'4', 'latin1', 'strict' + with self.assertRaisesRegex(TypeError, '1 is not a string'): + class FirstFailedStrEnum(StrEnum): + one = 1 + two = '2' + with self.assertRaisesRegex(TypeError, "2 is not a string"): + class SecondFailedStrEnum(StrEnum): + one = '1' + two = 2, + three = '3' + with self.assertRaisesRegex(TypeError, '2 is not a string'): + class ThirdFailedStrEnum(StrEnum): + one = '1' + two = 2 + with self.assertRaisesRegex(TypeError, 'encoding must be a string, not %r' % (sys.getdefaultencoding, )): + class ThirdFailedStrEnum(StrEnum): + one = '1' + two = b'2', sys.getdefaultencoding + with self.assertRaisesRegex(TypeError, 'errors must be a string, not 9'): + class ThirdFailedStrEnum(StrEnum): + one = '1' + two = b'2', 'ascii', 9 class TestOrder(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst b/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst new file mode 100644 index 000000000000000..605c346f37a81d8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst @@ -0,0 +1,2 @@ +StrEnum added: it ensures that all members are already strings or string +candidates From f37cb918470907290f4774f869839b62b5942588 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 22 Sep 2020 08:08:54 +0300 Subject: [PATCH 339/486] bpo-41756: Refactor gen_send_ex(). (GH-22330) --- Objects/genobject.c | 193 +++++++++++++++++++++++--------------------- 1 file changed, 99 insertions(+), 94 deletions(-) diff --git a/Objects/genobject.c b/Objects/genobject.c index 24aca988354c5ae..f0943ae847c5438 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -136,13 +136,15 @@ gen_dealloc(PyGenObject *gen) PyObject_GC_Del(gen); } -static PyObject * -gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_return_value) +static PySendResult +gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, + int exc, int closing) { PyThreadState *tstate = _PyThreadState_GET(); PyFrameObject *f = gen->gi_frame; PyObject *result; + *presult = NULL; if (f != NULL && _PyFrame_IsExecuting(f)) { const char *msg = "generator already executing"; if (PyCoro_CheckExact(gen)) { @@ -152,7 +154,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_retur msg = "async generator already executing"; } PyErr_SetString(PyExc_ValueError, msg); - return NULL; + return PYGEN_ERROR; } if (f == NULL || _PyFrameHasCompleted(f)) { if (PyCoro_CheckExact(gen) && !closing) { @@ -165,19 +167,12 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_retur } else if (arg && !exc) { /* `gen` is an exhausted generator: - only set exception if called from send(). */ - if (PyAsyncGen_CheckExact(gen)) { - PyErr_SetNone(PyExc_StopAsyncIteration); - } - else { - if (is_return_value != NULL) { - *is_return_value = 1; - Py_RETURN_NONE; - } - PyErr_SetNone(PyExc_StopIteration); - } + only return value if called from send(). */ + *presult = Py_None; + Py_INCREF(*presult); + return PYGEN_RETURN; } - return NULL; + return PYGEN_ERROR; } assert(_PyFrame_IsRunnable(f)); @@ -193,7 +188,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_retur "just-started async generator"; } PyErr_SetString(PyExc_TypeError, msg); - return NULL; + return PYGEN_ERROR; } } else { /* Push arg onto the frame's value stack */ @@ -229,69 +224,77 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing, int *is_retur /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ - if (result && _PyFrameHasCompleted(f)) { - if (result == Py_None) { - /* Delay exception instantiation if we can */ - if (PyAsyncGen_CheckExact(gen)) { - PyErr_SetNone(PyExc_StopAsyncIteration); - Py_CLEAR(result); - } - else if (arg) { - if (is_return_value != NULL) { - *is_return_value = 1; - } - else { - /* Set exception if not called by gen_iternext() */ - PyErr_SetNone(PyExc_StopIteration); - Py_CLEAR(result); - } - } - else { - Py_CLEAR(result); - } + if (result) { + if (!_PyFrameHasCompleted(f)) { + *presult = result; + return PYGEN_NEXT; } - else { - /* Async generators cannot return anything but None */ - assert(!PyAsyncGen_CheckExact(gen)); - if (is_return_value != NULL) { - *is_return_value = 1; - } - else { - _PyGen_SetStopIterationValue(result); - Py_CLEAR(result); - } + assert(result == Py_None || !PyAsyncGen_CheckExact(gen)); + if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) { + /* Return NULL if called by gen_iternext() */ + Py_CLEAR(result); } } - else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { - const char *msg = "generator raised StopIteration"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine raised StopIteration"; + else { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + const char *msg = "generator raised StopIteration"; + if (PyCoro_CheckExact(gen)) { + msg = "coroutine raised StopIteration"; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "async generator raised StopIteration"; + } + _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "async generator raised StopIteration"; + else if (PyAsyncGen_CheckExact(gen) && + PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) + { + /* code in `gen` raised a StopAsyncIteration error: + raise a RuntimeError. + */ + const char *msg = "async generator raised StopAsyncIteration"; + _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); } - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - - } - else if (!result && PyAsyncGen_CheckExact(gen) && - PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) - { - /* code in `gen` raised a StopAsyncIteration error: - raise a RuntimeError. - */ - const char *msg = "async generator raised StopAsyncIteration"; - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); } - if ((is_return_value && *is_return_value) || !result || _PyFrameHasCompleted(f)) { - /* generator can't be rerun, so release the frame */ - /* first clean reference cycle through stored exception traceback */ - _PyErr_ClearExcState(&gen->gi_exc_state); - gen->gi_frame->f_gen = NULL; - gen->gi_frame = NULL; - Py_DECREF(f); - } + /* generator can't be rerun, so release the frame */ + /* first clean reference cycle through stored exception traceback */ + _PyErr_ClearExcState(&gen->gi_exc_state); + gen->gi_frame->f_gen = NULL; + gen->gi_frame = NULL; + Py_DECREF(f); + + *presult = result; + return result ? PYGEN_RETURN : PYGEN_ERROR; +} + +PySendResult +PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **result) +{ + assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen)); + assert(result != NULL); + assert(arg != NULL); + + return gen_send_ex2(gen, arg, result, 0, 0); +} +static PyObject * +gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +{ + PyObject *result; + if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { + _PyGen_SetStopIterationValue(result); + } + Py_CLEAR(result); + } return result; } @@ -299,22 +302,16 @@ PyDoc_STRVAR(send_doc, "send(arg) -> send 'arg' into generator,\n\ return next yielded value or raise StopIteration."); -PyObject * -_PyGen_Send(PyGenObject *gen, PyObject *arg) +static PyObject * +gen_send(PyGenObject *gen, PyObject *arg) { - return gen_send_ex(gen, arg, 0, 0, NULL); + return gen_send_ex(gen, arg, 0, 0); } -PySendResult -PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **result) +PyObject * +_PyGen_Send(PyGenObject *gen, PyObject *arg) { - assert(result != NULL); - - int is_return_value = 0; - if ((*result = gen_send_ex(gen, arg, 0, 0, &is_return_value)) == NULL) { - return PYGEN_ERROR; - } - return is_return_value ? PYGEN_RETURN : PYGEN_NEXT; + return gen_send(gen, arg); } PyDoc_STRVAR(close_doc, @@ -396,7 +393,7 @@ gen_close(PyGenObject *gen, PyObject *args) } if (err == 0) PyErr_SetNone(PyExc_GeneratorExit); - retval = gen_send_ex(gen, Py_None, 1, 1, NULL); + retval = gen_send_ex(gen, Py_None, 1, 1); if (retval) { const char *msg = "generator ignored GeneratorExit"; if (PyCoro_CheckExact(gen)) { @@ -444,7 +441,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, gen->gi_frame->f_state = state; Py_DECREF(yf); if (err < 0) - return gen_send_ex(gen, Py_None, 1, 0, NULL); + return gen_send_ex(gen, Py_None, 1, 0); goto throw_here; } if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { @@ -496,10 +493,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, assert(gen->gi_frame->f_lasti >= 0); gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send_ex(gen, val, 0, 0, NULL); + ret = gen_send(gen, val); Py_DECREF(val); } else { - ret = gen_send_ex(gen, Py_None, 1, 0, NULL); + ret = gen_send_ex(gen, Py_None, 1, 0); } } return ret; @@ -553,7 +550,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } PyErr_Restore(typ, val, tb); - return gen_send_ex(gen, Py_None, 1, 0, NULL); + return gen_send_ex(gen, Py_None, 1, 0); failed_throw: /* Didn't use our arguments, so restore their original refcounts */ @@ -582,7 +579,15 @@ gen_throw(PyGenObject *gen, PyObject *args) static PyObject * gen_iternext(PyGenObject *gen) { - return gen_send_ex(gen, NULL, 0, 0, NULL); + PyObject *result; + assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen)); + if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) { + if (result != Py_None) { + _PyGen_SetStopIterationValue(result); + } + Py_CLEAR(result); + } + return result; } /* @@ -767,7 +772,7 @@ static PyMemberDef gen_memberlist[] = { }; static PyMethodDef gen_methods[] = { - {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc}, + {"send",(PyCFunction)gen_send, METH_O, send_doc}, {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ @@ -1082,13 +1087,13 @@ coro_wrapper_dealloc(PyCoroWrapper *cw) static PyObject * coro_wrapper_iternext(PyCoroWrapper *cw) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0, NULL); + return gen_iternext((PyGenObject *)cw->cw_coroutine); } static PyObject * coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) { - return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0, NULL); + return gen_send((PyGenObject *)cw->cw_coroutine, arg); } static PyObject * @@ -1601,7 +1606,7 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg) } o->ags_gen->ag_running_async = 1; - result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0, NULL); + result = gen_send((PyGenObject*)o->ags_gen, arg); result = async_gen_unwrap_value(o->ags_gen, result); if (result == NULL) { @@ -1957,7 +1962,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) assert(o->agt_state == AWAITABLE_STATE_ITER); - retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0, NULL); + retval = gen_send((PyGenObject *)gen, arg); if (o->agt_args) { return async_gen_unwrap_value(o->agt_gen, retval); } else { From 6860b821277a1b7fbc202d7b3c4111ece002aeb6 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Tue, 22 Sep 2020 01:43:55 -0400 Subject: [PATCH 340/486] bpo-40181: Remove '/' reminder in IDLE calltips. (GH-22350) The marker was added to the language in 3.8 and 3.7 only gets security patches. --- Lib/idlelib/NEWS.txt | 3 +++ Lib/idlelib/calltip.py | 4 ---- Lib/idlelib/idle_test/test_calltip.py | 8 +++----- .../next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst | 2 ++ 4 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index fd762077b1b3cf9..f8ec6ab50529719 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-40181: In calltips, stop reminding that '/' marks the end of +positional-only arguments. + bpo-41468: Improve IDLE run crash error message (which users should never see). diff --git a/Lib/idlelib/calltip.py b/Lib/idlelib/calltip.py index d4092c7847186bf..b02f87207d8db18 100644 --- a/Lib/idlelib/calltip.py +++ b/Lib/idlelib/calltip.py @@ -118,7 +118,6 @@ def get_entity(expression): _first_param = re.compile(r'(?<=\()\w*\,?\s*') _default_callable_argspec = "See source or doc" _invalid_method = "invalid method signature" -_argument_positional = " # '/' marks preceding args as positional-only." def get_argspec(ob): '''Return a string describing the signature of a callable object, or ''. @@ -146,9 +145,6 @@ def get_argspec(ob): else: argspec = '' - if '/' in argspec and len(argspec) < _MAX_COLS - len(_argument_positional): - # Add explanation TODO remove after 3.7, before 3.9. - argspec += _argument_positional if isinstance(fob, type) and argspec == '()': # If fob has no argument, use default callable argspec. argspec = _default_callable_argspec diff --git a/Lib/idlelib/idle_test/test_calltip.py b/Lib/idlelib/idle_test/test_calltip.py index d386b5cd8132124..4d53df17d8cc7c7 100644 --- a/Lib/idlelib/idle_test/test_calltip.py +++ b/Lib/idlelib/idle_test/test_calltip.py @@ -61,18 +61,16 @@ class SB: __call__ = None if List.__doc__ is not None: tiptest(List, - f'(iterable=(), /){calltip._argument_positional}' + f'(iterable=(), /)' f'\n{List.__doc__}') tiptest(list.__new__, '(*args, **kwargs)\n' 'Create and return a new object. ' 'See help(type) for accurate signature.') tiptest(list.__init__, - '(self, /, *args, **kwargs)' - + calltip._argument_positional + '\n' + + '(self, /, *args, **kwargs)\n' 'Initialize self. See help(type(self)) for accurate signature.') - append_doc = (calltip._argument_positional - + "\nAppend object to the end of the list.") + append_doc = "\nAppend object to the end of the list." tiptest(list.append, '(self, object, /)' + append_doc) tiptest(List.append, '(self, object, /)' + append_doc) tiptest([].append, '(object, /)' + append_doc) diff --git a/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst b/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst new file mode 100644 index 000000000000000..b6866e19c4d41ac --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst @@ -0,0 +1,2 @@ +In calltips, stop reminding that '/' marks the end of positional-only +arguments. From 95f106d18d66ea705a046475cab6e086ae970a67 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 22 Sep 2020 00:05:27 -0700 Subject: [PATCH 341/486] Enum: add extended AutoNumber example (GH-22349) --- Doc/library/enum.rst | 26 ++++++++++++++++++++++++++ Misc/ACKS | 1 + 2 files changed, 27 insertions(+) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 843d961afc4f723..3e9b1f9db3550f8 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -925,6 +925,32 @@ Using an auto-numbering :meth:`__new__` would look like:: >>> Color.GREEN.value 2 +To make a more general purpose ``AutoNumber``, add ``*args`` to the signature:: + + >>> class AutoNumber(NoValue): + ... def __new__(cls, *args): # this is the only change from above + ... value = len(cls.__members__) + 1 + ... obj = object.__new__(cls) + ... obj._value_ = value + ... return obj + ... + +Then when you inherit from ``AutoNumber`` you can write your own ``__init__`` +to handle any extra arguments:: + + >>> class Swatch(AutoNumber): + ... def __init__(self, pantone='unknown'): + ... self.pantone = pantone + ... AUBURN = '3497' + ... SEA_GREEN = '1246' + ... BLEACHED_CORAL = () # New color, no Pantone code yet! + ... + >>> Swatch.SEA_GREEN + + >>> Swatch.SEA_GREEN.pantone + '1246' + >>> Swatch.BLEACHED_CORAL.pantone + 'unknown' .. note:: diff --git a/Misc/ACKS b/Misc/ACKS index 01ee1cb42d39d0d..e4bd3da6b6c40ab 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1723,6 +1723,7 @@ Févry Thibault Lowe Thiderman Nicolas M. Thiéry James Thomas +Reuben Thomas Robin Thomas Brian Thorne Christopher Thorne From 7d63980d98e000c3b9a6e8494ce2f6cdcc153bb0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 22 Sep 2020 12:42:28 +0200 Subject: [PATCH 342/486] Py_IS_TYPE() macro uses Py_TYPE() (GH-22341) --- Include/object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/object.h b/Include/object.h index 10f1d6a3dff2dd1..6ee4ee7848551e3 100644 --- a/Include/object.h +++ b/Include/object.h @@ -141,7 +141,7 @@ static inline PyTypeObject* _Py_TYPE(const PyObject *ob) { static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { - return ob->ob_type == type; + return Py_TYPE(ob) == type; } #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) From f3e13f110b5aba8777718d9c7ac7f6d1f222d85f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 22 Sep 2020 16:16:46 +0300 Subject: [PATCH 343/486] bpo-40670: More reliable validation of statements in timeit.Timer. (GH-22358) It now accepts "empty" statements (only whitespaces and comments) and rejects misindentent statements. --- Lib/test/test_timeit.py | 9 +++++++++ Lib/timeit.py | 1 + .../Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst diff --git a/Lib/test/test_timeit.py b/Lib/test/test_timeit.py index e02d4a71a9ba7c9..72a104fc1a6790d 100644 --- a/Lib/test/test_timeit.py +++ b/Lib/test/test_timeit.py @@ -77,6 +77,9 @@ def test_timer_invalid_stmt(self): self.assertRaises(SyntaxError, timeit.Timer, stmt='break') self.assertRaises(SyntaxError, timeit.Timer, stmt='continue') self.assertRaises(SyntaxError, timeit.Timer, stmt='from timeit import *') + self.assertRaises(SyntaxError, timeit.Timer, stmt=' pass') + self.assertRaises(SyntaxError, timeit.Timer, + setup='while False:\n pass', stmt=' break') def test_timer_invalid_setup(self): self.assertRaises(ValueError, timeit.Timer, setup=None) @@ -86,6 +89,12 @@ def test_timer_invalid_setup(self): self.assertRaises(SyntaxError, timeit.Timer, setup='break') self.assertRaises(SyntaxError, timeit.Timer, setup='continue') self.assertRaises(SyntaxError, timeit.Timer, setup='from timeit import *') + self.assertRaises(SyntaxError, timeit.Timer, setup=' pass') + + def test_timer_empty_stmt(self): + timeit.Timer(stmt='') + timeit.Timer(stmt=' \n\t\f') + timeit.Timer(stmt='# comment') fake_setup = "import timeit\ntimeit._fake_timer.setup()" fake_stmt = "import timeit\ntimeit._fake_timer.inc()" diff --git a/Lib/timeit.py b/Lib/timeit.py index 6c3ec01067f2d41..9dfd454936e6b8c 100755 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -72,6 +72,7 @@ def inner(_it, _timer{init}): _t0 = _timer() for _i in _it: {stmt} + pass _t1 = _timer() return _t1 - _t0 """ diff --git a/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst b/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst new file mode 100644 index 000000000000000..0436194d736ab4f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst @@ -0,0 +1,3 @@ +More reliable validation of statements in :class:`timeit.Timer`. It now +accepts "empty" statements (only whitespaces and comments) and rejects +misindentent statements. From 3dbc1bbea1bb4a4694a532567e388610d0f2e37d Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 22 Sep 2020 08:01:17 -0700 Subject: [PATCH 344/486] bpo-41817: use new StrEnum to ensure all members are strings (GH-22348) * use new StrEnum to ensure all members are strings --- Lib/tkinter/__init__.py | 14 +++++++------- .../2020-09-22-00-23-30.bpo-41817.bnh-VG.rst | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 1067ab6a8b8a1d9..3919397d3cead24 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -144,12 +144,12 @@ def _splitdict(tk, v, cut_minus=True, conv=None): return dict -class EventType(str, enum.Enum): +class EventType(enum.StrEnum): KeyPress = '2' - Key = KeyPress, + Key = KeyPress KeyRelease = '3' ButtonPress = '4' - Button = ButtonPress, + Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' @@ -180,10 +180,10 @@ class EventType(str, enum.Enum): Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented - VirtualEvent = '35', # undocumented - Activate = '36', - Deactivate = '37', - MouseWheel = '38', + VirtualEvent = '35' # undocumented + Activate = '36' + Deactivate = '37' + MouseWheel = '38' def __str__(self): return self.name diff --git a/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst b/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst new file mode 100644 index 000000000000000..6a634bb613260b6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst @@ -0,0 +1 @@ +fix `tkinter.EventType` Enum so all members are strings, and none are tuples From c1b3c0fe4227fe51098bf056a4501aae2dd10d10 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 22 Sep 2020 16:53:03 +0100 Subject: [PATCH 345/486] bpo-41602: raise SIGINT exit code on KeyboardInterrupt from pymain_run_module (#21956) Closes bpo issue 41602 --- Lib/test/test_runpy.py | 94 +++++++++++++++++-- .../2020-08-25-19-25-36.bpo-41602.Z64s0I.rst | 1 + Modules/main.c | 4 + 3 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index f8274a981cb1c03..2954dfedc7e4282 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -1,15 +1,18 @@ # Test the runpy module -import unittest -import os +import contextlib +import importlib.machinery, importlib.util import os.path -import sys +import pathlib +import py_compile import re +import signal +import subprocess +import sys import tempfile -import importlib, importlib.machinery, importlib.util -import py_compile +import textwrap +import unittest import warnings -import pathlib -from test.support import verbose, no_tracing +from test.support import no_tracing, verbose from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -752,5 +755,82 @@ def test_encoding(self): self.assertEqual(result['s'], "non-ASCII: h\xe9") +class TestExit(unittest.TestCase): + STATUS_CONTROL_C_EXIT = 0xC000013A + EXPECTED_CODE = ( + STATUS_CONTROL_C_EXIT + if sys.platform == "win32" + else -signal.SIGINT + ) + @staticmethod + @contextlib.contextmanager + def tmp_path(*args, **kwargs): + with temp_dir() as tmp_fn: + yield pathlib.Path(tmp_fn) + + + def run(self, *args, **kwargs): + with self.tmp_path() as tmp: + self.ham = ham = tmp / "ham.py" + ham.write_text( + textwrap.dedent( + """\ + raise KeyboardInterrupt + """ + ) + ) + super().run(*args, **kwargs) + + def assertSigInt(self, *args, **kwargs): + proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) + self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) + self.assertEqual(proc.returncode, self.EXPECTED_CODE) + + def test_pymain_run_file(self): + self.assertSigInt([sys.executable, self.ham]) + + def test_pymain_run_file_runpy_run_module(self): + tmp = self.ham.parent + run_module = tmp / "run_module.py" + run_module.write_text( + textwrap.dedent( + """\ + import runpy + runpy.run_module("ham") + """ + ) + ) + self.assertSigInt([sys.executable, run_module], cwd=tmp) + + def test_pymain_run_file_runpy_run_module_as_main(self): + tmp = self.ham.parent + run_module_as_main = tmp / "run_module_as_main.py" + run_module_as_main.write_text( + textwrap.dedent( + """\ + import runpy + runpy._run_module_as_main("ham") + """ + ) + ) + self.assertSigInt([sys.executable, run_module_as_main], cwd=tmp) + + def test_pymain_run_command_run_module(self): + self.assertSigInt( + [sys.executable, "-c", "import runpy; runpy.run_module('ham')"], + cwd=self.ham.parent, + ) + + def test_pymain_run_command(self): + self.assertSigInt([sys.executable, "-c", "import ham"], cwd=self.ham.parent) + + def test_pymain_run_stdin(self): + self.assertSigInt([sys.executable], input="import ham", cwd=self.ham.parent) + + def test_pymain_run_module(self): + ham = self.ham + self.assertSigInt([sys.executable, "-m", ham.stem], cwd=ham.parent) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst new file mode 100644 index 000000000000000..fa3d2f1aa374ec5 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst @@ -0,0 +1 @@ +Add tests for SIGINT handling in the runpy module. diff --git a/Modules/main.c b/Modules/main.c index 4a76f4461bf6108..2cc891f61aadd1b 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -287,7 +287,11 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(module); return pymain_exit_err_print(); } + _Py_UnhandledKeyboardInterrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); + if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { + _Py_UnhandledKeyboardInterrupt = 1; + } Py_DECREF(runpy); Py_DECREF(runmodule); Py_DECREF(module); From be70ace0f6795a1b68fe34aabec6c829f795a952 Mon Sep 17 00:00:00 2001 From: Bas van Beek <43369155+BvB93@users.noreply.github.com> Date: Tue, 22 Sep 2020 17:55:34 +0200 Subject: [PATCH 346/486] bpo-41810: Reintroduce `types.EllipsisType`, `.NoneType` & `.NotImplementedType` (GH-22336) closes issue 41810 --- Doc/library/constants.rst | 13 +++++++----- Doc/library/types.rst | 21 +++++++++++++++++++ Doc/whatsnew/3.10.rst | 8 +++++++ Lib/test/test_types.py | 10 +++++++++ Lib/types.py | 3 +++ Misc/ACKS | 1 + .../2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 3 +++ 7 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index f17e1a37875168f..38dd552a0363acc 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -19,19 +19,21 @@ A small number of constants live in the built-in namespace. They are: .. data:: None - The sole value of the type ``NoneType``. ``None`` is frequently used to - represent the absence of a value, as when default arguments are not passed to a - function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`. + An object frequently used to represent the absence of a value, as when + default arguments are not passed to a function. Assignments to ``None`` + are illegal and raise a :exc:`SyntaxError`. + ``None`` is the sole instance of the :data:`NoneType` type. .. data:: NotImplemented - Special value which should be returned by the binary special methods + A special value which should be returned by the binary special methods (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. It should not be evaluated in a boolean context. + ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type. .. note:: @@ -59,8 +61,9 @@ A small number of constants live in the built-in namespace. They are: .. index:: single: ...; ellipsis literal .. data:: Ellipsis - The same as the ellipsis literal "``...``". Special value used mostly in conjunction + The same as the ellipsis literal "``...``". Special value used mostly in conjunction with extended slicing syntax for user-defined container data types. + ``Ellipsis`` is the sole instance of the :data:`types.EllipsisType` type. .. data:: __debug__ diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 79acdf4499afd2f..25fa750f2ccacf1 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -103,6 +103,13 @@ If you instantiate any of these types, note that signatures may vary between Pyt Standard names are defined for the following types: +.. data:: NoneType + + The type of :data:`None`. + + .. versionadded:: 3.10 + + .. data:: FunctionType LambdaType @@ -186,6 +193,13 @@ Standard names are defined for the following types: .. versionadded:: 3.7 +.. data:: NotImplementedType + + The type of :data:`NotImplemented`. + + .. versionadded:: 3.10 + + .. data:: MethodDescriptorType The type of methods of some built-in data types such as :meth:`str.join`. @@ -236,6 +250,13 @@ Standard names are defined for the following types: Defaults to ``None``. Previously the attribute was optional. +.. data:: EllipsisType + + The type of :data:`Ellipsis`. + + .. versionadded:: 3.10 + + .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) The type of traceback objects such as found in ``sys.exc_info()[2]``. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index ce888fec1d8c972..f88281a934ca195 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -145,6 +145,14 @@ Add :data:`sys.orig_argv` attribute: the list of the original command line arguments passed to the Python executable. (Contributed by Victor Stinner in :issue:`23427`.) +types +----- + +Reintroduced the :data:`types.EllipsisType`, :data:`types.NoneType` +and :data:`types.NotImplementedType` classes, providing a new set +of types readily interpretable by type checkers. +(Contributed by Bas van Beek in :issue:`41810`.) + unittest -------- diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index f499fb9c8c51a44..52a59d54f044d9f 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -713,6 +713,16 @@ def test_or_type_repr(self): assert repr(int | None) == "int | None" assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]" + def test_ellipsis_type(self): + self.assertIsInstance(Ellipsis, types.EllipsisType) + + def test_notimplemented_type(self): + self.assertIsInstance(NotImplemented, types.NotImplementedType) + + def test_none_type(self): + self.assertIsInstance(None, types.NoneType) + + class MappingProxyTests(unittest.TestCase): mappingproxy = types.MappingProxyType diff --git a/Lib/types.py b/Lib/types.py index 9642e7212caac64..532f4806fc02264 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -296,5 +296,8 @@ def wrapped(*args, **kwargs): GenericAlias = type(list[int]) Union = type(int | str) +EllipsisType = type(Ellipsis) +NoneType = type(None) +NotImplementedType = type(NotImplemented) __all__ = [n for n in globals() if n[:1] != '_'] diff --git a/Misc/ACKS b/Misc/ACKS index e4bd3da6b6c40ab..7b743464c1c1c81 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -134,6 +134,7 @@ Robin Becker Torsten Becker Bill Bedford Michał Bednarski +Bas van Beek Ian Beer Stefan Behnel Reimer Behrends diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst new file mode 100644 index 000000000000000..515aea9e36ce956 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -0,0 +1,3 @@ +:data:`types.EllipsisType`, :data:`types.NotImplementedType` and +:data:`types.NoneType` have been reintroduced, providing a new set +of types readily interpretable by static type checkers. From cdeddcb878a1550da2bab657e5c5b9fbddca7fa0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Tue, 22 Sep 2020 13:21:58 -0400 Subject: [PATCH 347/486] bpo-35764: Rewrite the IDLE Calltips doc section (GH-22363) --- Doc/library/idle.rst | 47 ++++++++++--------- Lib/idlelib/NEWS.txt | 2 + Lib/idlelib/help.html | 43 +++++++++-------- .../2020-09-22-11-13-45.bpo-35764.VoNa8y.rst | 1 + 4 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 43096b014fed349..a59a5d3a465703c 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -527,30 +527,33 @@ by typing '_' after '.', either before or after the box is opened. Calltips ^^^^^^^^ -A calltip is shown when one types :kbd:`(` after the name of an *accessible* -function. A name expression may include dots and subscripts. A calltip -remains until it is clicked, the cursor is moved out of the argument area, -or :kbd:`)` is typed. When the cursor is in the argument part of a definition, -the menu or shortcut display a calltip. - -A calltip consists of the function signature and the first line of the -docstring. For builtins without an accessible signature, the calltip -consists of all lines up the fifth line or the first blank line. These -details may change. - -The set of *accessible* functions depends on what modules have been imported -into the user process, including those imported by Idle itself, -and what definitions have been run, all since the last restart. +A calltip is shown automatically when one types :kbd:`(` after the name +of an *accessible* function. A function name expression may include +dots and subscripts. A calltip remains until it is clicked, the cursor +is moved out of the argument area, or :kbd:`)` is typed. Whenever the +cursor is in the argument part of a definition, select Edit and "Show +Call Tip" on the menu or enter its shortcut to display a calltip. + +The calltip consists of the function's signature and docstring up to +the latter's first blank line or the fifth non-blank line. (Some builtin +functions lack an accessible signature.) A '/' or '*' in the signature +indicates that the preceding or following arguments are passed by +position or name (keyword) only. Details are subject to change. + +In Shell, the accessible functions depends on what modules have been +imported into the user process, including those imported by Idle itself, +and which definitions have been run, all since the last restart. For example, restart the Shell and enter ``itertools.count(``. A calltip -appears because Idle imports itertools into the user process for its own use. -(This could change.) Enter ``turtle.write(`` and nothing appears. Idle does -not import turtle. The menu or shortcut do nothing either. Enter -``import turtle`` and then ``turtle.write(`` will work. - -In an editor, import statements have no effect until one runs the file. One -might want to run a file after writing the import statements at the top, -or immediately run an existing file before editing. +appears because Idle imports itertools into the user process for its own +use. (This could change.) Enter ``turtle.write(`` and nothing appears. +Idle does not itself import turtle. The menu entry and shortcut also do +nothing. Enter ``import turtle``. Thereafter, ``turtle.write(`` +will display a calltip. + +In an editor, import statements have no effect until one runs the file. +One might want to run a file after writing import statements, after +adding function definitions, or after opening an existing file. .. _code-context: diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index f8ec6ab50529719..7eea0a47aa6e8e9 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2020-10-05? ====================================== +bpo-35764: Rewrite the Calltips doc section. + bpo-40181: In calltips, stop reminding that '/' marks the end of positional-only arguments. diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index b2853cffe0c26d6..0edd3917e1ffa5c 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -509,26 +509,29 @@

    Automatic indentation

    Calltips

    -

    A calltip is shown when one types ( after the name of an accessible -function. A name expression may include dots and subscripts. A calltip -remains until it is clicked, the cursor is moved out of the argument area, -or ) is typed. When the cursor is in the argument part of a definition, -the menu or shortcut display a calltip.

    -

    A calltip consists of the function signature and the first line of the -docstring. For builtins without an accessible signature, the calltip -consists of all lines up the fifth line or the first blank line. These -details may change.

    -

    The set of accessible functions depends on what modules have been imported -into the user process, including those imported by Idle itself, -and what definitions have been run, all since the last restart.

    +

    A calltip is shown automatically when one types ( after the name +of an accessible function. A function name expression may include +dots and subscripts. A calltip remains until it is clicked, the cursor +is moved out of the argument area, or ) is typed. Whenever the +cursor is in the argument part of a definition, select Edit and “Show +Call Tip” on the menu or enter its shortcut to display a calltip.

    +

    The calltip consists of the function’s signature and docstring up to +the latter’s first blank line or the fifth non-blank line. (Some builtin +functions lack an accessible signature.) A ‘/’ or ‘*’ in the signature +indicates that the preceding or following arguments are passed by +position or name (keyword) only. Details are subject to change.

    +

    In Shell, the accessible functions depends on what modules have been +imported into the user process, including those imported by Idle itself, +and which definitions have been run, all since the last restart.

    For example, restart the Shell and enter itertools.count(. A calltip -appears because Idle imports itertools into the user process for its own use. -(This could change.) Enter turtle.write( and nothing appears. Idle does -not import turtle. The menu or shortcut do nothing either. Enter -import turtle and then turtle.write( will work.

    -

    In an editor, import statements have no effect until one runs the file. One -might want to run a file after writing the import statements at the top, -or immediately run an existing file before editing.

    +appears because Idle imports itertools into the user process for its own +use. (This could change.) Enter turtle.write( and nothing appears. +Idle does not itself import turtle. The menu entry and shortcut also do +nothing. Enter import turtle. Thereafter, turtle.write( +will display a calltip.

    +

    In an editor, import statements have no effect until one runs the file. +One might want to run a file after writing import statements, after +adding function definitions, or after opening an existing file.

    Code Context

    @@ -975,7 +978,7 @@

    Navigation



    - Last updated on Sep 09, 2020. + Last updated on Sep 22, 2020. Found a bug?
    diff --git a/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst b/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst new file mode 100644 index 000000000000000..eb62d3699d5febb --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst @@ -0,0 +1 @@ +Rewrite the Calltips doc section. From b278344aebf67a0b731875e05dfba711fbfec779 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Tue, 22 Sep 2020 13:00:07 -0700 Subject: [PATCH 348/486] bpo-41816: `StrEnum.__str__` is `str.__str__` (GH-22362) use `str.__str__` for `StrEnum` so that `str(StrEnum.member)` is the same as directly accessing the string value of the `StrEnum` member --- Doc/library/enum.rst | 15 +++++++++++++++ Lib/enum.py | 2 ++ Lib/test/test_enum.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 3e9b1f9db3550f8..118002bef19f851 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -622,6 +622,11 @@ an incorrect member:: Before :class:`StrEnum`, ``Directions.NORTH`` would have been the :class:`tuple` ``('north',)``. +.. note:: + + Unlike other Enum's, ``str(StrEnum.member)`` will return the value of the + member instead of the usual ``"EnumClass.member"``. + .. versionadded:: 3.10 @@ -1243,3 +1248,13 @@ all named flags and all named combinations of flags that are in the value:: >>> Color(7) # not named combination +``StrEnum`` and :meth:`str.__str__` +""""""""""""""""""""""""""""""""""" + +An important difference between :class:`StrEnum` and other Enums is the +:meth:`__str__` method; because :class:`StrEnum` members are strings, some +parts of Python will read the string data directly, while others will call +:meth:`str()`. To make those two operations have the same result, +:meth:`StrEnum.__str__` will be the same as :meth:`str.__str__` so that +``str(StrEnum.member) == StrEnum.member`` is true. + diff --git a/Lib/enum.py b/Lib/enum.py index 589b17fd6977754..40ff25b9cdad37b 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -718,6 +718,8 @@ def __new__(cls, *values): member._value_ = value return member + __str__ = str.__str__ + def _reduce_ex_by_name(self, proto): return self.name diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 8e84d929429ebf0..3431040f98a726d 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2036,6 +2036,37 @@ class GoodStrEnum(StrEnum): two = '2' three = b'3', 'ascii' four = b'4', 'latin1', 'strict' + self.assertEqual(GoodStrEnum.one, '1') + self.assertEqual(str(GoodStrEnum.one), '1') + self.assertEqual(GoodStrEnum.one, str(GoodStrEnum.one)) + self.assertEqual(GoodStrEnum.one, '{}'.format(GoodStrEnum.one)) + # + class DumbMixin: + def __str__(self): + return "don't do this" + class DumbStrEnum(DumbMixin, StrEnum): + five = '5' + six = '6' + seven = '7' + self.assertEqual(DumbStrEnum.seven, '7') + self.assertEqual(str(DumbStrEnum.seven), "don't do this") + # + class EnumMixin(Enum): + def hello(self): + print('hello from %s' % (self, )) + class HelloEnum(EnumMixin, StrEnum): + eight = '8' + self.assertEqual(HelloEnum.eight, '8') + self.assertEqual(HelloEnum.eight, str(HelloEnum.eight)) + # + class GoodbyeMixin: + def goodbye(self): + print('%s wishes you a fond farewell') + class GoodbyeEnum(GoodbyeMixin, EnumMixin, StrEnum): + nine = '9' + self.assertEqual(GoodbyeEnum.nine, '9') + self.assertEqual(GoodbyeEnum.nine, str(GoodbyeEnum.nine)) + # with self.assertRaisesRegex(TypeError, '1 is not a string'): class FirstFailedStrEnum(StrEnum): one = 1 From 4c15ba971c1886f92825cbac5342ca28cb36a8c4 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 22 Sep 2020 20:01:12 -0700 Subject: [PATCH 349/486] bpo-41513: Improve order of adding fractional values. Improve variable names. (GH-22368) --- Modules/mathmodule.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 935759ec671ca52..5cd31b7dd4acfbb 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2502,8 +2502,8 @@ exactly equal) was verified for 1 billion random inputs with n=5. [7] static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { - const double T27 = 134217729.0; /* ldexp(1.0, 27)+1.0) */ - double x, csum = 1.0, oldcsum, scale, frac=0.0, frac_mid=0.0, frac_lo=0.0; + const double T27 = 134217729.0; /* ldexp(1.0, 27) + 1.0) */ + double x, scale, oldcsum, csum = 1.0, frac1 = 0.0, frac2 = 0.0, frac3 = 0.0; double t, hi, lo, h; int max_e; Py_ssize_t i; @@ -2539,18 +2539,18 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac1 += (oldcsum - csum) + x; x = 2.0 * hi * lo; assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac_mid += (oldcsum - csum) + x; + frac2 += (oldcsum - csum) + x; assert(csum + lo * lo == csum); - frac_lo += lo * lo; + frac3 += lo * lo; } - h = sqrt(csum - 1.0 + (frac_lo + frac_mid + frac)); + h = sqrt(csum - 1.0 + (frac1 + frac2 + frac3)); x = h; t = x * T27; @@ -2562,21 +2562,21 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac1 += (oldcsum - csum) + x; x = -2.0 * hi * lo; assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac_mid += (oldcsum - csum) + x; + frac2 += (oldcsum - csum) + x; x = -lo * lo; assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac_lo += (oldcsum - csum) + x; + frac3 += (oldcsum - csum) + x; - x = csum - 1.0 + (frac_lo + frac_mid + frac); + x = csum - 1.0 + (frac1 + frac2 + frac3); return (h + x / (2.0 * h)) / scale; } /* When max_e < -1023, ldexp(1.0, -max_e) overflows. @@ -2591,9 +2591,9 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) assert(fabs(csum) >= fabs(x)); oldcsum = csum; csum += x; - frac += (oldcsum - csum) + x; + frac1 += (oldcsum - csum) + x; } - return max * sqrt(csum - 1.0 + frac); + return max * sqrt(csum - 1.0 + frac1); } #define NUM_STACK_ELEMS 16 From 499db01567337ba1fd3e046ff65afdbdda363c41 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 23 Sep 2020 05:33:21 -0500 Subject: [PATCH 350/486] bpo-1635741: Port _lsprof extension to multi-phase init (PEP 489) (GH-22220) --- ...2020-09-12-18-34-34.bpo-1635741.lh335O.rst | 2 + Modules/_lsprof.c | 215 ++++++++++-------- Modules/clinic/_lsprof.c.h | 21 +- 3 files changed, 139 insertions(+), 99 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst new file mode 100644 index 000000000000000..ba61819df9e082f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst @@ -0,0 +1,2 @@ +Port the :mod:`_lsprof` extension module to multi-phase initialization +(:pep:`489`). diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index a4ba7d523003381..78d464d1481d75e 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -55,12 +55,22 @@ module _lsprof class _lsprof.Profiler "ProfilerObject *" "&ProfilerType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e349ac952152f336]*/ -static PyTypeObject PyProfiler_Type; #include "clinic/_lsprof.c.h" -#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) -#define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type) +typedef struct { + PyTypeObject *profiler_type; + PyTypeObject *stats_entry_type; + PyTypeObject *stats_subentry_type; +} _lsprof_state; + +static inline _lsprof_state* +_lsprof_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_lsprof_state *)state; +} /*** External Timers ***/ @@ -478,28 +488,24 @@ static PyStructSequence_Field profiler_subentry_fields[] = { }; static PyStructSequence_Desc profiler_entry_desc = { - "_lsprof.profiler_entry", /* name */ - NULL, /* doc */ - profiler_entry_fields, - 6 + .name = "_lsprof.profiler_entry", + .doc = "", + .fields = profiler_entry_fields, + .n_in_sequence = 6 }; static PyStructSequence_Desc profiler_subentry_desc = { - "_lsprof.profiler_subentry", /* name */ - NULL, /* doc */ - profiler_subentry_fields, - 5 + .name = "_lsprof.profiler_subentry", + .doc = "", + .fields = profiler_subentry_fields, + .n_in_sequence = 5 }; -static int initialized; -static PyTypeObject StatsEntryType; -static PyTypeObject StatsSubEntryType; - - typedef struct { PyObject *list; PyObject *sublist; double factor; + _lsprof_state *state; } statscollector_t; static int statsForSubEntry(rotating_node_t *node, void *arg) @@ -509,7 +515,7 @@ static int statsForSubEntry(rotating_node_t *node, void *arg) ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; int err; PyObject *sinfo; - sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, + sinfo = PyObject_CallFunction((PyObject*) collect->state->stats_subentry_type, "((Olldd))", entry->userObj, sentry->callcount, @@ -547,7 +553,7 @@ static int statsForEntry(rotating_node_t *node, void *arg) collect->sublist = Py_None; } - info = PyObject_CallFunction((PyObject*) &StatsEntryType, + info = PyObject_CallFunction((PyObject*) collect->state->stats_entry_type, "((OllddO))", entry->userObj, entry->callcount, @@ -566,6 +572,8 @@ static int statsForEntry(rotating_node_t *node, void *arg) /*[clinic input] _lsprof.Profiler.getstats + cls: defining_class + list of profiler_entry objects. getstats() -> list of profiler_entry objects @@ -592,10 +600,11 @@ profiler_subentry objects: [clinic start generated code]*/ static PyObject * -_lsprof_Profiler_getstats_impl(ProfilerObject *self) -/*[clinic end generated code: output=9461b451e9ef0f24 input=ade04fa384ce450a]*/ +_lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=1806ef720019ee03 input=445e193ef4522902]*/ { statscollector_t collect; + collect.state = PyType_GetModuleState(cls); if (pending_exception(self)) { return NULL; } @@ -735,7 +744,9 @@ profiler_dealloc(ProfilerObject *op) flush_unmatched(op); clearEntries(op); Py_XDECREF(op->externalTimer); - Py_TYPE(op)->tp_free(op); + PyTypeObject *tp = Py_TYPE(op); + tp->tp_free(op); + Py_DECREF(tp); } static int @@ -782,91 +793,107 @@ Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\ is, in seconds).\n\ "); -static PyTypeObject PyProfiler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lsprof.Profiler", /* tp_name */ - sizeof(ProfilerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)profiler_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - profiler_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - profiler_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)profiler_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ +static PyType_Slot _lsprof_profiler_type_spec_slots[] = { + {Py_tp_doc, (void *)profiler_doc}, + {Py_tp_methods, profiler_methods}, + {Py_tp_dealloc, profiler_dealloc}, + {Py_tp_init, profiler_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_free, PyObject_Del}, + {0, 0} +}; + +static PyType_Spec _lsprof_profiler_type_spec = { + .name = "_lsprof.Profiler", + .basicsize = sizeof(ProfilerObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = _lsprof_profiler_type_spec_slots, }; static PyMethodDef moduleMethods[] = { {NULL, NULL} }; +static int +_lsprof_traverse(PyObject *module, visitproc visit, void *arg) +{ + _lsprof_state *state = _lsprof_get_state(module); + Py_VISIT(state->profiler_type); + Py_VISIT(state->stats_entry_type); + Py_VISIT(state->stats_subentry_type); + return 0; +} + +static int +_lsprof_clear(PyObject *module) +{ + _lsprof_state *state = _lsprof_get_state(module); + Py_CLEAR(state->profiler_type); + Py_CLEAR(state->stats_entry_type); + Py_CLEAR(state->stats_subentry_type); + return 0; +} + +static void +_lsprof_free(void *module) +{ + _lsprof_clear((PyObject *)module); +} + +static int +_lsprof_exec(PyObject *module) +{ + _lsprof_state *state = PyModule_GetState(module); + + state->profiler_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &_lsprof_profiler_type_spec, NULL); + if (state->profiler_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->profiler_type) < 0) { + return -1; + } + + state->stats_entry_type = PyStructSequence_NewType(&profiler_entry_desc); + if (state->stats_entry_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->stats_entry_type) < 0) { + return -1; + } + + state->stats_subentry_type = PyStructSequence_NewType(&profiler_subentry_desc); + if (state->stats_subentry_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->stats_subentry_type) < 0) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _lsprofslots[] = { + {Py_mod_exec, _lsprof_exec}, + {0, NULL} +}; static struct PyModuleDef _lsprofmodule = { PyModuleDef_HEAD_INIT, - "_lsprof", - "Fast profiler", - -1, - moduleMethods, - NULL, - NULL, - NULL, - NULL + .m_name = "_lsprof", + .m_doc = "Fast profiler", + .m_size = sizeof(_lsprof_state), + .m_methods = moduleMethods, + .m_slots = _lsprofslots, + .m_traverse = _lsprof_traverse, + .m_clear = _lsprof_clear, + .m_free = _lsprof_free }; PyMODINIT_FUNC PyInit__lsprof(void) { - PyObject *module, *d; - module = PyModule_Create(&_lsprofmodule); - if (module == NULL) - return NULL; - d = PyModule_GetDict(module); - if (PyType_Ready(&PyProfiler_Type) < 0) - return NULL; - PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); - - if (!initialized) { - if (PyStructSequence_InitType2(&StatsEntryType, - &profiler_entry_desc) < 0) - return NULL; - if (PyStructSequence_InitType2(&StatsSubEntryType, - &profiler_subentry_desc) < 0) - return NULL; - } - Py_INCREF((PyObject*) &StatsEntryType); - Py_INCREF((PyObject*) &StatsSubEntryType); - PyModule_AddObject(module, "profiler_entry", - (PyObject*) &StatsEntryType); - PyModule_AddObject(module, "profiler_subentry", - (PyObject*) &StatsSubEntryType); - initialized = 1; - return module; + return PyModuleDef_Init(&_lsprofmodule); } diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index 50762e3ff35960e..5d9c209eab85635 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -31,14 +31,25 @@ PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, " inlinetime inline time (not in further subcalls)"); #define _LSPROF_PROFILER_GETSTATS_METHODDEF \ - {"getstats", (PyCFunction)_lsprof_Profiler_getstats, METH_NOARGS, _lsprof_Profiler_getstats__doc__}, + {"getstats", (PyCFunction)(void(*)(void))_lsprof_Profiler_getstats, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_getstats__doc__}, static PyObject * -_lsprof_Profiler_getstats_impl(ProfilerObject *self); +_lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); static PyObject * -_lsprof_Profiler_getstats(ProfilerObject *self, PyObject *Py_UNUSED(ignored)) +_lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _lsprof_Profiler_getstats_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":getstats", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _lsprof_Profiler_getstats_impl(self, cls); + +exit: + return return_value; } -/*[clinic end generated code: output=24c525812713e00f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4727cfebecdd22d input=a9049054013a1b77]*/ From 30876e0175f7399deffce8f9d5dab77f86c638b3 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 23 Sep 2020 05:38:16 -0500 Subject: [PATCH 351/486] bpo-1635741, unicodedata: add ucd_type parameter to UCD_Check() macro (GH-22328) Co-authored-by: Victor Stinner --- Modules/unicodedata.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 8a1198a2b712d93..8e11cfc4dafa923 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -92,7 +92,10 @@ static PyMemberDef DB_members[] = { /* forward declaration */ static PyTypeObject UCD_Type; -#define UCD_Check(o) Py_IS_TYPE(o, &UCD_Type) + +// Check if self is an instance of UCD_Type. +// Return 0 if self is NULL (when the PyCapsule C API is used). +#define UCD_Check(self, ucd_type) (self != NULL && Py_IS_TYPE(self, ucd_type)) static PyObject* new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), @@ -135,7 +138,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, long rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -223,7 +226,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, double rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -268,7 +271,7 @@ unicodedata_UCD_category_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->category; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed != 0xFF) index = old->category_changed; @@ -295,7 +298,7 @@ unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->bidirectional; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -324,7 +327,7 @@ unicodedata_UCD_combining_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->combining; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -352,7 +355,7 @@ unicodedata_UCD_mirrored_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->mirrored; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -379,7 +382,7 @@ unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->east_asian_width; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -413,7 +416,7 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) code = (int)c; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) return PyUnicode_FromString(""); /* unassigned */ @@ -460,7 +463,7 @@ get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *co { if (code >= 0x110000) { *index = 0; - } else if (self && UCD_Check(self) && + } else if (UCD_Check(self, &UCD_Type) && get_old_record(self, code)->category_changed==0) { /* unassigned in old version */ *index = 0; @@ -558,7 +561,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) continue; } /* normalization changes */ - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); if (value != 0) { stack[stackptr++] = value; @@ -799,7 +802,7 @@ is_normalized_quickcheck(PyObject *self, PyObject *input, { /* An older version of the database is requested, quickchecks must be disabled. */ - if (self && UCD_Check(self)) + if (UCD_Check(self, &UCD_Type)) return NO; Py_ssize_t i, len; @@ -1066,7 +1069,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) return 0; - if (self && UCD_Check(self)) { + if (UCD_Check(self, &UCD_Type)) { /* in 3.2.0 there are no aliases and named sequences */ const change_record *old; if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) From f76fee0288d5db2c9ac51508b329e9eb0608dace Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 14:04:57 +0200 Subject: [PATCH 352/486] bpo-41834: Remove _Py_CheckRecursionLimit variable (GH-22359) Remove the global _Py_CheckRecursionLimit variable: it has been replaced by ceval.recursion_limit of the PyInterpreterState structure. There is no need to keep the variable for the stable ABI, since Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() were not usable in Python 3.8 and older: these macros accessed PyThreadState members, whereas the PyThreadState structure is opaque in the limited C API. --- Doc/whatsnew/3.10.rst | 4 ++++ Include/internal/pycore_ceval.h | 2 -- .../2020-09-22-14-47-12.bpo-41834.nrOrDU.rst | 3 +++ PC/python3dll.c | 1 - Python/ceval.c | 16 +++------------- Tools/c-analyzer/TODO | 1 - Tools/c-analyzer/known.tsv | 1 - 7 files changed, 10 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index f88281a934ca195..606fad2fdcf0592 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -314,3 +314,7 @@ Removed * Removed ``PyUnicode_AsUnicodeCopy()``. Please use :c:func:`PyUnicode_AsUCS4Copy` or :c:func:`PyUnicode_AsWideCharString` (Contributed by Inada Naoki in :issue:`41103`.) + +* Removed ``_Py_CheckRecursionLimit`` variable: it has been replaced by + ``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` structure. + (Contributed by Victor Stinner in :issue:`41834`.) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index aafb533b57d5f04..bbb667ea32d27ef 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -63,8 +63,6 @@ extern void _PyEval_ReleaseLock(PyThreadState *tstate); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -PyAPI_DATA(int) _Py_CheckRecursionLimit; - #ifdef USE_STACKCHECK /* With USE_STACKCHECK macro defined, trigger stack checks in _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */ diff --git a/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst b/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst new file mode 100644 index 000000000000000..07043dce5a6274e --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst @@ -0,0 +1,3 @@ +Remove the ``_Py_CheckRecursionLimit`` variable: it has been replaced by +``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` +structure. Patch by Victor Stinner. diff --git a/PC/python3dll.c b/PC/python3dll.c index f72f2c8af19d2bf..ff69ea7ca5efaa4 100644 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -663,7 +663,6 @@ EXPORT_FUNC(PyWeakref_NewProxy) EXPORT_FUNC(PyWeakref_NewRef) EXPORT_FUNC(PyWrapper_New) -EXPORT_DATA(_Py_CheckRecursionLimit) EXPORT_DATA(_Py_EllipsisObject) EXPORT_DATA(_Py_FalseStruct) EXPORT_DATA(_Py_NoneStruct) diff --git a/Python/ceval.c b/Python/ceval.c index 3de372f45a25170..4bb4b820b8e17a5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -741,15 +741,12 @@ Py_MakePendingCalls(void) /* The interpreter's recursion limit */ #ifndef Py_DEFAULT_RECURSION_LIMIT -#define Py_DEFAULT_RECURSION_LIMIT 1000 +# define Py_DEFAULT_RECURSION_LIMIT 1000 #endif -int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; - void _PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) { - _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; #ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS _gil_initialize(&ceval->gil); #endif @@ -797,14 +794,11 @@ Py_SetRecursionLimit(int new_limit) { PyThreadState *tstate = _PyThreadState_GET(); tstate->interp->ceval.recursion_limit = new_limit; - if (_Py_IsMainInterpreter(tstate)) { - _Py_CheckRecursionLimit = new_limit; - } } /* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() - if the recursion_depth reaches _Py_CheckRecursionLimit. - If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit + if the recursion_depth reaches recursion_limit. + If USE_STACKCHECK, the macro decrements recursion_limit to guarantee that _Py_CheckRecursiveCall() is regularly called. Without USE_STACKCHECK, there is no need for this. */ int @@ -819,10 +813,6 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); return -1; } - if (_Py_IsMainInterpreter(tstate)) { - /* Needed for ABI backwards-compatibility (see bpo-31857) */ - _Py_CheckRecursionLimit = recursion_limit; - } #endif if (tstate->recursion_critical) /* Somebody asked that we don't check for recursion. */ diff --git a/Tools/c-analyzer/TODO b/Tools/c-analyzer/TODO index 1134055f9a8fd81..f5c1a92f856959c 100644 --- a/Tools/c-analyzer/TODO +++ b/Tools/c-analyzer/TODO @@ -66,7 +66,6 @@ Objects/tupleobject.c:_Py_tuple_zero_allocs Py_ssize_t _Py_ Objects/typeobject.c:next_version_tag static unsigned int next_version_tag Python/Python-ast.c:init_types():initialized static int initialized Python/bootstrap_hash.c:urandom_cache static struct { int fd; dev_t st_dev; ino_t st_ino; } urandom_cache -Python/ceval.c:_Py_CheckRecursionLimit int _Py_CheckRecursionLimit Python/ceval.c:lltrace static int lltrace Python/ceval.c:make_pending_calls():busy static int busy Python/dynload_shlib.c:handles static struct { dev_t dev; ino_t ino; void *handle; } handles[128] diff --git a/Tools/c-analyzer/known.tsv b/Tools/c-analyzer/known.tsv index f92b45e5b4d8599..f8c12a3944d9b7d 100644 --- a/Tools/c-analyzer/known.tsv +++ b/Tools/c-analyzer/known.tsv @@ -805,7 +805,6 @@ Objects/iterobject.c - PyCallIter_Type variable PyTypeObject PyCallIter_Type Objects/capsule.c - PyCapsule_Type variable PyTypeObject PyCapsule_Type Objects/cellobject.c - PyCell_Type variable PyTypeObject PyCell_Type Objects/methodobject.c - PyCFunction_Type variable PyTypeObject PyCFunction_Type -Python/ceval.c - _Py_CheckRecursionLimit variable int _Py_CheckRecursionLimit Objects/descrobject.c - PyClassMethodDescr_Type variable PyTypeObject PyClassMethodDescr_Type Objects/funcobject.c - PyClassMethod_Type variable PyTypeObject PyClassMethod_Type Objects/codeobject.c - PyCode_Type variable PyTypeObject PyCode_Type From 596e658320a4cb3dfa27b2c09890dd1e2c30cde8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 14:05:32 +0200 Subject: [PATCH 353/486] bpo-40521: Fix PyUnicode_InternInPlace() (GH-22376) Fix PyUnicode_InternInPlace() when the INTERNED_STRINGS macro is not defined (when the EXPERIMENTAL_ISOLATED_SUBINTERPRETERS macro is defined). --- Objects/unicodeobject.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fd0e8e008adae4c..f32ab417c364caf 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15754,6 +15754,10 @@ PyUnicode_InternInPlace(PyObject **p) this. */ Py_SET_REFCNT(s, Py_REFCNT(s) - 2); _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; +#else + // PyDict expects that interned strings have their hash + // (PyASCIIObject.hash) already computed. + (void)unicode_hash(s); #endif } From a9474c72ac692eb355aa445671674f5f004a0f82 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 14:06:55 +0200 Subject: [PATCH 354/486] bpo-40941: Fix fold_tuple_on_constants() compiler warnings (GH-22378) Add explicit casts to fix compiler warnings in fold_tuple_on_constants(). The limit of constants per code is now INT_MAX, rather than UINT_MAX. --- Python/compile.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Python/compile.c b/Python/compile.c index 3ebf221cf02b716..0f9e5c276c7b7ba 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -6100,13 +6100,11 @@ fold_tuple_on_constants(struct instr *inst, PyTuple_SET_ITEM(newconst, i, constant); } Py_ssize_t index = PyList_GET_SIZE(consts); -#if SIZEOF_SIZE_T > SIZEOF_INT - if ((size_t)index >= UINT_MAX - 1) { + if ((size_t)index >= (size_t)INT_MAX - 1) { Py_DECREF(newconst); PyErr_SetString(PyExc_OverflowError, "too many constants"); return -1; } -#endif if (PyList_Append(consts, newconst)) { Py_DECREF(newconst); return -1; @@ -6116,7 +6114,7 @@ fold_tuple_on_constants(struct instr *inst, inst[i].i_opcode = NOP; } inst[n].i_opcode = LOAD_CONST; - inst[n].i_oparg = index; + inst[n].i_oparg = (int)index; return 0; } From 7e87ccf2e5f8526fa85db79b00414ab44c593edb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 14:07:16 +0200 Subject: [PATCH 355/486] bpo-40941: Fix stackdepth compiler warnings (GH-22377) Explicitly cast a difference of two pointers to int: PyFrameObject.f_stackdepth is an int. --- Python/ceval.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 4bb4b820b8e17a5..6430e792b8c5d8b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1433,9 +1433,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (_Py_TracingPossible(ceval2) && tstate->c_tracefunc != NULL && !tstate->tracing) { int err; - /* see maybe_call_line_trace + /* see maybe_call_line_trace() for expository comments */ - f->f_stackdepth = stack_pointer-f->f_valuestack; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); err = maybe_call_line_trace(tstate->c_tracefunc, tstate->c_traceobj, @@ -2265,7 +2265,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); f->f_lasti -= sizeof(_Py_CODEUNIT); f->f_state = FRAME_SUSPENDED; - f->f_stackdepth = stack_pointer-f->f_valuestack; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); goto exiting; } @@ -2282,7 +2282,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) retval = w; } f->f_state = FRAME_SUSPENDED; - f->f_stackdepth = stack_pointer-f->f_valuestack; + f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); goto exiting; } From f6cd7a0e50dc5af2e84a63e6da17de6343cd0bb7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 14:08:38 +0200 Subject: [PATCH 356/486] bpo-40170: Use inline _PyType_HasFeature() function (GH-22375) Use _PyType_HasFeature() in the _io module and in structseq implementation. Replace PyType_HasFeature() opaque function call with _PyType_HasFeature() inlined function. --- Modules/_io/iobase.c | 3 ++- Objects/structseq.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index a8e55c34799bd5b..195862df5dc0600 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -349,8 +349,9 @@ iobase_dealloc(iobase *self) if (_PyIOBase_finalize((PyObject *) self) < 0) { /* When called from a heap type's dealloc, the type will be decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ - if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) + if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) { Py_INCREF(Py_TYPE(self)); + } return; } _PyObject_GC_UNTRACK(self); diff --git a/Objects/structseq.c b/Objects/structseq.c index bd20ce3fbdcb942..8ae8f28cbc580f9 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -94,7 +94,7 @@ structseq_dealloc(PyStructSequence *obj) Py_XDECREF(obj->ob_item[i]); } PyObject_GC_Del(obj); - if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { Py_DECREF(tp); } } From d5b7fc661fb2ae74e0388a5c156b346f564a4ed2 Mon Sep 17 00:00:00 2001 From: sblondon Date: Wed, 23 Sep 2020 14:28:58 +0200 Subject: [PATCH 357/486] bpo-37779 : Add information about the overriding behavior of ConfigParser.read (GH-15177) Co-Authored-By: Kyle Stanley Co-Authored-By: Paul Ganssle --- Doc/library/configparser.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 2e22a549ee2813d..646e8a317f52c3e 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -135,6 +135,30 @@ involves the ``DEFAULT`` section which provides default values for all other sections [1]_. Note also that keys in sections are case-insensitive and stored in lowercase [1]_. +It is possible to read several configurations into a single +:class:`ConfigParser`, where the most recently added configuration has the +highest priority. Any conflicting keys are taken from the more recent +configuration while the previously existing keys are retained. + +.. doctest:: + + >>> another_config = configparser.ConfigParser() + >>> another_config.read('example.ini') + ['example.ini'] + >>> another_config['topsecret.server.com']['Port'] + '50022' + >>> another_config.read_string("[topsecret.server.com]\nPort=48484") + >>> another_config['topsecret.server.com']['Port'] + '48484' + >>> another_config.read_dict({"topsecret.server.com": {"Port": 21212}}) + >>> another_config['topsecret.server.com']['Port'] + '21212' + >>> another_config['topsecret.server.com']['ForwardX11'] + 'no' + +This behaviour is equivalent to a :meth:`ConfigParser.read` call with several +files passed to the *filenames* parameter. + Supported Datatypes ------------------- From 23800be3e3f6cda8e102c2a3298173f186527e41 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 23 Sep 2020 09:44:31 -0400 Subject: [PATCH 358/486] bpo-41841: Prepare IDLE News for 3.10 (GH-22379) --- Lib/idlelib/NEWS.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 7eea0a47aa6e8e9..38b98644942f9e1 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,5 +1,5 @@ -What's New in IDLE 3.9.0 (since 3.8.0) -Released on 2020-10-05? +What's New in IDLE 3.10.0 (since 3.9.0) +Released on 2021-10-04? ====================================== @@ -8,6 +8,11 @@ bpo-35764: Rewrite the Calltips doc section. bpo-40181: In calltips, stop reminding that '/' marks the end of positional-only arguments. + +What's New in IDLE 3.9.0 (since 3.8.0) +Released on 2020-10-05? +====================================== + bpo-41468: Improve IDLE run crash error message (which users should never see). From 937a5be2d85981ad5e0106de220cab71ed6cb195 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 23 Sep 2020 11:17:26 -0400 Subject: [PATCH 359/486] bpo-41844: Add IDLE section to What's New 3.9 (GN-22382) --- Doc/whatsnew/3.9.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e9fc496e47e24e2..95188b7493ad448 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -387,6 +387,20 @@ http HTTP status codes ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` are added to :class:`http.HTTPStatus`. (Contributed by Dong-hee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) +IDLE and idlelib +---------------- + +Add option to toggle cursor blink off. (Contributed by Zackery Spytz +in :issue:`4603`.) + +Escape key now closes IDLE completion windows. (Contributed by Johnny +Najera in :issue:`38944`.) + +Add keywords to module name completion list. (Contributed by Terry J. +Reedy in :issue:`37765`.) + +The changes above have been backported to 3.8 maintenance releases. + imaplib ------- From e0e1c2e516381fd72ef45fd2169eccd25aa4b0d0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 23 Sep 2020 11:19:05 -0400 Subject: [PATCH 360/486] bpo-33822: Update IDLE section of What's New 3.8 (GH-22383) --- Doc/whatsnew/3.8.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index a2fa17811b3fc89..6a9fa3415694654 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -870,8 +870,18 @@ clipboard. Converting strings from Tcl to Python and back now never fails. (Many people worked on this for eight years but the problem was finally solved by Serhiy Storchaka in :issue:`13153`.) +New in 3.8.1: + +Add option to toggle cursor blink off. (Contributed by Zackery Spytz +in :issue:`4603`.) + +Escape key now closes IDLE completion windows. (Contributed by Johnny +Najera in :issue:`38944`.) + The changes above have been backported to 3.7 maintenance releases. +Add keywords to module name completion list. (Contributed by Terry J. +Reedy in :issue:`37765`.) inspect ------- From 76420512fa91163b8ff2b13d0b3ef2c362219148 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 23 Sep 2020 12:43:45 -0600 Subject: [PATCH 361/486] bpo-30155: Add macros to get tzinfo from datetime instances (GH-21633) Add PyDateTime_DATE_GET_TZINFO() and PyDateTime_TIME_GET_TZINFO() macros. --- Doc/c-api/datetime.rst | 11 +++++++++++ Doc/whatsnew/3.10.rst | 6 ++++++ Include/datetime.h | 8 ++++++++ Lib/test/datetimetester.py | 14 ++++++++++---- .../C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst | 3 +++ Modules/_datetimemodule.c | 11 +++-------- Modules/_testcapimodule.c | 6 ++++-- Modules/_zoneinfo.c | 4 +--- 8 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index bd4f1ff446bcf4c..415ce4cac67f154 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -185,6 +185,11 @@ must not be ``NULL``, and the type is not checked: Return the microsecond, as an int from 0 through 999999. +.. c:function:: PyObject* PyDateTime_DATE_GET_TZINFO(PyDateTime_DateTime *o) + + Return the tzinfo (which may be ``None``). + + .. versionadded:: 3.10 Macros to extract fields from time objects. The argument must be an instance of :c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, @@ -209,6 +214,12 @@ and the type is not checked: Return the microsecond, as an int from 0 through 999999. +.. c:function:: PyObject* PyDateTime_TIME_GET_TZINFO(PyDateTime_Time *o) + + Return the tzinfo (which may be ``None``). + + .. versionadded:: 3.10 + Macros to extract fields from time delta objects. The argument must be an instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 606fad2fdcf0592..1228f2695496c58 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -231,6 +231,12 @@ New Features Python executable. (Contributed by Victor Stinner in :issue:`23427`.) +* The :c:func:`PyDateTime_DATE_GET_TZINFO` and + :c:func:`PyDateTime_TIME_GET_TZINFO` macros have been added for accessing + the ``tzinfo`` attributes of :class:`datetime.datetime` and + :class:`datetime.time` objects. + (Contributed by Zackery Spytz in :issue:`30155`.) + Porting to Python 3.10 ---------------------- diff --git a/Include/datetime.h b/Include/datetime.h index 5d9f2558f924d0b..bb565201a164d7e 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -115,6 +115,10 @@ typedef struct /* Apply for date and datetime instances. */ + +// o is a pointer to a time or a datetime object. +#define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) + #define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ ((PyDateTime_Date*)o)->data[1]) #define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) @@ -128,6 +132,8 @@ typedef struct (((PyDateTime_DateTime*)o)->data[8] << 8) | \ ((PyDateTime_DateTime*)o)->data[9]) #define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) +#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ + ((PyDateTime_DateTime *)(o))->tzinfo : Py_None) /* Apply for time instances. */ #define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) @@ -138,6 +144,8 @@ typedef struct (((PyDateTime_Time*)o)->data[4] << 8) | \ ((PyDateTime_Time*)o)->data[5]) #define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) +#define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ + ((PyDateTime_Time *)(o))->tzinfo : Py_None) /* Apply for time delta instances */ #define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 520a51df8799976..8b61c26f9e5c24c 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -5991,30 +5991,36 @@ class DateTimeSubclass(datetime): for klass in [datetime, DateTimeSubclass]: for args in [(1993, 8, 26, 22, 12, 55, 99999), - (1993, 8, 26, 22, 12, 55, 99999)]: + (1993, 8, 26, 22, 12, 55, 99999, + timezone.utc)]: d = klass(*args) with self.subTest(cls=klass, date=args): - hour, minute, second, microsecond = _testcapi.PyDateTime_DATE_GET(d) + hour, minute, second, microsecond, tzinfo = \ + _testcapi.PyDateTime_DATE_GET(d) self.assertEqual(hour, d.hour) self.assertEqual(minute, d.minute) self.assertEqual(second, d.second) self.assertEqual(microsecond, d.microsecond) + self.assertIs(tzinfo, d.tzinfo) def test_PyDateTime_TIME_GET(self): class TimeSubclass(time): pass for klass in [time, TimeSubclass]: - for args in [(12, 30, 20, 10), (12, 30, 20, 10)]: + for args in [(12, 30, 20, 10), + (12, 30, 20, 10, timezone.utc)]: d = klass(*args) with self.subTest(cls=klass, date=args): - hour, minute, second, microsecond = _testcapi.PyDateTime_TIME_GET(d) + hour, minute, second, microsecond, tzinfo = \ + _testcapi.PyDateTime_TIME_GET(d) self.assertEqual(hour, d.hour) self.assertEqual(minute, d.minute) self.assertEqual(second, d.second) self.assertEqual(microsecond, d.microsecond) + self.assertIs(tzinfo, d.tzinfo) def test_timezones_offset_zero(self): utc0, utc1, non_utc = _testcapi.get_timezones_offset_zero() diff --git a/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst b/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst new file mode 100644 index 000000000000000..a276759da793388 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst @@ -0,0 +1,3 @@ +Add :c:func:`PyDateTime_DATE_GET_TZINFO` and +:c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo`` +attributes of :class:`datetime.datetime` and :class:`datetime.time` objects. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 74a54e74ae0fec9..0631272429f4f14 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -115,14 +115,9 @@ class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCa #define SET_TD_SECONDS(o, v) ((o)->seconds = (v)) #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) -/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns - * p->hastzinfo. - */ -#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) -#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_Time *)(p))->tzinfo : Py_None) -#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) +#define HASTZINFO _PyDateTime_HAS_TZINFO +#define GET_TIME_TZINFO PyDateTime_TIME_GET_TZINFO +#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO /* M is a char or int claiming to be a valid month. The macro is equivalent * to the two-sided Python test * 1 <= M <= 12 diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7536d29535038c7..0e098779696b737 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2677,8 +2677,9 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) minute = PyDateTime_DATE_GET_MINUTE(obj); second = PyDateTime_DATE_GET_SECOND(obj); microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); - return Py_BuildValue("(llll)", hour, minute, second, microsecond); + return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2690,8 +2691,9 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) minute = PyDateTime_TIME_GET_MINUTE(obj); second = PyDateTime_TIME_GET_SECOND(obj); microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); - return Py_BuildValue("(llll)", hour, minute, second, microsecond); + return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); } static PyObject * diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 2cee65fac6dd042..bee59b8d2ae0cc6 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -484,9 +484,7 @@ zoneinfo_tzname(PyObject *self, PyObject *dt) return tti->tzname; } -#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) -#define GET_DT_TZINFO(p) \ - (HASTZINFO(p) ? ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) +#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO static PyObject * zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) From ef5e98eb2c47748ad7b7099abb72cfaa40c7d32e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 23:21:19 +0200 Subject: [PATCH 362/486] bpo-41833: threading.Thread now uses the target name (GH-22357) --- Doc/library/threading.rst | 9 +++-- Lib/test/test_threading.py | 34 +++++++++++++++++-- Lib/threading.py | 20 ++++++++--- .../2020-09-22-13-51-14.bpo-41833.6HVDjT.rst | 2 ++ 4 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 7fcf93d74610eba..7eb12fe116bd2da 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -264,8 +264,10 @@ since it is impossible to detect the termination of alien threads. *target* is the callable object to be invoked by the :meth:`run` method. Defaults to ``None``, meaning nothing is called. - *name* is the thread name. By default, a unique name is constructed of the - form "Thread-*N*" where *N* is a small decimal number. + *name* is the thread name. By default, a unique name is constructed + of the form "Thread-*N*" where *N* is a small decimal number, + or "Thread-*N* (target)" where "target" is ``target.__name__`` if the + *target* argument is specified. *args* is the argument tuple for the target invocation. Defaults to ``()``. @@ -280,6 +282,9 @@ since it is impossible to detect the termination of alien threads. base class constructor (``Thread.__init__()``) before doing anything else to the thread. + .. versionchanged:: 3.10 + Use the *target* name if *name* argument is omitted. + .. versionchanged:: 3.3 Added the *daemon* argument. diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index d02d3b346f9cc8e..2f0f3ae0946a579 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -20,6 +20,7 @@ import signal import textwrap +from unittest import mock from test import lock_tests from test import support @@ -86,6 +87,33 @@ def tearDown(self): class ThreadTests(BaseTestCase): + @cpython_only + def test_name(self): + def func(): pass + + thread = threading.Thread(name="myname1") + self.assertEqual(thread.name, "myname1") + + # Convert int name to str + thread = threading.Thread(name=123) + self.assertEqual(thread.name, "123") + + # target name is ignored if name is specified + thread = threading.Thread(target=func, name="myname2") + self.assertEqual(thread.name, "myname2") + + with mock.patch.object(threading, '_counter', return_value=2): + thread = threading.Thread(name="") + self.assertEqual(thread.name, "Thread-2") + + with mock.patch.object(threading, '_counter', return_value=3): + thread = threading.Thread() + self.assertEqual(thread.name, "Thread-3") + + with mock.patch.object(threading, '_counter', return_value=5): + thread = threading.Thread(target=func) + self.assertEqual(thread.name, "Thread-5 (func)") + # Create a bunch of threads, let each do some work, wait until all are # done. def test_various_ops(self): @@ -531,7 +559,7 @@ def test_main_thread_after_fork_from_nonmain_thread(self): import os, threading, sys from test import support - def f(): + def func(): pid = os.fork() if pid == 0: main = threading.main_thread() @@ -544,14 +572,14 @@ def f(): else: support.wait_process(pid, exitcode=0) - th = threading.Thread(target=f) + th = threading.Thread(target=func) th.start() th.join() """ _, out, err = assert_python_ok("-c", code) data = out.decode().replace('\r', '') self.assertEqual(err, b"") - self.assertEqual(data, "Thread-1\nTrue\nTrue\n") + self.assertEqual(data, "Thread-1 (func)\nTrue\nTrue\n") def test_main_thread_during_shutdown(self): # bpo-31516: current_thread() should still point to the main thread diff --git a/Lib/threading.py b/Lib/threading.py index ab29db77a747a2d..06c77f70fe74f59 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -745,10 +745,9 @@ class BrokenBarrierError(RuntimeError): # Helper to generate new thread names -_counter = _count().__next__ -_counter() # Consume 0 so first non-main thread has id 1. -def _newname(template="Thread-%d"): - return template % _counter() +_counter = _count(1).__next__ +def _newname(name_template): + return name_template % _counter() # Active thread administration _active_limbo_lock = _allocate_lock() @@ -800,8 +799,19 @@ class is implemented. assert group is None, "group argument must be None for now" if kwargs is None: kwargs = {} + if name: + name = str(name) + else: + name = _newname("Thread-%d") + if target is not None: + try: + target_name = target.__name__ + name += f" ({target_name})" + except AttributeError: + pass + self._target = target - self._name = str(name or _newname()) + self._name = name self._args = args self._kwargs = kwargs if daemon is not None: diff --git a/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst b/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst new file mode 100644 index 000000000000000..abb3a077d91b814 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst @@ -0,0 +1,2 @@ +The :class:`threading.Thread` constructor now uses the target name if the +*target* argument is specified but the *name* argument is omitted. From 8c1db309464437b7d92fdd63d47a2be20007ae32 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 23:25:40 +0200 Subject: [PATCH 363/486] bpo-41654: Fix compiler warning in MemoryError_dealloc() (GH-22387) Fix warning: Objects\exceptions.c(2324,56): warning C4098: 'MemoryError_dealloc': 'void' function returning a value --- Objects/exceptions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index b08cbdd6aed3572..b14da20db0c4e76 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2321,7 +2321,8 @@ MemoryError_dealloc(PyBaseExceptionObject *self) /* If this is a subclass of MemoryError, we don't need to * do anything in the free-list*/ if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) { - return Py_TYPE(self)->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); + return; } _PyObject_GC_UNTRACK(self); From 54d2a861582726c8b40d11d3e80740bb19cd0dbb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2020 23:25:54 +0200 Subject: [PATCH 364/486] bpo-41428: Fix compiler warnings in unionobject.c (GH-22388) Use Py_ssize_t type rather than int, to store lengths in unionobject.c. Fix warnings: Objects\unionobject.c(189,71): warning C4244: '+=': conversion from 'Py_ssize_t' to 'int', possible loss of data Objects\unionobject.c(182,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data Objects\unionobject.c(205,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data Objects\unionobject.c(437,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data --- Objects/unionobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 0ef7abb4c55c28e..e055a55e91715ca 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -179,8 +179,8 @@ union_richcompare(PyObject *a, PyObject *b, int op) static PyObject* flatten_args(PyObject* args) { - int arg_length = PyTuple_GET_SIZE(args); - int total_args = 0; + Py_ssize_t arg_length = PyTuple_GET_SIZE(args); + Py_ssize_t total_args = 0; // Get number of total args once it's flattened. for (Py_ssize_t i = 0; i < arg_length; i++) { PyObject *arg = PyTuple_GET_ITEM(args, i); @@ -434,7 +434,7 @@ _Py_Union(PyObject *args) unionobject* result = NULL; // Check arguments are unionable. - int nargs = PyTuple_GET_SIZE(args); + Py_ssize_t nargs = PyTuple_GET_SIZE(args); for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(args, iarg); if (arg == NULL) { From 6bcb6bc8e1f4c15fef036c8637c78cee158be91a Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 24 Sep 2020 15:30:09 -0400 Subject: [PATCH 365/486] bpo-41775: Make 'IDLE Shell' the shell title (#22399) 'Python Shell' may have contributed to some beginners confusing 'IDLE' with ' Python'. --- Lib/idlelib/NEWS.txt | 2 ++ Lib/idlelib/pyshell.py | 2 +- Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 38b98644942f9e1..754034200a1f621 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2021-10-04? ====================================== +bpo-41775: Make 'IDLE Shell' the shell title. + bpo-35764: Rewrite the Calltips doc section. bpo-40181: In calltips, stop reminding that '/' marks the end of diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 66ae0f7435daba7..b69916dbe876cae 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -833,7 +833,7 @@ def display_executing_dialog(self): class PyShell(OutputWindow): - shell_title = "Python " + python_version() + " Shell" + shell_title = "IDLE Shell " + python_version() # Override classes ColorDelegator = ModifiedColorDelegator diff --git a/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst b/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst new file mode 100644 index 000000000000000..59605fa40235fb6 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst @@ -0,0 +1 @@ +Use 'IDLE Shell' as shell title From c436e0659e8f1f5797fde71bde12af19240a9666 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Sep 2020 14:04:19 +0100 Subject: [PATCH 366/486] bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395) * Account for control blocks in 'except' in compiler. Fixes #39934. --- Lib/test/test_syntax.py | 9 +++++++++ .../2020-09-24-12-15-45.bpo-39934.YVHTCF.rst | 3 +++ Python/compile.c | 19 +++++++++++-------- 3 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 4657fd1c0d8a72b..09c6eb3375409b6 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -950,6 +950,15 @@ def test_empty_line_after_linecont(self): except SyntaxError: self.fail("Empty line after a line continuation character is valid.") + @support.cpython_only + def test_nested_named_except_blocks(self): + code = "" + for i in range(12): + code += f"{' '*i}try:\n" + code += f"{' '*(i+1)}raise Exception\n" + code += f"{' '*i}except Exception as e:\n" + code += f"{' '*4*12}pass" + self._check_error(code, "too many statically nested blocks") def test_main(): support.run_unittest(SyntaxTestCase) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst new file mode 100644 index 000000000000000..92cd1ba234d215d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst @@ -0,0 +1,3 @@ +Correctly count control blocks in 'except' in compiler. Ensures that a +syntax error, rather a fatal error, occurs for deeply nested, named +exception handlers. diff --git a/Python/compile.c b/Python/compile.c index 0f9e5c276c7b7ba..f2563d7f7a411cb 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -108,8 +108,8 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE }; +enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER }; struct fblockinfo { enum fblocktype fb_type; @@ -1623,9 +1623,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - PyErr_SetString(PyExc_SyntaxError, - "too many statically nested blocks"); - return 0; + return compiler_error(c, "too many statically nested blocks"); } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; @@ -1665,6 +1663,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, { switch (info->fb_type) { case WHILE_LOOP: + case EXCEPTION_HANDLER: return 1; case FOR_LOOP: @@ -1675,7 +1674,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP(c, POP_TOP); return 1; - case EXCEPT: + case TRY_EXCEPT: ADDOP(c, POP_BLOCK); return 1; @@ -3060,14 +3059,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) return 0; ADDOP_JUMP(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) + if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, EXCEPT, body); + compiler_pop_fblock(c, TRY_EXCEPT, body); ADDOP_JUMP(c, JUMP_FORWARD, orelse); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); + /* Runtime will push a block here, so we need to account for that */ + if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) + return 0; for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); @@ -3152,6 +3154,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) } compiler_use_next_block(c, except); } + compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); ADDOP(c, RERAISE); compiler_use_next_block(c, orelse); VISIT_SEQ(c, stmt, s->v.Try.orelse); From 01503d1c07c0bd7aee6e06e6c9f8d1e9dbe3fdfa Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 25 Sep 2020 14:08:50 -0400 Subject: [PATCH 367/486] Fix logging error message (GH-22410) Same changes as #22276 squashed to a single commit. Just hoping to get Travis to cooperate by opening a new PR... Automerge-Triggered-By: @vsajip --- Lib/logging/__init__.py | 3 ++- Lib/test/test_logging.py | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 94361ca75f4f31a..d8a88db378436b8 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -194,7 +194,8 @@ def _checkLevel(level): raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: - raise TypeError("Level not an integer or a valid string: %r" % level) + raise TypeError("Level not an integer or a valid string: %r" + % (level,)) return rv #--------------------------------------------------------------------------- diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index d23fbfb4fe281b1..4cd8c7e25daa938 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3720,7 +3720,15 @@ def tzname(self, dt): utc = UTC() -class FormatterTest(unittest.TestCase): +class AssertErrorMessage: + + def assert_error_message(self, exception, message, *args, **kwargs): + try: + self.assertRaises((), *args, **kwargs) + except exception as e: + self.assertEqual(message, str(e)) + +class FormatterTest(unittest.TestCase, AssertErrorMessage): def setUp(self): self.common = { 'name': 'formatter.test', @@ -3744,12 +3752,6 @@ def get_record(self, name=None): result.update(self.variants[name]) return logging.makeLogRecord(result) - def assert_error_message(self, exception, message, *args, **kwargs): - try: - self.assertRaises(exception, *args, **kwargs) - except exception as e: - self.assertEqual(message, e.message) - def test_percent(self): # Test %-formatting r = self.get_record() @@ -3868,7 +3870,7 @@ def test_format_validate(self): # Testing failure for '-' in field name self.assert_error_message( ValueError, - "invalid field name/expression: 'name-thing'", + "invalid format: invalid field name/expression: 'name-thing'", logging.Formatter, "{name-thing}", style="{" ) # Testing failure for style mismatch @@ -3891,7 +3893,7 @@ def test_format_validate(self): # Testing failure for invalid spec self.assert_error_message( ValueError, - "bad specifier: '.2ff'", + "invalid format: bad specifier: '.2ff'", logging.Formatter, '{process:.2ff}', style='{' ) self.assertRaises(ValueError, logging.Formatter, '{process:.2Z}', style='{') @@ -3901,12 +3903,12 @@ def test_format_validate(self): # Testing failure for mismatch braces self.assert_error_message( ValueError, - "invalid format: unmatched '{' in format spec", + "invalid format: expected '}' before end of string", logging.Formatter, '{process', style='{' ) self.assert_error_message( ValueError, - "invalid format: unmatched '{' in format spec", + "invalid format: Single '}' encountered in format string", logging.Formatter, 'process}', style='{' ) self.assertRaises(ValueError, logging.Formatter, '{{foo!r:4.2}', style='{') @@ -4867,7 +4869,7 @@ def process(self, msg, kwargs): self.assertIs(self.logger.manager, orig_manager) -class LoggerTest(BaseTest): +class LoggerTest(BaseTest, AssertErrorMessage): def setUp(self): super(LoggerTest, self).setUp() @@ -4879,7 +4881,12 @@ def setUp(self): self.addCleanup(logging.shutdown) def test_set_invalid_level(self): - self.assertRaises(TypeError, self.logger.setLevel, object()) + self.assert_error_message( + TypeError, 'Level not an integer or a valid string: None', + self.logger.setLevel, None) + self.assert_error_message( + TypeError, 'Level not an integer or a valid string: (0, 0)', + self.logger.setLevel, (0, 0)) def test_exception(self): msg = 'testing exception: %r' From 94b707b5db332c0c1229b07fb71c2b4ec6c27590 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 26 Sep 2020 12:48:41 +0200 Subject: [PATCH 368/486] bpo-41428: Fix compiler warning in unionobject.c (GH-22416) Use Py_ssize_t type rather than int, to store lengths in unionobject.c. Fix the warning: Objects\unionobject.c(205,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data --- Objects/unionobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/unionobject.c b/Objects/unionobject.c index e055a55e91715ca..8cfb2a664753f8d 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -202,8 +202,8 @@ flatten_args(PyObject* args) PyTypeObject* arg_type = Py_TYPE(arg); if (arg_type == &_Py_UnionType) { PyObject* nested_args = ((unionobject*)arg)->args; - int nested_arg_length = PyTuple_GET_SIZE(nested_args); - for (int j = 0; j < nested_arg_length; j++) { + Py_ssize_t nested_arg_length = PyTuple_GET_SIZE(nested_args); + for (Py_ssize_t j = 0; j < nested_arg_length; j++) { PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); Py_INCREF(nested_arg); PyTuple_SET_ITEM(flattened_args, pos, nested_arg); @@ -231,7 +231,7 @@ dedup_and_flatten_args(PyObject* args) return NULL; } // Add unique elements to an array. - int added_items = 0; + Py_ssize_t added_items = 0; for (Py_ssize_t i = 0; i < arg_length; i++) { int is_duplicate = 0; PyObject* i_element = PyTuple_GET_ITEM(args, i); From e0fe5b85fabc466c676bdf56a0b1a411ff30ea4d Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 26 Sep 2020 19:56:26 +0900 Subject: [PATCH 369/486] bpo-1635741: Port _bisect module to multi-phase init (GH-22415) --- .../2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst | 1 + Modules/_bisectmodule.c | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst new file mode 100644 index 000000000000000..252dab35a1368a0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst @@ -0,0 +1 @@ +Port the :mod:`_bisect` module to the multi-phase initialization API (:pep:`489`). diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 82d800d9a8790f4..277e9755f272117 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -237,18 +237,14 @@ common approach.\n"); static struct PyModuleDef _bisectmodule = { PyModuleDef_HEAD_INIT, - "_bisect", - module_doc, - -1, - bisect_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_bisect", + .m_doc = module_doc, + .m_methods = bisect_methods, + .m_size = 0 }; PyMODINIT_FUNC PyInit__bisect(void) { - return PyModule_Create(&_bisectmodule); + return PyModuleDef_Init(&_bisectmodule); } From 635cb124dc317956860757b9aa814144c7b570d7 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sat, 26 Sep 2020 21:47:25 -0300 Subject: [PATCH 370/486] Revert "Fix all Python Cookbook links (#22205)" (GH-22424) This commit reverts commit ac0333e1e117b7f61ed7ef1dbcdb6e515ada603b as the original links are working again and they provide extended features such as comments and alternative versions. --- Doc/faq/programming.rst | 2 +- Doc/howto/urllib2.rst | 2 +- Doc/library/bisect.rst | 2 +- Doc/library/collections.abc.rst | 2 +- Doc/library/collections.rst | 4 ++-- Doc/library/difflib.rst | 2 +- Doc/library/math.rst | 2 +- Doc/library/random.rst | 2 +- Doc/library/shelve.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/tutorial/whatnow.rst | 2 +- Doc/whatsnew/3.2.rst | 4 ++-- Lib/collections/__init__.py | 2 +- Lib/heapq.py | 2 +- Lib/test/test_math.py | 2 +- Tools/peg_generator/pegen/sccutils.py | 4 ++-- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index fd0adc378bfa6f7..4f4ea8b18176c26 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1141,7 +1141,7 @@ How do you remove duplicates from a list? See the Python Cookbook for a long discussion of many ways to do this: - https://github.com/ActiveState/code/tree/master/recipes/Python/52560_Remove_duplicates/recipe-52560.py + https://code.activestate.com/recipes/52560/ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 38623371fbabff5..046a88af62f0b3e 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -601,5 +601,5 @@ This document was reviewed and revised by John Lee. scripts with a localhost server, I have to prevent urllib from using the proxy. .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe - `_. + `_. diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 6666d55abe2e503..6bf7814b257f4ab 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -60,7 +60,7 @@ The following functions are provided: .. seealso:: `SortedCollection recipe - `_ that uses + `_ that uses bisect to build a full-featured collection class with straight-forward search methods and support for a key-function. The keys are precomputed to save unnecessary calls to the key function during searches. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index a6038098675da21..db0e25bb0772eb2 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -308,7 +308,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: .. seealso:: - * `OrderedSet recipe `_ for an + * `OrderedSet recipe `_ for an example built on :class:`MutableSet`. * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index a7d01b3f397a70f..f538da5e1c9faaf 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -135,12 +135,12 @@ The class can be used to simulate nested scopes and is useful in templating. :attr:`~collections.ChainMap.parents` property. * The `Nested Contexts recipe - `_ has options to control + `_ has options to control whether writes and other mutations apply only to the first mapping or to any mapping in the chain. * A `greatly simplified read-only version of Chainmap - `_. + `_. :class:`ChainMap` Examples and Recipes diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 009b7976dff15fe..aa08988c8b36f71 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -633,7 +633,7 @@ If you want to know how to change the first sequence into the second, use work. * `Simple version control recipe - `_ for a small application + `_ for a small application built with :class:`SequenceMatcher`. diff --git a/Doc/library/math.rst b/Doc/library/math.rst index f152c45a87aa378..bbf64643ff59fc7 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -123,7 +123,7 @@ Number-theoretic and representation functions For further discussion and two alternative approaches, see the `ASPN cookbook recipes for accurate floating point summation - `_\. + `_\. .. function:: gcd(*integers) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 4e97b1dbad85c1f..0cdf0a6ac4a477e 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -57,7 +57,7 @@ from sources provided by the operating system. `Complementary-Multiply-with-Carry recipe - `_ for a compatible alternative + `_ for a compatible alternative random number generator with a long period and comparatively simple update operations. diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index a94255bbf698e9e..f08c58179a2f9f0 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -75,7 +75,7 @@ Two additional methods are supported: .. seealso:: - `Persistent dictionary recipe `_ + `Persistent dictionary recipe `_ with widely supported storage formats and having the speed of native dictionaries. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2eee22c79af7691..0ffe7b7526fa768 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1404,7 +1404,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe `_ + * The `linspace recipe `_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index aa417ede4022863..d201d7061f98015 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -679,7 +679,7 @@ always available. additional garbage collector overhead if the object is managed by the garbage collector. - See `recursive sizeof recipe `_ + See `recursive sizeof recipe `_ for an example of using :func:`getsizeof` recursively to find the size of containers and all their contents. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 38ce9f0a900c283..3208201312b8710 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -43,7 +43,7 @@ More Python resources: for download. Once you begin releasing code, you can register it here so that others can find it. -* https://github.com/ActiveState/code/tree/master/recipes/Python: The Python Cookbook is a +* https://code.activestate.com/recipes/langs/python/: The Python Cookbook is a sizable collection of code examples, larger modules, and useful scripts. Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 37bae34ce74adcb..06bee9966c0be24 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -781,8 +781,8 @@ functools (Contributed by Raymond Hettinger and incorporating design ideas from Jim Baker, Miki Tebeka, and Nick Coghlan; see `recipe 498245 - `_\, `recipe 577479 - `_\, :issue:`10586`, and + `_\, `recipe 577479 + `_\, :issue:`10586`, and :issue:`10593`.) * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index f4da9d0cefd6bf6..5d75501645fc4a7 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -574,7 +574,7 @@ class Counter(dict): # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm - # https://github.com/ActiveState/code/tree/master/recipes/Python/259174_bag_collection_class/recipe-259174.py + # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): diff --git a/Lib/heapq.py b/Lib/heapq.py index 5895562db4142bc..fabefd87f8bf8c8 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -456,7 +456,7 @@ def merge(*iterables, key=None, reverse=False): # 2) Made multiple passes over the data. # 3) Made more comparisons in common cases (small k, large n, semi-random input). # See the more detailed comparison of approach at: -# https://github.com/ActiveState/code/tree/master/recipes/Python/577573_Compare_algorithms/recipe-577573.py +# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest def nsmallest(n, iterable, key=None): """Find the n smallest elements in a dataset. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2abe5b028b355dd..a6f6483f55d897c 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -611,7 +611,7 @@ def testFsum(self): def msum(iterable): """Full precision summation. Compute sum(iterable) without any intermediate accumulation of error. Based on the 'lsum' function - at https://github.com/ActiveState/code/tree/master/recipes/Python/393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py + at http://code.activestate.com/recipes/393090/ """ tmant, texp = 0, 0 diff --git a/Tools/peg_generator/pegen/sccutils.py b/Tools/peg_generator/pegen/sccutils.py index 0c295196607ec8b..1f0586bb2f7d6db 100644 --- a/Tools/peg_generator/pegen/sccutils.py +++ b/Tools/peg_generator/pegen/sccutils.py @@ -18,7 +18,7 @@ def strongly_connected_components( exactly once; vertices not part of a SCC are returned as singleton sets. - From https://github.com/ActiveState/code/tree/master/recipes/Python/578507_Strongly_connected_components_directed/recipe-578507.py. + From http://code.activestate.com/recipes/578507/. """ identified: Set[str] = set() stack: List[str] = [] @@ -81,7 +81,7 @@ def topsort( {B, C} {A} - From https://github.com/ActiveState/code/tree/master/recipes/Python/577413_Topological_Sort/recipe-577413.py. + From http://code.activestate.com/recipes/577413/. """ # TODO: Use a faster algorithm? for k, v in data.items(): From ecdc6753c71c111502449966ad6f778cabd170f4 Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Sun, 27 Sep 2020 00:43:18 -0300 Subject: [PATCH 371/486] bpo-41858: Clarify line in optparse doc (GH-22407) The existing line is easily read as being incomplete. --- Doc/library/optparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index c1a18e014743190..b1094198f4c8448 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -55,7 +55,7 @@ equivalent to the above example:: -q -foutfile -qfoutfile -Additionally, users can run one of :: +Additionally, users can run one of the following :: -h --help From 37e67ca0542543f9cefff078d1cf76fa5d57e18e Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Sun, 27 Sep 2020 14:14:50 +0200 Subject: [PATCH 372/486] bpo-41861: Convert _sqlite3 cache and node static types to heap types (GH-22417) --- Modules/_sqlite/cache.c | 137 +++++++++++------------------------ Modules/_sqlite/cache.h | 6 +- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/module.c | 2 +- 4 files changed, 48 insertions(+), 99 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 758fc022f781087..c417ce872d368da 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -29,7 +29,7 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) { pysqlite_Node* node; - node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); + node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0)); if (!node) { return NULL; } @@ -48,10 +48,13 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) void pysqlite_node_dealloc(pysqlite_Node* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_DECREF(self->key); Py_DECREF(self->data); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) @@ -88,6 +91,7 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) void pysqlite_cache_dealloc(pysqlite_Cache* self) { + PyTypeObject *tp = Py_TYPE(self); pysqlite_Node* node; pysqlite_Node* delete_node; @@ -109,7 +113,8 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) } Py_DECREF(self->mapping); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) @@ -253,6 +258,20 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) Py_RETURN_NONE; } +static PyType_Slot pysqlite_NodeType_slots[] = { + {Py_tp_dealloc, pysqlite_node_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {0, NULL}, +}; + +static PyType_Spec pysqlite_NodeType_spec = { + .name = MODULE_NAME ".Node", + .basicsize = sizeof(pysqlite_Node), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_NodeType_slots, +}; +PyTypeObject *pysqlite_NodeType = NULL; + static PyMethodDef cache_methods[] = { {"get", (PyCFunction)pysqlite_cache_get, METH_O, PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, @@ -261,102 +280,32 @@ static PyMethodDef cache_methods[] = { {NULL, NULL} }; -PyTypeObject pysqlite_NodeType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME "Node", /* tp_name */ - sizeof(pysqlite_Node), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_node_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot pysqlite_CacheType_slots[] = { + {Py_tp_dealloc, pysqlite_cache_dealloc}, + {Py_tp_methods, cache_methods}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_cache_init}, + {0, NULL}, }; -PyTypeObject pysqlite_CacheType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cache", /* tp_name */ - sizeof(pysqlite_Cache), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - cache_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cache_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Spec pysqlite_CacheType_spec = { + .name = MODULE_NAME ".Cache", + .basicsize = sizeof(pysqlite_Cache), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_CacheType_slots, }; +PyTypeObject *pysqlite_CacheType = NULL; -extern int pysqlite_cache_setup_types(void) +extern int pysqlite_cache_setup_types(PyObject *mod) { - int rc; - - pysqlite_NodeType.tp_new = PyType_GenericNew; - pysqlite_CacheType.tp_new = PyType_GenericNew; - - rc = PyType_Ready(&pysqlite_NodeType); - if (rc < 0) { - return rc; + pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_NodeType_spec, NULL); + if (pysqlite_NodeType == NULL) { + return -1; } - rc = PyType_Ready(&pysqlite_CacheType); - return rc; + pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_CacheType_spec, NULL); + if (pysqlite_CacheType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 529010967c4f3a9..0afdf7f09b65c78 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -59,8 +59,8 @@ typedef struct int decref_factory; } pysqlite_Cache; -extern PyTypeObject pysqlite_NodeType; -extern PyTypeObject pysqlite_CacheType; +extern PyTypeObject *pysqlite_NodeType; +extern PyTypeObject *pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); void pysqlite_node_dealloc(pysqlite_Node* self); @@ -69,6 +69,6 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); void pysqlite_cache_dealloc(pysqlite_Cache* self); PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); -int pysqlite_cache_setup_types(void); +int pysqlite_cache_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 81fc1335371a6fc..121850ae7e1f32a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -133,7 +133,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } Py_DECREF(isolation_level); - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); + self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82f58eb24802616..625d065a317bab7 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -355,7 +355,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) (pysqlite_row_setup_types() < 0) || (pysqlite_cursor_setup_types() < 0) || (pysqlite_connection_setup_types() < 0) || - (pysqlite_cache_setup_types() < 0) || + (pysqlite_cache_setup_types(module) < 0) || (pysqlite_statement_setup_types() < 0) || (pysqlite_prepare_protocol_setup_types() < 0) ) { From 2ec6e7ad35f6dbe9b9661ed4935e9c57f22388eb Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sun, 27 Sep 2020 16:07:04 -0300 Subject: [PATCH 373/486] [doc] Leverage the fact that the actual types can now be indexed for typing (GH-22340) This shows users that they can use the actual types. Using deprecated types is confusing. This also prefers colections.abc.Sized instead of the alias typing.Sized. I guess the aliases were created to make it convenient to import all collections related types from the same place. This should be backported to 3.9. Automerge-Triggered-By: @gvanrossum --- Doc/glossary.rst | 10 +++------ Doc/library/typing.rst | 49 ++++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 7be755e4113108b..9fdbdb1a83f2805 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -1084,19 +1084,15 @@ Glossary Type aliases are useful for simplifying :term:`type hints `. For example:: - from typing import List, Tuple - def remove_gray_shades( - colors: List[Tuple[int, int, int]]) -> List[Tuple[int, int, int]]: + colors: list[tuple[int, int, int]]) -> list[tuple[int, int, int]]: pass could be made more readable like this:: - from typing import List, Tuple - - Color = Tuple[int, int, int] + Color = tuple[int, int, int] - def remove_gray_shades(colors: List[Color]) -> List[Color]: + def remove_gray_shades(colors: list[Color]) -> list[Color]: pass See :mod:`typing` and :pep:`484`, which describe this functionality. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index d31c65d38e1abbb..3b824d0a4a8da00 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -38,10 +38,9 @@ Type aliases ============ A type alias is defined by assigning the type to the alias. In this example, -``Vector`` and ``List[float]`` will be treated as interchangeable synonyms:: +``Vector`` and ``list[float]`` will be treated as interchangeable synonyms:: - from typing import List - Vector = List[float] + Vector = list[float] def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] @@ -51,11 +50,11 @@ A type alias is defined by assigning the type to the alias. In this example, Type aliases are useful for simplifying complex type signatures. For example:: - from typing import Dict, Tuple, Sequence + from collections.abc import Sequence - ConnectionOptions = Dict[str, str] - Address = Tuple[str, int] - Server = Tuple[Address, ConnectionOptions] + ConnectionOptions = dict[str, str] + Address = tuple[str, int] + Server = tuple[Address, ConnectionOptions] def broadcast_message(message: str, servers: Sequence[Server]) -> None: ... @@ -64,7 +63,7 @@ Type aliases are useful for simplifying complex type signatures. For example:: # being exactly equivalent to this one. def broadcast_message( message: str, - servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None: + servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None: ... Note that ``None`` as a type hint is a special case and is replaced by @@ -157,7 +156,7 @@ type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``. For example:: - from typing import Callable + from collections.abc import Callable def feeder(get_next_item: Callable[[], str]) -> None: # Body @@ -181,7 +180,7 @@ subscription to denote expected types for container elements. :: - from typing import Mapping, Sequence + from collections.abc import Mapping, Sequence def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... @@ -191,7 +190,8 @@ called :class:`TypeVar`. :: - from typing import Sequence, TypeVar + from collections.abc import Sequence + from typing import TypeVar T = TypeVar('T') # Declare type variable @@ -235,7 +235,7 @@ class body. The :class:`Generic` base class defines :meth:`__class_getitem__` so that ``LoggedVar[t]`` is valid as a type:: - from typing import Iterable + from collections.abc import Iterable def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None: for var in vars: @@ -266,7 +266,8 @@ This is thus invalid:: You can use multiple inheritance with :class:`Generic`:: - from typing import TypeVar, Generic, Sized + from collections.abc import Sized + from typing import TypeVar, Generic T = TypeVar('T') @@ -275,7 +276,8 @@ You can use multiple inheritance with :class:`Generic`:: When inheriting from generic classes, some type variables could be fixed:: - from typing import TypeVar, Mapping + from collections.abc import Mapping + from typing import TypeVar T = TypeVar('T') @@ -288,13 +290,14 @@ Using a generic class without specifying type parameters assumes :data:`Any` for each position. In the following example, ``MyIterable`` is not generic but implicitly inherits from ``Iterable[Any]``:: - from typing import Iterable + from collections.abc import Iterable class MyIterable(Iterable): # Same as Iterable[Any] User defined generic type aliases are also supported. Examples:: - from typing import TypeVar, Iterable, Tuple, Union + from collections.abc import Iterable + from typing import TypeVar, Union S = TypeVar('S') Response = Union[Iterable[S], int] @@ -303,9 +306,9 @@ User defined generic type aliases are also supported. Examples:: ... T = TypeVar('T', int, float, complex) - Vec = Iterable[Tuple[T, T]] + Vec = Iterable[tuple[T, T]] - def inproduct(v: Vec[T]) -> T: # Same as Iterable[Tuple[T, T]] + def inproduct(v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]] return sum(x*y for x, y in v) .. versionchanged:: 3.7 @@ -408,7 +411,7 @@ to be explicitly marked to support them, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code. For example, this conforms to the :pep:`484`:: - from typing import Sized, Iterable, Iterator + from collections.abc import Sized, Iterable, Iterator class Bucket(Sized, Iterable[int]): ... @@ -421,7 +424,7 @@ allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized`` and ``Iterable[int]`` by static type checkers. This is known as *structural subtyping* (or static duck-typing):: - from typing import Iterator, Iterable + from collections.abc import Iterator, Iterable class Bucket: # Note: no base classes ... @@ -1371,10 +1374,10 @@ Asynchronous programming The variance and order of type variables correspond to those of :class:`Generator`, for example:: - from typing import List, Coroutine - c = None # type: Coroutine[List[str], str, int] + from collections.abc import Coroutine + c = None # type: Coroutine[list[str], str, int] ... - x = c.send('hi') # type: List[str] + x = c.send('hi') # type: list[str] async def bar() -> None: x = await c # type: int From 8b6b2189708b1351851420806a74345e091d2cf3 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 29 Sep 2020 01:16:21 +0900 Subject: [PATCH 374/486] bpo-41870: Use PEP 590 vectorcall to speed up bool() (GH-22427) * bpo-41870: Use PEP 590 vectorcall to speed up bool() * bpo-41870: Add NEWS.d --- .../2020-09-27-22-23-14.bpo-41870.2v6_v4.rst | 2 ++ Objects/boolobject.c | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst new file mode 100644 index 000000000000000..13a6bb04a28fd0b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst @@ -0,0 +1,2 @@ +Speed up calls to ``bool()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Dong-hee Na. diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 720835b98aa65ee..ab7669cb240deb9 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -55,6 +55,30 @@ bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return PyBool_FromLong(ok); } +static PyObject * +bool_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + long ok = 0; + if (!_PyArg_NoKwnames("bool", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) { + return NULL; + } + + assert(PyType_Check(type)); + if (nargs) { + ok = PyObject_IsTrue(args[0]); + } + if (ok < 0) { + return NULL; + } + return PyBool_FromLong(ok); +} + /* Arithmetic operations redefined to return bool if both args are bool. */ static PyObject * @@ -170,6 +194,7 @@ PyTypeObject PyBool_Type = { 0, /* tp_init */ 0, /* tp_alloc */ bool_new, /* tp_new */ + .tp_vectorcall = bool_vectorcall, }; /* The objects representing bool values False and True */ From ef4596eef20a8ff4ebb4e0f41a0a3be7efa97618 Mon Sep 17 00:00:00 2001 From: Jan Mazur <16736821+mzr@users.noreply.github.com> Date: Mon, 28 Sep 2020 20:53:33 +0200 Subject: [PATCH 375/486] bpo-40105: ZipFile truncate in append mode with shorter comment (GH-19337) --- Lib/test/test_zipfile.py | 3 +++ Lib/zipfile.py | 2 ++ .../next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst | 2 ++ 3 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 2851051425bf12f..687e43df780d653 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1856,11 +1856,14 @@ def test_comments(self): self.assertEqual(zipf.comment, b"an updated comment") # check that comments are correctly shortened in append mode + # and the file is indeed truncated with zipfile.ZipFile(TESTFN,mode="w") as zipf: zipf.comment = b"original comment that's longer" zipf.writestr("foo.txt", "O, for a Muse of Fire!") + original_zip_size = os.path.getsize(TESTFN) with zipfile.ZipFile(TESTFN,mode="a") as zipf: zipf.comment = b"shorter comment" + self.assertTrue(original_zip_size > os.path.getsize(TESTFN)) with zipfile.ZipFile(TESTFN,mode="r") as zipf: self.assertEqual(zipf.comment, b"shorter comment") diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 915698f9e058893..816f8582bbf6d59 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1918,6 +1918,8 @@ def _write_end_record(self): centDirSize, centDirOffset, len(self._comment)) self.fp.write(endrec) self.fp.write(self._comment) + if self.mode == "a": + self.fp.truncate() self.fp.flush() def _fpclose(self, fp): diff --git a/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst b/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst new file mode 100644 index 000000000000000..f71a7a1e697a48e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst @@ -0,0 +1,2 @@ +ZipFile truncates files to avoid corruption when a shorter comment is provided +in append ("a") mode. Patch by Jan Mazur. From 1dba9b0c2d2d48dd710ce66704b08a5b60c137c6 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 29 Sep 2020 05:41:23 +0900 Subject: [PATCH 376/486] bpo-41875: Use __builtin_unreachable when possible (GH-22433) --- Include/pymacro.h | 4 +++- .../next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst diff --git a/Include/pymacro.h b/Include/pymacro.h index 856cae774d61c76..202b936d964f00d 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -118,7 +118,9 @@ "We've reached an unreachable state. Anything is possible.\n" \ "The limits were in our heads all along. Follow your dreams.\n" \ "https://xkcd.com/2200") -#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +# define Py_UNREACHABLE() __builtin_unreachable() +#elif defined(__clang__) || defined(__INTEL_COMPILER) # define Py_UNREACHABLE() __builtin_unreachable() #elif defined(_MSC_VER) # define Py_UNREACHABLE() __assume(0) diff --git a/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst b/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst new file mode 100644 index 000000000000000..3e409ec2e7c2024 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst @@ -0,0 +1,2 @@ +Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() if only the +compiler is able to use it. Patch by Dong-hee Na. From e3625f2b89df6df7b10213aa779899c588ee32b7 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 29 Sep 2020 05:41:11 +0800 Subject: [PATCH 377/486] bpo-41842: Add codecs.unregister() function (GH-22360) Add codecs.unregister() and PyCodec_Unregister() functions to unregister a codec search function. --- Doc/c-api/codec.rst | 8 ++++++ Doc/library/codecs.rst | 11 +++++--- Doc/whatsnew/3.10.rst | 10 ++++++++ Include/codecs.h | 8 ++++++ Lib/test/test_codecs.py | 12 +++++++++ Misc/ACKS | 1 + .../2020-09-27-20-43-16.bpo-41842.bCakAj.rst | 2 ++ .../2020-09-23-22-52-24.bpo-41842.lIuhC9.rst | 1 + Modules/_codecsmodule.c | 22 ++++++++++++++++ Modules/clinic/_codecsmodule.c.h | 13 +++++++++- Python/codecs.c | 25 +++++++++++++++++++ 11 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst create mode 100644 Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 172dcb326a4bc43..235c77c945cc5be 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -10,6 +10,14 @@ Codec registry and support functions As side effect, this tries to load the :mod:`encodings` package, if not yet done, to make sure that it is always first in the list of search functions. +.. c:function:: int PyCodec_Unregister(PyObject *search_function) + + Unregister a codec search function and clear the registry's cache. + If the search function is not registered, do nothing. + Return 0 on success. Raise an exception and return -1 on error. + + .. versionadded:: 3.10 + .. c:function:: int PyCodec_KnownEncoding(const char *encoding) Return ``1`` or ``0`` depending on whether there is a registered codec for diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index f071057293eece4..a0265135205901b 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -163,11 +163,14 @@ function: :class:`CodecInfo` object. In case a search function cannot find a given encoding, it should return ``None``. - .. note:: - Search function registration is not currently reversible, - which may cause problems in some cases, such as unit testing or - module reloading. +.. function:: unregister(search_function) + + Unregister a codec search function and clear the registry's cache. + If the search function is not registered, do nothing. + + .. versionadded:: 3.10 + While the builtin :func:`open` and the associated :mod:`io` module are the recommended approach for working with encoded text files, this module diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 1228f2695496c58..f74dd1aa247a340 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -109,6 +109,12 @@ base64 Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support the Base32 Encoding with Extended Hex Alphabet. +codecs +------ + +Add a :func:`codecs.unregister` function to unregister a codec search function. +(Contributed by Hai Shi in :issue:`41842`.) + curses ------ @@ -237,6 +243,10 @@ New Features :class:`datetime.time` objects. (Contributed by Zackery Spytz in :issue:`30155`.) +* Add a :c:func:`PyCodec_Unregister` function to unregister a codec + search function. + (Contributed by Hai Shi in :issue:`41842`.) + Porting to Python 3.10 ---------------------- diff --git a/Include/codecs.h b/Include/codecs.h index 3ad0f2b5aae79c7..37ecfb4ab757b41 100644 --- a/Include/codecs.h +++ b/Include/codecs.h @@ -27,6 +27,14 @@ PyAPI_FUNC(int) PyCodec_Register( PyObject *search_function ); +/* Unregister a codec search function and clear the registry's cache. + If the search function is not registered, do nothing. + Return 0 on success. Raise an exception and return -1 on error. */ + +PyAPI_FUNC(int) PyCodec_Unregister( + PyObject *search_function + ); + /* Codec registry lookup API. Looks up the given encoding and returns a CodecInfo object with diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 3dd56820cd1078e..ed508f36ad42343 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1641,6 +1641,18 @@ def test_register(self): self.assertRaises(TypeError, codecs.register) self.assertRaises(TypeError, codecs.register, 42) + def test_unregister(self): + name = "nonexistent_codec_name" + search_function = mock.Mock() + codecs.register(search_function) + self.assertRaises(TypeError, codecs.lookup, name) + search_function.assert_called_with(name) + search_function.reset_mock() + + codecs.unregister(search_function) + self.assertRaises(LookupError, codecs.lookup, name) + search_function.assert_not_called() + def test_lookup(self): self.assertRaises(TypeError, codecs.lookup) self.assertRaises(LookupError, codecs.lookup, "__spam__") diff --git a/Misc/ACKS b/Misc/ACKS index 7b743464c1c1c81..85001daf67d234d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1575,6 +1575,7 @@ Akash Shende Charlie Shepherd Bruce Sherwood Gregory Shevchenko +Hai Shi Alexander Shigin Pete Shinners Michael Shiplett diff --git a/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst b/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst new file mode 100644 index 000000000000000..116d08f49085961 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst @@ -0,0 +1,2 @@ +Add :c:func:`PyCodec_Unregister` function to unregister a codec search +function. diff --git a/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst b/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst new file mode 100644 index 000000000000000..306b02d76fffe2c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst @@ -0,0 +1 @@ +Add :func:`codecs.unregister` function to unregister a codec search function. diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 952072102d5d8d1..08a3d4ab024cc2d 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -68,6 +68,27 @@ _codecs_register(PyObject *module, PyObject *search_function) Py_RETURN_NONE; } +/*[clinic input] +_codecs.unregister + search_function: object + / + +Unregister a codec search function and clear the registry's cache. + +If the search function is not registered, do nothing. +[clinic start generated code]*/ + +static PyObject * +_codecs_unregister(PyObject *module, PyObject *search_function) +/*[clinic end generated code: output=1f0edee9cf246399 input=dd7c004c652d345e]*/ +{ + if (PyCodec_Unregister(search_function) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + /*[clinic input] _codecs.lookup encoding: str @@ -992,6 +1013,7 @@ _codecs_lookup_error_impl(PyObject *module, const char *name) static PyMethodDef _codecs_functions[] = { _CODECS_REGISTER_METHODDEF + _CODECS_UNREGISTER_METHODDEF _CODECS_LOOKUP_METHODDEF _CODECS_ENCODE_METHODDEF _CODECS_DECODE_METHODDEF diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 249065c9fd05a44..e2ebb6861299e46 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -15,6 +15,17 @@ PyDoc_STRVAR(_codecs_register__doc__, #define _CODECS_REGISTER_METHODDEF \ {"register", (PyCFunction)_codecs_register, METH_O, _codecs_register__doc__}, +PyDoc_STRVAR(_codecs_unregister__doc__, +"unregister($module, search_function, /)\n" +"--\n" +"\n" +"Unregister a codec search function and clear the registry\'s cache.\n" +"\n" +"If the search function is not registered, do nothing."); + +#define _CODECS_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)_codecs_unregister, METH_O, _codecs_unregister__doc__}, + PyDoc_STRVAR(_codecs_lookup__doc__, "lookup($module, encoding, /)\n" "--\n" @@ -2827,4 +2838,4 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=eeead01414be6e42 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a97e2ddf3e69072 input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index 0f18c27e5fe461c..a8233a73c4ed3f5 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -50,6 +50,31 @@ int PyCodec_Register(PyObject *search_function) return -1; } +int +PyCodec_Unregister(PyObject *search_function) +{ + PyInterpreterState *interp = PyInterpreterState_Get(); + PyObject *codec_search_path = interp->codec_search_path; + /* Do nothing if codec_search_path is not created yet or was cleared. */ + if (codec_search_path == NULL) { + return 0; + } + + assert(PyList_CheckExact(codec_search_path)); + Py_ssize_t n = PyList_GET_SIZE(codec_search_path); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *item = PyList_GET_ITEM(codec_search_path, i); + if (item == search_function) { + if (interp->codec_search_cache != NULL) { + assert(PyDict_CheckExact(interp->codec_search_cache)); + PyDict_Clear(interp->codec_search_cache); + } + return PyList_SetSlice(codec_search_path, i, i+1, NULL); + } + } + return 0; +} + extern int _Py_normalize_encoding(const char *, char *, size_t); /* Convert a string to a normalized Python string(decoded from UTF-8): all characters are From 0c658e0f3272f57959c85236b6b674e152de6eed Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Tue, 29 Sep 2020 00:05:04 +0200 Subject: [PATCH 378/486] bpo-41861: Convert _sqlite3 PrepareProtocolType to heap type (GH-22428) --- Modules/_sqlite/microprotocols.c | 4 +- Modules/_sqlite/module.c | 6 +-- Modules/_sqlite/prepare_protocol.c | 69 +++++++++++------------------- Modules/_sqlite/prepare_protocol.h | 4 +- Modules/_sqlite/statement.c | 4 +- 5 files changed, 33 insertions(+), 54 deletions(-) diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 3b2d7f42b87353d..64095adb4db2b2c 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -56,7 +56,7 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) PyObject* key; int rc; - if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; + if (proto == NULL) proto = (PyObject*)pysqlite_PrepareProtocolType; key = Py_BuildValue("(OO)", (PyObject*)type, proto); if (!key) { @@ -152,7 +152,7 @@ PyObject * pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) { PyObject *obj, *alt = NULL; - PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; + PyObject *proto = (PyObject*)pysqlite_PrepareProtocolType; if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; return pysqlite_microprotocols_adapt(obj, proto, alt); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 625d065a317bab7..d0a546c008de281 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -176,7 +176,7 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) pysqlite_BaseTypeAdapted = 1; } - rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); + rc = pysqlite_microprotocols_add(type, (PyObject*)pysqlite_PrepareProtocolType, caster); if (rc == -1) return NULL; @@ -357,7 +357,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) (pysqlite_connection_setup_types() < 0) || (pysqlite_cache_setup_types(module) < 0) || (pysqlite_statement_setup_types() < 0) || - (pysqlite_prepare_protocol_setup_types() < 0) + (pysqlite_prepare_protocol_setup_types(module) < 0) ) { Py_XDECREF(module); return NULL; @@ -365,7 +365,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_TYPE(module, pysqlite_ConnectionType); ADD_TYPE(module, pysqlite_CursorType); - ADD_TYPE(module, pysqlite_PrepareProtocolType); + ADD_TYPE(module, *pysqlite_PrepareProtocolType); ADD_TYPE(module, pysqlite_RowType); if (!(dict = PyModule_GetDict(module))) { diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 05a2ca5a652f5e3..7daf8a620096a92 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -30,54 +30,33 @@ int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* arg void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) { - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *tp = Py_TYPE(self); + + tp->tp_free(self); + Py_DECREF(tp); } -PyTypeObject pysqlite_PrepareProtocolType= { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".PrepareProtocol", /* tp_name */ - sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_prepare_protocol_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot type_slots[] = { + {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_prepare_protocol_init}, + {0, NULL}, +}; + +static PyType_Spec type_spec = { + .name = MODULE_NAME ".PrepareProtocol", + .basicsize = sizeof(pysqlite_PrepareProtocol), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, + .slots = type_slots, }; -extern int pysqlite_prepare_protocol_setup_types(void) +PyTypeObject *pysqlite_PrepareProtocolType = NULL; + +extern int pysqlite_prepare_protocol_setup_types(PyObject *module) { - pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; - Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); - return PyType_Ready(&pysqlite_PrepareProtocolType); + pysqlite_PrepareProtocolType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &type_spec, NULL); + if (pysqlite_PrepareProtocolType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/prepare_protocol.h b/Modules/_sqlite/prepare_protocol.h index 3998a55e51cafee..d0f717c754c1d5f 100644 --- a/Modules/_sqlite/prepare_protocol.h +++ b/Modules/_sqlite/prepare_protocol.h @@ -31,12 +31,12 @@ typedef struct PyObject_HEAD } pysqlite_PrepareProtocol; -extern PyTypeObject pysqlite_PrepareProtocolType; +extern PyTypeObject *pysqlite_PrepareProtocolType; int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); -int pysqlite_prepare_protocol_setup_types(void); +int pysqlite_prepare_protocol_setup_types(PyObject *module); #define UNKNOWN (-1) #endif diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 02e47a02b718ccc..0458e1171ebdda0 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -255,7 +255,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -306,7 +306,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; From 305f95c290879416b4c0442b95df6e82b3d5289b Mon Sep 17 00:00:00 2001 From: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> Date: Mon, 28 Sep 2020 20:55:52 -0400 Subject: [PATCH 379/486] bpo-41873: Add vectorcall for float() (GH-22432) --- Lib/test/test_float.py | 3 +++ .../2020-09-28-08-58-28.bpo-41873.VzEDhA.rst | 1 + Objects/floatobject.c | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 9651281e24edbe7..99c81f0b72a5a35 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -64,6 +64,9 @@ def test_float(self): # See bpo-34087 self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f') + def test_noargs(self): + self.assertEqual(float(), 0.0) + def test_underscores(self): for lit in VALID_UNDERSCORE_LITERALS: if not any(ch in lit for ch in 'jJxXoObB'): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst new file mode 100644 index 000000000000000..ee2636704c29920 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst @@ -0,0 +1 @@ +Calls to ``float()`` are now faster due to the ``vectorcall`` calling convention. Patch by Dennis Sweeney. \ No newline at end of file diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 0606f29ff5408da..d0af0ea1a982574 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1649,6 +1649,24 @@ float_subtype_new(PyTypeObject *type, PyObject *x) return newobj; } +static PyObject * +float_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + if (!_PyArg_NoKwnames("float", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("float", nargs, 0, 1)) { + return NULL; + } + + PyObject *x = nargs >= 1 ? args[0] : _PyLong_Zero; + return float_new_impl((PyTypeObject *)type, x); +} + + /*[clinic input] float.__getnewargs__ [clinic start generated code]*/ @@ -1937,6 +1955,7 @@ PyTypeObject PyFloat_Type = { 0, /* tp_init */ 0, /* tp_alloc */ float_new, /* tp_new */ + .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; int From 3b5ee0d32c1990f4a2d073a54c9fe5d5651e39f4 Mon Sep 17 00:00:00 2001 From: Ram Rachum Date: Tue, 29 Sep 2020 04:32:10 +0300 Subject: [PATCH 380/486] bpo-41773: Raise exception for non-finite weights in random.choices(). (GH-22441) --- Doc/library/random.rst | 4 ++-- Lib/random.py | 4 +++- Lib/test/test_random.py | 16 ++++++++++++++++ .../2020-09-28-23-22-25.bpo-41773.oKkus0.rst | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 0cdf0a6ac4a477e..af5131df280c247 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -180,8 +180,8 @@ Functions for sequences The *weights* or *cum_weights* can use any numeric type that interoperates with the :class:`float` values returned by :func:`random` (that includes - integers, floats, and fractions but excludes decimals). Behavior is - undefined if any weight is negative. A :exc:`ValueError` is raised if all + integers, floats, and fractions but excludes decimals). Weights are assumed + to be non-negative and finite. A :exc:`ValueError` is raised if all weights are zero. For a given seed, the :func:`choices` function with equal weighting diff --git a/Lib/random.py b/Lib/random.py index 3ea369b81b3e50f..139e8a40bb2724b 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -48,7 +48,7 @@ from warnings import warn as _warn from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin -from math import tau as TWOPI, floor as _floor +from math import tau as TWOPI, floor as _floor, isfinite as _isfinite from os import urandom as _urandom from _collections_abc import Set as _Set, Sequence as _Sequence from itertools import accumulate as _accumulate, repeat as _repeat @@ -492,6 +492,8 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1): total = cum_weights[-1] + 0.0 # convert to float if total <= 0.0: raise ValueError('Total of weights must be greater than zero') + if not _isfinite(total): + raise ValueError('Total of weights must be finite') bisect = _bisect hi = n - 1 return [population[bisect(cum_weights, random() * total, 0, hi)] diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index a80e71e67e4c6ce..0c1fdeec9915ee8 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -324,6 +324,22 @@ def test_choices_with_all_zero_weights(self): with self.assertRaises(ValueError): self.gen.choices('AB', [0.0, 0.0]) + def test_choices_negative_total(self): + with self.assertRaises(ValueError): + self.gen.choices('ABC', [3, -5, 1]) + + def test_choices_infinite_total(self): + with self.assertRaises(ValueError): + self.gen.choices('A', [float('inf')]) + with self.assertRaises(ValueError): + self.gen.choices('AB', [0.0, float('inf')]) + with self.assertRaises(ValueError): + self.gen.choices('AB', [-float('inf'), 123]) + with self.assertRaises(ValueError): + self.gen.choices('AB', [0.0, float('nan')]) + with self.assertRaises(ValueError): + self.gen.choices('AB', [float('-inf'), float('inf')]) + def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In # particular, through 2.2.1 it failed to reset a piece of state used diff --git a/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst b/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst new file mode 100644 index 000000000000000..cef7ff0188354e8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst @@ -0,0 +1,2 @@ +Note in documentation that :func:`random.choices` doesn't support non-finite +weights, raise :exc:`ValueError` when given non-finite weights. From e48da3b422bde5b1544477185c165f68d4728de4 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Tue, 29 Sep 2020 01:02:44 -0400 Subject: [PATCH 381/486] bpo-41774: Add programming FAQ entry (GH-22402) In the "Sequences (Tuples/Lists)" section, add "How do you remove multiple items from a list". --- Doc/faq/programming.rst | 15 +++++++++++++++ .../2020-09-24-15-35-13.bpo-41774.5IqdGP.rst | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 4f4ea8b18176c26..76ae4d260fad468 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1164,6 +1164,21 @@ This converts the list into a set, thereby removing duplicates, and then back into a list. +How do you remove multiple items from a list +-------------------------------------------- + +As with removing duplicates, explicitly iterating in reverse with a +delete condition is one possibility. However, it is easier and faster +to use slice replacement with an implicit or explicit forward iteration. +Here are three variations.:: + + mylist[:] = filter(keep_function, mylist) + mylist[:] = (x for x in mylist if keep_condition) + mylist[:] = [x for x in mylist if keep_condition] + +If space is not an issue, the list comprehension may be fastest. + + How do you make an array in Python? ----------------------------------- diff --git a/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst b/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst new file mode 100644 index 000000000000000..af8e02437cb2b56 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst @@ -0,0 +1,2 @@ +In Programming FAQ "Sequences (Tuples/Lists)" section, add "How do you +remove multiple items from a list". From 34bbd693f1654f0a96ee26f432bb0574124bc0fc Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 29 Sep 2020 10:09:13 +0100 Subject: [PATCH 382/486] bpo-41670: Remove outdated predict macro invocation. (GH-22026) Remove PREDICTion of POP_BLOCK from FOR_ITER. --- Lib/test/test_sys_settrace.py | 17 +++++++++++++++++ .../2020-08-31-11-37-59.bpo-41670.vmRJRx.rst | 4 ++++ Python/ceval.c | 2 -- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 3f902b1fe74ce83..dd4418dd98b22a0 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -602,6 +602,23 @@ def run(tracer): self.compare_events(doit_async.__code__.co_firstlineno, tracer.events, events) + def test_loop_in_try_except(self): + # https://bugs.python.org/issue41670 + + def func(): + try: + for i in []: pass + return 1 + except: + return 2 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'return')]) + class SkipLineEventsTraceTestCase(TraceTestCase): """Repeat the trace tests, but with per-line events skipped""" diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst new file mode 100644 index 000000000000000..6ad5fb6dc9bb403 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst @@ -0,0 +1,4 @@ +Prevent line trace being skipped on platforms not compiled +with ``USE_COMPUTED_GOTOS``. +Fixes issue where some lines nested within a try-except block +were not being traced on Windows. diff --git a/Python/ceval.c b/Python/ceval.c index 6430e792b8c5d8b..6bd2d6bc13d86f1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2311,7 +2311,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) } case TARGET(POP_BLOCK): { - PREDICTED(POP_BLOCK); PyFrame_BlockPop(f); DISPATCH(); } @@ -3366,7 +3365,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) STACK_SHRINK(1); Py_DECREF(iter); JUMPBY(oparg); - PREDICT(POP_BLOCK); DISPATCH(); } From 175ff106ef83147a85747d1a8e9db427063da08b Mon Sep 17 00:00:00 2001 From: Max Smolens Date: Wed, 30 Sep 2020 18:05:51 -0400 Subject: [PATCH 383/486] Fix grammar in secrets module documentation (GH-22467) From `In particularly,` to `In particular,` --- Doc/library/secrets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index bc4766da2785b36..afa8e2d385fa465 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -21,7 +21,7 @@ The :mod:`secrets` module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets. -In particularly, :mod:`secrets` should be used in preference to the +In particular, :mod:`secrets` should be used in preference to the default pseudo-random number generator in the :mod:`random` module, which is designed for modelling and simulation, not security or cryptography. From a7a1955c6fef9801f60e0c74db724dabca60e1ff Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 1 Oct 2020 13:50:40 +0900 Subject: [PATCH 384/486] bpo-41870: Avoid the test when nargs=0 (GH-22462) --- Objects/boolobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/boolobject.c b/Objects/boolobject.c index ab7669cb240deb9..b786966533e1d6a 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -72,9 +72,9 @@ bool_vectorcall(PyObject *type, PyObject * const*args, assert(PyType_Check(type)); if (nargs) { ok = PyObject_IsTrue(args[0]); - } - if (ok < 0) { - return NULL; + if (ok < 0) { + return NULL; + } } return PyBool_FromLong(ok); } From b5c008f10e1dd6493caf63cb2f0ca33eee33d08d Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Thu, 1 Oct 2020 15:24:31 +0200 Subject: [PATCH 385/486] bpo-41861: Convert _sqlite3 RowType and StatementType to heap types (GH-22444) --- Modules/_sqlite/cache.c | 4 +- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/cursor.c | 2 +- Modules/_sqlite/module.c | 6 +- Modules/_sqlite/prepare_protocol.c | 2 +- Modules/_sqlite/row.c | 94 ++++++++++-------------------- Modules/_sqlite/row.h | 4 +- Modules/_sqlite/statement.c | 71 +++++++++------------- Modules/_sqlite/statement.h | 4 +- 9 files changed, 71 insertions(+), 118 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index c417ce872d368da..0b02be4f0bec985 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -267,7 +267,7 @@ static PyType_Slot pysqlite_NodeType_slots[] = { static PyType_Spec pysqlite_NodeType_spec = { .name = MODULE_NAME ".Node", .basicsize = sizeof(pysqlite_Node), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .slots = pysqlite_NodeType_slots, }; PyTypeObject *pysqlite_NodeType = NULL; @@ -291,7 +291,7 @@ static PyType_Slot pysqlite_CacheType_slots[] = { static PyType_Spec pysqlite_CacheType_spec = { .name = MODULE_NAME ".Cache", .basicsize = sizeof(pysqlite_Cache), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .slots = pysqlite_CacheType_slots, }; PyTypeObject *pysqlite_CacheType = NULL; diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 121850ae7e1f32a..91e9046f50cb05b 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1234,7 +1234,7 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py _pysqlite_drop_unused_statement_references(self); - statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); + statement = PyObject_New(pysqlite_Statement, pysqlite_StatementType); if (!statement) { return NULL; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 5cfb4b97d61dfe3..dbbdb12caddd6d3 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -472,7 +472,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) if (self->statement->in_use) { Py_SETREF(self->statement, - PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); + PyObject_New(pysqlite_Statement, pysqlite_StatementType)); if (!self->statement) { goto error; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index d0a546c008de281..8ac9ea8477363b4 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -352,11 +352,11 @@ PyMODINIT_FUNC PyInit__sqlite3(void) module = PyModule_Create(&_sqlite3module); if (!module || - (pysqlite_row_setup_types() < 0) || + (pysqlite_row_setup_types(module) < 0) || (pysqlite_cursor_setup_types() < 0) || (pysqlite_connection_setup_types() < 0) || (pysqlite_cache_setup_types(module) < 0) || - (pysqlite_statement_setup_types() < 0) || + (pysqlite_statement_setup_types(module) < 0) || (pysqlite_prepare_protocol_setup_types(module) < 0) ) { Py_XDECREF(module); @@ -366,7 +366,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_TYPE(module, pysqlite_ConnectionType); ADD_TYPE(module, pysqlite_CursorType); ADD_TYPE(module, *pysqlite_PrepareProtocolType); - ADD_TYPE(module, pysqlite_RowType); + ADD_TYPE(module, *pysqlite_RowType); if (!(dict = PyModule_GetDict(module))) { goto error; diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 7daf8a620096a92..089d66b98108571 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -46,7 +46,7 @@ static PyType_Slot type_slots[] = { static PyType_Spec type_spec = { .name = MODULE_NAME ".PrepareProtocol", .basicsize = sizeof(pysqlite_PrepareProtocol), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, + .flags = Py_TPFLAGS_DEFAULT, .slots = type_slots, }; diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 4b47108278a0ab4..85179e7f4df056a 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -26,10 +26,13 @@ void pysqlite_row_dealloc(pysqlite_Row* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->data); Py_XDECREF(self->description); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -192,7 +195,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { + if (PyObject_TypeCheck(_other, pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); if (eq < 0) { @@ -206,73 +209,40 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, Py_RETURN_NOTIMPLEMENTED; } -PyMappingMethods pysqlite_row_as_mapping = { - /* mp_length */ (lenfunc)pysqlite_row_length, - /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, - /* mp_ass_subscript */ (objobjargproc)0, -}; - -static PySequenceMethods pysqlite_row_as_sequence = { - /* sq_length */ (lenfunc)pysqlite_row_length, - /* sq_concat */ 0, - /* sq_repeat */ 0, - /* sq_item */ (ssizeargfunc)pysqlite_row_item, -}; - - -static PyMethodDef pysqlite_row_methods[] = { +static PyMethodDef row_methods[] = { {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, PyDoc_STR("Returns the keys of the row.")}, {NULL, NULL} }; +static PyType_Slot row_slots[] = { + {Py_tp_dealloc, pysqlite_row_dealloc}, + {Py_tp_hash, pysqlite_row_hash}, + {Py_tp_methods, row_methods}, + {Py_tp_richcompare, pysqlite_row_richcompare}, + {Py_tp_iter, pysqlite_iter}, + {Py_mp_length, pysqlite_row_length}, + {Py_mp_subscript, pysqlite_row_subscript}, + {Py_sq_length, pysqlite_row_length}, + {Py_sq_item, pysqlite_row_item}, + {Py_tp_new, pysqlite_row_new}, + {0, NULL}, +}; -PyTypeObject pysqlite_RowType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Row", /* tp_name */ - sizeof(pysqlite_Row), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_row_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pysqlite_row_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)pysqlite_iter, /* tp_iter */ - 0, /* tp_iternext */ - pysqlite_row_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Spec row_spec = { + .name = MODULE_NAME ".Row", + .basicsize = sizeof(pysqlite_Row), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = row_slots, }; -extern int pysqlite_row_setup_types(void) +PyTypeObject *pysqlite_RowType = NULL; + +extern int pysqlite_row_setup_types(PyObject *module) { - pysqlite_RowType.tp_new = pysqlite_row_new; - pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; - pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; - return PyType_Ready(&pysqlite_RowType); + pysqlite_RowType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &row_spec, NULL); + if (pysqlite_RowType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/row.h b/Modules/_sqlite/row.h index 4ad506f8dd96873..2dac41e89e12d83 100644 --- a/Modules/_sqlite/row.h +++ b/Modules/_sqlite/row.h @@ -33,8 +33,8 @@ typedef struct _Row PyObject* description; } pysqlite_Row; -extern PyTypeObject pysqlite_RowType; +extern PyTypeObject *pysqlite_RowType; -int pysqlite_row_setup_types(void); +int pysqlite_row_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 0458e1171ebdda0..4682d286c581c2d 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -371,6 +371,8 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self) void pysqlite_statement_dealloc(pysqlite_Statement* self) { + PyTypeObject *tp = Py_TYPE(self); + if (self->st) { Py_BEGIN_ALLOW_THREADS sqlite3_finalize(self->st); @@ -385,7 +387,8 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self) PyObject_ClearWeakRefs((PyObject*)self); } - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } /* @@ -458,50 +461,30 @@ static int pysqlite_check_remaining_sql(const char* tail) return 0; } -PyTypeObject pysqlite_StatementType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Statement", /* tp_name */ - sizeof(pysqlite_Statement), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyMemberDef stmt_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Statement, in_weakreflist), READONLY}, + {NULL}, +}; +static PyType_Slot stmt_slots[] = { + {Py_tp_members, stmt_members}, + {Py_tp_dealloc, pysqlite_statement_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {0, NULL}, +}; + +static PyType_Spec stmt_spec = { + .name = MODULE_NAME ".Statement", + .basicsize = sizeof(pysqlite_Statement), + .flags = Py_TPFLAGS_DEFAULT, + .slots = stmt_slots, }; +PyTypeObject *pysqlite_StatementType = NULL; -extern int pysqlite_statement_setup_types(void) +extern int pysqlite_statement_setup_types(PyObject *module) { - pysqlite_StatementType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_StatementType); + pysqlite_StatementType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &stmt_spec, NULL); + if (pysqlite_StatementType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 5002f02dc5b3926..b426036002815ab 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -43,7 +43,7 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Statement; -extern PyTypeObject pysqlite_StatementType; +extern PyTypeObject *pysqlite_StatementType; int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); void pysqlite_statement_dealloc(pysqlite_Statement* self); @@ -55,6 +55,6 @@ int pysqlite_statement_finalize(pysqlite_Statement* self); int pysqlite_statement_reset(pysqlite_Statement* self); void pysqlite_statement_mark_dirty(pysqlite_Statement* self); -int pysqlite_statement_setup_types(void); +int pysqlite_statement_setup_types(PyObject *module); #endif From 8d8d60def61be245ace9848100d50f1a065c0ce0 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Thu, 1 Oct 2020 16:03:21 +0200 Subject: [PATCH 386/486] bpo-41861: Convert _sqlite3 CursorType and ConnectionType to heap types (GH-22478) --- Modules/_sqlite/connection.c | 80 +++++++++++++++--------------------- Modules/_sqlite/connection.h | 4 +- Modules/_sqlite/cursor.c | 76 ++++++++++++++-------------------- Modules/_sqlite/cursor.h | 4 +- Modules/_sqlite/module.c | 10 ++--- Modules/_sqlite/row.c | 2 +- 6 files changed, 74 insertions(+), 102 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 91e9046f50cb05b..69203f85e055537 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -220,6 +220,8 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset void pysqlite_connection_dealloc(pysqlite_Connection* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->statement_cache); /* Clean up if user has not called .close() explicitly. */ @@ -236,7 +238,9 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) Py_XDECREF(self->collations); Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); + + tp->tp_free(self); + Py_DECREF(tp); } /* @@ -281,13 +285,13 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, } if (factory == NULL) { - factory = (PyObject*)&pysqlite_CursorType; + factory = (PyObject*)pysqlite_CursorType; } cursor = PyObject_CallOneArg(factory, (PyObject *)self); if (cursor == NULL) return NULL; - if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { + if (!PyObject_TypeCheck(cursor, pysqlite_CursorType)) { PyErr_Format(PyExc_TypeError, "factory must return a cursor, not %.100s", Py_TYPE(cursor)->tp_name); @@ -1494,7 +1498,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, - &pysqlite_ConnectionType, &target, + pysqlite_ConnectionType, &target, &pages, &progress, &name, &sleep_obj)) { return NULL; } @@ -1831,50 +1835,32 @@ static struct PyMemberDef connection_members[] = {NULL} }; -PyTypeObject pysqlite_ConnectionType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Connection", /* tp_name */ - sizeof(pysqlite_Connection), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)pysqlite_connection_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - connection_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - connection_methods, /* tp_methods */ - connection_members, /* tp_members */ - connection_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_connection_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot connection_slots[] = { + {Py_tp_dealloc, pysqlite_connection_dealloc}, + {Py_tp_doc, (void *)connection_doc}, + {Py_tp_methods, connection_methods}, + {Py_tp_members, connection_members}, + {Py_tp_getset, connection_getset}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_connection_init}, + {Py_tp_call, pysqlite_connection_call}, + {0, NULL}, +}; + +static PyType_Spec connection_spec = { + .name = MODULE_NAME ".Connection", + .basicsize = sizeof(pysqlite_Connection), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = connection_slots, }; -extern int pysqlite_connection_setup_types(void) +PyTypeObject *pysqlite_ConnectionType = NULL; + +extern int pysqlite_connection_setup_types(PyObject *module) { - pysqlite_ConnectionType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_ConnectionType); + pysqlite_ConnectionType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &connection_spec, NULL); + if (pysqlite_ConnectionType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 206085e00a00c70..aadf439034fe282 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -106,7 +106,7 @@ typedef struct PyObject* NotSupportedError; } pysqlite_Connection; -extern PyTypeObject pysqlite_ConnectionType; +extern PyTypeObject *pysqlite_ConnectionType; PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); void pysqlite_connection_dealloc(pysqlite_Connection* self); @@ -122,6 +122,6 @@ int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObjec int pysqlite_check_thread(pysqlite_Connection* self); int pysqlite_check_connection(pysqlite_Connection* con); -int pysqlite_connection_setup_types(void); +int pysqlite_connection_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index dbbdb12caddd6d3..3c09c1c6b7e50ce 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -33,7 +33,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* { pysqlite_Connection* connection; - if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) + if (!PyArg_ParseTuple(args, "O!", pysqlite_ConnectionType, &connection)) { return -1; } @@ -74,6 +74,8 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) { + PyTypeObject *tp = Py_TYPE(self); + /* Reset the statement if the user has not closed the cursor */ if (self->statement) { pysqlite_statement_reset(self->statement); @@ -91,7 +93,8 @@ static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) PyObject_ClearWeakRefs((PyObject*)self); } - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -898,56 +901,39 @@ static struct PyMemberDef cursor_members[] = {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY}, {NULL} }; static const char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); -PyTypeObject pysqlite_CursorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cursor", /* tp_name */ - sizeof(pysqlite_Cursor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - cursor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ - cursor_methods, /* tp_methods */ - cursor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cursor_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot cursor_slots[] = { + {Py_tp_dealloc, pysqlite_cursor_dealloc}, + {Py_tp_doc, (void *)cursor_doc}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, pysqlite_cursor_iternext}, + {Py_tp_methods, cursor_methods}, + {Py_tp_members, cursor_members}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_cursor_init}, + {0, NULL}, +}; + +static PyType_Spec cursor_spec = { + .name = MODULE_NAME ".Cursor", + .basicsize = sizeof(pysqlite_Cursor), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = cursor_slots, }; -extern int pysqlite_cursor_setup_types(void) +PyTypeObject *pysqlite_CursorType = NULL; + +extern int pysqlite_cursor_setup_types(PyObject *module) { - pysqlite_CursorType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_CursorType); + pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL); + if (pysqlite_CursorType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index 4a20e756f7829d9..3e6cde167f94c84 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -52,7 +52,7 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Cursor; -extern PyTypeObject pysqlite_CursorType; +extern PyTypeObject *pysqlite_CursorType; PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); @@ -64,7 +64,7 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); -int pysqlite_cursor_setup_types(void); +int pysqlite_cursor_setup_types(PyObject *module); #define UNKNOWN (-1) #endif diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 8ac9ea8477363b4..102026663abd839 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -82,7 +82,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* } if (factory == NULL) { - factory = (PyObject*)&pysqlite_ConnectionType; + factory = (PyObject*)pysqlite_ConnectionType; } if (PySys_Audit("sqlite3.connect", "O", database) < 0) { @@ -353,8 +353,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void) if (!module || (pysqlite_row_setup_types(module) < 0) || - (pysqlite_cursor_setup_types() < 0) || - (pysqlite_connection_setup_types() < 0) || + (pysqlite_cursor_setup_types(module) < 0) || + (pysqlite_connection_setup_types(module) < 0) || (pysqlite_cache_setup_types(module) < 0) || (pysqlite_statement_setup_types(module) < 0) || (pysqlite_prepare_protocol_setup_types(module) < 0) @@ -363,8 +363,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void) return NULL; } - ADD_TYPE(module, pysqlite_ConnectionType); - ADD_TYPE(module, pysqlite_CursorType); + ADD_TYPE(module, *pysqlite_ConnectionType); + ADD_TYPE(module, *pysqlite_CursorType); ADD_TYPE(module, *pysqlite_PrepareProtocolType); ADD_TYPE(module, *pysqlite_RowType); diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 85179e7f4df056a..76b6f04f0ccbfda 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -49,7 +49,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) return NULL; - if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { + if (!PyObject_TypeCheck((PyObject*)cursor, pysqlite_CursorType)) { PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); return NULL; } From 298c8570adfc73c09a31e5cd08a639bcd081a552 Mon Sep 17 00:00:00 2001 From: Robert Smallshire Date: Thu, 1 Oct 2020 18:30:08 +0200 Subject: [PATCH 387/486] bpo-26680: Incorporate is_integer in all built-in and standard library numeric types (GH-6121) * bpo-26680: Adds support for int.is_integer() for compatibility with float.is_integer(). The int.is_integer() method always returns True. * bpo-26680: Adds a test to ensure that False.is_integer() and True.is_integer() are always True. * bpo-26680: Adds Real.is_integer() with a trivial implementation using conversion to int. This default implementation is intended to reduce the workload for subclass implementers. It is not robust in the presence of infinities or NaNs and may have suboptimal performance for other types. * bpo-26680: Adds Rational.is_integer which returns True if the denominator is one. This implementation assumes the Rational is represented in it's lowest form, as required by the class docstring. * bpo-26680: Adds Integral.is_integer which always returns True. * bpo-26680: Adds tests for Fraction.is_integer called as an instance method. The tests for the Rational abstract base class use an unbound method to sidestep the inability to directly instantiate Rational. These tests check that everything works correct as an instance method. * bpo-26680: Updates documentation for Real.is_integer and built-ins int and float. The call x.is_integer() is now listed in the table of operations which apply to all numeric types except complex, with a reference to the full documentation for Real.is_integer(). Mention of is_integer() has been removed from the section 'Additional Methods on Float'. The documentation for Real.is_integer() describes its purpose, and mentions that it should be overridden for performance reasons, or to handle special values like NaN. * bpo-26680: Adds Decimal.is_integer to the Python and C implementations. The C implementation of Decimal already implements and uses mpd_isinteger internally, we just expose the existing function to Python. The Python implementation uses internal conversion to integer using to_integral_value(). In both cases, the corresponding context methods are also implemented. Tests and documentation are included. * bpo-26680: Updates the ACKS file. * bpo-26680: NEWS entries for int, the numeric ABCs and Decimal. Co-authored-by: Robert Smallshire --- Doc/library/decimal.rst | 14 +++++++++ Doc/library/numbers.rst | 26 +++++++++++----- Doc/library/stdtypes.rst | 14 +++------ Lib/_pydecimal.py | 25 +++++++++++++++ Lib/numbers.py | 21 ++++++++++++- Lib/test/decimaltestdata/extra.decTest | 18 +++++++++++ Lib/test/test_bool.py | 5 +++ Lib/test/test_decimal.py | 24 ++++++++++++++ Lib/test/test_fractions.py | 11 +++++++ Lib/test/test_long.py | 4 +++ Lib/test/test_numeric_tower.py | 31 +++++++++++++++++++ Misc/ACKS | 1 + .../2018-03-15-11-51-36.bpo-26680.wOWYps.rst | 2 ++ .../2018-03-15-11-55-04.bpo-26680.eKAi85.rst | 3 ++ .../2018-03-15-11-56-48.bpo-26680.Udkhn4.rst | 2 ++ Modules/_decimal/_decimal.c | 6 ++-- Modules/_decimal/docstrings.h | 13 ++++++-- Objects/clinic/longobject.c.h | 20 +++++++++++- Objects/longobject.c | 14 +++++++++ 19 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst create mode 100644 Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst create mode 100644 Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index e194649e30d85c0..7a6497305952f1e 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -621,6 +621,13 @@ Decimal objects Return :const:`True` if the argument is either positive or negative infinity and :const:`False` otherwise. + .. method:: is_integer() + + Return :const:`True` if the argument is a finite integral value and + :const:`False` otherwise. + + .. versionadded:: 3.10 + .. method:: is_nan() Return :const:`True` if the argument is a (quiet or signaling) NaN and @@ -1215,6 +1222,13 @@ In addition to the three supplied contexts, new contexts can be created with the Returns ``True`` if *x* is infinite; otherwise returns ``False``. + .. method:: is_integer(x) + + Returns ``True`` if *x* is finite and integral; otherwise + returns ``False``. + + .. versionadded:: 3.10 + .. method:: is_nan(x) Returns ``True`` if *x* is a qNaN or sNaN; otherwise returns ``False``. diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index 1b594952ead7241..5d49f5eb96b7ad8 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -49,19 +49,30 @@ The numeric tower numbers. In short, those are: a conversion to :class:`float`, :func:`math.trunc`, - :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``, - ``%``, ``<``, ``<=``, ``>``, and ``>=``. + :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, + :func:`~Real.is_integer`, ``//``, ``%``, ``<``, ``<=``, ``>``, and ``>=``. Real also provides defaults for :func:`complex`, :attr:`~Complex.real`, :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`. + .. method:: is_integer() + + Returns :const:`True` if this number has a finite and integral value, + otherwise :const:`False`. This is a default implementation which + relies on successful conversion to :class:`int`. It may be overridden + in subclasses (such as it is in :class:`float`) for better performance, + or to handle special values such as NaN which are not + convertible to :class:`int`. + + .. versionadded:: 3.10 + .. class:: Rational Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which - should be in lowest terms. With these, it provides a default for - :func:`float`. + should be in lowest terms. With these, it provides defaults for + :func:`float` and :func:`~Real.is_integer`. .. attribute:: numerator @@ -75,9 +86,10 @@ The numeric tower .. class:: Integral Subtypes :class:`Rational` and adds a conversion to :class:`int`. Provides - defaults for :func:`float`, :attr:`~Rational.numerator`, and - :attr:`~Rational.denominator`. Adds abstract methods for ``**`` and - bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, ``~``. + defaults for :func:`float`, :attr:`~Rational.numerator`, + :attr:`~Rational.denominator`, and :func:`~Real.is_integer`. Adds abstract + methods for ``**`` and bit-string operations: ``<<``, ``>>``, ``&``, ``^``, + ``|``, ``~``. Notes for type implementors diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 0ffe7b7526fa768..62f39da2a72a2d1 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -310,6 +310,10 @@ the operations, see :ref:`operator-summary`): +---------------------+---------------------------------+---------+--------------------+ | ``x ** y`` | *x* to the power *y* | \(5) | | +---------------------+---------------------------------+---------+--------------------+ +| ``x.is_integer()`` | ``True`` if *x* has a finite | | :func:`~numbers\ | +| | and integral value, otherwise | | .Real.is_integer` | +| | ``False``. | | | ++---------------------+---------------------------------+---------+--------------------+ .. index:: triple: operations on; numeric; types @@ -583,16 +587,6 @@ class`. float also has the following additional methods. :exc:`OverflowError` on infinities and a :exc:`ValueError` on NaNs. -.. method:: float.is_integer() - - Return ``True`` if the float instance is finite with integral - value, and ``False`` otherwise:: - - >>> (-2.0).is_integer() - True - >>> (3.2).is_integer() - False - Two methods support conversion to and from hexadecimal strings. Since Python's floats are stored internally as binary numbers, converting a float to or from a diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index ab989e5206a9e90..8c0ef570922197b 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -3164,6 +3164,12 @@ def is_zero(self): """Return True if self is a zero; otherwise return False.""" return not self._is_special and self._int == '0' + def is_integer(self): + """Return True is self is finite and integral; otherwise False.""" + if self._is_special: + return False + return self.to_integral_value(rounding=ROUND_FLOOR) == self + def _ln_exp_bound(self): """Compute a lower bound for the adjusted exponent of self.ln(). In other words, compute r such that self.ln() >= 10**r. Assumes @@ -4659,6 +4665,25 @@ def is_zero(self, a): a = _convert_other(a, raiseit=True) return a.is_zero() + def is_integer(self, a): + """Return True if the operand is integral; otherwise return False. + + >>> ExtendedContext.is_integer(Decimal('0')) + True + >>> ExtendedContext.is_integer(Decimal('2.50')) + False + >>> ExtendedContext.is_integer(Decimal('-0E+2')) + True + >>> ExtendedContext.is_integer(Decimal('-0.5')) + False + >>> ExtendedContext.is_integer(Decimal('NaN')) + False + >>> ExtendedContext.is_integer(10) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_integer() + def ln(self, a): """Returns the natural (base e) logarithm of the operand. diff --git a/Lib/numbers.py b/Lib/numbers.py index ed815ef41ebe121..0634f62ff123c46 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -148,7 +148,7 @@ class Real(Complex): """To Complex, Real adds the operations that work on real numbers. In short, those are: a conversion to float, trunc(), divmod, - %, <, <=, >, and >=. + is_integer, %, <, <=, >, and >=. Real also provides defaults for the derived operations. """ @@ -242,6 +242,17 @@ def __le__(self, other): """self <= other""" raise NotImplementedError + def is_integer(self): + """Return True if the Real is integral; otherwise return False. + + This default implementation can be overridden in subclasses + for performance reasons or to deal with values such as NaN, + which would otherwise cause an exception to be raised. + """ + # Although __int__ is not defined at this level, the int + # constructor falls back to __trunc__, which we do have. + return self == int(self) + # Concrete implementations of Complex abstract methods. def __complex__(self): """complex(self) == complex(float(self), 0)""" @@ -290,6 +301,10 @@ def __float__(self): """ return self.numerator / self.denominator + def is_integer(self): + """Return True if the Rational is integral; otherwise return False.""" + return self.denominator == 1 + class Integral(Rational): """Integral adds a conversion to int and the bit-string operations.""" @@ -386,4 +401,8 @@ def denominator(self): """Integers have a denominator of 1.""" return 1 + def is_integer(self): + """Return True; all Integrals represent an integral value.""" + return True + Integral.register(int) diff --git a/Lib/test/decimaltestdata/extra.decTest b/Lib/test/decimaltestdata/extra.decTest index b630d8e3f9d45ed..2f0719ed22342a2 100644 --- a/Lib/test/decimaltestdata/extra.decTest +++ b/Lib/test/decimaltestdata/extra.decTest @@ -2346,6 +2346,24 @@ bool2096 iszero sNaN -> 0 bool2097 iszero -sNaN -> 0 bool2098 iszero sNaN123 -> 0 bool2099 iszero -sNaN123 -> 0 +bool2100 is_integer -1.0 -> 1 +bool2101 is_integer 0.0 -> 1 +bool2102 is_integer 1.0 -> 1 +bool2103 is_integer 42 -> 1 +bool2104 is_integer 1e2 -> 1 +bool2105 is_integer 1.5 -> 0 +bool2106 is_integer 1e-2 -> 0 +bool2107 is_integer NaN -> 0 +bool2109 is_integer -NaN -> 0 +bool2110 is_integer NaN123 -> 0 +bool2111 is_integer -NaN123 -> 0 +bool2112 is_integer sNaN -> 0 +bool2113 is_integer -sNaN -> 0 +bool2114 is_integer sNaN123 -> 0 +bool2115 is_integer -sNaN123 -> 0 +bool2116 is_integer Infinity -> 0 +bool2117 is_integer -Infinity -> 0 + ------------------------------------------------------------------------ -- The following tests (pwmx0 through pwmx440) are for the -- diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 7b3a3859e089325..bc201e10ff2671f 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -354,6 +354,11 @@ def test_real_and_imag(self): self.assertIs(type(False.real), int) self.assertIs(type(False.imag), int) + def test_always_is_integer(self): + # Issue #26680: Incorporating number.is_integer into bool + self.assertTrue(all(b.is_integer() for b in (False, True))) + + def test_main(): support.run_unittest(BoolTest) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index dbd58e8a6519b19..efb41fd46505661 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -276,6 +276,7 @@ def setUp(self): 'is_snan', 'is_subnormal', 'is_zero', + 'is_integer', 'same_quantum') def read_unlimited(self, v, context): @@ -2726,6 +2727,7 @@ def test_named_parameters(self): self.assertRaises(TypeError, D(1).is_snan, context=xc) self.assertRaises(TypeError, D(1).is_signed, context=xc) self.assertRaises(TypeError, D(1).is_zero, context=xc) + self.assertRaises(TypeError, D(1).is_integer, context=xc) self.assertFalse(D("0.01").is_normal(context=xc)) self.assertTrue(D("0.01").is_subnormal(context=xc)) @@ -3197,6 +3199,15 @@ def test_is_zero(self): self.assertEqual(c.is_zero(10), d) self.assertRaises(TypeError, c.is_zero, '10') + def test_is_integer(self): + Decimal = self.decimal.Decimal + Context = self.decimal.Context + + c = Context() + b = c.is_integer(Decimal(10)) + self.assertEqual(c.is_integer(10), b) + self.assertRaises(TypeError, c.is_integer, '10') + def test_ln(self): Decimal = self.decimal.Decimal Context = self.decimal.Context @@ -4360,6 +4371,19 @@ def test_implicit_context(self): self.assertTrue(Decimal("-1").is_signed()) self.assertTrue(Decimal("0").is_zero()) self.assertTrue(Decimal("0").is_zero()) + self.assertTrue(Decimal("-1").is_integer()) + self.assertTrue(Decimal("0").is_integer()) + self.assertTrue(Decimal("1").is_integer()) + self.assertTrue(Decimal("42").is_integer()) + self.assertTrue(Decimal("1e2").is_integer()) + self.assertFalse(Decimal("1.5").is_integer()) + self.assertFalse(Decimal("1e-2").is_integer()) + self.assertFalse(Decimal("NaN").is_integer()) + self.assertFalse(Decimal("-NaN").is_integer()) + self.assertFalse(Decimal("sNaN").is_integer()) + self.assertFalse(Decimal("-sNaN").is_integer()) + self.assertFalse(Decimal("Inf").is_integer()) + self.assertFalse(Decimal("-Inf").is_integer()) # Copy with localcontext() as c: diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 0845f7921c39ec7..811b58fd8f56aac 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -724,6 +724,17 @@ def denominator(self): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) + def test_is_integer(self): + # Issue #26680: Incorporating number.is_integer into Fraction + self.assertTrue(F(-1, 1).is_integer()) + self.assertTrue(F(0, 1).is_integer()) + self.assertTrue(F(1, 1).is_integer()) + self.assertTrue(F(42, 1).is_integer()) + self.assertTrue(F(2, 2).is_integer()) + self.assertTrue(F(8, 4).is_integer()) + self.assertFalse(F(1, 2).is_integer()) + self.assertFalse(F(1, 3).is_integer()) + self.assertFalse(F(2, 3).is_integer()) if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index c97842b5bfd2338..669826c0fa3c1bf 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1381,6 +1381,10 @@ class myint(int): self.assertEqual(type(numerator), int) self.assertEqual(type(denominator), int) + def test_int_always_is_integer(self): + # Issue #26680: Incorporating number.is_integer into int + self.assertTrue(all(x.is_integer() for x in (-1, 0, 1, 42))) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_numeric_tower.py b/Lib/test/test_numeric_tower.py index c54dedb8b793a0a..4e46aacad82b6aa 100644 --- a/Lib/test/test_numeric_tower.py +++ b/Lib/test/test_numeric_tower.py @@ -6,6 +6,7 @@ import sys import operator +from numbers import Real, Rational, Integral from decimal import Decimal as D from fractions import Fraction as F @@ -198,5 +199,35 @@ def test_complex(self): self.assertRaises(TypeError, op, v, z) +class IsIntegerTest(unittest.TestCase): + + def test_real_is_integer(self): + self.assertTrue(Real.is_integer(-1.0)) + self.assertTrue(Real.is_integer(0.0)) + self.assertTrue(Real.is_integer(1.0)) + self.assertTrue(Real.is_integer(42.0)) + + self.assertFalse(Real.is_integer(-0.5)) + self.assertFalse(Real.is_integer(4.2)) + + def test_rational_is_integer(self): + self.assertTrue(Rational.is_integer(F(-1, 1))) + self.assertTrue(Rational.is_integer(F(0, 1))) + self.assertTrue(Rational.is_integer(F(1, 1))) + self.assertTrue(Rational.is_integer(F(42, 1))) + self.assertTrue(Rational.is_integer(F(2, 2))) + self.assertTrue(Rational.is_integer(F(8, 4))) + + self.assertFalse(Rational.is_integer(F(1, 2))) + self.assertFalse(Rational.is_integer(F(1, 3))) + self.assertFalse(Rational.is_integer(F(2, 3))) + + def test_integral_is_integer(self): + self.assertTrue(Integral.is_integer(-1)) + self.assertTrue(Integral.is_integer(0)) + self.assertTrue(Integral.is_integer(1)) + self.assertTrue(Integral.is_integer(1729)) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/ACKS b/Misc/ACKS index 85001daf67d234d..9be0e777ca29427 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1611,6 +1611,7 @@ Roman Skurikhin Ville Skyttä Michael Sloan Nick Sloan +Robert Smallshire Václav Šmilauer Allen W. Smith Christopher Smith diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst new file mode 100644 index 000000000000000..93325ffffcbfc68 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst @@ -0,0 +1,2 @@ +The int type now supports the x.is_integer() method for compatibility with +float. diff --git a/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst b/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst new file mode 100644 index 000000000000000..8b2e818383041a5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst @@ -0,0 +1,3 @@ +The x.is_integer() method is incorporated into the abstract types of the +numeric tower, Real, Rational and Integral, with appropriate default +implementations. diff --git a/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst b/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst new file mode 100644 index 000000000000000..df75e080fa6ee09 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst @@ -0,0 +1,2 @@ +The d.is_integer() method is added to the Decimal type, for compatibility +with other number types. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e7c44acba02fc2e..5200b1a48e4bfad 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -4138,6 +4138,7 @@ Dec_BoolFunc(mpd_isqnan) Dec_BoolFunc(mpd_issnan) Dec_BoolFunc(mpd_issigned) Dec_BoolFunc(mpd_iszero) +Dec_BoolFunc(mpd_isinteger) /* Boolean functions, optional context arg */ Dec_BoolFuncVA(mpd_isnormal) @@ -4772,6 +4773,7 @@ static PyMethodDef dec_methods [] = { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan }, { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed }, { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, + { "is_integer", dec_mpd_isinteger, METH_NOARGS, doc_is_integer}, /* Boolean functions, optional context arg */ { "is_normal", (PyCFunction)(void(*)(void))dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal }, @@ -5183,6 +5185,7 @@ DecCtx_BoolFunc_NO_CTX(mpd_isqnan) DecCtx_BoolFunc_NO_CTX(mpd_issigned) DecCtx_BoolFunc_NO_CTX(mpd_issnan) DecCtx_BoolFunc_NO_CTX(mpd_iszero) +DecCtx_BoolFunc_NO_CTX(mpd_isinteger) static PyObject * ctx_iscanonical(PyObject *context UNUSED, PyObject *v) @@ -5464,6 +5467,7 @@ static PyMethodDef context_methods [] = { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan }, { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal }, { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero }, + { "is_integer", ctx_mpd_isinteger, METH_O, doc_ctx_is_integer }, /* Functions with a single decimal argument */ { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */ @@ -6097,5 +6101,3 @@ PyInit__decimal(void) return NULL; /* GCOV_NOT_REACHED */ } - - diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index f7fd6e795299845..bd602ab278e0edd 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -260,6 +260,11 @@ Return True if the argument is a (positive or negative) zero and False\n\ otherwise.\n\ \n"); +PyDoc_STRVAR(doc_is_integer, +"is_integer($self, /)\n--\n\n\ +Return True if the argument is finite and integral, otherwise False.\n\ +\n"); + PyDoc_STRVAR(doc_ln, "ln($self, /, context=None)\n--\n\n\ Return the natural (base e) logarithm of the operand. The function always\n\ @@ -685,6 +690,11 @@ PyDoc_STRVAR(doc_ctx_is_zero, Return True if x is a zero, False otherwise.\n\ \n"); +PyDoc_STRVAR(doc_ctx_is_integer, +"is_integer($self, x, /)\n--\n\n\ ++Return True if x is finite and integral, False otherwise.\n\ ++\n"); + PyDoc_STRVAR(doc_ctx_ln, "ln($self, x, /)\n--\n\n\ Return the natural (base e) logarithm of x.\n\ @@ -879,6 +889,3 @@ Convert a number to a string using scientific notation.\n\ #endif /* DOCSTRINGS_H */ - - - diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 4bd47b116f883c6..16e6f7e619e8721 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -121,6 +121,24 @@ int___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } +PyDoc_STRVAR(int_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Returns True for all integers."); + +#define INT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, + +static PyObject * +int_is_integer_impl(PyObject *self); + +static PyObject * +int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_is_integer_impl(self); +} + PyDoc_STRVAR(int___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" @@ -367,4 +385,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb exit: return return_value; } -/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=022614978e2fcdf3 input=a9049054013a1b77]*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 92514d4154e2cbb..bc5b49dcf8b56fc 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5233,6 +5233,19 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return result; } +/*[clinic input] +int.is_integer + +Returns True for all integers. +[clinic start generated code]*/ + +static PyObject * +int_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=90f8e794ce5430ef input=1c1a86957301d26d]*/ +{ + Py_RETURN_TRUE; +} + /*[clinic input] int.__sizeof__ -> Py_ssize_t @@ -5547,6 +5560,7 @@ static PyMethodDef long_methods[] = { {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, INT___ROUND___METHODDEF + INT_IS_INTEGER_METHODDEF INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF From 2e9503f1f715410adf7ba90df38e5dbf05fed5ed Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 1 Oct 2020 18:57:37 +0200 Subject: [PATCH 388/486] bpo-21955: Change my nickname in BINARY_ADD comment (GH-22481) --- Python/ceval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index 6bd2d6bc13d86f1..7c6cf83bc9ac012 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1701,7 +1701,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; - /* NOTE(haypo): Please don't try to micro-optimize int+int on + /* NOTE(vstinner): Please don't try to micro-optimize int+int on CPython using bytecode, it is simply worthless. See http://bugs.python.org/issue21955 and http://bugs.python.org/issue10044 for the discussion. In short, From f931b97d203c34d75cf2f13fedbdf7dc8102126d Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Thu, 1 Oct 2020 20:22:14 -0300 Subject: [PATCH 389/486] [doc] Update references to NumPy (GH-22458) Numeric(al) Python to NumPy. It seems the old name hasn't been used for some time. --- Doc/faq/programming.rst | 2 +- Doc/library/array.rst | 5 ++--- Doc/library/functions.rst | 4 +--- Doc/tutorial/floatingpoint.rst | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 76ae4d260fad468..0b486d7e7e254ac 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1191,7 +1191,7 @@ difference is that a Python list can contain objects of many different types. The ``array`` module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also -note that the Numeric extensions and others define array-like structures with +note that NumPy and other third party packages define array-like structures with various characteristics as well. To get Lisp-style linked lists, you can emulate cons cells using tuples:: diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 78020738bf4f75b..ff3ec6b1fd723be 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -257,7 +257,6 @@ Examples:: Packing and unpacking of External Data Representation (XDR) data as used in some remote procedure call systems. - `The Numerical Python Documentation `_ - The Numeric Python extension (NumPy) defines another array type; see - http://www.numpy.org/ for further information about Numerical Python. + `NumPy `_ + The NumPy package defines another array type. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7543fc4b10d4666..c49bb0c9de70cac 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1512,14 +1512,12 @@ are always available. They are listed here in alphabetical order. .. class:: slice(stop) slice(start, stop[, step]) - .. index:: single: Numerical Python - Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to ``None``. Slice objects have read-only data attributes :attr:`~slice.start`, :attr:`~slice.stop` and :attr:`~slice.step` which merely return the argument values (or their default). They have no other explicit functionality; - however they are used by Numerical Python and other third party extensions. + however they are used by NumPy and other third party packages. Slice objects are also generated when extended indexing syntax is used. For example: ``a[start:stop:step]`` or ``a[start:stop, i]``. See :func:`itertools.islice` for an alternate version that returns an iterator. diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index 0c0eb526fa9ed60..b98de6e56a00319 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -158,7 +158,7 @@ which implements arithmetic based on rational numbers (so the numbers like 1/3 can be represented exactly). If you are a heavy user of floating point operations you should take a look -at the Numerical Python package and many other packages for mathematical and +at the NumPy package and many other packages for mathematical and statistical operations supplied by the SciPy project. See . Python provides tools that may help on those rare occasions when you really From 2b81082e9d6ce2eec5ac338d2f4901cf6afa4946 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 1 Oct 2020 19:30:54 -0700 Subject: [PATCH 390/486] Update link to supporting references (GH-22488) --- Modules/mathmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 5cd31b7dd4acfbb..45b03028753a3fe 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2494,7 +2494,7 @@ exactly equal) was verified for 1 billion random inputs with n=5. [7] 3. Square root differential correction: https://arxiv.org/pdf/1904.09481.pdf 4. Data dependency graph: https://bugs.python.org/file49439/hypot.png 5. https://www.wolframalpha.com/input/?i=Maclaurin+series+sqrt%28h**2+%2B+x%29+at+x%3D0 -6. Analysis of internal accuracy: https://bugs.python.org/file49435/best_frac.py +6. Analysis of internal accuracy: https://bugs.python.org/file49484/best_frac.py 7. Commutativity test: https://bugs.python.org/file49448/test_hypot_commutativity.py */ From 0aa5000c9f6231d8574d423a9b138ce23e8e5acf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 2 Oct 2020 14:49:00 +0200 Subject: [PATCH 391/486] bpo-41692: Deprecate PyUnicode_InternImmortal() (GH-22486) The PyUnicode_InternImmortal() function is now deprecated and will be removed in Python 3.12: use PyUnicode_InternInPlace() instead. --- Doc/whatsnew/3.10.rst | 8 ++++++++ Include/unicodeobject.h | 5 ++++- .../next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst | 3 +++ Objects/unicodeobject.c | 9 +++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index f74dd1aa247a340..957a3e791ecb69a 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -299,6 +299,14 @@ Porting to Python 3.10 Unicode object without initial data. (Contributed by Inada Naoki in :issue:`36346`.) +Deprecated +---------- + +* The ``PyUnicode_InternImmortal()`` function is now deprecated + and will be removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` + instead. + (Contributed by Victor Stinner in :issue:`41692`.) + Removed ------- diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 500ce242e9f0e85..90b3299fd26ceb4 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -261,11 +261,14 @@ PyAPI_FUNC(PyObject *) PyUnicode_FromFormat( ); PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); -PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( const char *u /* UTF-8 encoded string */ ); +// PyUnicode_InternImmortal() is deprecated since Python 3.10 +// and will be removed in Python 3.12. Use PyUnicode_InternInPlace() instead. +Py_DEPRECATED(3.10) PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); + /* Use only if you know it's a string */ #define PyUnicode_CHECK_INTERNED(op) \ (((PyASCIIObject *)(op))->state.interned) diff --git a/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst b/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst new file mode 100644 index 000000000000000..1be37c6572271bd --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst @@ -0,0 +1,3 @@ +The ``PyUnicode_InternImmortal()`` function is now deprecated and will be +removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` instead. +Patch by Victor Stinner. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f32ab417c364caf..cf72238a8d05854 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15764,6 +15764,15 @@ PyUnicode_InternInPlace(PyObject **p) void PyUnicode_InternImmortal(PyObject **p) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_InternImmortal() is deprecated; " + "use PyUnicode_InternInPlace() instead", 1) < 0) + { + // The function has no return value, the exception cannot + // be reported to the caller, so just log it. + PyErr_WriteUnraisable(NULL); + } + PyUnicode_InternInPlace(p); if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; From 4515dd36db34d9cf893de7fe9eb76a9a9fd3d88e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 3 Oct 2020 02:18:01 +1000 Subject: [PATCH 392/486] bpo-41802: Document 'PyDict_DelItem' can raise a 'KeyError' (GH-22291) --- Doc/c-api/dict.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 769484134ed5154..8e0d6845463490a 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -81,14 +81,16 @@ Dictionary Objects .. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key) Remove the entry in dictionary *p* with key *key*. *key* must be hashable; - if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` - on failure. + if it isn't, :exc:`TypeError` is raised. + If *key* is not in the dictionary, :exc:`KeyError` is raised. + Return ``0`` on success or ``-1`` on failure. .. c:function:: int PyDict_DelItemString(PyObject *p, const char *key) - Remove the entry in dictionary *p* which has a key specified by the string - *key*. Return ``0`` on success or ``-1`` on failure. + Remove the entry in dictionary *p* which has a key specified by the string *key*. + If *key* is not in the dictionary, :exc:`KeyError` is raised. + Return ``0`` on success or ``-1`` on failure. .. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) From 5f66de5b30ed6c27b7cf41f480ecf43b9704fef8 Mon Sep 17 00:00:00 2001 From: Hansraj Das Date: Sat, 3 Oct 2020 01:51:45 +0530 Subject: [PATCH 393/486] Typo fix - "mesasge" should be "message" (GH-22498) * Correct at 2 places in email module --- Lib/email/message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/email/message.py b/Lib/email/message.py index 12626026179608e..3701b305532b4c1 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -141,7 +141,7 @@ def as_string(self, unixfrom=False, maxheaderlen=0, policy=None): header. For backward compatibility reasons, if maxheaderlen is not specified it defaults to 0, so you must override it explicitly if you want a different maxheaderlen. 'policy' is passed to the - Generator instance used to serialize the mesasge; if it is not + Generator instance used to serialize the message; if it is not specified the policy associated with the message instance is used. If the message object contains binary data that is not encoded @@ -958,7 +958,7 @@ def as_string(self, unixfrom=False, maxheaderlen=None, policy=None): header. maxheaderlen is retained for backward compatibility with the base Message class, but defaults to None, meaning that the policy value for max_line_length controls the header maximum length. 'policy' is - passed to the Generator instance used to serialize the mesasge; if it + passed to the Generator instance used to serialize the message; if it is not specified the policy associated with the message instance is used. """ From 12f7475d6a6825faf6b80e7005bff9ec78d9474a Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Fri, 2 Oct 2020 19:36:26 -0300 Subject: [PATCH 394/486] Fix is_typeddict markup (#22501) --- Doc/library/typing.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 3b824d0a4a8da00..cbb18954a6764a4 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1666,12 +1666,13 @@ Introspection helpers Check if a type is a :class:`TypedDict`. For example:: - class Film(TypedDict): - title: str - year: int - is_typeddict(Film) # => True - is_typeddict(Union[list, str]) # => False + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False .. versionadded:: 3.10 From 496f2545a6e3099cc6e506df8c9a7a1fefb6ab80 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Fri, 2 Oct 2020 20:15:28 -0300 Subject: [PATCH 395/486] [doc] Fix link to abc.collections.Iterable (GH-22502) Automerge-Triggered-By: @gvanrossum --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index cbb18954a6764a4..35e0445889b1721 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -903,7 +903,7 @@ These are not used in annotations. They are building blocks for creating generic Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. This raises :exc:`TypeError` when applied to a non-protocol class. This allows a simple-minded structural check, very similar to "one trick ponies" - in :mod:`collections.abc` such as :class:`Iterable`. For example:: + in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example:: @runtime_checkable class Closable(Protocol): From 29d52051c5816229d142b2efa4c7162e69dfef92 Mon Sep 17 00:00:00 2001 From: scoder Date: Sat, 3 Oct 2020 08:07:07 +0200 Subject: [PATCH 396/486] bpo-41900: C14N 2.0 serialisation failed for unprefixed attributes when a default namespace was defined. (GH-22474) --- Lib/test/test_xml_etree.py | 8 ++++++++ Lib/xml/etree/ElementTree.py | 5 +++++ .../next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst | 2 ++ 3 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index d22c35d92c4e330..3f1f3781e488c1c 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -3899,6 +3899,14 @@ def test_simple_roundtrip(self): #self.assertEqual(c14n_roundtrip(""), #'') + # Namespace issues + xml = '' + self.assertEqual(c14n_roundtrip(xml), xml) + xml = '' + self.assertEqual(c14n_roundtrip(xml), xml) + xml = '' + self.assertEqual(c14n_roundtrip(xml), xml) + def test_c14n_exclusion(self): xml = textwrap.dedent("""\ diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index da2bcad0b4d6298..7a269001d6e18f6 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1876,6 +1876,11 @@ def _qname(self, qname, uri=None): self._declared_ns_stack[-1].append((uri, prefix)) return f'{prefix}:{tag}' if prefix else tag, tag, uri + if not uri: + # As soon as a default namespace is defined, + # anything that has no namespace (and thus, no prefix) goes there. + return tag, tag, uri + raise ValueError(f'Namespace "{uri}" is not declared in scope') def data(self, data): diff --git a/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst b/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst new file mode 100644 index 000000000000000..6586c09ec985d52 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst @@ -0,0 +1,2 @@ +C14N 2.0 serialisation in xml.etree.ElementTree failed for unprefixed attributes +when a default namespace was defined. From 47e1b4c8f628068c2851a2c6e1a74c2cda3b0c46 Mon Sep 17 00:00:00 2001 From: Ram Rachum Date: Sat, 3 Oct 2020 12:52:13 +0300 Subject: [PATCH 397/486] bpo-40833: Clarify Path.rename doc-string regarding relative paths (GH-20554) --- Doc/library/pathlib.rst | 8 ++++++++ Lib/pathlib.py | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 23486b625072f36..9526a03b053986c 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1008,6 +1008,10 @@ call fails (for example because the path doesn't exist). >>> target.open().read() 'some text' + The target path may be absolute or relative. Relative paths are interpreted + relative to the current working directory, *not* the directory of the Path + object. + .. versionchanged:: 3.8 Added return value, return the new Path instance. @@ -1018,6 +1022,10 @@ call fails (for example because the path doesn't exist). instance pointing to *target*. If *target* points to an existing file or directory, it will be unconditionally replaced. + The target path may be absolute or relative. Relative paths are interpreted + relative to the current working directory, *not* the directory of the Path + object. + .. versionchanged:: 3.8 Added return value, return the new Path instance. diff --git a/Lib/pathlib.py b/Lib/pathlib.py index babc443dd3b3043..147be2ff0dddfcc 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1366,17 +1366,26 @@ def link_to(self, target): def rename(self, target): """ - Rename this path to the given path, - and return a new Path instance pointing to the given path. + Rename this path to the target path. + + The target path may be absolute or relative. Relative paths are + interpreted relative to the current working directory, *not* the + directory of the Path object. + + Returns the new Path instance pointing to the target path. """ self._accessor.rename(self, target) return self.__class__(target) def replace(self, target): """ - Rename this path to the given path, clobbering the existing - destination if it exists, and return a new Path instance - pointing to the given path. + Rename this path to the target path, overwriting if that path exists. + + The target path may be absolute or relative. Relative paths are + interpreted relative to the current working directory, *not* the + directory of the Path object. + + Returns the new Path instance pointing to the target path. """ self._accessor.replace(self, target) return self.__class__(target) From b85c4f41bb37e4ee47ca435fd82d44a8cd0ad9c8 Mon Sep 17 00:00:00 2001 From: Ram Rachum Date: Sat, 3 Oct 2020 13:43:47 +0300 Subject: [PATCH 398/486] bpo-41867: List options for timespec in docstrings of isoformat methods (GH-22418) --- Lib/datetime.py | 6 ++++-- Modules/_datetimemodule.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Lib/datetime.py b/Lib/datetime.py index 3090978508c9211..ea86bcb8b2388a4 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1421,7 +1421,8 @@ def isoformat(self, timespec='auto'): part is omitted if self.microsecond == 0. The optional argument timespec specifies the number of additional - terms of the time to include. + terms of the time to include. Valid options are 'auto', 'hours', + 'minutes', 'seconds', 'milliseconds' and 'microseconds'. """ s = _format_time(self._hour, self._minute, self._second, self._microsecond, timespec) @@ -1906,7 +1907,8 @@ def isoformat(self, sep='T', timespec='auto'): time, default 'T'. The optional argument timespec specifies the number of additional - terms of the time to include. + terms of the time to include. Valid options are 'auto', 'hours', + 'minutes', 'seconds', 'milliseconds' and 'microseconds'. """ s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + _format_time(self._hour, self._minute, self._second, diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 0631272429f4f14..94868717e6a04cc 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -4663,7 +4663,10 @@ static PyMethodDef time_methods[] = { {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" "[+HH:MM].\n\n" - "timespec specifies what components of the time to include.\n")}, + "The optional argument timespec specifies the number " + "of additional terms\nof the time to include. Valid " + "options are 'auto', 'hours', 'minutes',\n'seconds', " + "'milliseconds' and 'microseconds'.\n")}, {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, @@ -6370,9 +6373,10 @@ static PyMethodDef datetime_methods[] = { "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" "sep is used to separate the year from the time, and " "defaults to 'T'.\n" - "timespec specifies what components of the time to include" - " (allowed values are 'auto', 'hours', 'minutes', 'seconds'," - " 'milliseconds', and 'microseconds').\n")}, + "The optional argument timespec specifies the number " + "of additional terms\nof the time to include. Valid " + "options are 'auto', 'hours', 'minutes',\n'seconds', " + "'milliseconds' and 'microseconds'.\n")}, {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS, PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, From e3f4fa00bc794a36f06425e8f3019fc1cc18d9d3 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 3 Oct 2020 15:28:51 +0100 Subject: [PATCH 399/486] bpo-41826: Fix compiler warnings in test_peg_generator (GH-22455) Co-authored-by: Skip Montanaro --- Lib/test/test_peg_generator/test_c_parser.py | 33 ++++++++++---------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index 2c13635d37dea34..0dffedca789c57b 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -90,7 +90,7 @@ def run_test(self, grammar_source, test_source): def test_c_parser(self) -> None: grammar_source = """ - start[mod_ty]: a=stmt* $ { Module(a, NULL, p->arena) } + start[mod_ty]: a[asdl_stmt_seq*]=stmt* $ { Module(a, NULL, p->arena) } stmt[stmt_ty]: a=expr_stmt { a } expr_stmt[stmt_ty]: a=expression NEWLINE { _Py_Expr(a, EXTRA) } expression[expr_ty]: ( l=expression '+' r=term { _Py_BinOp(l, Add, r, EXTRA) } @@ -232,7 +232,7 @@ def test_nasty_mutually_left_recursive(self) -> None: def test_return_stmt_noexpr_action(self) -> None: grammar_source = """ start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } - statements[asdl_seq*]: a=statement+ { a } + statements[asdl_stmt_seq*]: a[asdl_stmt_seq*]=statement+ { a } statement[stmt_ty]: simple_stmt simple_stmt[stmt_ty]: small_stmt small_stmt[stmt_ty]: return_stmt @@ -246,7 +246,7 @@ def test_return_stmt_noexpr_action(self) -> None: def test_gather_action_ast(self) -> None: grammar_source = """ - start[mod_ty]: a=';'.pass_stmt+ NEWLINE ENDMARKER { Module(a, NULL, p->arena) } + start[mod_ty]: a[asdl_stmt_seq*]=';'.pass_stmt+ NEWLINE ENDMARKER { Module(a, NULL, p->arena) } pass_stmt[stmt_ty]: a='pass' { _Py_Pass(EXTRA)} """ test_source = """ @@ -258,7 +258,7 @@ def test_gather_action_ast(self) -> None: def test_pass_stmt_action(self) -> None: grammar_source = """ start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } - statements[asdl_seq*]: a=statement+ { a } + statements[asdl_stmt_seq*]: a[asdl_stmt_seq*]=statement+ { a } statement[stmt_ty]: simple_stmt simple_stmt[stmt_ty]: small_stmt small_stmt[stmt_ty]: pass_stmt @@ -273,10 +273,11 @@ def test_pass_stmt_action(self) -> None: def test_if_stmt_action(self) -> None: grammar_source = """ start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } - statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) } - statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } | simple_stmt + statements[asdl_stmt_seq*]: a=statement+ { (asdl_stmt_seq*)_PyPegen_seq_flatten(p, a) } + statement[asdl_stmt_seq*]: a=compound_stmt { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } | simple_stmt - simple_stmt[asdl_seq*]: a=small_stmt b=further_small_stmt* [';'] NEWLINE { _PyPegen_seq_insert_in_front(p, a, b) } + simple_stmt[asdl_stmt_seq*]: a=small_stmt b=further_small_stmt* [';'] NEWLINE { + (asdl_stmt_seq*)_PyPegen_seq_insert_in_front(p, a, b) } further_small_stmt[stmt_ty]: ';' a=small_stmt { a } block: simple_stmt | NEWLINE INDENT a=statements DEDENT { a } @@ -299,14 +300,14 @@ def test_if_stmt_action(self) -> None: def test_same_name_different_types(self) -> None: grammar_source = """ - start[mod_ty]: a=import_from+ NEWLINE ENDMARKER { Module(a, NULL, p->arena)} + start[mod_ty]: a[asdl_stmt_seq*]=import_from+ NEWLINE ENDMARKER { Module(a, NULL, p->arena)} import_from[stmt_ty]: ( a='from' !'import' c=simple_name 'import' d=import_as_names_from { _Py_ImportFrom(c->v.Name.id, d, 0, EXTRA) } | a='from' '.' 'import' c=import_as_names_from { _Py_ImportFrom(NULL, c, 1, EXTRA) } ) simple_name[expr_ty]: NAME - import_as_names_from[asdl_seq*]: a=','.import_as_name_from+ { a } + import_as_names_from[asdl_alias_seq*]: a[asdl_alias_seq*]=','.import_as_name_from+ { a } import_as_name_from[alias_ty]: a=NAME 'as' b=NAME { _Py_alias(((expr_ty) a)->v.Name.id, ((expr_ty) b)->v.Name.id, p->arena) } """ test_source = """ @@ -320,12 +321,12 @@ def test_same_name_different_types(self) -> None: def test_with_stmt_with_paren(self) -> None: grammar_source = """ start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } - statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) } - statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } + statements[asdl_stmt_seq*]: a=statement+ { (asdl_stmt_seq*)_PyPegen_seq_flatten(p, a) } + statement[asdl_stmt_seq*]: a=compound_stmt { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } compound_stmt[stmt_ty]: with_stmt with_stmt[stmt_ty]: ( - a='with' '(' b=','.with_item+ ')' ':' c=block { - _Py_With(b, _PyPegen_singleton_seq(p, c), NULL, EXTRA) } + a='with' '(' b[asdl_withitem_seq*]=','.with_item+ ')' ':' c=block { + _Py_With(b, (asdl_stmt_seq*) _PyPegen_singleton_seq(p, c), NULL, EXTRA) } ) with_item[withitem_ty]: ( e=NAME o=['as' t=NAME { t }] { _Py_withitem(e, _PyPegen_set_expr_context(p, o, Store), p->arena) } @@ -346,12 +347,12 @@ def test_with_stmt_with_paren(self) -> None: def test_ternary_operator(self) -> None: grammar_source = """ start[mod_ty]: a=expr ENDMARKER { Module(a, NULL, p->arena) } - expr[asdl_seq*]: a=listcomp NEWLINE { _PyPegen_singleton_seq(p, _Py_Expr(a, EXTRA)) } + expr[asdl_stmt_seq*]: a=listcomp NEWLINE { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, _Py_Expr(a, EXTRA)) } listcomp[expr_ty]: ( a='[' b=NAME c=for_if_clauses d=']' { _Py_ListComp(b, c, EXTRA) } ) - for_if_clauses[asdl_seq*]: ( - a=(y=[ASYNC] 'for' a=NAME 'in' b=NAME c=('if' z=NAME { z })* + for_if_clauses[asdl_comprehension_seq*]: ( + a[asdl_comprehension_seq*]=(y=[ASYNC] 'for' a=NAME 'in' b=NAME c[asdl_expr_seq*]=('if' z=NAME { z })* { _Py_comprehension(_Py_Name(((expr_ty) a)->v.Name.id, Store, EXTRA), b, c, (y == NULL) ? 0 : 1, p->arena) })+ { a } ) """ From 81b58370800d5e0f96c7eb6dc39152f1c671d617 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 3 Oct 2020 10:58:39 -0400 Subject: [PATCH 400/486] bpo-40564: Avoid copying state from extant ZipFile. (GH-22371) bpo-40564: Avoid copying state from extant ZipFile. --- Lib/test/test_zipfile.py | 33 +++++++++++++++++++ Lib/zipfile.py | 23 +++++++++---- .../2020-09-23-03-33-37.bpo-40564.iXQqMq.rst | 1 + 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 687e43df780d653..3bb9ce995c2a17f 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2889,6 +2889,33 @@ def test_open(self): data = strm.read() assert data == "content of a" + def test_open_write(self): + """ + If the zipfile is open for write, it should be possible to + write bytes or text to it. + """ + zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w')) + with zf.joinpath('file.bin').open('wb') as strm: + strm.write(b'binary contents') + with zf.joinpath('file.txt').open('w') as strm: + strm.write('text file') + + def test_open_extant_directory(self): + """ + Attempting to open a directory raises IsADirectoryError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(IsADirectoryError): + zf.joinpath('b').open() + + def test_open_missing_directory(self): + """ + Attempting to open a missing directory raises FileNotFoundError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(FileNotFoundError): + zf.joinpath('z').open() + def test_read(self): for alpharep in self.zipfile_alpharep(): root = zipfile.Path(alpharep) @@ -2986,6 +3013,12 @@ def test_implied_dirs_performance(self): data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] zipfile.CompleteDirs._implied_dirs(data) + def test_read_does_not_close(self): + for alpharep in self.zipfile_ondisk(): + with zipfile.ZipFile(alpharep) as file: + for rep in range(2): + zipfile.Path(file, 'a.txt').read_text() + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 816f8582bbf6d59..da3e40e5dbd41b2 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2197,13 +2197,12 @@ def make(cls, source): if not isinstance(source, ZipFile): return cls(source) - # Only allow for FastPath when supplied zipfile is read-only + # Only allow for FastLookup when supplied zipfile is read-only if 'r' not in source.mode: cls = CompleteDirs - res = cls.__new__(cls) - vars(res).update(vars(source)) - return res + source.__class__ = cls + return source class FastLookup(CompleteDirs): @@ -2292,17 +2291,29 @@ class Path: __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" def __init__(self, root, at=""): + """ + Construct a Path from a ZipFile or filename. + + Note: When the source is an existing ZipFile object, + its type (__class__) will be mutated to a + specialized type. If the caller wishes to retain the + original type, the caller should either create a + separate ZipFile object or pass a filename. + """ self.root = FastLookup.make(root) self.at = at - def open(self, mode='r', *args, **kwargs): + def open(self, mode='r', *args, pwd=None, **kwargs): """ Open this entry as text or binary following the semantics of ``pathlib.Path.open()`` by passing arguments through to io.TextIOWrapper(). """ - pwd = kwargs.pop('pwd', None) + if self.is_dir(): + raise IsADirectoryError(self) zip_mode = mode[0] + if not self.exists() and zip_mode == 'r': + raise FileNotFoundError(self) stream = self.root.open(self.at, zip_mode, pwd=pwd) if 'b' in mode: if args or kwargs: diff --git a/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst b/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst new file mode 100644 index 000000000000000..085534734ec948d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst @@ -0,0 +1 @@ +In ``zipfile.Path``, mutate the passed ZipFile object type instead of making a copy. Prevents issues when both the local copy and the caller’s copy attempt to close the same file handle. \ No newline at end of file From df07be5b5a7dce9055f32e04e7ec721720596e74 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sat, 3 Oct 2020 12:51:13 -0300 Subject: [PATCH 401/486] [doc] Fix link to abc.collections.Iterable (GH-22520) Missed this occurrence before, sorry. Also changed "the PEP" to "PEP". Automerge-Triggered-By: @gvanrossum --- Doc/library/typing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 35e0445889b1721..e2ae539d957e6d1 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -406,10 +406,10 @@ Initially :pep:`484` defined Python static type system as using a class ``B`` is expected if and only if ``A`` is a subclass of ``B``. This requirement previously also applied to abstract base classes, such as -:class:`Iterable`. The problem with this approach is that a class had +:class:`~collections.abc.Iterable`. The problem with this approach is that a class had to be explicitly marked to support them, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code. -For example, this conforms to the :pep:`484`:: +For example, this conforms to :pep:`484`:: from collections.abc import Sized, Iterable, Iterator From 810d44169c3f06661fe4cb61d3e053af50a9c9d3 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 4 Oct 2020 02:16:56 +0900 Subject: [PATCH 402/486] bpo-41922: Use PEP 590 vectorcall to speed up reversed() (GH-22523) --- .../2020-10-04-01-02-58.bpo-41922.kHGT8I.rst | 2 ++ Objects/enumobject.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst new file mode 100644 index 000000000000000..3c4de2c93555f20 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst @@ -0,0 +1,2 @@ +Speed up calls to ``reversed()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Dong-hee Na. diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 4a83bb45aa6678e..9d8449bb30f2a3d 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -314,6 +314,24 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return (PyObject *)ro; } +static PyObject * +reversed_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + assert(PyType_Check(type)); + + if (!_PyArg_NoKwnames("reversed", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("reversed", nargs, 1, 1)) { + return NULL; + } + + return reversed_new_impl((PyTypeObject *)type, args[0]); +} + static void reversed_dealloc(reversedobject *ro) { @@ -445,4 +463,5 @@ PyTypeObject PyReversed_Type = { PyType_GenericAlloc, /* tp_alloc */ reversed_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)reversed_vectorcall, }; From 1119448553f3617a4abeebdb183b657673340854 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 3 Oct 2020 20:45:55 +0100 Subject: [PATCH 403/486] bpo-41840: Report module-level globals as both local and global in the symtable module (GH-22391) --- Lib/symtable.py | 19 ++++++++++++------- Lib/test/test_symtable.py | 18 ++++++++++++++++-- .../2020-09-23-23-17-59.bpo-41840.QRFr4L.rst | 3 +++ 3 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst diff --git a/Lib/symtable.py b/Lib/symtable.py index 9ff27ef74ffe83e..98db1e2557d37f2 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -39,7 +39,7 @@ def __call__(self, table, filename): _newSymbolTable = SymbolTableFactory() -class SymbolTable(object): +class SymbolTable: def __init__(self, raw_table, filename): self._table = raw_table @@ -52,7 +52,7 @@ def __repr__(self): else: kind = "%s " % self.__class__.__name__ - if self._table.name == "global": + if self._table.name == "top": return "<{0}SymbolTable for module {1}>".format(kind, self._filename) else: return "<{0}SymbolTable for {1} in {2}>".format(kind, @@ -124,7 +124,9 @@ def lookup(self, name): if sym is None: flags = self._table.symbols[name] namespaces = self.__check_children(name) - sym = self._symbols[name] = Symbol(name, flags, namespaces) + module_scope = (self._table.name == "top") + sym = self._symbols[name] = Symbol(name, flags, namespaces, + module_scope=module_scope) return sym def get_symbols(self): @@ -214,13 +216,14 @@ def get_methods(self): return self.__methods -class Symbol(object): +class Symbol: - def __init__(self, name, flags, namespaces=None): + def __init__(self, name, flags, namespaces=None, *, module_scope=False): self.__name = name self.__flags = flags self.__scope = (flags >> SCOPE_OFF) & SCOPE_MASK # like PyST_GetScope() self.__namespaces = namespaces or () + self.__module_scope = module_scope def __repr__(self): return "".format(self.__name) @@ -244,7 +247,8 @@ def is_parameter(self): def is_global(self): """Return *True* if the sysmbol is global. """ - return bool(self.__scope in (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT)) + return bool(self.__scope in (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) + or (self.__module_scope and self.__flags & DEF_BOUND)) def is_nonlocal(self): """Return *True* if the symbol is nonlocal.""" @@ -258,7 +262,8 @@ def is_declared_global(self): def is_local(self): """Return *True* if the symbol is local. """ - return bool(self.__scope in (LOCAL, CELL)) + return bool(self.__scope in (LOCAL, CELL) + or (self.__module_scope and self.__flags & DEF_BOUND)) def is_annotated(self): """Return *True* if the symbol is annotated. diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index fa514917a1f0210..a30e53496039be4 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -11,6 +11,8 @@ glob = 42 some_var = 12 +some_non_assigned_global_var = 11 +some_assigned_global_var = 11 class Mine: instance_var = 24 @@ -19,6 +21,8 @@ def a_method(p1, p2): def spam(a, b, *var, **kw): global bar + global some_assigned_global_var + some_assigned_global_var = 12 bar = 47 some_var = 10 x = 23 @@ -88,14 +92,14 @@ def test_children(self): def test_lineno(self): self.assertEqual(self.top.get_lineno(), 0) - self.assertEqual(self.spam.get_lineno(), 12) + self.assertEqual(self.spam.get_lineno(), 14) def test_function_info(self): func = self.spam self.assertEqual(sorted(func.get_parameters()), ["a", "b", "kw", "var"]) expected = ['a', 'b', 'internal', 'kw', 'other_internal', 'some_var', 'var', 'x'] self.assertEqual(sorted(func.get_locals()), expected) - self.assertEqual(sorted(func.get_globals()), ["bar", "glob"]) + self.assertEqual(sorted(func.get_globals()), ["bar", "glob", "some_assigned_global_var"]) self.assertEqual(self.internal.get_frees(), ("x",)) def test_globals(self): @@ -106,6 +110,9 @@ def test_globals(self): self.assertFalse(self.internal.lookup("x").is_global()) self.assertFalse(self.Mine.lookup("instance_var").is_global()) self.assertTrue(self.spam.lookup("bar").is_global()) + # Module-scope globals are both global and local + self.assertTrue(self.top.lookup("some_non_assigned_global_var").is_global()) + self.assertTrue(self.top.lookup("some_assigned_global_var").is_global()) def test_nonlocal(self): self.assertFalse(self.spam.lookup("some_var").is_nonlocal()) @@ -116,6 +123,9 @@ def test_nonlocal(self): def test_local(self): self.assertTrue(self.spam.lookup("x").is_local()) self.assertFalse(self.spam.lookup("bar").is_local()) + # Module-scope globals are both global and local + self.assertTrue(self.top.lookup("some_non_assigned_global_var").is_local()) + self.assertTrue(self.top.lookup("some_assigned_global_var").is_local()) def test_free(self): self.assertTrue(self.internal.lookup("x").is_free()) @@ -234,6 +244,10 @@ def test_bytes(self): top = symtable.symtable(code, "?", "exec") self.assertIsNotNone(find_block(top, "\u017d")) + def test_symtable_repr(self): + self.assertEqual(str(self.top), "") + self.assertEqual(str(self.spam), "") + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst b/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst new file mode 100644 index 000000000000000..e96942d8ebd07f5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst @@ -0,0 +1,3 @@ +Fix a bug in the :mod:`symtable` module that was causing module-scope global +variables to not be reported as both local and global. Patch by Pablo +Galindo. From 39b5ae0ebc89e14e5fa47285f56ed349ebd96ca1 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sat, 3 Oct 2020 19:10:59 -0300 Subject: [PATCH 404/486] [doc] Use list[int] instead of List[int] (etc.) in a few more places (GH-22524) This changes a few occurrences left behind by #22340. Automerge-Triggered-By: @gvanrossum --- Doc/library/dataclasses.rst | 4 ++-- Doc/library/typing.rst | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 6e74af062d9e724..e706f7fcc566d89 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -188,7 +188,7 @@ Module-level decorators, classes, and functions @dataclass class C: - mylist: List[int] = field(default_factory=list) + mylist: list[int] = field(default_factory=list) c = C() c.mylist += [1, 2, 3] @@ -301,7 +301,7 @@ Module-level decorators, classes, and functions @dataclass class C: - mylist: List[Point] + mylist: list[Point] p = Point(10, 20) assert asdict(p) == {'x': 10, 'y': 20} diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index e2ae539d957e6d1..f712dfea13f2c91 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -661,7 +661,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn and should not be set on instances of that class. Usage:: class Starship: - stats: ClassVar[Dict[str, int]] = {} # class variable + stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable :data:`ClassVar` accepts only types and cannot be further subscribed. @@ -774,10 +774,10 @@ These can be used as types in annotations using ``[]``, each having a unique syn * ``Annotated`` can be used with nested and generic aliases:: T = TypeVar('T') - Vec = Annotated[List[Tuple[T, T]], MaxLen(10)] + Vec = Annotated[list[tuple[T, T]], MaxLen(10)] V = Vec[int] - V == Annotated[List[Tuple[int, int]], MaxLen(10)] + V == Annotated[list[tuple[int, int]], MaxLen(10)] .. versionadded:: 3.9 @@ -1540,7 +1540,7 @@ Functions and decorators def process(response: None) -> None: ... @overload - def process(response: int) -> Tuple[int, str]: + def process(response: int) -> tuple[int, str]: ... @overload def process(response: bytes) -> str: @@ -1679,8 +1679,8 @@ Introspection helpers .. class:: ForwardRef A class used for internal typing representation of string forward references. - For example, ``List["SomeClass"]`` is implicitly transformed into - ``List[ForwardRef("SomeClass")]``. This class should not be instantiated by + For example, ``list["SomeClass"]`` is implicitly transformed into + ``list[ForwardRef("SomeClass")]``. This class should not be instantiated by a user, but may be used by introspection tools. Constant From a2889371128f4727e2317bdb744b2689a814e832 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 4 Oct 2020 03:46:44 +0300 Subject: [PATCH 405/486] bpo-41887: omit leading spaces/tabs on ast.literal_eval (#22469) Also document that eval() does this (the same way). --- Doc/library/ast.rst | 5 ++++- Doc/library/functions.rst | 3 +++ Lib/ast.py | 2 +- Lib/test/test_ast.py | 6 ++++++ .../next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst | 2 ++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 755c60fba64115a..62138efcce9110c 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1586,6 +1586,9 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.9 Now supports creating empty sets with ``'set()'``. + .. versionchanged:: 3.10 + For string inputs, leading spaces and tabs are now stripped. + .. function:: get_docstring(node, clean=True) @@ -1820,4 +1823,4 @@ to stdout. Otherwise, the content is read from stdin. `Parso `_ is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python versions). Parso is also able to list multiple syntax errors - in your python file. \ No newline at end of file + in your python file. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index c49bb0c9de70cac..263c52a63dea848 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -506,6 +506,9 @@ are always available. They are listed here in alphabetical order. returns the current global and local dictionary, respectively, which may be useful to pass around for use by :func:`eval` or :func:`exec`. + If the given source is a string, then leading and trailing spaces and tabs + are stripped. + See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. diff --git a/Lib/ast.py b/Lib/ast.py index d860917f4d03ae3..d8bd3373701dec6 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -59,7 +59,7 @@ def literal_eval(node_or_string): sets, booleans, and None. """ if isinstance(node_or_string, str): - node_or_string = parse(node_or_string, mode='eval') + node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval') if isinstance(node_or_string, Expression): node_or_string = node_or_string.body def _raise_malformed_node(node): diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 5f57ce8724482af..be4b0f78ce9053e 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1005,6 +1005,12 @@ def test_literal_eval_malformed_dict_nodes(self): malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)]) self.assertRaises(ValueError, ast.literal_eval, malformed) + def test_literal_eval_trailing_ws(self): + self.assertEqual(ast.literal_eval(" -1"), -1) + self.assertEqual(ast.literal_eval("\t\t-1"), -1) + self.assertEqual(ast.literal_eval(" \t -1"), -1) + self.assertRaises(IndentationError, ast.literal_eval, "\n -1") + def test_bad_integer(self): # issue13436: Bad error message with invalid numeric values body = [ast.ImportFrom(module='time', diff --git a/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst new file mode 100644 index 000000000000000..2a43ab3f2890c78 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst @@ -0,0 +1,2 @@ +Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document +stripping of spaces and tabs for :func:`eval`. From 3a37597088faad848707fae270f50a28586d4439 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 4 Oct 2020 14:16:04 +0100 Subject: [PATCH 406/486] bpo-41898: add caveat on root logger seeing all messages in assertLogs doc (GH-22526) --- Doc/library/unittest.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index a52df9ee01578ce..f04ec91270eebe2 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1091,7 +1091,8 @@ Test cases If given, *logger* should be a :class:`logging.Logger` object or a :class:`str` giving the name of a logger. The default is the root - logger, which will catch all messages. + logger, which will catch all messages that were not blocked by a + non-propagating descendent logger. If given, *level* should be either a numeric logging level or its string equivalent (for example either ``"ERROR"`` or From 1acf96b5ca0865df13d78f099e79b5bbf8c8b4ab Mon Sep 17 00:00:00 2001 From: Hansraj Das Date: Sun, 4 Oct 2020 21:39:26 +0530 Subject: [PATCH 407/486] Delete extra 'the' from `Formatter` class docstring (GH-22530) --- Lib/logging/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index d8a88db378436b8..787cb4eefa10613 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -523,7 +523,7 @@ class Formatter(object): responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the - the style-dependent default value, "%(message)s", "{message}", or + style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of From fad58924eca0841e55da0f688baa3ef57ebd9411 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 4 Oct 2020 17:45:31 +0100 Subject: [PATCH 408/486] bpo-41490: Bump vendored pip to version 20.2.3 (#22527) --- Lib/ensurepip/__init__.py | 31 ++++++++---------- ...ny.whl => pip-20.2.3-py2.py3-none-any.whl} | Bin 1490666 -> 1503696 bytes 2 files changed, 14 insertions(+), 17 deletions(-) rename Lib/ensurepip/_bundled/{pip-20.1.1-py2.py3-none-any.whl => pip-20.2.3-py2.py3-none-any.whl} (54%) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 21320a83198cab3..cb2882e3360fcf2 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -3,6 +3,7 @@ import sys import runpy import tempfile +import subprocess from importlib import resources from . import _bundled @@ -14,7 +15,7 @@ _SETUPTOOLS_VERSION = "47.1.0" -_PIP_VERSION = "20.1.1" +_PIP_VERSION = "20.2.3" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), @@ -23,22 +24,18 @@ def _run_pip(args, additional_paths=None): - # Add our bundled software to the sys.path so we can import it - if additional_paths is not None: - sys.path = additional_paths + sys.path - - # Invoke pip as if it's the main module, and catch the exit. - backup_argv = sys.argv[:] - sys.argv[1:] = args - try: - # run_module() alters sys.modules and sys.argv, but restores them at exit - runpy.run_module("pip", run_name="__main__", alter_sys=True) - except SystemExit as exc: - return exc.code - finally: - sys.argv[:] = backup_argv - - raise SystemError("pip did not exit, this should never happen") + # Run the bootstraping in a subprocess to avoid leaking any state that happens + # after pip has executed. Particulary, this avoids the case when pip holds onto + # the files in *additional_paths*, preventing us to remove them at the end of the + # invocation. + code = f""" +import runpy +import sys +sys.path = {additional_paths or []} + sys.path +sys.argv[1:] = {args} +runpy.run_module("pip", run_name="__main__", alter_sys=True) +""" + return subprocess.run([sys.executable, "-c", code], check=True).returncode def version(): diff --git a/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-20.2.3-py2.py3-none-any.whl similarity index 54% rename from Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-20.2.3-py2.py3-none-any.whl index ea1d0f7c8604a4cad61409c8ec927d5cac5e5c0e..7ebdc0f31d4e3ec28cab71df496213e7be7711bf 100644 GIT binary patch delta 715671 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

    XMADPR^h_0VHu=>d2Ev<- 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

    _=dlknIqQ3JrW3=C2bZBVm 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 z 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

    1vwy=r?%T={uu=oImx7&T3`l%}He*n7 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൤ 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 z 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

    k2$^d0J3 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

    U&%D-pr-3_ zD0LFh$vEo(9v_Yb1)FBIryLk#xE;hA(!$G{E`B`i+&N2cGv>2qm#GYAJR1yN-Ix*Z zy$@mU)ec3#w%vbP=^j{dv{tm`HedZv>I|Db?_Xas{`yd>({!>S+5ng1=*uTAkvtOj z&7iJ*x2wz`*UoMCbG(kSme26G(o!lJI)D40Jo2uE#@yB~WjM?oMNTFA7#o=ht~5GX z$0CwSuFm_eDC4S1_hib(;oqy2&Yl)0&0<59W%Kz)Fh0#bN9d2Xv>j#JnJLS2U z&w}=u!p@Oq(;nikx&6%AN^eo9dhv2fr6DQxd}q>p<<&NgHBq{LuV}x3S6~^7_2)Xs z93!p&&^YWZq!Yc+SK(SX@&pjx>H-qW2NYy;2M()`_24Xb#L{EQg=tV1lD7539V6Y`|a1=+hO@1jxrZ;%}Z zS(bjzkSjlF`heE?;n+}LDfyRVeAf|_#)qAa_C|!5RqpU{VoNLy^Uhi~;1>|NHr8o8>{p;)7O|nH5Ot`#AgD z4yq&9-_pd~{U=Cg!_C!{a!^!`kDSs&dfgCNtJl%Czpyt~H{z5kn;=*h3%>c>IW z)`}C;Dq+ZSV#TVDo_^QE{_?{W_4^wZnOE%9G*T*Dq(Q+xF&>iQzwM%-pltTYpDL(% z0;CSX?mwo8Q3PI0epDwVoIV@6g)Ob>%xl@M^4bok;uZLr)G?PF5JkT-&IbR9o!KFI zO{qEGoSp;AZTDcCyw9uH(;Y8=v3D` zAJTVfhP%R$FQu8J`a5vNzpw+_s#*Sc)N z)xEr9-=VmEV2Rj511UId8ICZ>!;V@%vL8^C>gb zXhzcg_YxdpBU-3*F3W$ccga#mexoCYQAMR;DFlWYWG%jm2`e}ytoGmcXQB?RMPZsz z<#VicOZQ-Mlt!J#2`gE}tiANNaB`xBy;ZvpYCg`oAit~lUzS;w_UaNM&5PxP5`?A? z-d}QpsIte9UmVEt64??1>1ge0KHVP%hoN>UpA!&d25D8etiOIaX{?5WFtiZ!$p>IZ z{{GSh*kKP{7XUldEq@Sv7Rpy&JJx-er*IL;Hg_IUy3dL3(@ci%Rb~Q1ra952TUR?T zkD}gOv6o#g4S?Z?bQs1&Je#Rz4T|?F$9E~dg300iauT3D*6A)oPx5Vs{+TY?YBT(& z!B(Ywf7ZSpBGu?WJp69}&c9?Npn;}MgyOSi^nw2DN@$LywwS&!W)g>VvgqV}Mylk` zqt)Q3OvQ{;cEI)h|&7P_$rhI3s)Mhdnr#XUk!8;5-Ag!x)@QF{t@_%s=HX0UbpD zfy*KA=I@9sLEz&=V{=P&+|fIQmdhD<_5)XS%8i@~Txx*+M$94rmzQk+Oe=^N{G1T` zw@>KYnFS5{FTgCr$|bffTN}1=1e4xz(vNBKI!<>#4x6!s{C29o5DoO%H;@}MjAmEq zwNI6m=L=R*=~?1_uZrR|5-S~~^4BLa`+9~Vu&5f4XrS4ABj`BUzEZ3^O{oYc%1b`d zX4{9)F~aBk?d3WT77GsA)GJH8;2DG70qxFNv|OA8BGnEa&QD27lulf8$V5)yf_v~| zZJC|UVa8kNlfQjiNB4X|cZ<4e$|Xt08Odeo-mg3JM|bPZ*C1h=!@HbTrwk}9vrO3W z6(Y~Lw`%8>(<*DIraVJwV>K_-g0~?6kS6yJ0847=pQn?E`kP42Rf+Ym#oc$-(&?JlN2te|Ijd~c}?8q9V|Zz6zT zQ`j<15Nzp{EdB-mV(#Ro zQxAFUKREWEy4pW=9gJlT?>-ht?$x+Zrfx{3l~AT;NaY)$!5_36x*y5MSn|8%2{lbV zfWR1!-1M9eC@7%F$xWx|x;UY9e6OS3KZv5;cQC>~7s!jaN(Xu0s=%lUq>J}I9pny6 zU2T!ZKWlU;1i>+jY6QtakZwRW-XI8KHgp4ur`=VFm8`-8nvDnmF{v@o2!;(Y2Ow5P zJ_jPof=*!a!tuSgUb2=+253_T2-w+&Y41BkgWZ>dk^xFPDB++KgOUPDGbnMORD+@q zf_Lip=M2GP>>s)s{tlIJ9d+~Wt6W#Vy@Dq1*gkYoU7D=Vc!<%Lv}Lf)aB_Z7Zj2r- z(K=e^Ez@aldHer@ma!7}*)sXkTRB?GX?NawW?pAVM3LXTBec3>6*4W0su)feQh7GX zvNTU?7GRk~`!c#|r-PPal^G3J7eWsgicLdXe{KF0vqE~=+Cc|@>~C_EJ`IH~W3e3! z-Or9vusih8moThedx8auMrq;A>zY5DhcF>`O?;fjq`iAYy?IS~Xvk*8fq$}2Sb8yH zt_O&uSkSoGdLu16$pQP>m*{)^$*CXV_x{B$cvOvE*5d)p@3Nz++EK59piBxGZJOPK z-3Z#l6$vL}sw)Esgg8CQKnS#P=rym}^srJnn8_D7vg8+*@vxJvv7VS$4Z+%BX;?Lvo z*LwJZILjq4!t(DVv!z<`ymKGe*^vFbUE667QG7Jm1c|$#@#pDly%?)>SHJZ4#Jhi$ z(a!hHpb_>^QBBK-yuZ3hP3K~_G@1WEL|%HH7QC2T>*{aa-+`JeO*Iu2GqYcx;>p%a zJE(LdTqEj#d;{*@OWr--*BT4*x&g;^0Z()*xdscyF{KI})^w5IEjS$adRE9Rrq=NL zTPv~&*PXjTpGV*tdvcZNgNx(N(_@&?6C|E?aUqAdH)%vsLCQ9BWvKf)rMgdKced5j zg|Jv}w|^1Iai`hLyrn6ZXqRS)`?TXmK5ZxM2{|o2m9q^xXm}u%3>|+9q5U1HH$yAj@RVAkjk^H5 zNht-A<+z7b$d}Q`0d_#ntA~E^YW+Rv2f}f<@R+mw)nSp6d&@MHn&|I2U+VoO37ibw z*ye1Z-&h>MXNIS0#Nh@`rU~qa(P@aZD`YV`F$EZ06Cx|`6gTvMow~_|Bif2n_WAQs zzh3F5ZO?UQ2d|-{ekNSjpodR$8%YA8$<}7v|aex?0E?-LFOY0JZs%i3ON->8uP^1o~IguW2+yAdMvwq{7)K*JnR5 zl0?BVo!A)yH=dmrCZG-3nxvpXUTTI6NQG|J?9q~YLXSi!Ha($rzlIMx#@~w&grspp z5?F-#$^r|=i3BvDn=xZvj1_3BA_ZDhDCmZ)OrmRtXr5V|yg42-{BeMhP(S?0_qV!- z(3m5n=YRZ`Gg2fQ*i&jc(t)#VD~`nI)_g??kRkbcqF#*f4S7=yyBvJJ^lvXt!ywzB zo#`2Au-A5Z2#>i@oMkq39J{phGude?e4A6YvB`Gup2H}KF33TG!{TrsX<2)fCwzSS zJ~WFJ`z4!ry*$VL+01bq2e;4prwd*U2glsX`J5QZS>v$|&-&Uy@KnTiZ{!^A&v^JoQz2- zjN#!O+Vb!jk}C{x_eam>=!2JLeAMt8MGKpw|pHrKVz0o~Th4$)UCHBh_Qt%fh7 zdq6~E>0wz(+fa>h`sIhv=JXHDJpUu^!7)m9?Set;ixXW-n=u$9r_swv^xV>>URMqa zvn(X-(!fg^-=IHRAZmgZN0n7NTKML7b3ezC?>4x@$VR{SU77Ny(~%S9X_L+RhELBg z@51D`UG<6y7f5rh$oNA4G|^T+Dd^o+H`d)e4;G#4#dH%8Z4viZYDTYTm44##qkgW{gE|~%c7@VK_GVyLT9##9t-kX3FV)sG zh?f?(S{cPXK+4_ysV3fA8~CV~`4IIj*l`Lq^7%|f8}u9jwZnb^L#hdJq_nbyhXx(>~biT0^MsC2p}mi z4MmwzI8Qf+kOaYL_{V~3GmLi;Czz2a!SiL76}v79=z6ZoJgnC9*lW%&-ny$IN; zrOv(SVs!V0A}!x}Xve=yH_THLOjMl>290sb@tt%WL(_Tq*>Z}EQj~hZQXvwUI8tdM zSDTl&4I}s&@q1s2TC?m2fa%hoSj3KMhAgM3V3>)jZX$HTa=^{JD4y}B8UrW#jBOnI z-9WUdZ0?|-uD2@vmQxYW=khJ$SXEo=@H= z9U;Xl)v1w#Dw~Enns=62g4T(Q=k4_G3OuvZ3Z#w}@9 z=jh_8Y|V`@%Sj=&X&Fi0y$m7)xA^B*8{cO{xTOX6;=(_>F9*6$K8Z_DW&EY|P#a7M zG?wpsv@lFsh21-aK$bWLukW!OgOv1mXGK9+aaslewVNK^M20gL{CWH7kkRzhKC(Al@(@#C z5*GeA7Y>McU7Np4%;7R!Fgo|Le8l()pG-KtB8w&v=Snx9Wb(h7HpQ?r%E3e|9KTW9iuDpMJ)twT=d zvXhdAHF_}=@UyCw;^#Eig`qVrV@XtQM(~B}?smMD$6w}>&4^BlqrDQViBX>6MXfJM zQbJ7Z!}=ao%m+1O-No$1YS?VdIDPX4ZX0*rhL$y^zyqWaZxd+NYVco`+$ccI;Xj9(D>3%_* z-J-v?G_5FWs+(EZJ|6FrSh%WsxMZO}!p|w=KqFwFNep z+{b09e>y`(Zm7<@hF(7#fSY93b)(&8HJxApaw!Gb9Qw1Q`H+B*wEHuj30dc)y-Tx! zh%L(uu@1T@_`1W*R#Het_;_lre+6~oUbWkG+O0!|Kyvlz3&EMzi9dP_b{Lxjr zP*3 z21>I`ujaXqhXX!den%%WUq(&@puv$7l-re~DV)0C`zD`stRMe?{X2Ba(xhBpC zw;vx{hcbNgeLzyY@fuACnOWRr&ds9inr^xKtGFoYvZWdJtNK5=sFX8Y3h!sW$R~Y; ziIg6iUwv0Ve*AvapnkV~=_C5d~LVNKm>@~VX+U%qPpLcGn)su0M3lGPlNt)_0=I6x)Egbtt8H=8-3;e%l52yHYK=&c2Zbku#{2nm!5u9P2};I) zku>S1*?=V1?u>&GzZrxxtWDqydo$=BDcaSASe^tq!m1hEd4lLbe{GrRf&Xn74%(GG zCnf3b!HJncJo$(hLZkNY!xI)`m$?VQWlIMgD>pBLM_yxE+%IA~;U+dUA%PcAT3Dba zkXu+_A_z{x!8T81iMf3cHxxY>^MNPkzme8^sq&ixeTqFTKe-tRT7Pm|6Fj}V#}~<3 zv=-YROMYt3m_U9?d!)_df$JK}0N#bed+JXK3b^8w@w}i55Kq-#f|HC`rC!&_u6R@` z3bj@>#?yqgs<$b+J$YVng!*ugcGRD{wkbn0svI)k7Ehf&z36&BvV0k$Z}bxsnxpX= zrheC`I=>Y;t4f6I6kQE1E)AHyw-nYXl1DaNx$B8aFwXZw( zTSojjc-@{f2s@pqd>Qd4bqH&XBgOVJ8A~@i20vhb+tA|ku1wNTQ@$o+Z`WD;OrBdG zLo#fl7AGp8c47_1&m?$cnJG55wOY>l*n&+*C5`Wcw=stm(DrG3|CBGP$ZBVVIeRY9 zaFs5$%nVrcrD}HAzL;(l+Z+(o>?Xw?x-oB@1EhN`i> zDO^+;kW5m!C8|`-hND1I=zntm$w=`1-k=($q_FglVI0e$4qC^cWp0nYr=(y*5bxfgCLLSw!2{Wqp3;#(NMZ78Y`7ae z<&n4WKlaq1zTF72uRL}wZOoxgIm1A7rcGE^&wRZqd4*J;sUP}yS{bM8Hbt6jdPI(= zqRShnFpt>zab-OxFC9D}h$O91cVdPq(H=D@!je5=KF|9J?3<_ii)ojke&Ez*&*bO7 zFo*O+1RQt|M85VeFGalHKQVXOk+I(#c{vffpEdgKQxf#*Qdzb6%CThFlzt&z?el&~ zUR9t!ucgOV50#M_Blq(%7Rt^fOKr!{P9e=Qlm6vlqB*Tp|JL=KWvw!kX~La_l?+w^ z=Oh*Zb?d56!^*s@YPyNqwazn>duYk>%I8^WFZR5ytegtF?G+4`7=qWk6i?|dqUk|T z$8}2c;0}uBE!>V4DQG(4W8?j1uci_tZgXg;H2*okd5PS;NQ|m0O0c781h1y3fWr;B zVkqtAu{)CamBj=L5k`D?0;8X^VQFhhB8PHm28R z`osL|iUcd3WZG{Itd{R#`*GRuUim#u`MRf=NO1>!q459h6^7CNEnT6EPEp0Im(zDh zzici@-i_T#bWEa^{?ofpbSJ)q`e`;~7d&y}{6FkjJ{)A*|CrIrQnsm3Wh9;yoEkaP z-u^-$>(#(8I(=8AuV=VbuQOx2$~v_s&~V!CcgoZS%Y&_U5cNq_xq5(gIwjj`>{hn3 zw@$^-MZw7tcg?r1X1Y8Yuj*K%!xJ*TmnDX1>29qbL)&lLM(Au_*3W52e6yVqQEj4A zcwN8l?@6FBhQ4DSezWyri#8%4!*-Z-hoaPI14hO$CNR6;{GtBodX|?S?DBGHr+Mo# zM$YK1@2q5sKU0X++U;Up;ggI|a`lxXlZzjJA!26%=g)tfOsf67LtXuT`@l8@d02@p zvj0-cX{OFz%wYyKJ=u*^mD^1IL8zJf;o)HG+c`G9xh^Nyq$iC+sS!F2fAw zAkHSc=_PoXkJypc=)sE=`>w}tUX-QJokCSJ9mejJ+o>zpBuL!#ml7=K+Ma*wgSg?B z)r29emqM69x_9M4xk+GQsO?rbre*81&N<)9cLP!KC1rnqab0!f*8a_H0I1W4)lfqx%f6c5zq( z%RLn_GHd#jg)cQRXe$+xUQy-aA&Ym3R)r+kGGyLXgzRzAQ2fr(4O)Bp0lC{v7lTBU zxrh8Mb0C)GtV7R&uZ42zv6eKG9>yvp+4O-$P~h7PR9UR8s6z zZaGr{pNW>njNMG)rY{PaN__v#YkKWF;Uf<(OM*xO(jx~yc2aBsj=J}D&Wpd4(-w<3 zD%|~22&3ItEwMB&gm+pGG2lBnEa+jk<3z}x|8Nl^Z`?g045>N=rwjECoNNeZwELzo z(R4XS3(xoS2^+fStppo-=LQ%6G2T`ag^2tDS3u~r88e9M)C-B5Enh*ZL^~nqo8)KA zAnZyO^f9-5>glnzAZ|ftW^|9HQflv14wO8`W+L#;LP@ZQ5Yhw-2u+BPNp8b2rBANb z2$B6G9>NEDZvUKs<%P*?;Qi;nYr%@bVqhRzUtlo^PJsW7G+?+8jIxxi^xq0<%VnEAuxlXd=wg)QB+;`&J!g zWl>|Y5}N^R>SW1%k=q2~3k)A9{XaIo&8S)@vy%HOWZ?Jkpw!EO8vF(dRx1Oi+XdqP zTV?ZO`N+ouf6F22hPc0#2%-*}c1yROnk>xvt;;FE&|EOG4G$Z2Y?j6R+sjT`)G=LF z%ygd#p}dm&{AK7;E33Crc+*E>CFp@;V2&Mc_fV`1!Gc`M-9x_aP+RSsKOC|dS0m0e z6AMf-aRe%FpPYesUP<*On0+h11oLj?ml3oOps5Hp1VIXD_YWFCsQ{B^vS41XDB`Lu z7yW9#vj9Qz0hwWq+8qowe#%=a`)X6_#1E0*=ZKSf@hi6)ku+aCN;Dk#WOt#{D*DJF zhPJ61F_S0mxUH{zlY8RAM>1Y}od-hTg1A?LyTN&rT`^Ep?qpXpQ7wj(c0Xf_Hh#u8 zD!G?Ib=Uz5){kC;b&OY4v}HPuFfc6_wp66t_`RuA%dy3=Oo!YFyqk+}7C@@aAf0f^ zasS{wcnejAU&hts_G(dAgKF~vvKNc_qxTz9L(>Y6@q9CmP4bvgCv_ti1gC;osh>Bd zfdvFQ&}TT{>(Z!n?wf^;x_5itPc`OSsUEohy=O1rXq%_j+V@9hK9(Xjd(rfBT>G8q zn)S2XeT;W@Mdy~=1T>%bqy&aj>3{|6NC}sKFX_1eI8~GN&xhV#P0mK#+j0MEk62b< z@b&GL7F#-)x0K`CSIJ@+2}(QGdlbpS4NcwJ)AIbaYJ=W^3joyvVuJ0k?McYVV*=I% zScQK9>j&(=aBBl0i$27+7;SpcEOzMZ&6Rp;F0WYb#rU`yORczydPa42;ZoY3=3|;<|pi&WZ+o;Qj{0*vX#9}jrDigVC6egXgbIt!8R5!-bWdC)j zOx3^gU3*K2*}UW(iBf&pY(E~@|M6DJaYX;v7t$c-(`{dUGClD2Q`IF}Gc)GQpF7WU zqnhdSI~)PWP^b|{Q(ZkSi~6)?WZUye^1=%R*o$Q`v6b`Pity&fn-9c&YTHaCbZQqO z&!+aw7XGfyrMQ2NDVRIHW$Vy+;+Jrb7wO|VM?A(iioXw>msT8`k2o(6oBRr2OtVKN zD!Xas%SNR$*k{|H5<3?zmUZx_eVOKjf~0CWmRn4gz0{x?>6Qdj>aOcgubinrKCw8e z!lv6Y+SG&>7~!+bEnYDs6sdISlN-f$_btM&^D(tr*|n-_XjFy<*Ek#p6Ir#6hjpTc zW)fVj6<$n+jwY+9j9nZXY@QS~-nQF40v>h-X^%1sn{Ml-wfM;wTdeS@EPV=$Hht23wK!KofjF)(?rA(v04dXoz^6sMLj@WTP z3ij@z0gNGnp#zK`U;?NCbBSy&N&;OHMEo>bR-hhmbCC#qJpSnc0>wpuqOt(|$&CQ% zXi@=6g5K}VNyUJ-(dzwH^6k#L3ldLuG!p{MrbmEL2+$765fXTN2K6aI5*5EK)K?nu zo0cZ!kZMd@yk>ElrBp%#k zC%g!s8uxbyndqO4kB~DEG7KSiarOt5X5ZZDTwc52xsnYHNDbOClcUiT=e?u|$qcLe z{{^A{i>gQj6SkEHo;umkK6N(#`xz-wJLd8u9eaI+wxYr5uX07PoLh3Qyf~uYpI)4Z zI2ZeJ+AvU){vKQ#9c?aebLdliYEvB28V72hMuA%e^&;TY$0ie=Z_P}eRj?)_;#L#O zJuS8R`a z=W1o{W59UfGdzNmXH@`KcDs=A;;3_HQAp<68XWk*KLkA8wW#x!pbAQq-S5_{bsPQF zMK<4U$dGUi{?g*ej*ZwHThZ0aM}BohDdIw~f~@kqEjOYU%DS9doQd5@JR)rl8;Vaq zNFN#1ca#|zIuY*S$|ra(+-guIMQ<(*E?kgr2};O=oA?V?&7o2B%}PW8cNy&#?Vo2j zIYOyLgU*jVB%(uz)l;%_7Uor`aXiSc(fjk9EF=PjryVJ%@rpUg(J=Z;hX-hoT=qrl zTv8=7+g?)8An=FC>(f>n%z?rl3&Qf$YH-2WM-kd7F^~Si^#5Qv1l&7=l`Xgun4&O^ zPkmn{#daE>4pr}k_mw+ZO2RZgGgS5HasMf2pp@tdK48QF^8^ntG=S-2m=@MR6Qn|D zU;sIXz*eEy#qvF+g0)Zkj$zo={@{LIYz5W+;9+It2$HAC4CZiSf@XUR_@vV>FRx1u zt=7ScrpEeE`gIfrd^#%|46ESs4f;DK5O7onyup^?(V_|l^E;{!`N$8e7Fr7B;+=aARRbJtc5IsVCVREG8W*j+ zIJCy>QNe=c|>77Lt)=$)$7=|5FM%x^HkieTJR(lp?mH=cj$)Ic@z|uP-SX+ zaqd1x3ty~hI(JLBZcTU*?>YB!Zrz@IErL4bH+uE!5H#`0fK{BW6#;UgCq6h5b)x5< z%9HSVNGMKJA$vZ6S^eemujv7yX6*?2<{&KseByU-o;dIV!`CiWT!9!t*XYmjm(?ND zuy6N~!qKVdCuqDQB*DrvBsb(ZJbmgGNz=%0nn-NOarna0KZFAAVv^qV{Mb zH=$?a^l0LZ^C6@DG@=I`$$ZtxJGH{%s~3D#4(c^j*2YYUa%%bi+&d7 zrH`T0j;wv^0NxNys^tzQ)jHK;gt1{O4}>eO8qB5~Rjb9)rrdg`qk zjp3v@8>_ z^RM%(V^0A;bH(hrghCyQnTUeOO-=GI%}tHx4vrG`B-DB zEA}_oo_)H6{SV6C0w}IvTNlRNB@FKF!QI{6HMj@&39bQxySqyQ2|hq@32wm&ZVB%H z&N=7achCLrdsVk;s{32t`c_YOt*+fuy}PF0{TbHtuKH=h)p?7JIhN@3x-ZAO0bEcd zAnSd&Be#B0-C^T~$02cn5W*O027e4TFQ({WZ@PR$ z1NTVskyH7`iAQZZ!-#~|!0jQ`W9w7+M)l%AynuOdjswgCGGHE@77&;Ozj z0BuB>m)1Bba;05hLvOTs)3)s)Muv-rOy-PF5r=Coo(jg#XJVcGw@rYG&%~T->Qa$Eo?nLI%*rayiyzgX%nv5 zdqGJ2H}8Yhv)5Ja!tXEy&d~g=+hA1BSFut_h1ws~OsRt?BIS|>wLfr~xa0Bt6(i!^ zOz6Fblz=B4(-EBB>mo)^Yh5Tx@0Wg8DtHGE#8s!SbFX72R1qsn;Jixb_Z==^dN!+{ z<$_IY#-#6aj^-v;kA@w^y;cm1@K92`NQ( zf>q_!TFkI!5(i)9<;C#8BKi!OXCsLOCr@9=tHBCwr$dKex>EAe*NCLx@E1KvfB)Cm zr2NGVtQp*g4WvT@@ROsY|IrJb^yWnN2F^^>g-`eu<&y|y5Ynr-Jb9nkUupySQ0k6e z^5O0YkuoUoB_&Bz6lhbEJCeXQdhlWaZ5m{nMM>2E_*VLzuR)|8n(OEjE@jL%LnpNq zNd$pabjgJ`+Iu|HkCX|00h|LGzKoIlDEsT!a$B21+hB&=Ksl0#lJn>iw;R&;co;p@ z34Mn?0~-7<34m$?P(cZAGvs~%MAR362!RX`K>!h>FCaol1Vo#Fh~lp(91!*Yi79c@ z6@8DFFiM}$r*IF57z+4NlA+(@UBPTKM8gkgBtb`)6hdRkNkCB~fcuUBuM&8hq4qJR zr11cVi3NzUAb_|Ah#vsK^j8rG5a$5#6(C0Q0fj$69LAJPBBiYHG%O*<`C8J~ZpP#_ z2GV=?t>i5sqxt~E3P4x^#8KE1@)!m{@I~h}4pVsd0oM&7k0D#qgKH_H^W0>~ns5__ zslEG<{RUL|DH4~E_jj;`wtPDqP6iZ8Gd8f6?tjZ;gC?h_VfugjNt^SFBqE_j?Q77Z z+U{e2+&U00=FH8N00{mv6aaX|1{iVx>|0q<{2K0RFN*1Eq+TbQD`w{7FNm z+%MYvj#X|88TRYgR2lB;*ti+_>)7NOrR&&O+KOAAuw`!TA)5Sa;*7a2g?Orb>L?Y& z3=y--VFK-rimQOzxjkftcTL9tEArm^Yxmno&09%=%n_CHNnvAv9NhWVK?#V?*!nye<(+DaKr z|D%}&c*_AV^6aG?_n_`_>X{qPE8_GUxopV3-#!d zZ<(y6)$kszeAU&G)IrZ9rnbvyPD@B=*4kWcqli#EY zPgRd8Vm9r+n6h}2=FOEom_MHNV+!lFsVbS%kdByWL)#UdFEie6VH0PVZDA9^^JxNe zAme2H-yoPz7hstqWPTHs{rd1Qyxr}Z_QRQ=5wjJ~T%~8Xx zAr@^{4AIsEg9{&t+d3{o2$qfmgg|%Y}CZmv%!_*3@US&sdPt(pC|KWJCgis~@c{HF>2Z}z{N%7CfGR5O)2 zdc*|;|F6sKrW$glw0TUR6H$uR*HS=R|8nF1kN%9O9c+q>*BxvY zFm@VGrs9#Sw5OP^WbLhD^tCB+(>gQdLICZ6e?z$bc^cMn*NVeYm!?6N9#hRN(E2w` zgP?kC-2&#c`ThT`83Du=Y3rIXq|Flmu@Rc!|7QQc%rYRj3J3;9ngIm=ugo+cwhV}6 zOqx@_W@FBvDb?%0$Qzdgud1V4$ozc|_tA@=^cA zZ+M9y645`f*CBUzOyRxk4|myxqIl#RSaU<$J4T@o=7E87>f|32&ykNxe*cD*2iS52QU#-aob!=N@fnE9X*SA1gDAe>^`b~ zmZdi=!L6GXc~{a>Ic+d^z~bQfhDR`tC{LztvRHShX5Ij954R2Bt6Hvkoob^ly?zaD z?L6|r5uBq}=$B0Mz@es6_B(ZDGmc_lFw)pTV2{S)=xza!iu49aE?u#!XcF`o#F6S@ z&zu)K$ipoM@GbrIJpn$9NZe^Y#G#mjoUmWgR}&DAzcN8=Igg9<=n{cUrGaUZpS0U{ z7&kcYxe>uJ{Mlg;X_5(u#kK^6npImy*vJ4HR7Olc8gGhUqhhOTaY^zp3wRVaOU93? zg+a~pO_^YvW}ZydWU;obMs*9ryg}*_i=x+mp@*0OZq!}|V;z@XpGc|Ee6YGlT5~^Z z5~93sUhcs$E0B3eGR}c`pJ4iyB%aBJpI>L(t+6_DYf}fvM=g*Kqwi=_p30C009t%U zLmY}#Bg9C@=OPhiw&Bmz1(H_>B+m#Cw*iXx-?YQ?rV#|b3x$h+K zDX{`5Y-xn_xo3osN=t+fTHh@YYGTRJI+ArnVZsQF8&LW z;l`gKvEk1WI5Cy8-)RF`s0Om24NR$O%ZE_C?^hFEy}fk+H2Ho7-xGU?8VP7gn9JGq zb(PI7fWu4XhMYmDRd%~T7v&&%KyO5V-hhGLAmDr8kudEs=xdK_TvUR`Dbx>KFrAoe zpzgFu_9U6w1^9K!gS@mA^JK~=Y7GiXdq?x^n(*&m# z^X$r0KWow(R^iso0d$hC;53uSB~)0PN8^lu{vk=NCx)&dB6D6?+9U+UBk5dUA+iKj z7EO*I9+bca;v_NQ09*36n{%rcqRL*89)2hSDj9e#j!3{3{6KjCe9d~T1{F!usRc?gVh)_O3e>5Opthzg-_UdDn< zNrsPH$@MMyapi}^>wcclld5n5eGOR22Rb!LxcJIca8fsfOY-4{47i20jk?s;NlkuZ zL4Yzyiy-`p)dWYgk{8M`cC|3snFIKwJFAcJ+F22Qu14=oF6M=ji(P?2V|0MMD5*s6 zO#lc!fEZ^0h+=?<1qk~8F*X$NApVVIZ~((z6ad;_fVqtUg6V5pwN9Z~Uf|Jh zldh@2OCKJH~04?VCR>&fY>E=Wv~rS z%QN_SK?MdEP7m0t>XZSts+@tXs(PFQEMw{))WFUJ39vJP3hYeiQ~4(LqCg(u60icr zH$f0k6x;%mC{?4x1!o9rsG1}P^7efyu*X20A-Rmr3q~IBU0+wC7zEA|VJUOwx834K z|LzR>AbtsbS5A`ssf_VdPo%@KHHs&W+uYo_p6)_NtU|beoyxb8DrBDZ!9oXxgU;wEh z9d+cYnRPJb_WgP|=3i@gObTvS;)_gLr$&-|NTNVGd>8tV6zngdPCld7fOI7FaELB} zrCBdaKJ&V5c1`)*Knw?zpZ-vOxnC<4Jk$i|c~;${$@yZ+F}sLvhhqjLHBoO-dIprk?$ABXQ=enwNA4s7_GZ;D?JMu`46-)~PQY36 zs<M|!~tste@hkHhJA9=mX%}C+2FXYj&dQThLKaAZ(Vdg^+IFD9>R+xZDvU4_4Wz- z?JeV8wpqt4!_)>zKzS`pwFn+bI`)%xflsAd#Et$*QoY6iTQzNs2nqd}@{rP0!xh=hYKH%OnYpS5b9XVToGZ?D0GR5k{=Zn< zU2@s$)GFtn%5UXo14<7?X0FKW{S*IM;F;i+qaTZzV>#?bWW@iwP@@>VAr zYzt%3tbZ$|Ed(Njt|pD2AgS+o!>A|s_oZ8%-R|3>z@X6RX6b9)ktLBT5+> zdXFTb)EP6k)i5}MMCx8|m`gh_!aZ`dK^>xgjn72*c2EP@#}ZrFjcflL5GNw`jBF7U zcXp3B_&~RI$u;=EyLRa@_#nG>i8}b8yLOove?8H@UjRB@^_pTQJSO&@660EEJIM!I z)Vi*SypAqa4uONeFMS>Awx~U80>7(0Y%=3oxLI;VQlbp*u}0gz6&j=n?y&^`A^^Zo zvGBOE&m%c!`&irHeIu#p*8x!Yofs$#>y`c;);7?%&qz+d)N`=MxnJL7@V#yLRsX>` z(xKdR!E-JJf7rzo9AQSYig@({Bjxr%F&nRCG(2 zpmZ+j+<$2PP2zy-YjUs{4ro^3Oy4}P{*R*ne>=P(ZBfA^ItQ><=u&Qi=%29R+BZB< zuQ|aF6Rvj&L8&j&18uy^41u#+$e>RQ!9(uS0 zfa>3Sd%NooW1*%iT;~HREdcj}z(Yu3cU{J` zwUGg$6lmK%+3q+jwTH-~h?$`Ae64`KIdgx{7>?+TBhkKxJLiTTN1(kL1{%Qu(L zp^#}>b`x&jcg3{P0+p}P(W`CYe#HoMhmN4Qp?mk?QE+XFav+K!uNHHmoa4o(W$1AJ zQ5dXjLG~lv%-Kk~Tsy)G zZIucqu{io?LwssYyxdayr+o(MsiqG2q|smL?A9(f);P0vqiL zwK1-Sel2ahbxvg9vXV6^winS(n;Vjf5~?ll!}_xFpT3I>caIkNw4=wJt)XQl4v z^TOBsMz}`3@aq!D!f{YIM0WaD7$0&t;h#tAzK2Qhalcfbu(>O87~!Aw=kRNjXR8h3 zKJ)N(a0~~i2(uQO7v_Z9;u+2H^2Dpp9DMLcrXEeXDU=f&gy;w@L}1xCkVVoi1BzFS zGQ~j%2+EiO-f~C&X=y+X6Ih^hAT-_~DUa&?*gdwNh>Jui{KRU3)z|+N&Y=(-5XynH zwbg)O$T5;^mcM*2Abo$~(az%pYby4KG^7zruum+Uft`e+Hu29M&Kj3K685tNCAWZo zCWrnoLdp*?DGO};5;SVjgvUN|7zMeQWG3PXg9X;k4xXGol1hS>O|PV#`!*K9;69yT z_2LdN8YAWH`b$2kvf&{77V^vD7@kQXrbIw38c{g1{oC}th(%*V@cm>E%%ix|d4Mtq zZu^R}4|staW7k-m#V)2#iADAPfy@FcW>yUe944Pz#1MiYxP^hM{bPiXC`24FkA)2j z;gfzRu4Ut!?A$U4vaUo*89}%NU7nB>$ZF=Ewy&^5SnU+KCT}DnELq0A%x`Mn?EMMI;RBNe1&uLfwVx@;nQ_=$hnfk_ z!ClHDIa1j2z(<}J%J6;c36Oci?k=_%2*5l@C+WGu#iCS02R|!v`XWb0sEMjKY05_4 zZD$&^pBjf%3e&yx=8sGqfA0LCl9EFIIrPK3R5~>V%f zqWqGCfS>AgNPlWOIZm57`>$PrMLfyd+;*QOZ2`ZR1danDvvmqIs@p$~j)*B1_oume z1^uDs_tyPD=q<0GQXafhTkeLi1T5-F zbuO#=dT;CKh>!#ClJK{0lCW$i`MC`wB?h3Ag4_nOqG?!fb=CDtv+(!;HIgWi)Es7R z>rk#VI`X@736|~(mPoBMx{X zfi<-;KYkZ3&2sc!i*K`W1x2E;CL(=-=7sOZFnh&a_qwHBe#l5fzo}n7A;dk<_f2_L=7m(+ z?UTP5f2O^EdNC?JmkNPB42B$+bN%e+HaePGCWymC*O zD4rwkBC4%Y zpu(x#tgSfI$v%YGtIdwhvG@C_wLD`Y9m9V0%FZX949xz615ypjHZ7}%nfzPb6XiZ} zcgccHh;pBS+8s9ch1*O(2lq zn_+JK$&gqzEPK5a8g4Qyn=Qp3o?cSLRf8VIR?=CtbS^@xsQeij6>_2FYeIop5=;S0QOJRhp&)#7A?Of&ZXw*Qi~5uDcxh{v;U41 zrJzEt-rx6LGe?a<->q=&3i@NWTj|^tB|HvBTDB++Z(ozTQ!l>hHcer3%4e_)7g7_-#>B0gt(x%P$I@#&ZilS|XIKcU_yqa52&-!e`IKmbBSye!ukatF zt4g5ovn9Viif0#-Un}C|{*Lz~Ay}O$u1H~z<%mE#pK?Hesz5e=(Z;xST=PbM%q5Y z@xtGHozR=oz=J^Lo>I4myz-fK_13NQVcOrZxdpj_lLv9!pxRVtFT-H@SJg_$mI7MB z5Rt+d@{8UhoOCTq#KNxx_}Ir9m}50)`4b#4n(UixzkQy=38{?EFE$|O4?Ovpws|q} z#x58JW8(z&>pB*6#6pNmU$F$eY~hg$^8mv(G;Gz{)SAvMXccmX?8xe^d6^q7cr^ zt-DY7yKOfI1p_!y4i|C?VF!!rzfWk-o`e=fc)3k6Er7w$q!Nj?d_{*(m{B08`jFFp#uBs#<+2zHr$R;Ca@uV zxoc%~@EdO4iGqRP3v^q|Dr)Erx0`T(;S2PAN3|HRImu)`&TB7!t}~YH5B@;eZA?%U zm+l&bKewT)M23<->hhO$cIpQ&{s0ABq(%%|b~|H)W4D`Rn{+!;Hm=oP!Q3ud6|CC+ zWufF?z}UD?Z`ZiM5K5v#+uO2Tq16iYySs<-`ngFOEDDytWV^uF_o>I}fe1eZCKV&? zZSBJc4~WJVBx=EgaoyeD$@D#df<+bI!`NP2+8;&q5q^ZT6TX;tAqgZtLO&%^@SC5TQ)!JIXA^+tIu&iW~CqxP(d*IB{J_M(8m)DD>EQtKd_5y8%n5yL`|>-ML*4$2 z3^>V)=I=vrSKs*gs}kxw%2Usj>pBiXgOzBHI0)|dsbgPZ&xubP0pN za=gB$Gj0p4Js)Eeq)VY-<>A2&f*A5W(lwjLN0H(l)P^q*i;%UJm*1E@K-HL>P%q;?M_SK<+0=>vLIuvGO%(qAZ0T~P9`LKXf0 z;Oc^k2fzPQOq%>B{-xcMdz7K|>|SlAdOcPZEa1cTmuZ_Fd7W2#IRZneE5X9yK|w(w zL0xLMsDJ$Ogad+s`wKHbusACJKyCK0I0w-GggWpz42b`PA!s<{r09R8Y@*%UQP5CO z2N`vYIE-K~O-RBV2U^!Hb8Y>Nu3&#JJPnPx52ieGICnIvq(-?{#T$DP+DXOdfaK4x z-+o9@^*k(3v3G}^bHQg0QVxcsW)Cfk{k&MSkR&&spm4jpJfK zqK>7*eX#k{`9V`F^+1EM@Ou-%kBnYAlxo&9^HPG*K0&wqTAEN&8dT@hnL(O8#Jgqj z2g9=Pfl^CnA6QA_H>Zn4vH3?A);S%Ko~ca-+@KDN`FH`+0O# z$`Eq0CKa*yvUqq80jz$@;TjYuOQ04-qKgidOce zmD7zCRBZ=e9#xZ5c&KONN@v%6Hr9fO`gTkOD@!E{yPP6mXi?`dl-aL^(O6o{6 znM_@XG=6v&{CsY6^lAUm%|S{(3MbL|`Ci;FhiUq`X`7F~k#j)$ zPVwNB^`(RhrgudgUL`-MQx77v*=*Bzc-&0CbblEZ7;fiW2=jH9{X*u~ZmT{ThBoll zu68aT#&Zi+1Go}=vMD^>V}nQYJVD=V0n<_R^>Ze8&#Z?v!)GiJPuqk;4LTBz-TO;s zDDS|{hji$==zs+Ok`6Q%Yl)v^Moh7-^%8^NrG9^y7IAv9Qd9RT=9X_OeNG6t{@pLH zmprH+HMbGFQPJ{ctQ09{<@^1rg9t{Yhct{-i_%Ttq}&HIP-`L-D9Q@msG|9 zdnEr#Ng&)R|NowO$*D4wAaXM~4Zcfqc`mSc*LPp3&IZfsFr$1&C+uCIO0$l+`IQZwO1ZN@_AMN|OYxijXD6B=>rXG~ z3EFau$BdNk8b~BtpN4;H>m$G>O8n{b7B)m6j2|R?dH`;S|8I|#HW_xDpU@b8pA~JL z7)o2fJgb7wVCTf413PQ0I1+PWbsg)WO;WNhIcAGvqKc&cC@ta+Pa<<~9;#{5v(huX zvhaBgvMv3HTfsS~U$e~Tx*jm&#M|Lb#$s_I%klg}LyecHBMgf(8)2J&cvK(M=r>5p z&Q!MW%pdQlFYa`xLJMtpGH4DXy)Vd*RVr>g*h9HkkGf9e53bOX^WgtnZa=@dwr*E% zpG&_)w<^5@8XeHkC5piJjz^if7bbB;DIjj%Z8{#jcZ>>C%8NuF(Vvu?`G6g`edxbc z6_J__u^b~dLSyZRNM<1|4L}W>HM(p?-m*IkDc8mQ*f!0NZ|)dgby4f4-R&;f_8Xsk z+i?yJ;-+(j1%JicaN~xzRnrwp%u)TkJ;S0`2rVMJut>Xc5mtA36dcdm(y6ZsW@Gks z(#pKVlAW9VETP*ekrQ%wF0L}ZmM72Yi&ASfBPLjNsIRr^<7?FWg5(jl>{P}c1?2n(Y0{B>c@v?&)3iG5BEDqi$_~iYip-#DiR#4 zn5{>hUQTYY+B(8xu+ENl??@!OjL(#vX3H%v)1_25H6>fPDQQr~#^Tt`=AC%8j$UOi z>W~`dhJ>Lem*{?8>w9<#j0Ps7oH7Py8Dy10u)u^3!qrw~(M4k{wzHR)Nynl=lNIqL zp6;;Y7AeKX>MP40FJZj&Po)MtTWPqwCN{$g$B*yZ2{WxWYn5*^=cFy$E){UT=KVsg z+q7GGBbmHAPja(F`(UgVUX>r480?!&T#{M^{`Uv*NetdX7%CJLDJ@jS4;CEaj0^`wkqwHBAi~Yn%jT7*&>ykZ zecuG_uf#T-+c1`^6VIYA(_&25RkrDvTt3!b4X>n?T&KjwBR-_9Qsg z4Z6YUkNxDR;%}Yv4CMtsT107GiorD<84dpDw~TMhByP-pL@im(eU` zG_toFW+R+vtQ^D0*Cn)J>SyPe@G6Xff^!na)D&A+&~V%N1D!dx+2t4N-$3O_A2?Z;fAzEzl8kv2T#k z5NI-%LkZ0)Dt%WQS?37N8lyK}Cil`TFeF2LMq_IgXXTp%1%9CN%-$_aU0O@wgsctj z{xT}m}?(q{2j3qPc z!czOa8XUTwteY*D&9qj^D7=MGdf1DM70?NR<7!L>x4ec3Owho3=?sDJ-IRJs-1gTZ ze}3@VmPl~3?PR@wV^efynTW{nyWw5q2BOZ*Z4fChaHYWOl%mUE#?X!rJ#J%@JS0#0 zd7Mdy)BuT!sqyw5&nqD%*vVXZOyvtq5>|hd)3l@z5|aIsHG0CefN1Eic*O;QTatAm zcf1SyJP)i12%)F^tOS<1R@_0N$G0yuY`7xfLeTkFzcyZ8OvD-Nk-S2e4hKel3uhYb zT$&5DRukLvv4o?GHe7##C9XYc4!vMdm^?cOoJ}$>V3HvIgQe>K9_$+EF5I1M9MUA> zK;V$ZL!+8T_W&PDl9-(x_`9T1)EK?|lpzI*Dxb>?V93AsvVFti>5_ z8Z|7*t#>6z6{kY}rp)6+k~i(_K2%+qO(wY>y20tck~8va{`b9szo-9J!R53a9PyQb z*h)p)+2O|k|E>I&S#Yla2S@Pcd%^A}FZZl`YQ%zqP{`M8{5P-#M0f10Si%LS(L3+C zMEw#m#?<^vUb?Bs<4(yQ$^UFjm)mW7X^Cx_aHp6M}3tvDEa_8*M&9yHo2?pnyGtp+IYW(cDD&KY+ z{gd-_3A6a_D0X;+vs-is{%-8vDg7Nt@Hc)8Y;o3i=q*0iXtncRW_zlVlMnGJsQLlc zvu_&8V~?)2dAatL#|>h2FvFHY()3EfrO2sl^3{UoMCo?=Zx;hZAM>R#nb++ZeMlPLKn+maJzscNJW`sstMFY#}vpkNp*a-c$aB>f0#0V z78jCqH9YErwN`l{s$mip)5jdg;+>J&x_D?~yOk>AMC)pJEP6)QM0G1HrId|xAJ7%l z`a}=udoF9E@p2Fth0#SN=b~meB>O*obxqK?t^Qox%Ds!EvZ#<^;#z0(=3KOd2qpl& zwT33gioSozwbQ2?rhrn{JzDMPss9547sMU0GXJ_4ya82eoxYn!N($dUj+Pi|aT7%t zjEzR{=E0dGa6d9kWAkqAE8)qvgY}rx>haosOLfmsL#i)irqw)O@=_t%7}9=ZR}v_t zI61PbO9n7q?Ry$?Z9+pz;A6bRECC#4;KoHFHS~F$&egLznf#GlsRV?Z@Hh@cL>}m7 zZsPj4;70X?uLi}J^&f-BA?o38tJVFRIIQl9Y z`z4IF>CTgIwUD(Kr_womXl-Y=Xp^eKsO|RFj2Hf~lnrHvuxjvWQHii}Pk9xCh--#( zBs;9m#@TGZb+mBh)4~UCOW)YV-)hsI$rJ5?1>oXS=wNC4RXb+md`iqQT;k>*aBV2ayzKcVpV!cdDtjN>CY?@4Pr%0F zqSlOSBx&P&sFl@7Tk)za-5UxWs1UVT+(NL08|g^)%Ou2hM@#o>#kWnhNeu=Rl|L?h2QGDu;NSG`armyqd z0L`2bje^%KV?Ku2RG_3phPV6^U45j#dsgYUwx^j4X)zo|MR#)7A4brz$RTYWzPbrv z0gFYGg!gG)2&BCIJ-?fe zURyxa`{_U#^d#Lw3qN?!NVYB^R5b>F)?Ki0+luC0LxkkyP5MKI|LmFI-+wtvWvF}d zAwofMW+aN^$b-@8jTo{vr|A?IzBhfOIfq|)ounUmze^)NqU4n4(e2@RCQ9AXp`GNF z%^CWtBg2(krj(A_N~P0nnL8{bOS5An5&I<=S*d+sqqos(IABo5aCegMUhwMyR(1pT z>ha-q0zHM+;MG>)Mx5+yrEcaimnq(ic|XkLsAOsLrW&}{h#;3G&N+*7WH?qK+lI<* zp>rvj#z3!mn?*ssofVZ0xeH%LS0O#~7Q>+Iw(4!Ilw$rK4$QqKlT@CeqP?AzZOxx-8%gQo+L~pMPU-th? z>eo?U&OLB{Xn&a)0ZHaNR>c;KnB_Tqnm_~`%B+7K{Bxp)o8upjMAxo+t zwASw;xDwx6Si05}m^sR=-q#j5PQk?lGO@DuW2Rs#oDWsrvcXcQl73b5->v_+;mgi$JTs6d)621Kp4sGJKnmjv^?)~1e zbV?)@`{{FE>vNbk)R2LVHqy-0xqW)Q<&9jLd#m-gtM%DhOYD94+YX|BFOz5TJ$ciK zgwOVOBe2G;Y)omGY3e>WJ~C;H`CphyLo=Eraqz+Iw(d-YmRaSWv&F%ks+#lm zW90L?FGu|^(=SyP&I6dI?`++VVqR^Bf|Vbv=QI*L!$NnWnB2QKlTL}3ryz)ejYrbFrvG7Lys14wqT?myt!W@p|s$(4`^GESuPt};N zM`=+0Kv_y?DuC8F@+uc zSqq~2F-UXwhrg2E@~nqbq0s`-AEMg)!AH(|vdLkmK#{X#vWc{F8r&tMGmx$^hL6i{ zbE*${G($`|u(y;tQKzeB^X7YtX5bq2pZJ(eZ|JE0B#bh<*O_@B;Q2~0mk<}CRAn4V z3s6D~*Cb~^1{ z4+pnf`T;@rc=x5 z?t+ANWV4AzH9seTHL#`2e3mF*m*xbqP3rta3d;52?tKSI^*x?o7W)&JSAI5nzP7b{ zliOTM80+oFif)N#P3D@7&u^WZ=dINRy;20`fprO5NoqO_R&h_Ih~?(wDAvP`outEx zrH3T#W4P@oP7O-;Fjlz?F8xV%h@pr`$dqd99~P{Q+vj)iAB|pQ5S1@i#w(Ik)7q@} zG3x?X6z=5ao#B7+d#om@42W0^GETQH)x1-RPYPn5wEFHbZoH%VadQ>9*WkYAtvTXd zo{3w#H8peITciJ|*zxbeatGBl`}5|*R@>*x+xzz_*}e0BI*rm3i!XS-zHfOY20z{s zu&bH{)~%W_t7dy=H}xM7bE?dId2W|yLSC}UfR-Q9_>6f)H|yt4f=}Cs`Qc3FqKML1 z`r!&jYy)i7Ot#``X2bY+a|LL-)g`mrf+H;>#}V=^W6Ijk=gEPL`Fda-1M~#@aMK1ka6unh&EO~Qx)L3j zvBq#(zW8*U!I<4z<2~G@4khDo>#L*tnu95@Xe=uO*9Acg-b7_R)Q!a8PKBB9Be5_@ z_Sg4Bsyaki92~r*9fq7Yw9&kMPpGXCI@)>)hOprV0!90{?~%vQ$r6Wx82>1#pa-L+ zzEFS#g(d2j_#$Yb+gn^c?82)7T$ zs3kc>AcK!z2Qeg#k_41?Pk03-vYbk}Vz3lFKVGT{I>GvNY}3D#HH9t1h1Ost`)6b8 z;7uF3eW#;hB#JB!)t`WqOoY0J`OLNaLFaH9Y#vet4Xsa0^_#tsQYb|ydV}9!DUf;Q zjSezOsj1Pn`JEyZljiV*rFH6F)(msb@a4e=N{k7RM(A9FjkpLU22-tZ2xpIe3W%3^ z&QN0Z9MmLr4 zGI)=0=8~c-uP#j4H^q1>_sttx?bTsu1=Etg?2`fEWZEZq_8OKyUtC(Utq;dxr2M`{ zI3|o+@z)N?IZF&xzzfD5Jo84*an|%Qf{z5)zW7i;M0{V1wusx6ZE5g#)j8(V@eQ2Q zh>LlTuFvSKCf&2?y#!&chF3l^bK;+ykI?A|9`BgLu3`;fWDtCDMd(*cv(o(hoUvYY zUi$w5Za|U097p%xAAPvri@~S?95sOU)MyzJ4)_!h>N{i5u<^7imy3SSFtIm?(R*I> z2gB}v#@Zr>od&%r|y6WdDUT3rMPa1ilG2t)N5&h^AdQK-Ih&fmo){DbqibN*fz=cl5!X3k81 zz@o!G5$pY(bK^kk2jf(?0B!>Gqy`o`$g5F$DzZ|EF|2n_%~-p8RxZvP#xo1hiG?P; zg$yG(Ek%`zu{JfvuT|edlzZL|alr`@_*R!q=CuhT^u0)g0p?BYwGCv@n5O^0r%yk( z9=x{=ab|QE<=cqN+0l6ybk4bt1pcsp6Zl_V)*Lw9%6 zf^&2or_SzY2tqT)NAGhyLGRx4u&#EigTl{AM{m3?F?eHqa^;N0e6@H^3nJ#O2bYSYR@*|Is5R=hTV(VFQEf}~2y~L_cmo)`-{`t>;-lO=a zhx-cVGoOqe^_rzw7z`$3LctglPv5ZF3b1e`SlCN07Z|$5V1~mff9u15DJBm!s7Xl* zNyBk~z<#U1CMoxaG~pTRceTPDb&oaZ9lIjl(hX)q zqc$;bs-^hg2neY1Ie26s4aAdLM0gm2Yn%jz^sqFiP&Ooi0tsU!#X2f~FFC_7DnUEb zp(2u=#EihISr1K!!&6?wwQ*z9gZjXoVYZZ9CGP?oMh6F1t3lh}+>cJd{4cAn)vAu{ zVBN2T4s?PQByEYxFaVBC1FB7dO5;8-RnkT~Q|d7XepkSV6c;%Fh4nQJz@n)mu95-@ z$GjK^T$(#{Nx#*Tc+aGN2M}yo4!?bXm1>?nL5`EfLKKs>W7bglJfppY(nCsc-5CIU z8a0o02XwtC0+3XM!dL(5Y;T6Wrdd(I>o)U{(_xC5C5vmQyNT;!Dtum)D;1{$5x5p+ zp-t3E6Y#$^&HT_+$f~g(mz!8vbZS`+%{m0O5I=}#N>1rJHsvgTAmN)t%Z0mS$)K$= zkj^Ox^h_iZf?^l&2CG$D#!zt5pLUm*-s-=lb%3Qh6seq&#-Rv>CT%d1qJ0=sfvKx_ zptb+x)nj8$PWq$K&Arjh>tDbeJcm&2N+9(1ud)` zCs8jae0$BRZ4v-~uDz|0``Op~aq>36vH5W+@kG8{;xrqfS!vzCB&ide-hbmntY#pG za*?E{+hC#3v%|E^%Yt6clj;g1e#!wFcEU@dG%qEsG;mzOBO=l@QPQ9-3T#E;B)uiKuix^#ho(%kis`n3=$zJq;i^KyE z33&Ra-VmF9_x#&0UcP=F-QbtguV1|U_W84?ub&S>VeMwn(FlxikIub%4X1kd=rOF2 zaqHD%dX)<)$LLPB8=O#sX(iA;bhLTwz;Jr|o%PEPciPNjen8-apIjbim$1#Y-s#Y} zmv>rGOvzw>xOro*DO6z+Vw@%rcFnj3@i1H+GlWQO=RS1qCmB2p(gpn#KU!+=vXb!` zaJ#o7Zk}j<1`HqXh+%tedK9-H2gMlB+-|QMjqXN*1zzf2qA$Bm$o-#AFwaZX7unwfB^& zGfG&cI^hBD;br&yE4k6_G-=ie`?T)Y&!Zd91B34)rsq37ul|$JZte~4RwtOzQm>=N zaMNy$JRI;$giMnKddlcLDgPXN-~g~mNzLCSsmWy29+yt2G8SuHE&+s`(QX>2C(qkk zjD3}VO-k-I&LsFpYQKgF8#;f@IPu^=VH3M82<>&i#Rumt0ZP+oE)v|=sI5+>^TI6o zl)ReB6t=m^lx-;*U>D$6g4dNV(V<7?foHy^{1TU2ZL0cD9*=Os5Xwu;Mo+nl`ccM6VQwHiwFc~7$(}F?9%FP zTyM6N#C`!wlB`shID$A#V7e={kIKt52??TgtW|{A>?bCe2x9hp6xX}NJtQz*Qtnm& zQiFr`sBxm9t0*YGgR7xyl3|q&TwvaW6QR-u8r0Xlt!DiCNnp_9v!lcRIe&0(@PrS4 zDi$S6bTJ>*6#Bf4)jtOZ)LL&bL(u(4kq+N<_MveO$8Y2FHns#axw*JWZ>sbr$rm&D zBI@J@0OEhwnOL=hAGbjyQrg@a1i2Nar-1CfYq<2SspmlMg8wh)Gc~I<{#r|FhNNaSS|kihHp(RH{S^OlD%L_U|0Qp#<=NVo(U4Fx)jE(=D((xX2Uz=0Qt`iAI#kO6D z0#=whB{W#-$nRzLE&z>|C8djh8=WMB3;UjO>-q8~XO311jSfhqDnPH+c!yxLKaLke z4$unRU?hwzfm~K(4%S6FK>9jN}9qRNd0t~IxVo%`ou^euSvg;&&2X_cvnv1Nk z*StnqxcbiV?aRZo#5l)2>ySdH~u_Phr=F&>Te@0waCUrC`0$+RJjSM{lL>Pw z5E&))wMtGB1^LUEg`uKsKJy+R_YQg;3A;{y5o(`7zrC7?3!(NSZ0}IwboTt9!Oogy z=QD~emCW~gbs1Mm<(^SuUNOm+kXI5Ee?K}^3yShn%1a*@UnP1)DJL_y({m2XOrV-i zQM_1Q-+~msupydu9j&3f{izO2@WmdahZcpo$P-v9un-=dQ$X}vF)y#x-F`4vS&poOZF?u3f1Fb$ zw!8(|9z2%`A3?SUZvzwDsr7kLSA3QSgBIbKMk$I;($!9d1R$A%h>2o~Q6Fh#!bh|; z**27b;AJ@qcJ<99d7)4%>*s+A&V-loNNi9fh>6FF7JJT)5&wQ8JA-qd9k0;TF3F-& zctvItAyuU7CjpQweY91(0IR7&f2@{69z4Y_Z!IR12_TCI49ypB65**mr)%l_2LEB0 zcFzTNzMAvFz_25ZneEih%0lO=0PGZ(XbtLvnXKR`%$}@@lw}ou*FGX`z@Pe}GAV`1 zNz)-7N72~~zm}_^py9z$VlTCZgeu8p86IPsRj3aIIe{^CZpS9J*TTU$fAbO^*nm4* z#E(jV*ye~-V0@bV)9^11`ccT1S~NUTrpiuJ7-6u3FQ z(-zIsBF_B>bHqNhCx)28YdoG+SzVD@b~Xa)HojSe_LX)MI5!A&2bq~juMn~nVw0`_ ztA%_~R}oq^(4G>;sKjVze}XF^bY+1|KAo!a1OaHi;v_YZ>`93lR=fizCR!HgcH*US zU_&b@)XPkPe{OeQ;f+mh)=@zumRve*^oB67Cf+gRRLI1^nohB$HSyM$vztTXBbczM zz1H0Ff7rpRIfpQFK|A2GP*>+&ocbc3#?j;djvwlrWd_e)GLPVOe++xDBehx8$<5}~ z5xp9;*h`*!JFS~*ap&!^Z!JQ4{{kAC6*)ld&V|)|+j(EJHKC^_k9k_wW|ZrF7ghU*-f|{Xv*!1r zx=wxrs;iXsmb#0vsBv>< zp@RBu;Ac(wexzPy=GIzdCi7{#@&#k74NcF68EG#C0gf0{JSB09r( z^pMWbhIG_6f28BPp*s3H_k$sL;-a_X%BY~d)OG~c1q(XT4QGl5Vob>o6&V+yQUS{g zaY?5n;FGj&%W;HZXvCLzXDs-pxH5hkZs>nexU?M$tE6zxbo2yeb=$SqY9f;!l!h<* zM2weDYmwzvkl5r%Gf{1n27Abq#g-tRv-HVFU&{p?RYo0{(i zbX}v+D!hPYQqOF~&`QWcw1iOcgJOBvZ#rl?Pzc7^>k# zxWwQE;#E{uKuh*nrg=NssQc+Ftj$Pzn$>H=D;_t^#U;3XRW_Z~KDR6jh7C7}eX2-T z=(XY&f5KD~p&_d;#Nna6ExsRpE!1IxALcKed(P5>X^5or$k6d)bJF+@mIkH%^#?RpS&TvT?~!xZd}mLEM`*nhtxjqTap#ii za+8}(`31?fPDHmw9+)Ip=MRNI^+et&f8fr*swg9k%xt?VnXD2X(a%F?8)j40lJKg! zFkpDyrB%7Hb(r}dT*1*%V1&v0hfXQSPhPQcs55~i9-vOt09+X~k}`0H`!ppSr2`Y> z_V!YO>J~U>6uSh@A9F`+ry_%+i2Azh1n?2%_3Och>m|hzk7I~>Kg(G%fwpCCQeP!$Nlh;=5yT8Q| zyu7>3q70Sz{6$t~s|up@3Zgnzf9aD~ME!T**S&6j!B*iTObO*MbyyPIFx&>x{2I!c z{Y8_r5M$3<^(iw`!_6J})78WDL)lHCDP4>{93ze9c(6r{;nQ z6TMFyA3fET4Dm{fEe6%NuC|~VZ-Kr?3LY-Gm_yDmH{{!hASg(Cn_5A-e=5qAttZHe zb-8iU!%h#>oDns1+#&t$e(xp9_X?G}uCu1jB2|St_FDoxM%+3z<2Boy&T~BYQGi*% zPpcRjl}thFECC?&CHG;&-reu6$m-^DK%cYpY6l)$6=CIPd$`Lo)i1j%pxUGLmb@|z zuF&7Ia1H zx>!efSzf6IJo3}hB=nna`C8q4!5`hww5ea^pyY)DS>5Ok22NFee`B>){WA=eNa`Fk zXSS>#(8W=6QX)u>U9*C<2W$N02ON+czdlr{MGvEuJ<-45zZ8P{sl?w)apgyS=%<-Z zMjA$Pkw&v}MIr)7tV|JJ0Abo(K%3#okxpmwSB_Kt7!P+^^>4RJ!1x|b5jaF^EON3? zMO{jNzLY;i=bhd?e^Kue?!LAc>~OmELn`{{(JgW6uzaabqM;!;8#F4L1oR~4i+XJ? z0yn0q#d4|^ljN&pEnNd-s|+%)1oj%)6vaQy++-eOlmHv)>S9;h@|epegT>0~I(DY< z9GW`2R%f&FxE;E?ar%4{z`z8`n1>96sr0nXsDJ3)JL+BLe=z&brk5X2)ufEgRV9VJ z@)7%nIqFxNRACv6bCVd5|4<9n$^0l zsACp+)>f6u%@ha%zIo2E6{sUT$Ek&33G03unDmUg&Cb*J-%*7@-k`a{iPsHXPz zuv#Kvj;h1Os}(=ItTD8u5qK7qifA~Xj?JuEAhXvNt-E=b=F=*v&HYWkad#2q78nE& zD*N-5D^SETo9L#GQE1hMD~B@bd7(S6l=r40qUM8Ee=aL{ZbpNoI$mkx=Q?Cfoo>Al zD7`HJF3BsAOx8-^a4(H(gx?y|1;>KbsY9f1RmOW``D6`P;BZ@KIUm#sDzEH@iQ{Fow&K7`=y zDKqHa8vg@OO9KQH000080P|F{P}{T>`*|7w0GM2tVPg^{e`|BwIFjG}E3kCUhMJXW zJsdl6McH*6d*WKh&c@C>&gbG#Bqec7ksLl^Yg75}+uZ;NfTaA$%w5%0oysMPWTVk& z^b=@slU**Ng3Y2hWbi+zyqLw2A0|Z@uqp|{oRy1^m0`XtSURJNgUs{c-zf*{vme8} zh|*+ZlZ~7~f1i0tKwxh!-bxsUU4$XsJUux)I=eU$9VT=yPt%g)1`6^pON*#X^A+Hm zr8)D{Wfq5J$bzu+qPTE2HfDLcWUf1_$|?_Cmqp7g%}eG@i!`pv(B;<~8{&Qt6=hXo zQ~ci8DD&0+27?db;XrXTb(S!!C<*hGM0oV`B@laZe}3j(d^$cp`T6K#BfRs&tYjwy zaFpk1zR%bu%W`kN^!8bj0==KZoX`s_@Na{z+vwPYUEN&`u4$lm$PWN^=3(g;)od2s zg@xU_rnW&C6C!~#PUrI|naj(xkiW9nD*@S3Ugx3wRg`(t?|=F5i+lL)=*QSf4f5$t&5EMMfiIaCccK_vdVOn zpAu-nFME7KKdj0{nh5cSxs)ibqNL>0_TKZ=e`CUj&-$ze_yGj(9*~Uc7le5dCj~_lB!MA(y?)>AWdv@@iFZ+yiLU}nR8n#U`Uy*>&c4#*vk+&3qe zf38L{kO@Kv`gd1E{|?!!2^+ERzh~nSfcvpm6ztNQ+v)VT&@X%YocFF<#A#W8_Ja;t zE^sT%vmES14#TrtZyM2msSnomhR~xKG>wv|bX~g$;~6npHU;A~jrz3`_4ez@m&38; zQ0S}2wqCQdGzn`sMCs_%0D0P#6Q{Q@e{;PCJoE~1@V(}_BnW`y&l-|I|B>Zs7Ut!u z9;DVOjk9YkL_Q3oegfcCp0o$Ct`ng68<9iHbx7q1zY%k70k!!Kf3Igd1&@<=VHM(q zxTk3v*8pJD67Ww^5hX?Gfp*)3qK`7E;nCi*;~@C`x$krfS#IIkxbMh2YuRDF7_Zv0*dYZplwy&3eBvO+BMq znAL}R?U;D$%hxUXvm8X}l~1EUCji2aZ=&GU7i{vC{e#gDHwwPKHmI3!@e>axQNa6v z&NoQty}StB63kp#ioTe_ny?asL6(1)9&W6h=cEb3x{;Q1%QVp@CCmaa7vY zmc^T3@S%$dh9Mdj3GP@LN3acwAi!cDoiGwkcJCr|P0QLQa#)TR1U4G}^#^qz&1??XCy%D=0z3w} zNy59*j*xGn0niK4X-~oBe_m9C>=JlKaj|LUKt(}$=0Jj%Kwc5vWngR}#So*$PAasQ z?8{$rrN-J60f26*GzM^bt~l}6a?&w~=3%Y-*~@K?1VJXmu+F*0d8G-aP>+XU^Z*&c z_3g74S0RsAICiI_qn?~L4h>liA|RuT6e!;F;LZucX*F-~>yS_ae}+85$d*0(u6Tx+ zDwOZO6sm(aC#WlI>8;ol6DmK=bKopYA`;TgFrrHGDM3!h5O$&M1&OrzzjY=^+CJ%W z3D^Ov8GGOvL76e=vU=*ymbfGP1N|MlUIw}k$qf%B-OoJ!ZT4w|*WHTu7BzVZNgHw- zb4kG$fsqwehIvJSe`aIsh^YPO0~^2CfvLc}H!mndlinINMBo@ZBU2B>m{G$Tgp;OG z-iz^j`{{()<31bJOc2pFG6R_)A@37VgBhBrVp?-Wp*4alTxjYAF^UjCcPUK}T4o7L zRx6K+G~pvgx-hO5GGAkqm_TZRwA4^v?T@Z|!i|C~W1PBLe_}sA{H*+92mT2zqD^!q zR8vi@4=eZW(VI^{SezFeCqxzCm}h=kfq|IdrB{{^)~>*}S%9HTOD~oH!l`YtpQ0p4 zZwnTrVUav5(MK|g9`qVA(M9Orpb%B*=YII*{lV$!`JpkdI_)(Ef1t{|AqHRu30jBN($cZDh#fcL ziztxn{QremXljJb!!SUYz{bQHx^HkBMf&c8Kw;yGd%+zkiE z@G)?71V>VzDoeS2nl(LOeM{3gt)e(6m=8`Dj7ka)#|xOnZNAl(X-7lwQ>dCj3J%^G zS8qNYe_m|SNb3p6!{4hYC-bSAQ%nd}K1>4J^0O~uMwDk4Hzv|F^=i8V$w>kEpyK2} zEy3uhzR-}revyQH{epZ^Js50jbl2znn$UN@9?L}j=o618_@!K^T>8Op;R=vmVbi5a z$H>zbwpjN96P)dG+e*EJi~!ppTTe=_>Q>dTn=DUH7Wo(E0}n!Ib%?>LS_ zenu{+snkQd#b2TjWsH`IF&m-OfE@}isxN+U|9dF`LFtMJjpvN_xdlvoWpeHH)+=BJ ze9IxeUJr>b{!xGlFsTy|Gyul|QvU#MHVfTV_+nN$e;sTS)P850tiYV%q!4n@RSeu_YBAI4DVy~cN@hqhJVl~ zP`y4wqMxCz3TQ76>uxE~K?sN{sYCc$)reL&r2ylVvd1WA+-fjdo<};-h+$6QmBJ6s zqXgHD&7cWwCtBGxNtmVUja6r2dfsDle^1%C23PqSq6|=?WR_x3ve8V6(QtwlQFfvg z)96?!t`Q3a(TvAMEq^4ku8x?{wA~`AYDRy0tER6BArkCFa-}Qt>u zG}>VJ-pP-ce(D{OXL#OWld>kWK@U%GQ zl?L4r!qm;VYSJo>biH1Hju+-CDrtoRJ)mZ{Wk~QeC#%n6x0BTf)*Kt%f20LCa~q3p zX}eScP`P3qR@}8|ZKIL=nR;tEzok)PUupgJ8@R7^S?=(~(#IOQ^vzDC+r2{PV&cS- zs_Afy+=si(|5XnqtO?}7`YcHM`}oDSwzX+!N;CEa%7d`*VcfW=0wP$e%E7D@g(Mhn zfU4Bt4&I~im)5=O7`PFLf7V4M37-~t2*dgurB$K2rwS4XMvZ8?wUW*wwKY*1=dhKn z)+em@FM;uyR%nP8g@i6ATAP8A=X(jOU8?R%TW)l#%a1;NOtwLwaDBact4eNh#NnTk z>^{k(JlRA1AvaKndJYmTwDcrj7)dK0@I4++CRTne!qA3~_F;FCf33b>la!i{gkZd6 zh2w#Npw#@T0sM;Q&~y+QZfMukg+HEMeXC*B7oS0**BPsO0?elw%-Y_xgJH>xP7k;) zh7(vUV5;?JjOZRpMIXYdFFo*SxxcXS3!G!&jz`m|oOD#x+`q*oH*)Io29Bt;y@>s& z{1+~qqV)2zK(V*2e=PI$q)_gLwNxiD1 zQk6I6-iJVi$+1LoEeV%5aGBM*d$H^8?pQ_wuPqr52Yt5FUD+YBZml zalU3=3E26M@yNOs%LlYfYtTVF`5&YLI_E#`p#f&fV8tf8e>{JCzR%7=h(gPh`DpFD zXHI&zUD9?LLQ;;W*Pli*RxA%>vo1ub= z-KR6OlaEcZswBdmyx2195jdC-dzAXxP}!!Z#1YWXrr6hhP02raWWzB&E?7fi zQ*MjY_R>q;#B?B%;)Yu>@p3)u>B?@RL26A5ov}1@loofci0e;?3tq@R?KfFodO#zL++m zMf6t{Xut{7F$nIWffg9yr%f(>4G5A~*!PY_;d$Jcq$U24M@x?%(%@A)UMcdeu3p60 zf6~Gc-I->6Q+tB8@b?P54Y)asbY@_RY1zU{7$1=H_Vm;NU;C^O+v&Jr7)Li@yplsm zaoJ*;r#E53$QTybzr&B&KqugN<|``XD)=TGC7Pv|1YRBhu4xWq6Ub`+rt8O=@)Are zw#ClU_B2kX+cSSQ3OPwsm;n{&4omJw17I=>B;05erkSo{$}k6~qi6gP6qyapVm5 zETtlixti$cn@;o!ReKA>DN4fNTG)YocKl*AG)!D4Sv7=K*H~bkL6d}tFS!~;fBkO1 z?L-B<@W7hK=SMiyi3i=#98j0gy3^J`Tz4UUs6DdY8s?Mob&Qm6$$s{tn92ri3i762 zz{8!M<2X&rSr1i~2MR}fuj&f@ewyZ@{hWGWD4(RdLiG$xT~30->HOADX?2cTP%nBo z1nssd2{R zJcUVFgjh_FA}yF9l7{jmAVQ0n2xBFBp{4vH^L*S#Xmh(OS~g~Qo>Ww(r3(oL-c9UI z7oaW?ro!o}b+KAb)3`1c4DWD>4x|~+ON1~lSUt?giV8+N4`f2ZF=*~{jhr1~{Ln>W zU(C)L(>ZdUbFuGg>p)0_f80}?^<97AsP3iRwH2(k3dw!FfRBAL~jRtVuJWW5M6tHTOiT#KNigPqY7FJthE z2vh>na!?Uq4~aFeyv0Dxv}q>oqMR*oDM+W}BU)BVmoI{MMZWU1e_k`{{eVY0 zA0r95+`EbCR{-4ltx9gh21ztulsK(`zTTMOy9-jcwzjw?bI=8?a|m>3le`kf5^Mvj zZxsDSZO54nn&_}oe@sKtXNA5bPR|74{lsbmufrQloAS zGVR8ibf~ei;)*cdT+&#_tUqcE$S{drP;?x8Lxpd^sNfwpOE3{fQ336vlihxV>rCL- zlPdOdJSqgPe*|Dld>Lb~<(ZK(^{;V^g|V5q;1et*HNj3)FB-vAOdib;j05r^jOH z(-FsaUAT1&kYPp9vG^HoA$jFo--Sf6eFHc(r|057h+`b)m}}x;UmD zHW976AiRW5ba;|Lyc-2(znxLF3@Pz*fa_J%kPiZ1QowQZ(;{h=1dh>?E&$ejfAGV} zp?mh}{Tn*ZJhxPE@{@jYDc4CM9CwC4f0b_K{Wg1857PTn6}{F4YiJ|57g z@f;J2=L9f#-VJbkdVX-}zB~B%mV@DE2fzrfR1jPH zH}-50PzEza=IPV9b2>jh4QhkpJ?hR z32T}-6GVih0$12Bh$JfMP@SniPPcTM*oBGXqg1P9bo4cJ$Mq~Dz7M&3je2*s#2#eY7Nk|;I)Mh0s`0*&}I0bu(`= zVNJf#mISk2zq6XCB0_cYbW|rTRKF9de?1-5zgnm=WPl{FTb4C^(rpkrNlcTsBL9;X zQZTYL1>yxakAQ5=s3f=r2}I|s7F^bXf6Er>Z1xDa;*oH(n4f%qkiLaD=k?H#vjv9k zkA+RD9amS-hY&-YgeB%*E1D0l0Q-5@_jBZUoK|dfBexB z`32!AM$S8(whU;=kg~!s3sJFmHP~Qnszi@yaTF#Fa z5rj}X+w*PD1M&9s)Gux7se;N@Ng-A_bEGh4e@=C)7EkZl zQlqyt#p^)hAuAukBj$&%AJ$VX5B}F@>fF98YaswxW8+$VHdN=o9xXfiTw~ZT%Mbfv z+Ofh@P~Wd*s4pw?D&?OKT;QxDF^_acvba+K?X&_Zqn?<*kRH zkmna{kKJxFwROvEsv3Fuf3o+evHeMu4kV?cdnnyCC>;q(_lCVcPQp<1|NNfrpX=Q} z7rhV1y>4l9Bk^iDJf72fsw#>*s&A0d-S`Z7`-XxZ`QcSgT=?tvxX`6|t&GWqDI{_? z!m3;dW#YAkbhuOzOWVGxQB zm34q?(a@@JhdXQfsjh;;y6~tyD}r zwK<(jl(JW&qW7j1S(;#}d!wWt@k+e_{+q=J$dqNIFA)# z$s|p3weB7`M1xx&UlMS1241tk+WP^F_tYp!zwhk=rVMDfjN{>JQEW6RXq+GHeC5D@ z08mQ<1QY-O00;o{RI^Yo`z@f;0ssJ{2A83J5;1>j(?o=geF=21wqYyFLTJ}P>55V8 zbE3_bjHLY9*#EwhY$r{du!bbI&+qO%Jw3Yv-{!(VE(!!XW(!_GAySkEGg!zBHP|_V zMO_+Dxxe^W@stju8rFsHsEtrE=)han?*f;Zhh5xWwHOAsh`uOOD!rk3xzdoTvMSIbWN5i43=49tN=TA?VHX;c1VmXWZGlgXDi#)#`nn65 zSPCbs3zZhqQiDvb6B;xf8iRTmOYEi+a@LOedOx{OE)ykH3saQ2t@YOrx+DcEK~TLak6o2lX`mMeWHkS$_2oTVJXC=z(Dv`eT19 zmd0$rh*A`sf~wjLU`awPNz#Ss!or+WbR`1Gw3NC`Vdp-EE4~5Y&@wB~ z)XBsGxuH&+l_)LSYVapkZ)*AO(Um;z?Hw55jHjD+j&Z(8dM>6& zQPHKhFWbV~%~-a9bH$2lYe>MuW6*!NI;>PW_vaMI2FuVD;p80pJ9^*BcvYdyqVP}u z?@7pVM{A?Kwm5D_-|Sn{RL2*CdT+>nQIUz79$A;_Q`SEXYH6mam-_a|4`DD zCv3{tqjYrdHGCdOzQ3^D)pt}^xWqzL&T%-xnBnqOgoHc9N97&eNYQh%MP~gMUy<0|XQR000O8^Hj4?!d5Hg_74C6cs!TSED{`-4%8M3 zm;8Ye3xCiz6S0wbcG|mZJ#o@B@%21S9Z#I5(@}gZL_soYiev%Gwo>=M-|hk+36hfS zIO&JeWFiY(Jo^G*vAY1b*xNIy*-WN_!S{5@Q1M>`|Nvni2%ckX0X|O>8 zC5l|jGFL0Wo8^in`JzZgDcDq$T&6l2%v8Q$aXed=OC{o%$wiT?lJSYo(`6}Q^Lxam z@NrI+jo~KoV5(C39igl@$3G&pAM?fyDX6Ur;LnI zp>ERf?Wz!6EwR-A*cO2;n(Z6x@y)$Ysekve634kNUy2KCYj-!GR_rmzID(l|o|>*F z%gL)e;pwK15|xI2rbm~Yn(@;o;i!6Q_*Xyi)9UX&O`%4erv}HPA?emp_DbdPXmxG< zjH0M+u+NMsUMz|q#0u=tQcYH~WK4eo!s)0rN;m(m#A|ST1-c}w7T*Rt8eL>($bYSC zc>z9vE2;DBM^T>TQ|Rd?eJ%9Z42HoTd7Mt|Wbc0nPbaYCt(1c}254|A`)nKlS1p1O z3#=gcr|H{hILt11DyNN>cL#4y4qqR|$IsusJ$Q2z0O}yN&jGjLccP3h#I!`+ha^A{ z*Er(0>27Hzkk46miV2bv4K$ttfpedNb=!@!3y^XdkY%xyTBCRhRqosjKoA6Gg(4hz>p9HCj9Flux9Ew`=PLo8BV$4Wm13OjB`Mc>?^lcW zE6XRpfz||1{e%T%~tQ>JDx7Zfl|4$gX5%n4vHDlN|Q?t zJ9G}a@rW%ov@v~_FH^Mm4EN{Usa~t+n8x41q;V{bVJ*A(oEG3wo{4&5Y*-}5&Ew39 z<1?<$;&`Y zC%YtQ>i~0QB{&f9UP?sRA|Yu|!SMa`5xZt%zWw18|9Br=vw!Unasr@&MC7~ICkJ5{ z5qw6<6Y}iwf)@b#hlw6Buh?Tj5{#UF7!D`kwUyd8@{*a^!rlL7*&Ab$${Z8OQUQf5ox^+f9N-tH;N9qjBr{_?AT{PSO5f79x^1$0x=F?q%HY5 zWWiLjE6(RIi*>$KiO`X^z#81K{+VN=xY)`N+~#Wm})Z;iX;JIybJ8itK^X;()CwgkdUS)L7Hs)p^Ap~NDGm+FWTCnK=F zt=q3MNmS&;u;C&+NlV3Lil+P^RIbfX2@azQ*}D`}NS8E;5;Fk?muQI+A%9XCbykel zI*=&=3v1A-m*EcQ${`oe=xg|_)))RBK0AIwqCXw)Y=3k5D0~n;>l>(dD=yX^quY}YaNWxZ~9 z=}hiEZJM%zeemlVOmVHkyLZnXcTIwyaGil5!nxC!1AVW3)(sQTgHG`O?M4;J*NJAV4^jj`7QuWGshb#0BglY%e$35Mwrqj6!xe)JkLj!ChTj=C z$JT@ew`BaN!`MQN*2gGF~_~_o%;Mir=J)WlS*MCz#HXZL(LvCH9sAX~~MO!M@ zUg4}ma5B1yu|~=pi_-3%(75-C4ar)luAJCbA>EAOq%G7vs@=C{)AjdbtijEC9+;Tr zUN!TN6bo>BrNR|`qfob~yH{dW)f)VC*b!3i3E*b8>;r77L*C}3<0DU}+}7v<#z&As z?1tl=(|=EURP}$gdEUv@-t#b~Z;QgPxNo2STxT}D+w*5S!|Bs^9jgWZEmwCw(`=3^ z%yXP}sW4Ny8f?6Bv1^mDwcKTPU+%l>xj(*=HXLcZfDv?HE*}- zv*lvqJutT|$hS{cCEhG;T&q1Dw2wSstG;1xAb)z&07Yn8;b(z|Nm|+q*oum!6FMHj zLk5}1lI`FM=gnfGy(dR&ssTpzTT^j{fQ@UNCz9hC1yeRsNe z+SyUuV!|4anJuB4q0|%X*DOJ6TqoG&%)axhG;rkUblL9yumpZX_l9*O_srt{P&{} z@Ryb)Ph`JC^@?1h_Vg1q%{w}7ggHU|wz-)X`<2{0Hzkib5Bm;aFIC%+u8(m4zQuM` zeDt=^{gVYs%XgAyEzR6&8rbUC=3;YSDEA|@~TtguC$Qo?iKOjm^BVVu>QgHV1 zfL#=`@gQxtohI$rrVEJ(+OH)Yr(z(Aq_5adRwb1ur?4q*iS#i638t8dur%y|$kU$t z{K}V(6xFKShkcNDceGUlOCaOCf`rzEO4m#^o#hc!&$w7>SxU}v2dsjW(%w+C2t|mh zG$!B-`>k-*gUE!IJ=b{(QVBhuSGk+tX6s%H&LMt|&XnCK5C47XqqE*>9}D7~f$u~8 zb?U$VR;A68eF_s|dQug&pLhq*_rQ( z?hPT2#LDY82i-&i$ubN~Z|Sy~zze}51~p>JDCyP4j4exB141<2s47t8di$akAAU7D zmC93cKFVw!g-yHF8PzU9fcCPD@!BkDehyI#)+FxC1g6}rY2rS~{m!hp17wr8(XE&* zR7U1^|9dpjTXah7|Hka}uGboH{>3B*sgrM2f10ufQE{p4OSG!lUbjw2i1(+q6RW}I z1+Vb>LNgkC6_7J=9ol-68$pwP%pgC&GJ7&@ zmP#H)M!}W%r+}(~I}+m$9(Veh?CUoch%9$(_B5>sY+wR@9 z{#7v?90*7f69@=5wZ9YvGnH={1F{vr03{Lp{}{r<*Q?D%KmY-OApPIZTBxar1t^fM zYo#bT5dZDvS%YHqzwn9uS`^6t!YNv>>QN-1{+qzjfdUTpUn$swq5}6{nLdF6>il1s z$A=pAza1C_P)q)|?}ixa=Kq$pOQTYQ{x|nj4pkWR|D21TRh@_D-?{D(Q|)F^aRGXI z7Pc17dV2r-lB)mc*=@2R0ZvQX+7VMAgJZI7X`;9UR!gkvSm04=Jt$$4Q_M4?e^vZK z|3lL;+fyhp{*ViX&q!K5cDQ|iGunB04~_Tj4OTBB(vu}%fgwIi8yrUgge3aH98~}u zbIEW2BaQ@r4VfB>v`5Jips)Ue?+-X0SvFU=yz3<YP z2OxZpg=m=Tx1&mCOF&tXMeTEj;nh$#CU`)>mg}pUj&Yry#grVmm59OtvZnKvtj8&W z@~BEnONknUs6i)g=i<<1v~YABQJ?;dpn3krt684ZfPx%(45o|UnSppynjnO%H zdv8@uf6g>)_);cmQ>U1iV;9ltrI;)1X4IO~Iyn!kx2IEc5+^AMnAPlTPqDFKR!Nab z&kczTk+&T#n{V`*S&WN+BiVDkEIN#K)d&YK;m2ON(ObHOxPrUcLnf!S04sZ%DLs@_B%%# zNhFtf)iw+sW;!D*l-~(R#TamP^4ig|@7VtRqEUgwczg}{=Mb>Wr>~|(-&+UW<;#Y{ zOJcTIr;8nAYn}Stc7pA`iBl<8%2;rSj30d0MeuilH(oQ@#k)zgS*rTz4G6nAFNO}x zJL!uZ%vGoo^*13o1>p}O6i(w@JgTS6Xc!QJ*wY&k2nD3}cE~WczQH{e+B=?-s)4l* zgPQ7G_EizQ<`O`oY2zH)N0R|t)rRCY4(5p)eS=FE?9ALft~_wR&wpF<1O$ z)=POebsA^X(hdDTl-M)dA5^u`??lIpsR1$^m%t(Ke+K05St|mHFc!+{=^{2f*T@jU zAUWL?L!nWuiUtub_<&k`E?B8FNlmIB?=@#p$1g$BmIX(-+;nS)%^xp4oO~}>&;HiE z?*qHU7Jh+v)xhDip}5bSP}xPu>J3gGdl*@o55i=^(8U!yRU5oHCO0OfjO;`pJfEy| z@b-E?-vC}h^33Ts&yD#dU27#bIIKS@$xfmN3KGr&S1f4OmCDBWAJ^0ajgN*w^|o3k zwAib7?KfSm9p0k3u{JMH6`ES5eB0uj6F<6k%qS{ht5jd2*eDv@LU5j>QqtO;rlkDY z4W>{#R$ZIiZ`?3G@kMdha5R*9kf;b8<}jtJ3IKRs6T%KhA1U-wboOFtNt^D`1wohU z;hq3-fyS-8WG|V;E;NgSH;r)kq79r!xX<6>_uE^C8yhoo<3m?7Fz(?kv5kt|!h;C+ z2;AQxS^Lby+crzqHjCf`Q^IWn1Q58}Lku2F*0ydtw8VR#zk<-&>hon;5A7tsk~l_m z+5mzs3)#7U3fot<51$^9Y`5|ZHhC;GS3Do|N3rANt~snygwqTX$*Xw*I(loW{yFUx z%!v= z8Oi1TD)gx@7n=1vlJ_S5=uz9!{;bbREmlLpw2wutR4cNh*TLDJ(d50Z;S4eCaydx7 zrn@ni978f;1z9FoG@ug+LyzG2>G}$p9fw&V#Y0x;k!7qd!?^5c!tW=mO#3hTj@y?@ zJ+zQVdjDUg5T^|rpBdI_Q~NGpjupu#sM6FAdK=|TD-sD$o$Td# zrO1SAE7fM3IfK5IU`Qeaev*$p$p){dg>x!%s|iOJs0kePnpK)LO~^?Om_rNGLR^?a zp|r1WZ(jhX2z~?~C5m|d>^Ujl4ear6k?Kto`#F?oe!#s2iW2c%0`;}Cy=SSA2A`hTUKH~iCe?6H zR=6?hd%$l0Ni>sdrws;Ngm4An|MPMFL*`^nRMr21|BW{42-<(6Z4Ri#{{wUbchqv& z|3(plP)+`a_-?_dc>lxp)G*X{)c+H9)ZS+8zzqfjcZ?=Lq2V4_k@EGweF+T3sHT<`r5?R{L} z)8nP=Z1Y|&FL&L4Nz&8PqeT9!oOMaxvkp$s6zV)&zNP+p)aIm&u7dqVdmX%h;2pC! z7pO641nUg#Rm1{NsH&#QS5ob87o>}pwbDYfe6AOVuBeK7zO&)`aWJc{C&Kf_KajORVpi2=pChpHnEhh7vGGG?BcqRO0HTQKT7nL|a)c3cabVDAhjK zkOv-+U2Y>_`G-8ZPSQQDEo4~8;uteBe9(|Lkj8*L=5Gxkr}b+I#=>k{xdE)sNy^s=oeqk=zslE8EZE=z3afYE-%X)7xtu)J;mr{OfEB$+p95afEqQ;> zNJPm20$(VeW(l8&kl-nVOGpyn>x-?wpwG_y*Kt4SwM95xP@L_$dMB($kk7$8S4Jm4 z8;|~xb}9oQp<)G{$x$RoQ#JEapxOA;KH-hQ@uHDw;yHN@WAZBdV6S7 zXKbNP^)~|l2V*`<4)0=5o((1$m)W7Til~NJ(25p`pzp~L4)!pKKjGxkyrk@}>S|)_NZBU(c_Z0Cd)o@fly@#YDVm0)tKLECH&V z@bX5$s-P40qd*3Mq7tLWZaF=3l*oq-903t8z2GlIDh+-_OCn9dVj0*{RTIcpCfla2$IqIuRXY$t7l2)Uvk>%d0$(k#iX zqy0SVap!N2fY9E}6b@7$2B@0L8kKjH=nVPU+#N5tPrve1l)cOc}uCCgo15j1^1N^<&JyH@h-C zZIFyhj`}fM9Em_Vy@V=zl}88vT6Am%(Rp%5@8EhNJNvT3|6l*I6*eE$?|;7*vBju$ z{{>&|3d~;ek^=#q1gH83qvEETm!c8?Y?9fg#aFLw6T-7M(@%b*&V6;^FDKg}e?A{06PBYUtw0jj(Ctau1Prb#--fbF+M2 ztzL+hTU9NA>3-zj-~E^UELsEJwS@trpAn#^%zK@*G_@W%o2QlgE2xSABpJ)zFa_QHJ(VJx=#)5$&16HQ+)A zDw1p0x;x;qqklj#RisJpk2;Q4pQu(l_^jyIvejL6QH{KWRfX9e`<>`Q9`RK*g5C#` zUy26c^yLR0^X%+GO33Nf%`K+|D5tvv7PVDOsO6GSFl8I(7e`}f4Ti2YI;vJ;**%}v z3?Ce7SiRl7pPp-Ti(RW-UAU$jm2R%8E-dNT-pRA|%70g0IBQ`tW*0gqSAvw-bzqD1 z^oO=SQ!SM&AfU6PWz@EcCfXTqPyJEthPawEK-wf{uy#8uSjO9dWB;QENU>ZzQav}# zxPp4~Dz-Nscm^Y9XjERiwcJdjxV@|>Pf<1K@ztXv1M!FjU1+TDm(kT|Bb4sm-lItF z-Ym=5aLRlFVOxpLEl&=5o;lCA$jkKXv~Fp3tk#vPj*+gG%4UC0_Dp8LWj3U4oes8n z**-u29+ce_jwT`;0%4s zZBP6XJ>sqUc$Mi2@d=VsGk}llGTI^3@}GvLjwp1J>pGUfVm=_WDji9HrYEI0a}~1L z*^OG?FQcsoRJ)S^qQtW>X_JVKje<#YMmv@qWPbS_Ybh)YA65PatWV*HXJD9|$Y$)( z4Nl9C)6>dXuyqvRHnT09S^JJN@c!=D@8639Cd9h~rNJKodfS3=(`vI03bB6suy?!V z9N?xks-zX@@ws~|TYl}Hx*$HFhv+B}Yi!Fnlm^g~z5O?U%npz(OA&Buqm)$vi}RV# z)!G>TE?*BWeoh|;Pg+w53ota}>EsD=lCMov@lg3Lu}Vv=7dFoe)(QcXWuNGnF0tqV zGSJf8&3D`oIOz}MhC747Aj{poRMYiaFn z&WxV#>-{w#_mpB3-~m6Iix=VZw!2vC8Y8aK02S7nQ4gA)IzX}eL#Fq?UGS1 ziYaC3-USUXaGZws0p)`%LNJ3Iqnxi$Pgi?`9C$$#V8o6zGymnMl}8EAl$P+Tg)X0Y z>TvP&WgMbM3x}+2>~eI+3yd8#6OF&E^c`l%MVJAwY2iLC9xL9TN0o&Z_Y1n`#Saul z0FKo8<0!BclGqw?=FF||evbR%9A1eA3A`99dLfs(&!Mwxm$d(MvKa(9m-E+bG+OW@ z%_^7RJ$6Ax3*0^2EjlB1p@_9(vx<94o%jaAkC84~ndY8`hRyyJ7SlB-(X%nAF)$7! zo-x(Gn-A2SR*?WXqym0hDdaSUT)W&bw>~=S1!J9n!c3mkOyD8&>bwh3&H|K1?lF80 z6yfrYh;elsI|$Pov*h>j?VFBMoJyG*9XhckNkU3<^yvOex(|`h5Fe;-I|`=KWJx)E z5b}jX;g8Yod)C_Du1&qbgubF%en@ahZMh);`nAC?&4cP&y_aMJEEZdw95`+UZ(a_X zPsqW+shX$L8Lg~c^qFg^SGVAC?S0?FG`mWr=T=KaeZ+Bn<}Yb_<&t@05w$^cJi3nr zku|Iqpr@*;sD$w?}kJ}$4Cb}H({ku~8Lr+H_1DyX>t z`9Ja^uScyiFI5w^=1xWS8!tvnEr@48IEj0F+I|pTP@wL6_dk#XzDt;J98C=~DwA3X zYU6|QM58094lG};LgZvn+nLd=fV!R9n^j0YJJvH&F}uaXI8l#F={sYj1fvupr@Ypm zgy9s~IOA7%n_(QF!wrEC-D7=_lFmaw+_AHJj@#EQ&H?%jVzl34fMU^J4oAeLR>fs| zJtSz%an7>?_0Z02Z&de4TZXNcuPsh%^**paq$wrr5eJWYTi)5;#DVKh=&hZJF9(_< zpN8}L??zsYr{8;CcU`>q71ZK+w^BSFjQDAK;|bv*8pPGVdY#K|jweAI#n#yHOv;U+JanezU*>7z{Av7rxf85Im8PDZh=ZKsqu4%~yKm_G8{s4`(zGGUj)o}uSJ!UObS>oPpo zyEW)ofixU;xpgTp6<{PUJ$lkEUu zyq(4EH$siohZ4kW8bc0dKU~?R#W5tqT6#4OvgoB6P7AR*Hzov}|h z5FftL+?%ilHWF`FX4UOEuEr~x2-~0dwFA*0V;YpAd+AAAc_IChZder zELQ#Bz?$A;2;E9ME7q1S$$zx2ZLo+^*ruM}1w@L#FV;9nm%J=oFJN7Px_aX&QPk-X z*1}}1huj<#Xq;h1&7aG#M(yTh|0>6_cs~1NsLNbRhMvF&=npUe=2VpkY5lQ@gJsJP zoeez0b~FA75XdhKSUzLRYT3~XoB}r*oq2a36Q=~j2zc~>)^(32VT~Pes4)9jj^Zk7 z8RrD=N{g~#ThvOfiVqo9IuF@FNi8gS`GJ1J>f)TRl4bMNN=58dT^;Vw)6Nwl@N1=T zG<$O99by*RfS`>63cw_eq(YG5jbybzVFGz&Nr9nF?^kS5Mrn+E*8Htnr{fJ8)xD(z zddZs6t@~#q!3~$FZ&3xs(j%F40S+rf1QTUZ$uqdUd=zJET4!s?6$I_Nd?NLPD)KXh8=&?^Ft$MM};%6NN< zln1(dbei-5Xyza!6i#KnXQg}eZM<#GDi9Z_2fQ06qx=;!Hs?zu5GEu=q*KbZ2;{cr z%iyioN3J|!CIJ87$Z3hfpQ4HBf^ObnVQ=EjaP`;5d`b{%WF}d-3qB@fmTvwF9Z;y2iF%YjD+cU) z8M8+U_19wXKr_XO4vciK7x()N;pguDZBcKYp4d>_7 zgxb{zIaU^FqBbY!{FT^;Dy;YP&p`H89LHXxf! zbO>5RU-*5H_}3?R%*<<`?VkzbsSy5@Nlj$|;U^FDQ;+7Ai#G;d(7{|a)3#z=e4B+U zLd+o-KiweIU$8F!<&i_n?gUDaV@=u}vLV+PP7au&6tqafPPE0hwQLCkh}?euxemaxu$%K*|C-Nws|Ma$ zFj9_Zg=Q;;l&hJ0V%g+$(_qbD;Y61#@tE8{4A$UL&;F8QQ6B6>awc^7EwYK9;A1EC zJ!>$X4q^l(&$RZ)>a(Vj77B)vCv;5!;ME_Zh^r?+dnd!ioA-0_W^?164)7da?kzYl z&yTAOE16gi>g#;yD7JMx-g|ufiV!kf;eo-Iq-BJoy9Ys~>G#^yUjZY-yQhZG#LoJ~ zRp&#Uw;pm+CKTR@wtIwL20SY(jeqS3AR+XI zpf~~TDrAI`URvBN8FM>U6&SOs>JuK1Y!Q@#O?C-wNFwhC`Z+k7sO+FCN`WITH?Gcd z_=oib#U@f_jF$PP54dS@J^v?`FmK$Y?FSzR-}Gp>?`EM9FZM;ivo`%zlkKY8yuD)9 zSUCd(TpeWR61;IO1uAWM#4OYSplg6~Ck?m=x#c7{o1I~-O-XzY9F8gp{eCKw$C#Wi zH?A#Ok2GNG8{KxY2j94>E{PH?@!-e8g7Y8ph~}Fv+ME_!9)Ek`A)YcFD$-5li37$? zd@sSZ%XT2IR?XnRU2C~;mqdn4KvK*9QyD1W>MRJJmFd=(w( z|BOi{Kk@A-;?;DPv%N>HB^i~xZm2z(zI(xdJPaq02BXJOG*P6}nDIOD}B` z*d<(s8X8GyC#b7$Bw=Vg2pQ}q*Lq^=1Flg^$XoTbD_`Fhp_bOAkF*)Vk;Nr!8ILv3 z&y5!IHx4zb&mXdPNb-dSl(_tfd4q7jIxLls&3Qk%eE)#1_7OBOtNh#~xbmd#Lqc;!_PxIkhm8%davPl3!8Qo<@LOX`% z<_>33|6NU~k;k()rHr8*;G8?Gc_OMzM@~=%4zm!fFuf2?t6`J_D7!ZHpp|9ri;|3e=)6Z0!lyAt?Uw<`mn%CBdZZKtFF$_A zxgOHUJek$HJqv9Ih_SO1B1&heiCz^>%gDc|QeQgZi*1a7%Pqos(FAazj@S4L4BbEO z1D1Ma{Oz0w&z0hp?sbQ4A8^8I868n|2}kXJ22RPu#4ulS|=bhmKvGL zDI}%$TfrvWp_*8t6$}%%+zQCl4T-Z>$EJ1aY}237+#~Y<=!ZGeZy3j|$ZCq~Z~IjQ zeRoo(>?P#b(Vkg|xdywf$73KdVmBibQ%6UW%;-~#)EcEAWg0tH(7=ppyK=9hJwCxa zHI~x|WfSlAa;Wq-JesSO?;-5%7OcEq!3mg=5oN7t&~cL+=Fl}~-Y-T1vq(P`aMq!+ zdDswtHC$T*!jpN%|6;8b2iT}}K}06oSQIr3%H!PXYL6mC-s~KP0K_;NHJu|dkQT@Y z8T5`^iQUG`f{dN~+uh0P$V!TYa>_~Yhl$Ox=FQ|c=Y1)lUj*m6ZQP+BvZ6uPd@sL# zv7}ZIn`&d#>~rEWpT+V9>%gqNDx2sq>b$o5y!oH!(Z-@)TGns1hWmHEG{jd^T2f zS-+InRNa7l&U0`(N?!v-!HyEIeKT*bA7mczKR*<@XdWwB-57gVfktcKXU?cX@2(ZV zt7RCdD7YxUqFJf=X&#}We43>umjGvh$ZxxQ@7|I-bsl^RkW|ynXEAYm8Qai$6OY%3 zOlY#t%)jD6mU#W<1Z=xJK4^`gz#?X$`nPJ z3|n}6csB`rAoOwU(=6M;ar2MxZrNrGRGu=jVRTMRc_xoyh=ASx1lqU0Dnt>C*+edr=}BES9c4y+$GKv$-B+KjjIV{^WI zzl2;zHp+fepJt(&Wowjrla?AYD-V%=^TZT{j17f{J|91Beb?7=e8u0|LhivBL7nhkl%P|#-%Sm z^GA_rW`JB>U4=|SIk$vuRFv>hoQw5mqME-E8S0?WHBQHW@`DhaVmZ)EfE-NeRfw8i zN*NwPlEIFZ{`~+PGcfcX1A{l!<;0<|f&?6j4lGC^59G$$0|i<2iA?^%!i!8GRk=fA zVqE659#;!JzGsQ7rqU}8K*d4h=XFeRBOka#!X(a~2g+}9<&bbE6WS>{z&D-LK6MWt zYzC>Bga+Xy^4oUB8dkv~pHCJBV4jlb#S)JH2HSVE>hbzMST>hggCmJ0+D>$@a{vTS z=Wqa{iF86n^8B(29c7)*D5m8!B<(abjeVMn3IGb(GuTw6PT&a!{2UG$%#7jN&m7*& zcfyMo4l1VdQANzCoEx4u&Y$_ZLUC4nTp=}3bHL)vEjvZ@H~d}5Q$|JPmUKz%hVSZL zk=;{DfRMqw#A;=Pj?MN`>WakvqAzK`48NPq9P%afsy}i^Xniloaw~fKO}t-k==Z(s zcyAE3ENxGBwO^NOkOy_+D5BO+M&DB}L~ZB!6Hi+m-5M|a z#Z(lF+Z7T475QAKnjeLl*!LP>%qfxjHFbKPBJiu(YXKYVdG8rQ>_Owfo1s9VX+`7IF0Jo*o7B~pHjuu>fau?VR zPk~4xvM2*)ijwP zj0hCjIJI~APw;@SSL|#Q+M5P>YFTn1>H+$2Dsvc_02`wvjjz_DE}{k1R%C*53bq4M z1&YLgmImn#_?&713yyiUPmSM|61lV*kb>@z9ZgfiTF0yMf1PQWPJCt?D}H+({(ZWw zV)fZm>HYi)bu(d^Si-X!;pULC@7v$VIBY`l=IwO}OT3i>bO4QhW&A{33y3|8Ur3DF zj890q;d0IzBsAtuiva#5*`?j5^DMy0Pwq3H67PWnh%b-4-%CS7caSnMQ+XQeVT5VY z0R~wsS#l5Dfe(3N>>3osIa|0Bcz1zQ`Rz6*WuHkh^fTape@onFXiKnO_3Uc`1L0G0 zXLp5u<}hKS9%!jlzG-Zdn0oo!dDGcKS?aWg>gWP=1_FOykx7SX&RpG4!TjjgU+);x zh@9Daz}HZ`%ROP7l(NOqfL#^l~3f)!mu6awA7pt*Gy4&IR{&K6~jD0y&CRczeTEy zhd9a)BPpl!pmMM_PBVvqKgdi~eU0fqU=M>rLBjMd`; z1J-S*`uu3_XWdaZ@#u)z*KhE~(UFu6L+;YKh2PmVX~+n!MClb0HGs2ITQAX(kes{O zJft6`!-Bk12qDLT?SVt!pI&rPm)6olwvolxWMLi?_61C71*?mfxwR)*aJ(4tW=ZV; z0E`roWq_2EMx8O|eGmVDo=K#mK;r84ZZ-yaUIlWdI3{nF~eF}xjmzi}+6 z63|${A?W9AkZ`k+&(hEYJP;$$ffqs0#-MF+%$tVD{qS{Dw9JUgxDh-Ie+jc9dd{}S z!Ka%3uHS+yl`l_)oJ$^5JfID7TNPCS7;B^S>#1g91{OHXabZi5T$-Zk0z-JkQwWlR zYAo%Pd%w{l3Sm$4YmO}SdEL%+JG3$5=w5@j6x7?$R7mZe1*bE&7H70ur49JBo_Y>( zgm*e3S@(`^Zyqw;hhkZUu?qrE+KfUDWFQP+AyCm+<4E(A4yF+90} zl*1=a9K2EEQ)eob5nO;3g14LiU>YxfSB(^~)YPWU&NuRA#l*-5uIT+E_SDOdJH$`v zVkE0c#@!)QFhoc$D{KFnDy}YbUuJhdzJG5eh&_Cw-6636l{97y9sg;D$uNAF#ZJhQ zy^YtP04>oAKAV4&Nt|K*#eW!7Lf>PI#{yrXV(%P2gzN2=BU>8sePARG2wh8`3oiCe zN_Uj%?sL<1O#JKKg>Z8C47(7__WqCnCq8)9II-mbP7O2BlI?3>h%g|~3Tsyx$pu7< zYwM-JT3M|I8%fAxLj&ZdrYeewch-AvL#Vvb6bu z1*|Ap?62P!o{D(0%{_1)e;qz&2q0_$00=1r-=X`#d|cD#H!xuFj<$0#BYiKo4hbw= z&TmyTk^#yt&p(;Zw{;pGwdQ@1CLHw`%&G4q81fHLi5?cr8X+M7lD&}ZU-CJ8jV4st zpZ?Qi0s#K%p+BErn~F2NSo=@A0V45EUE@|W%<^34#5ZbhTDF`K1PeBjpil8uZlf-U z`Ax4p$JNpyF2z==XlS&}BYw;V955oPzLY5VJWA9u3+P-O0p1T_OH))I^(C;%3GkMw zH4!w&C#9I6e>^h)Cgh}6Y%vG!=D42^ItX)=T^ZhYXa*#9r*d~*hp^ioA#eC-GS;gq z1wy9Dk_zvT)ztSjYIYR53O52j-zSIt#f6|}7#JjnN|L9N6tnTF+2>r=;>44%;h5xY zh45nolzT{xq!deYUq=w)p~dQ#-F8}Y`pnnb#Y02jmvch^V)(S$jn-c91$M&4U%@}L z;Oh8pU**r|9()~s%9$MSA^xXaKbaZ4=~xWG->iYy*?aaMqtVdaaWw3EY-l~m2jYL} zP)`^3afhmeN43DNLkv8g3aK~9^+iuW#6=%agsm;3Z~T)1(`Z->*R*{}znr30$n14S z($J1weM-gvMW@`J3Cd(mMTjXsW7CePX1^sN-S`jk6=Fu7tlaQ&#?GovehXEd@mPX!CBe^F) z>cVS{4BfoUBv5z#8ihgh56qMukzY7(6(o94avQsVKbo*+3i+jwT*l7QY5sD*SRMY* zdbm3x2}BJ9!8V2xWW@YI_9p?$s+kmabmOt_oD%t@oSt&a8KX&G3=X!bPMG|>v+&$o z5#W(#d&11L@j3_!oDK+>K8j@Nl|yZMtTAcwm3Y`8P5E$)g;)f204s5wOaNAy@JmQ( z*xF|UlpT<4?_U++b~PmeyKP|I6Mk9C$z$hyAEI^j5Qa)F=|2>_Ci1!k-n_e{YYB|< z1344E{k>fp%KKdGdYK~|=Ra$T$U5IH%DjY~>K~*#&xN$RtJ>D;Lg0*h0 zBD8v$fv8*G0oM8J)UY{NR8C*rZw&ZbO}|Yvnsg8^S8t1g-PS9v8_gEN- zZkvmCC$P=M+$=?G*mUS{Uzm&1ttd^{C@Z6aK-CtP_0tbfj z51iWw$Er7QBl$kpI;{Ftp#OxG#Fd>B zj5RQjWfg<>z+v@ee-3}kG!idPv}$s#;yWHuIQtUGo5}V%jk={J=qE}WvLZACz;a>T zln-xFJ^J`D$Ov1=9zasayANEQFVcCfJ5F@}-G8%X0@5Eh+$_p7rx{U0&4t_SU-!D7 z9csiV>c3M8z-l+szv(LJ5zqdTucx8h^Oor}aSye3wutnq1q(%QTBj?n^^jrC zjRnQO1;GDqh*ly9Gd3<-RsVJe5VyJqbMzlniL|EnFc5`Nx>&TFyZzY`s|&df7K@$a zvLA_9@0YadQ6CKTb?C?8Ll`qO$O1nDe(EaD`9}2;=|1#F2=SEd-5*p-sDS|=F&S=` zLdfY(Lp5K;fZLZPm+$p>h@J+bR0-@&jHndKZEOsq@+yiyo%o?5cKewCm}uw>wq(osGaMU?kPk%0J9hGT7Deke#-sz_44cj+3K4vUV4Z><+K!gmydV4!n*5P~R|%82hU`S|!50 zFw_?E1a3I(kYv<9`*&lRtT#xWGfPsF+_j~(2Y>gz{%pcAqTiOe>R`~f4i;x9vNED~ z^xunrc`5lwl`a2`WhcsoX(Ra)xarKCIA?KlO0@Q^J-|O?yO}k*b^cJ2LVR}=ae9CI zu5aSr`QGQMbYGeXaI*_v^?jaR)Egvq1tW0q^dHGKGYvZ?zWWXGdjB-t-x$sT#0Kx| zYX8I%+!&cPfYc@l4B>RA6^V56D+&FN_*_;eDy*O)R-TU4`dq+DNPvSs=5ykoCHD?^ ztJpkA$1SEz!cyTW%CGM&B>#HfBf?ArP{Xv_WuRYhAv!yhF(w=D5>RA`+Ph66ju?xzrykq$Ovq z$Hu_MEI^andHbZlDlx0>v8v#H!Qb514JT}Ca@&k!Y)fY|I2=`o;MQXcNA}F~TTs{? zLZDED$iIZ*fWe>_`o@UXIposO>X0Pv52{nG0L3q@)@HSv1GtO%!e=I7*tcLBwzHKn z;v|JBqZ=yKM=`emv?nVdU{pg1#c0DBzO)-e)y_@s588fdBj}Ow=Qp=<+qJi@BhEle zJ`&bmpP=zGodbG4!PVIkJMj+p)EZ~QMPA(gt*xyWfc4^|_L!$&TB-e60zLRx0iAiq zbk?sO@9Ox`Aa;@A8R;2{>t0Tf86vL0yVD$82Fx`2m^zKb6R3spgGHp>lKQSP>Kf!e zB5Q*KdJh|A!|86*a+CQl-WBPxrBpFjlfoFz(+)28m#fQNJf8g|c6U(SkB}F(wK3Jdqe=_WEbukxU>CG)ySi?(c-xcAgfMCk$Ute#&P)gQv-RL| zaPTZf;x(2meZJuCy*4gF={t{wHm(-xDCsAvsXngcMm=BIeh1_aka22azG}~ zn@iol9nR0upTv;au)TXMlg<=yMDWZjO}aU3UQ>1$(8LstJue`PYgy5o$M|k$?L6=4 zZPIhV+n`xJX_9HxTt1O$U2X+Pu3)~&n~2PP zDo~UyU$KbSwM@p4Zk|`oUXHGCS?sHu^HofCu?bZk6xGl*>maCXvZ)z?dPDWbCu6C! z?xv~~OKyHwvAZ56*ShRhRjpb6ZNuWLypvfxlbNK)Fu@a=-j8Rscwp1Kl&sq`fiX?M zE@kij=;<22vThg>Yw7|}mW&i_-zkc=7<`;*jI5uySU3H2uG*mfDW8J*sFSSJj9rdB zHwC?HK{Bs~7_yh|C*=R4sy1CSZwcazPX4>3a$b-w8LOc@lQ*oM4YLz-_TIZ!*jz*3 zY{8Kb?R4gpEb)so!#y-bBYj5bv zkquIA$-d}jCqFw27WB7iF4M0rYT>cri;1qK)H7XGz~jtE3Fyq)qor-((zz<8X5&DU zAr^KAepFQzggh1?l?IsaTG&~P-$zXI>NMY&h`*(*ewI|cESRx(8Il>0o^%FHtD^&O z@B`e&W?w$kW*bL%71=yj)YjE?E=)@zGpnd0)32a?)z3-{SMVx7Dy$!muM9gSFE`jo z_1BW#Qqy3t9O3Tl8bLHuC$Do_tC}pV^mB`~uzc1xy@~*8Cg5AicJVkG`KcE$uJ9lW zxojqMyYy-~R3f{ywPS&CKp@i{ zy^`r__CT#|(0CcuJJg%duiU&dE2R6p{Dt!8FO3d?0lgO>-i*_>LTu>HZr;4WD>vjaVdSC{?mMtZqgNns7$8uDbWcOO zp+WyRpJD?WDQ1ov#UO(wS8icQ+tsDS7?n6$ER zwl;wLLhR4FCHL<^gUbA1Sww^AI+w^`0#_({vl*!Su1e)l8ySiVMo%mfta}V-<=Ewr zc!5|mPMl`}i4AyyZ@aYiANJZiWG4FWCn`eeJE&m zBaS0d!G2pHuupYAgkvIFQU$`i{?TsUSc3gef!}k$HV)*Y&4RtW-M1;ww*qi+dlYfa z9h8Ec4P3Z4dcb8+`U6g+;K+YzolNw`*()3wh}@VGp%{O9C;Wp~CZV-GUz9?i?t3m2+oW zZsCx--1m_Bn>vQBCEh+Mp*sy@`LKeppHD}xl-1xgcp*`4nPRIYM9Ye%t0ZZ%T&o|^ z3GSXp5`q1Wl!>VDfGI=eO$?yD2hITp%%Ec3{JetRQ>S6+?^|)9Zflilhc|=K5HQ4L zN)_6`s&@Eh{r7=YpodstZT0t8kn_6ql1E-Zf^Q5;3O5D}?9{7NS2rj{nU?Higj6QU zI;MGX)WYxwI-70n(-<3pkloHOFyh;~OB}@o4m6EOA$?GJ+A%1#q&e!A^D6-OGHxpo z_TS=Ki{(WEgz5p~B9~*6lh(i(!k}U(wus5}b_)f-PUY5Ch(yj>eKIW712e!ZAPJ(3 ziv5Mz$?AGkN}zIgxN(I9ZA)b|whKcu&*Z>|!+p76rNQ{t6Y!#_Ka7kF5QKp*u}g}u z5z_O1YklR-!ziLqF!Plq>sS<%$Up)0U~plYB`A5wM16#3_8RwKD*Y{rp55aWaFo?7 zIN1{W9o?zFS5T>;{&j_r;}SW`5h39$8DY4>uOgzm^UrzJ0$VhAUp*xelhEW+mse2f0a;R0UyOhB zH242`Su+5Gj^q$d&~D+_vu&H2#{4yP0_v}+$t2OSdhRTT?BmOM+JEk{{D${w@kbvF zQTHom0hT3)q>}2i{sI5K1f#4?a4}qH5Cql^C_VueZmg1i9!LQ_Vj%^|$0WY-)jw0dQ6!WTqzKd_*(ZdFN z)j!XGB44wTASq&mHRXq%;6(e#su2|!3pDI{$*)jeMeRS18XXKMnqlfA#tI=1c_Ojb z5#{oFQ8S8nAAQk-N7~J5-648Qglz^&fQSgQ<48g$JxG%fTYF>#1GLyA>OqnPFPN{Z z7>$2>FP&Sg6nCt_dOZruE1OV6NB!#%vJ^qM0Kupk29ci6O@x~^1seWsd!4VUodvaU zB-avk)lf~T+N;{n3w`X=&>n7}B?3Pa+;_}M0u3nGYN4>ZrqX@;$rYTn(r2$OWhrOk z{Ab~nPO>tRP1ecJ2EZ$&q#Lo!r#Uy+s(7%;v=FFRcQuWw?ZxO_hGV}q`4+|5E2f`Q z2w)uyVS~3E@^{c6UjZ8JrFnuW)Qt-3S@A5KQ|Kg*M$%2TkJ@Y@lFFwtqLkkoqq zre(*bRBlvF)~!(tegtEtu=k(ZB5(Lp0;h<#+iNYsk*f*PpQ1EJY=mT>-!uX z;V$MYD!=a6NUw>6UQ8yIRiV7uT4_E~sL`ATsf**G5UZ&<9fc@qx;Acy%lA*#-V_tg1?2Gd?ug7=L3Sj#%l9ojll-L1>>13V4;jSIXST& z6T--EYWDpu?D#WG3NSJS>^U>wP-61o1YA=j5sPw2Nu!#4FX^7)jrnK3rF}BN+A@6M zaooi@sc7+LyGF?HqVgU@zlgn(d{L*Hst?>SKoSneoRT0hhPj0$Xs!lv;D{9itT?e%3TM5Mi;stT1 zSR2~3P($zXzwh2|#vRu!Pk|VDFQ7B&%K%L0R6)_gzZwP^g6LOJ8F9-9KlbpA^D;bt zZ-dibcX*s2r#hBT6P!Pj-Km~MbAZ|f@X`Ij%Hj+*4oZH9UF`$oZN` zGj)R}M9Aay|E3csHX4HEL6%ptC~Huew}eA2U0Q~jVumbX!f2LJwnzGxZ7RaI#aZ1C*r@+^=i1V9pw2VXi5pRENuO zprv4!L@S#JtZp7R_V^}E7>XW`?XM!pWB3tIHbv%I4aEFWY#mAx4byY>Xu?k2Y$b=4CyB)_~>8T z%L&Kqm^wPXp=DGs4)CoOyKM9-1{GdNIuo^$bq^?NWqHV#JB)=lK^(J@C)MPKYn`Yv1?ENFUN+!4ROuC5N8OKOC@K*2q}2V7VxE zjIehpGvgHA+v|9(L;+UzP?kh9id?{)d+y8aXWhBX`R$i@G5Cp%QT3~LbSydXlJ499 zhM=nOqSl}SAf%#FFw-+`b z20yTf#GKqXoZ84MPY>X%8^L!Im*qJPbYm|_D>0+Y`A%NexPr9CFAB(W3}6j4To|O?E}nqZEr|7R*GNAk}fM$6F!nT*_T%(J5Ow00%Eje<6*1sTa=t-PM)28ToH)KS zJ+l-SvZrCu5yz}9k$#ZbM^IbkH#>P(Vv6d(n(T3h;GKMPSFWo%Y*C{uASQmaYuu8y ziz8)DE9mR6`PayXq6-jwi}?zim7L>zZPVX0R*Big;bO$NLTLnFSb62oF@!#;YPk4r zZe;y_+q4YK?R-ElgyFA@CSXVUoL>$WH}X5*qxqR)5x?9gDU=+T#oeo4XPC##TA5g>^{T$v;6N+o*eXRMx3bQOXl!w5PPJ$6V zEK|m5K#09NT@K^60+Zvp7mDN}DsQ%cTH*&PE>N#C?LvHJCvhSP){yrz_ugjzbbM1Y zuh9cOyuAsO+Ygc=ocA{8z!N1wG2+3a8NZssBZJ_`Hx?Zf^?_h|`F5IQOKD%kCt}0cO0ME}$SoH}n`fX`ukiZAO zU1^U795yyy%rY#54`p~goU=ms@AX4_f{R>gLgTK<6lf#sl~tFpOOt}=`DB2KJE5mF z9H@7svq;aVXk_H?dV_9HqbT^IMHF9^Xo+0od2@WyKHz*zbA`P=Of4Z?7=6u?>o$ss zT7KV$*Sk?n-uI0tms={7x5`BA3Yr`|W*HBJ)dd372E@}H10GyrU__p5BM3vjY@@L) zWgjAE?A%pjq63MP!Pj~yjZc8&c-bRe?L51mvBf}t<_&0y%c4P*!7XbS#ci@0<|l)Y zt*XAS>%1?=->90*Dap8a-k6Sh@{3GiEx}yzTICd6(<}kuNdF5*SmPQ<+lsv1`Wj8v_we6!m(q<_&6n z(u*6WkVOkXuVsWR5Q>9@s(S-iI!78jU|PRgpm2<-dkZnJ6h^SXcND9iWX91EjSX&$ zVsdWISDaHKw~<(N#f?GFS8z3(ch)+?_R(8(`I+mwr4dJ)7-Hnc5DbveM3Y7AcC#id zP?q21)}=1i)jO+}aAjh=&6ZS7lY~&0?k3TDxW@g5oBA)F)A6|O+PuWPC=JPo22_7~i&6um8q&l*QbY7$@}jEOu5n`A7lu4i){ zZ92x;Y=P&wvwB}`NBe$EQmT9^nu~n*{Z-H*S`Y&`OcGk=3^vm4jxZtK8$ zT_cwF^XP$U_Q)(y-#dxx{@`F_aX|hn%4WuEU^3(=SpHAo)(K$gFM>pu&I`wL3S_KW zw!9CMq3xGkFN`*zscJ;i51(9+CGGQ*=F;>tMwmByXuPqazjY{utBRy`dQiAN@d|54llK^UtYnu? zmGLjip-`%Q&LtEbtF(y|dK$<6Vlye}&d*j?J#GV_#J}X7b1;#5DA^p@%>uza!yYL! z_`5pp5Ie3253ISuQQ3k!;YN_`{(Oi;N6~B|L}(U-9v?sw_XGOX{@$| zH1$;oHN$sN3sKyJ{NrhCV?qMQj58;m7uM=BZ_h!MImk&F!|^1JU{K_&ys`2~ZyTUp z>KAV?xFWD*W@K=Xe)~IvXknY>&(QJt8-%PP^SaB8Pz(1mg$Gzlia=7_GZYSM0x-tYVE`}zHu&s~;UxtPuLZDM`pQ^Qv17KA zQtsIZ!NrYA8CubZU3;OVY)QN5cn?;c*_tCPX0dU!tVjDzSWwO?#6KW1a>|%Tpx5wn z3>{A_1wk^Ul)npB-(IF6xyUmR`P)H_nZA2w<(SMc%QSRH-hy4eXB&#-efJETsCj~k zzX3Vd1bde&@M1jQacWa1ptdA&C^FrC1l@Tve^9|FB$ow%(sRrwG&c^-Ixl17BuWL? zItz0ipk-=Q#`^=H`^ydKoCgTHCmIM|b|Y*GA|aqkS<@nF4ciGPbW+oGH{G*?0+_lD zF3urft+AVPNs*rCVUm#akzTCII}_zN zL-2e3I-u4W_Rwqy2qIJ5n($)I4g0LU#UQ0@5Ys%pNCXw2dqs2)afe3OebH{$E+=B; zL1<;yjyG-<;}Q}~t(61dNNe8kE(*AG>H2AH;4B6SpSbw@huYFHep1;U{FEB=-GDBm z*8-R@{%KBmG0%Ccz_YadnSz?o7~ADCnum4y2X)vILx#9F!Dv2!-*Hz?NTanAhg(>| zJ$=i>I3jw`u;c6;amJl5sbJ*yr02jG8sEh*HduAf!rs!8GdQYO#b~vOO72Jstb->f zh`S{xr#H@trn7&kQrQRE$p_kT9KhO4m8!V(*>bL{#UhE&^x)}qS}#{Ch0`hd`H^%g zre#ro>JcF|WohQ0;6jZenHS3kXV+jy`^@yW=yJ8&?@Z@k%E5dlQ&j7TMiGCUN3wc? zWs~I0RvO|?<@g&Qqf2kDA9F>9l~H)+j_}~PknUj0b?X}lM3tSGB9BUJegGW~qAq_E zv>NO8CDz*8eQTnhygeR}26^Q?B4G-zF6w!Hx1if*vd;Tcvt3T$xKsCc{od}AG5h+v z0!SQ}ThvLUf$41>Lv(H&@nvYvp1GT5^h@t5)nHp?4Dw-2EfX1I&JD+pmXQX_xS`g^ zKUg-(FE#lBNAvu+{yeUyae|y}B&sF3Vg@@yuo%%Xw5>wEoKjhq^V0LHWFwPQr5T^Zc?vTjZ zDci`h4&XJ^?U{I4?YJb7=LF7nT4QK=jXyk&jbmOdMqH~AVyw1w)qqTnIi*D2S`*44 z;3z(s9$`S9pP_)Y-2$M(d2}kXi(1QYP3v-|GTi!i76FSn{B0s-&r3j{6;R%3^E^}a z&NODq3>*)&g{|@yPbz4mh7#~#eEHorJi4N%G<=`W#2BOe6CNy(POsEUH~C0nU!5#O zxwv7kJDk)ZVkYKMDDI)7)IGY1$+&`dUs?`fSn?AD&!Acm4FR}rRby#}4MY zf{+gM+7^U(^VrP!2F7Qme>rnHflD~;wYH0%?bTTrE#s86*Rrp*(Oaf4Bf7-TI4DQs zRC|TU9>6;U_5tvwxe4-G6WrydZ<5QFk<;uKLf_)Q`XUST0KUy0YxCzKJtHUmI#ZC^NOECkIbf1Jsg?3;<|Kh7?&7{q| zsj%@ULIWi_k4RRJ&-ap+l{mjGkvNrIGaOg-Z? zBZlx1#xi|NY>X$YtW~ck-loUxP#z^W|A)T?v6IuC0g24fIt2aXJ zMUR9Z_XZ|z2|6!_@eJxHBq1m4ne;3BdL;RTQZ^H{*hcoMGz$V{ZLm z=r&96UIC=8qOOJayerhk(FA|$JJP4O_;gib4fhI zQMXmvZ(O^>-;2I{T}v@nK26~Cd+F1`jrKJuFad^3N9*4(B46ZYE&Z{+D|bOG^L8-A zmeDPt31;1ep!ea}x_1oc6p5KMlLdQUYV{r%&+gZNKw^NIQxzilCl?T6*&BU8@5L%N zdl?uJzrB92Ck8box*EULA8!{jHvL%pWPegk(GT!d&0HT1vM+*LvBI;a`#jf+>$@3> zOHjnW-08kosCa`(NN$-Dl=%;|=L+-aW?= z!-A`$whQ{vqES$T1g>3C4oO2z2bd-&vNcEzt>Z(`FvTD8i*?aPtDk$y5i@&;AXt3M z(gpY=BUsOkBb#zCZDG6{jYI#aNgCNw-zac+57|x@lH-#cJc(Xvso34@z`z%Z56HM6Qy1_)VfN2+xwUkW znHL(zDH?|R^c}VQK9*lm_rrl{#yN=uM{OqB1pMWlsE}!O12saTjCG&+8<9@l3&X@K z_`~xTW!V74nU1&CQ*I(T*UVe;G#_D%qdChK-Z_sWaVW76^= z5>VNSyA8Y)Dv4LMY_wf6$VND+yRCeJIy(=i^+#h_w7F;D0HRmvz@ox72JQ$!8_*jcoy9M zTDxmk&W67ElaI#1-lIN=?+|6zW<50s_MR=ZYaoZ{S12Nr(Refd$wlOu-B?A%)y{Ma?D)QwLcfe&csb z-BF;-yN3#9)pj+`IJEq(t?V!}cVBx;nO~+M|8-Ae>KUm_kA&+gO>RYL2m4$i1E8># z14p~yVp?}!^vEI(hZv7vA5T49ZGb#^SywBYC+IcrCJG;2Kw2dJ>*MNSBaOJE@P76u zQUX9y(&1Z$YswKC+TkI@3&b|i4$XXq14LGBn_G)QJe1pzrnRtQW_9j?jqM_7CR>nS z()-E8Mb2W{nMmCHn)9Bnva&CbTEAkK{V6Wo$ax=`nURK;7}90y7SM+MoM~G;2e}f*uciv}O3v>OKGqZ} zWp@H?QYN&hoQq6Wk@Q$s`Ay7e9j$kVn+uRG?R9yt%dUqnF)`5R&SDvf@d#Wmojf<5S zGDlXk+<31w2CB5C_x{k8y=|KRKCWtOsaJlz(-8Qt+fd%F@Td*2IVD_4xx!DHK#G6a zTF~g#de}H^($;KHO%lqTSE1TFyqBT){Bw>3wGO&f!Iinr8;=UDm z^Y_)ZG_0k5L;$Zd3}1Ok!X`F%zFEb8L2LM4nw>0iVJ&$|MropT9-V0~ErOv4U}$lF z39P7w$Sb)Q^R$nBtdi%Rvq%S3l#oKnE34gXT6G9siY|VRL0N(dSV4q}vd=%;FpI!z zQk6x3;UHIS=rz32#`-fr91XIuB0U&lUiovS!}S{opLq>vbdDT-+s-zR@bruMI8`lcbheDpkm+Ho~v(dH3(Brl~%)=IMsmH-=(LkFLY zythM}Y>35mJavBRxv*`vA z8M@C+-{?H7!7%b8lw<`Z=x`r0TeD(kGjWaC2QecM*pvyB?keBwxfip>&2i zi6b|bmo61%3{57d6+~iB1hNWXxpjrd*;5yEWaw2~>Z%rllFjBf=n=%m5 zC>xJg#OiVTKx8E$1M9ChlB{@K-tCRWuY7a)3L;4T#Y71g)7!m8zRAgVhE@^wc`tJ08HI@NS*6Y+TD&hbX* z)ew|!T6yCDq10Qej9GIcSAO6yOumK^mY@X37Ry_&H5a7!23S2eNt}H0j zpBTkgGa&0W=!&_jb+mF9IErFbgi%5xM^i+=pP`iBGOaqIYiRUbkrP-YOl3-|fI#l~ zG7i})W86~Pjs*!R#w;%?_ryXO3#;#8rnzqHaz}idr`TCvai!8OFQBedU+u($9^eA- z1*V@#h{D3jWFXn%XSP-#+3kOR^YyE0mM%{}!fPoDOvWnoEIW@suR$N^WsUt;g|TG- zy)5|{1y{hH&O65OUNWK*Uy>*{Y2abg-?icZ3vm%% zVe^CFzho{trod<)ySg_Wu|ZZM!X-!8sPvJ>P-D?Hf)CT0(dWanryZ&HHWt%wo$0@g z5#n?#87BU)#d)sPGX)B$ADljo#K!TbWXqKKzJ1(9nu11DGhMhT>u@l96o#^7K+AT` z|ATq7q3w;PCXz7i+m0IOwStI=wEtR)C6ZB1g^sZ^Yp+u9Xcv=eW-W8KK{$DNN+_3A zt>VE4FaFLqyZ!_2o+{B*7z3^+ipij4dpCZsKwC?yRs8ZICi zLwFP#8}7!@+JV)9{IuuCnA{dQOVA=EG_C3GneN8W0i<07P(GCdUoru=C)`L+KOgW< zS&C#xmX;w&B56CZXJeB2l{E3xeWq z+4G)}&tlWD+!5Dk#S)#?BRP z!4uo6*+7H_(i?kgd4;%kV%iz+OtXDSOfBQ-LSl}=n}Y>B(Z2;tGnXt7O!pib81pdt zAOl70?VJtFt`{h_vm?Cc?hOSkV#OXA9aYgJr&)lX<_niz5tJZ>OljUvWaJdP>Br2L za>S-a)XS@!)UBE^1O(f%{fhqiGQ{IBt~h;SsQR}~OFSplV$b+Ifze}dXEbNJ02Ru- zd$~z-1j&T)6PslV!hdaYHb13X=A4Qb+V;AKP;5A>h~^dl4CXSRU}*nR3Mioe zEm?G8O?b{`1FJvVF4LRih0EEkRD`y*oG#|mS3K$1<0c!fe6(3rC}ND++VmJ7bzDu| zS6LETQS!`{qupzjy$51HN)=_^Xt~&s1_)v|;yuauNGL};+}i{IjObyByL#YW?x@Zm z#hdKwF(>p^g!D-pe>5|Jmeer}xV-Aenrif}p7T%I*N>_reE&`zI-|y-eQD;dftP&P zx&7`*KkaSHcMT1P)i~OLM>x&EyDHZ z12#T4%djf4B%T2PLN@~~7U@Lx7+Jh*k z45xe@agf$r!^MrVZ4H#C1i2C;Q^hF04O>(Ck0}b3qV;;sxp9J5Cy`qv5!y~VIiF$2 zZ59txUSI)2@xyDM#jdYzs8(QcQ+H&#tw{gV^D!*Je)A^)?(@+Z%}QBf2Q?XLL)7Ps z__7w|I>SX;$u`0;p##O}&#yo}v%g0ZiTBTsg<)c;s(f%>u$?L7miuDPzmpjvIXfm) z2dR}wjW&p>Y(L)mD&q~+_HW;%^V0G5VrJt2iE67kIToK(|s+4}}KaQU&&j>!# zQ|QqI0flV^y0D^_0p?D&9}g2?i0<4GS<4UdVX}+coRWrNInb;dZ2k6H5bgkONk#v_ zJ?UrB8t%L1`3r_v`eUvr{Y_7gufqdm-vo9bSZ?}LpqEeVXZ2vH8Km}jkr@xH#Jc(& zcFE)StUV84+uQe;jWjB<(Qu`(26O4TQ!Y4F04+xQkTuO25;kdpB5^^bXF`l~^ltrK z!<;dj=cC>jXpkZdG-$CFWCpqjb|J|cp}(^xRI`Tc3H@J75aL|G85861v@^(GfV(7Q z|A$F?*2aZ$^D|~sRPiaI+?nUFpSYv8Y5`3)c%5+G)^(4l;FAD6iVMLb{?bDy6aREM zpuyN~*guZVR%7y|iQ!kjkP{Nk;h+maXruJ-{EO&H;FXvNNJpK+0#i=uYAGy7!ul~nNy^p!((2=PV!g=!eQp*AI_jFMGKQW`s;Ffmj?fnI3gi!F_6)oQ2?K%`n}&!h#& zc@lC6J3sm9O;_ESc{MX#C2BH1p51XqER|l>J_Nc2Wf@x@id>2v+lri@S;g5W26)ig zl5D-`3Vm_N=%fLzFf@Sx`xFl`V7=a=!3H9t9sF~{V0S(tw*hN9t_`O<@CyPkP-Xy* z3$ZiM2_~Czq4c)jw!PSRW!Sy|3YJSxi<`xL!01nF@4FisE@u1KJ(b~eF@W7gw@Og%)^ z!2obmIHIaRSRno;>z)-w;9z@JnEM@dstf)$REEE31p3-7bqyo>N(;wCJdlM;1+%#M zYm2MjXTF=zEvYm87nPncps>@t6O3Ef_nME4L!yf9w-lsLW;(_b#R@=Ed!ikF&BNT+ z1fP435kDi4YDegGDy=SkXvH9}`yom?QpUAd<8?LE@ulO9lrifWk6y^(%HY{e)FzWn z8293|UhyPF)LtQ7 zpWTY;!z3tK5L0%$A;_K=Cr9Df-|aZCh?GZqhXd;y>5898RUX+;J(ZYi_yY|xF#W*v z0G*XC1WRVC&7CO(;5UH7pYQ}_ld}gvxW{yhgLH!R0O$T_3W}ovjtu!t-fpX;AHC+3 zMt+aeY^oGN266S5iaRJ92d3V^8xG8-as0z^fbn33+#gvnuL)LMD-%5ibP~hQD7W0+ z(Krz$hLlZv&u}NUhT|?oG4pdJqdo|Nbl)^mMobn@#SAzCwoP?eynHan2YyA9hjEV8 zt7+DNxALJ34?#%WFVAPrt;VRv=#|k*%1(+JOBqj!BkU<4rY#i02YB&Ch&>*of1pQ+ zj)7J^{Cn}zr|K>@L@aShrxq3tR|+&~6|9aQyYjpX7_C6eKv9)@C}6|p#bo26E5Rhf zCV_{xjn7B|P<~eZbrOkyVg3o;f@+Ye()9Sh0#PS2ms}K zV$TAn2ZEqT(7nJ{!^P2$u~C-=!;@?;RiI<3|=yySP7*;i)%~Dj*7SkSGjBI&R7Ha!(nx6JW8E zQIBj6CaMDnIy8gJp#C6%^#=&f8lEiLRSA{yR#3`AY5^NYaKk1alYcl(`A5VSqb;>G zVQJk;2zl`FLU|#E=AI_~E}(@j%K)J;;o*P);NXc%jPsJru?&$<-ZX)c08fW5J0V|= z9PNPle-Cs)s+ghzm>(+&QsdM420M&sxU&aOjBK3Ei&yPo{Xhdf&%5j4ZWDV>^NM)% zC3wIYFW6wt(i7tOC(M~x@1glHwv?GBj2;WWs z@JoM;_JNY1<;d3f2?An^>3_VyF*Nh8q>t1JZm@kC>h;nvuPbyc{^8Q+%4vna3W^LP+a>!qdIKPjR6MDXuCqrn9$~BF7o`IDp{++iQr&McJueFe+ z-aC*PJG3b(vXLH=zpY9%-LztU%2)nHFlb>NHZ;d8xel5^#%Z;XE1Ybv0+u`iyGoh{ z^oepCTjcU!Gr5Z6_9rYF||5bn}8YBL2TY@l5X@FRW3y#%xR1Dh1;$I4}14ul6M z{`6V~ogec8kBjDt8`l&1=Hcbp1gOkh+_$!A`_R!czq+^aNk1S1v-8YTV-*9$%B{nV zjEr!lg%Nuzy<)AAAVc6E-@F5E$PBin4?prC1>zx#gwjpLRh&YcL>IOj1v_@ zMXvGxBQFUr1m=vR3Ie-fxswGpp3}i;br6;~nB1&BuaUr-9Xu$-6vrav8WDm$#G3Cm zER%-Yj(^EGe5dPpciE7M> zgiEu%#&h$I(rE8+*x=I10Pa0%R*1GqVt(Lvg{3?RwuQzDpvBoO{}NJP?ok)nQ1`r} zVSAD^Ty`NPZFer5Hy8k7eoD}sueS@rWpl#tvXmzSGy53iu2b480nE4zWR!g!oa(w7 zBjng^8P%@bj4eIyHcdgR;eUdijm>x-_3I+1uiNJ)2bvKp-Z--K3th5S;$@irQV2*$ z4*>>=I8tK+jN-qxi={})w0zad*SFo_d;AoGetAAd+w+mv%hoyKjy#@()V8d{`r#Th z?^kv4(jz1{2GjA&`9*cNS?$`)sUty#7KO>;=ktmR%yy1O`-@!603b@^86`bH-H_yB18beHQ6 z9C7K&zddkx%nkT_do#Q5z{!cS*m5nB1F11rCvPI4y5q^?rcNF8@b|z@TC|`D{|D@B=qqqXtQ!hE)@p}ucA7zSh!S&=9>kr*P zcGp(9>&5tDS^p|9iRirGVKj|%xSHUJdG2JP0`Y{YK0HzV@1moYPfYypcv}&R1HGZm zz6$?7YPyf_I@UHu;mkwv@>9K%;ETWCumJB{*#C}4QvMm~By3HO2 z3}A`R#$`i1Y3GU7@URYOgiIl+c`XFpj;5=zS~p!zInt$4M|u=QYBop?1P*9EN#*Tk zB|dY2S4i@C8&oX~+OVv=>)$9Zw@|!%R@)N4sF~U@PR~d8HBhz4?pzmBLye@|D4NXn zWrSUZm)n(z$8{EIjwre8Jco^a$|Ka%lQ{PhON&Oo%DjSDjW< z`Ed|TO_Q`^xT*I}7gwLg0Yvjf&7O2PqV;{9yqwY;vUC38PZ+D!HX1H0o6EiD6VNwP zgs+IbY14+YJJ@&v0cNJBm)|I~YaTcZen#V~98XA8 zW6scsI!CiBETfvNnw?Y2KN{(nzU~xH1O{)EAVKQ69T45Hd#Vs+gW3U!z(*(>MUBX8 z*{5U60gynDlIe0i(>jE#{DdPhRgKy8S!d$LjKI&%2Gy`+uA%NCr>$=kueTd`5roxS$jTjU{`; z{&~*ae1+cbx3By7xycXKp1i1Ri-VaTtk~YT#PDjnWj3;ponxxHMe%pSwdZ~T@I)uP zAM|%R;oQhP)T;i4(;X5Tw$K#|)woVDO}&kx;&KxR z$u7R46V(P=2Sc)x>oj?B`CKSXcU7w@hQ26jm6Ai0v)!^{sf#5l3}xRBa_Oopm;lhA zk;Z)eMorj{#JH=E?tQhCt&gPWo(^} z=oWmWp9&l94V*)7DxlWu{YsF;h(1IMca?9Tv;Fr}8RSg2OoXiQ3JC|KmHvMIQ8mev zeQ%=vM-VC1@NpS12Vn{)HT)x#g3G}X!TKw3KeoUB*7S*QBirG8MJ{~99Ahs49KHCN z!y@3eYyISibK;!4E50f=0C7eMG=TdRJb1x|Dtgu}4~PX@MC)VTg*zV zjAZpyNE(SShRH%NCJ(55i3ZS9*dgBc;S|8ucY|c5Nw(Vts6X^6T^}ah8eEt>P z5|~}__^op;Tj+}jMo@$0cK-oRIxsV05@L!rO<7b^{vdJ9t^$6-OB$VqG&j8HM6qm^ zCet^Gv7YU!VxjIE2hzo#8+<_fu*=V<&$5|3CRvaAGKc;t272qXtoFzd_4Ujs9yKq; z_G}rD$dSBhKVN7-#cBmtB3D7oL{KGxOnweGj}&}XQv$p^iV`s5P)KsYiivvkrfn9= z{Zxe_WRm}yjiDQURJeq10-ortt<}Z$J#&s!+y7WFrYuqiP3Yk($XFmT5nybJ>NOF) z;^ww$QY)659jBE0x$>DkF3>dY;~0&RoLvt1Df%R#`0dqiNL3bW{P_UyGDY{E2^)w( zujFNIg?#r8U}2gXq5^KM$$=`8dypR{Up`~ZB&sv z7vz(-{ytY+=})xtpKK$e(v*4e`HfrzEf;3j;V*BF6KPkax4pezZ+FK53E^ypHg5>P zCBZ8E_ZP~lOja_gco#DgNO5WSqKJ&!OMTwfie$c}G6Qwb6GnuGmrvt`CTh+rY@d0m z&9KEtYy-d5PUt{P2e))wqk>~-Y{av95|}V+RL>3JW#cpNeVMAGP8&(o(~LLNN7+4+ zLHo!U58bX;L?q*nE_wajDn}>vNFp9Urr^d`ulZrq_5^%dX014^queUy_6c5|w|K}i zj#N*Hz!|?)Z~_~%lf&*bOH*^<>2)X2n8YdA9!u-#e71;Q;BdhobVZN3!UtkO(h(X6 zVinT#jg5dd5GXCy*0rn7BXOx>PIQ1iTw_HdeftF%85WIIOujFtu0MK{BQy}eJkxBM zi2>i9S)h`~>;r|peT)uMb#v8`+3otKo^^Z65fEh?&H9Lp5Ky%wX1pm6BKi17fd?;j zM7Cr^Rw@?cKBFql1T>K|QUcf=R~gwff*K9Vol~#XQkP$w&G9g?<}SUzdh$k_qMMat zV2~w-e)z3bve0#J15-Fd!W0xvsH1d`J$z1oW=w&@Un5oQBc%R zyZD@DbJ|Bm zDYvM8^3JT?=3pxCcsfs2h>GHq_PnMSP#wW@y2ANH!d^&(&64icHCohZ?+0c(8i|O9 zu{U(RSMv1RGU2BmNd^O0#SfaVn9Y#>9Zz5 zE`R$$$}f;(hkc&ls(bH$WPg_t%}cguvT&3Pey{p1O5dEjN`F&>q*^Umzf_F z5d0?7G1-d6tDVf6@ypK$XwEPTM^@w);w>9CHsxh$xsV;w5o2X{6ky}@TCe-uvc${5G zsHYuT9&me}+oaf_I-OKDM_t);Vp(A##p0)eZhE!YY`%Wk22Po9tCHlKXJeGm=Ccg{ z>@7HdBjW5FhQX%0<5U!Z&e2j7cEQ8+=Y+xo35_A8Ff$Ke0-a<{Iyzk3EIr5bxeKjK zjS4%6!@!*%S<)mmcK&dw$#2uHZvM-xRg+#6C}M|vfVo}*BTrPn!Bt#yM+!k&Yq--rS{c?2US|2>7gbTRTXlf%_t@pF6GHf z;UESWysxcxOZraDm@}e@#L77Ilt*S(sA#rGO&HEEQztL|Y`CS(B&Y!6OR87jB=@?k zL%y~&6`$A0rXZE*oUGv5SOw7xxHRm~n~OJSSgG~r;g28IRYQXOb|H9OVznx#;`9k- zAxP-0YhtLMmBZWy)?|!hVJbdd{v;;--4HAOKJOY1eUOC^()F0Xo{LYpIZVma5j+J* z?3RDj-;?&?)R53;yZd7l(soml#S&txR4*?Ah!FNah}8%<1N@yRiM4MgHUFv@=Q+7e zHMZwlj2)mYQ|(O_Cd|>pLf|1rjp;*^th1M(;Qx`U?r#C!n3ApY-!MtbU4E;_c6MpDt{RcC#(oQaF9t>84w6% znETvzuAH5btwHMhX@=Vtbc5tRU)U}C#~y?ybV|gMDzy&#E`LNUc=!2lI))^hxf4=MavlR9?(X15 zCJk@fd|qW%`Mn~P*kZG1>j@5?nP1T~}FHwj48(1g(!6jN%YQxYB6=x32=q!^v zmV!v{Zqf{h3=}+X)IUdWrFJ~n{`|qV2gTc~1i6BmTw&{+CmGmXmH6!&oGte52f?Tj zJ4@QuX=usDj)(h+U%k5>JedzbZ{`Rl4kpcvk1fr@;SU{LCo{Aqz z_))Xp1^*O;i4F^y-ZCjp5N(Qy*k6TD04ZS|VBHiZ!Eo$wg0s>A8; z(5>zl{?JFn!1W^;1kogXk@r8NBI?dG@TGpx>|v&&3);&B%{b;RB{Bot$19c%8jX+L z#evj#dlBS-w%&ATej;k9{jrbVhQP8d(q}`%>vQU(mTXY@ZBdE#hs!4exR{COsSKP# zy#$DZ*HNe2(Qxt~?`h9gbDXrzTZ2dN*O@)b+leCoTc4a){tO+k&x%Ia{O$r8#HI~) zyI&*r$!LVc7A4{r%+8Bf6#I^j0az*6{8uq zk#UiuP0wtBY!8Vgvh+h%(EM8bZUF->U7`lva=npiS}`-J)|Cf>Gu&>PzYF*;!_7C_ z$3v_I4v7JPxr?(8`|O}#3b)+s^G-?UCdxo}k|FO&t^L*3{jLL`bTGrpba5+~T*B=7 zcRa6|N5n2<5t6*|&N}f|wQc^dGbg;QV~@Wd91ey;F*oP3>WJftImt+jbgTjn&wVZRZUd+qP{qPGj4)ZO?aRp1C-8`xmUe_hKMHnh`^) z>{e9CN#wGb6I3TU>cPRs-rcG>@b)on;FHd%L81}vOMv`pp6%n7uZ8uuY!u)-IHb!} z_6H|fXB?Fo=Ec%$%BrNKTKov*_NF61Q!FF~9HyDnw#}M(1;e43bK1i!BfD2Kz0#*; z$vTiPqY5LZrE<{Prcu+T3)%@}<{6rvq>sx!RNyX7aWLa;q*kFPF}4dqcAZ38`ZlrJ z1oqzKD!8UB6P;aqhoQcAb~$9C0qqZTYHkpSLV0CSG(R1}7Hfp_#aF*fqngb-{XiYS z#E+@JlPd2&_fbagTt0Ujt)pDJ!Aq*hcVMQoaVeRktz#J}%_jVTu=mcwC381!D0TW@ zbL{wy+6JiF>M ziyZA0i&DqdQ0n&Z5m&+WKnXcl@-WLr-JJ!t?6|DLF1EW{84r8t6mdrE+x-!^T)|9v zB!Dj=DIzz}Lq)s|G^FbuBKzu5f~cF)~=Ma?!F-^OJFYnJ^S! z|AU;S(($CcxD-XVa^}se36@2|juI&K^4e>kIcC*QHcE9eapdeTi#ILMM}76$9X5`c zp0d>ziCet`=SBUmO*?PDLunL1CHo9X;GrQTBeJ$K&(-!%b-1?Gyg08!(0}JdxN>4# z`?=c$r|_KItv`9RvYnT>VTIXeSdRSm>d&%kJh5L5FIEz*+vnl#NS47l0Pz!$!1m$A zJ^?ZDxzrR1$Gk3oX1rE~SJRuu%{4E{SZf2EVkXEOLqj>M z;7EXN2X0a_Lr}8f23z5r4BcyrsU7qTao^Uhjb4ZA@V%1bLTZdIqJ=EZKB@81yu=Xf z9V&yIaCUGV;YShIi5>^=QjoDIowe^=5KeBPZEQKtorMuqA)i(Ks1E z;8KTgIN4)_I-j?LE~f&xE9r*vYD-t=~Hm?h~(t1Ywr!Ife+#N@i8`VU>!rH_i^AQ z`=GDGc2}%zG^KMfn@J`>JF7q3ft=rMY4wlXTY~inL#3nWAIc|x zG~;E;&NMr622218nXjw}L#Ygg84(#DrqaM6%fEM6p-#5XnV&E1mwb9dLCIw_(}i`r zgR$V$&k*ae06_AiLfkJ4G=>Pi)vg!q9?GTq(WSgI&|Le0XTE#$Wev|}*%w?F96Snt zW@Y)+u@7Drt%}^}la2Z29KP+`$w4A&hgb?5TiJr|j(J>mAt8$$*n;ywHp03*!8jgel88=B>27eBQ z!4o4dTP+|E7wa$Wd`p#sd?Fcfek*^nn$gNjl2uD8t@fWXv+e%_pgu1wCH6{^jGE6X z=lkN$F##r)oQw|?B(xp{Wr-7c&ce(Glf@{O8oLCi-RR|QcRLi~-Xz1>@}z-6C%vCFl^=%zBBBpr6zpdUGGaL0nI3He1NdRTVrJ+H?lQYamk7`=7T%}xNPwHGoDLZs zCjN7L5=q@QRJ7D{!Z_$XJ%1*9x{@iab4(6T(PY+*n4?gO5?;g!JwCFaqs zkbW972SV#VD|jp3>zEIh;#ilBGT}+JCICs|-V_BBM5+|=M^4?@^HeocN9T(zR$g4x z;12xlMETyEsZTin%%5 z*(ov_EoUv^4Ss|MT@98O2z>wDwfLDYh??Mbxl`+@Tq|;kC#YtaY5w4u{OqZ>tC6SR z%Me5;GD^XJ`_>s=P`-eBn>4g5yxkY+0R`8bhq z<5aw}$QVY-NRZEe6#=EuTNB(ueinPIkH{aUD612`9_HzjSzwFcVuwgqC?4rVO zTmc`3a=}y(#S?LDKA`}H^lLHN)2q`R1~pocvO9)59VGZ$5e+v7`!Z3omSydQFAAAU z6+;(R#8IgHy3tU}Dj+7C;Ej}%QgXtdVaO1ScY{B1RUI+Ja7&}aV#vRZf{J^NB0pwJ zT9WMzEyZ5%fzIhm-PmsH z&?(pVdDqLqVlEj~o&RrpG*?)CA}Xchf&5gVYrJqXzi;~0hyp>5;jgI0RWIj=tj8RN zoy{)#hb}>`G(i5}zGnY%hs2SACnX!tyQ2uc4!J=Q1@rPR+-E*%iNAF{pT!1M4qPN# zSb;VOgujBR1t+SlytdyBpoB2VgxMOvkKH0H@V&P|3z#O$5v7^B5peq({;KO#&u66} zqUSfrYQ|&dD-u5_Z{qXduletJ%&yiFd%4u`euyge{Qeo?u8x?q?7gH)2Lm#X@OuZ=pS1AbC5Nd^`-JSW4vbPL!$Sd zmXy;&X$M$&iVbp*;$C$HA`V+{V>bAx=2cf!u`fBoBW}%3BhAN@CkIotnvw`kc>-v3 z=2%(~h^ton3i}6W{SE(mt+KVH3+rMu^%;|m=Pe_cI$c|}U?dW}IC^^Z5&YbxdrzbX zHIjZc*L$5AhAE?QkY<7NLWJ^qf#?3*cElgj=>%AI%G{U28-J`mra9ijp>JEIbt*v5 zBBpI6$f~aB#ihUHmEA>RqF|Hf(F%xp+1-7H_#eUu%Y zxI*t{&?d&iO9^)*qc>w~1$0t3u!bZ^EE*BJe>|GjCsxqUMdz|&*)v@ul&V3j<__*W zB1;_=t9z7vhRV|bZ#W}u82^*|e+#`>^YzaNupl74#Q#s{l{3PC1FCVYWA|HbI{?T^ zYZ6%N^9u|Z?Ls663FclUj(Rpz+WX&_^BsIKBv3O5OE-5_#8K&)C^LE1fMK9ZPJWKAfZ!G12s3X zFc>y)$6T3)4z^ZAfkci?CQj&s6qg5!GTU;5dru#az~?37!{M18(g8%QpvdqhB#d#w zQNA18B|+5_MWVQkWEmYZsSKTy;UIk3RN;z7dIWM3v6Q$RsDN}%`z#XgyBZB(PsT(r z(1C+yf=I?R|Eqtb4ap)!MZ{QN6}OP@`mQRKbo=Clz$wxYnyhR4{S%YlC1v$x@Tk4T0!* zSSI8+?bu`~Fylt{cV9cayI2l->L@pBc4~4cY_J~00K4kU^WE8Z15Dk}kB-Sj{%gon zMx>q&eKnnq4(;wrI;rfmGZ+jGXHeV-XZ*nZuJsy=Wt@_}&#lgI^EYE)jCi3-Rz@`9 zU&u52NsWQT&o8CG;b(7?Q-*0)!T75z=?ZeW{~9(GftergW`ueu5cTxqlS7pG?lsg8 zovscI>exEEm3>h$RVKb&STA!Z*Fca-BjKitQk?K`3>t@ z`(yomP>Imp8BKUBm+}7HdiA19^WYqD>iKkS#S8g+x7v&ck|x-@`@=zzOu6C3WiI)1 zQ>;Yy0q=AI!wuI~)9NP_ikGCE)DS9C4dSxx9i2Ji8D#1Gd36vhAO5P!j8x^yi=Y29N0RO1$DoM2Xn>Hd)m-_ zD8cS9|8iU~pQ5R4#ML2rQ_L-{S-^E($-Z?T0TEVny_z(hj0?1IqTV-3sL%)u*L}ev zE2$_W%)dHN54x!Wf0;r>K&{*2^eWqHB9Z#T<5+bd68MTlRWM)}19f3km`O^q z7g-rVjOxz><@-d?UzPXQrD`qM&w!d<5_o9@fG^%a;jAj|CxT6Er2cz*XrpfloV^x2(y7I|XrVUOs%+R@+{(HdJGJY1&(JAkba^CX~%7 zf3ne9*x7f=uIhfppol}B^6I%q>C!3yf==Xjn3yK^$ZkeWq*hgG7Xyf66X*y{E;SbZ zqm&JmAgh0;7R7DAna=3P>(F$z3VrN*J4F3J*P0DFCCO6+6QxTkI)Ik;rh#WzO3=+u zMD3iTTxZFWzm;B&w0Fx(sA=|tT=Io3Gs7cQ!%a}me|ndmyZZqRFTA zXw7zx&I=ELD7;u#$ltW;NRXH9hi1{QS_Nf4lVXk{8LsYt;C+6wagn=94OX)b1^0VL zai5W`mPyaPzKhabvh5V9O8S6(SE&^zxJOjXzE&6mZPRBheoO+&G|ix`}h2z%dU)U3|7oOki&=Yf7LYi33_ zVE+_7_o-=J-i-RQ4wTOY}cKVQfT;0l19KFIEqU?&FXA8W=OdO<$yv8h8pnNN~GI z6BYRTsxoxy7$(%fKthw{e#DS!$)GPZG{K3uci)x!Wr|V^#=p)@9+7aOcBc3nuX87{=a+r<8I|QW7LP%W*kO=_B(cD5+nsskkcu; znWcbQ3~jZpgoiikKYw806K9GoWph(uGcV=BE*yKCxE1b*usa$ZjVELLnO5GBrn(=Y z#hdc;V1K{#)1vJH^W2dJ4TIk)kv$jK9hpKQCa;qs!!4D3%lr3fX9=DHYQ##_IW>>-C@vBf(9AS z+=S0x3xx&V4n09t8AM8rw|rcU-gz*krM~P}`$nf95vt!OE8F}|HP?IXg6M_b>AnaYu<5uV zshVEeO2^s*TC_E-ZGPFa@?+m?u%mCX5ETJi2p<-NU(@&?x%v>|eHI=-{KQea4Bx<3 zgaGqvn6%R)LkbfQ{pAyOMRa~LS3$aUJ?56%L8V%an_|Mqm*#A+uZO6&v_G#VGGvYsiA5rfvKRcl{L}U?hwD<4tfXD1*u(yt~ zMoKTm>t8O_tfqsfBPfXR8s=U6g>&kNoZnbvcYZLCSm4cgPHU>`UKjXwrNGCUL z6F=IGu(CvbP1t8hE9k$OjLfg8njeXCFwJo`iz&8)okE&vxtCwj$3tIs&oOiJMuGxO=?!-N1(D4ZJSpTwWdUjJ0`?R^I zjZ+X{$bR`v-i`As^%UVhzCmS}7eUwlWr)m9<37PUZ5!l&KcG^fZ7{|l{%?1}q74QO zDANBNHKSU+*&skbyx~%JF8-@Xh~C43Pi3*gKm%9|VNeXU+-3Z!Sn#mDF)U6;jzr_> zm>m}ldc;(k4py}4`8jx6uQvn>Fy zR{e+Q&82A?vqW|N>jtP;(kiX5@OST;!&(`l*=6{pJSF*FPi)Ksss|;!E7tiWJXmN_=xQT;YdYt5XA^INEkhzvRtGWA6bbC9Jp5*8u&|hkC zUICEs#;ee`8jU8~3*AW;ky(2Xwecm`;KWzU`p=@ycWN;0#ACz&6EG@g!p4+?x9 zlwORbCLW%4TDIH;S+%_Ih_2bp1%px>ZAhYN&8rQ~1-c#{bAV)J6BwMGKs6 zQ#d(E|CYJSGLUhfFqp&A;+kx-Xen!Slkz{6?%n`Y~#tfVQa8<+@%4Q8OU zK{2uY{c?G4Fz70$a6ItcEjA17W(mCPd3-WJA)`+r^J}#$Zf*|z><|kZq4eQe;oSuX zR|vw#Zu~7$BJqP!9!3Vktord=(!*}NP;_gS=KzYAB8H0u6@OpV?nEr*k7!B7Uc!0> z-Fu&og(#@NWGGV7QqvG>G;eCJj`VQ~i1a*7G~xvh=uh6d2oR2kDnBaYK`+1<7})t< z5qFT&lh2X5*Cy~xhPuoZM>VT97{_6;yo-cnZ|+^GlqPhqlZdC#hpWI{l;qL8-8XAub?z68Vq0 z+gP}yzBXJ>NZphGcN>M5-dphe=_czYgdg92qq6D)w9A*eHljF}3=84X0yMW?9llrd z?`T0OjSw9@zRAlQcZMwg^p(cG-d_P$Ix7gLNvW&5g81!yU?#DV{7}FQLMe5F4`c_y zdXJWMXt3fr*MH6n`(WRq|26?lrfL7)CBG^D;Fq^AA|Cfn{wDa6!F+bnD_78kHT#Uu zJhMp3eTOf^wV%0)?{2+S=9FcDdxDt`6R6(n*yqvN#!pu~e(?D2js7;6J8|SCGmg!j z{~iYd-|3wB+iMNNBqq5S?2?J>%#^;$@kF`-fZX^;-$QfJJEy?M{SEiqu8vG-%$m#~ z#%j<12ANg|Ck!6M{|hbpngQlvs30I?T&aC+|3M4=J{BS{i2wgTZ0BMqe{X4@tuos< z*CuP2d44x~cRfBT>4H}?%(k>QoW#v}MU#DAX5$Kq|GYa=!6-xhO&O7eJLMhH*^I%L zLUCSVN1=%J>*7gti9wH6nTu2L;e7<**mCmRc=*zrmMgPhZAByhA`xwsuvW_YPfaf4 zZ>C}(jzRq*Bn10~*AzyL!e!H!Q(LO#qO_6AQbk8G+oA8XY!HQ;ujg|Sl+fM5t4ghyCsX{FO)8phlV+FG&|TE49JPsDFw zM1$6tbOr16WcAgE_}zS$8Vi|1fBijRm~@WAt85K6ZualVQa_EM-=T-@GL)EXXfmb; z>|T1E<&EfJ#>1w<4hJ!X3j>gNm^-6gQzT0@DPJ67ofm>!`Gk*0LP({-;*l^4DE6A4(Tq8Y}GAK6C5 z)$gJ25d#Q*w<|Wi?mzidFo6I()6JQ^XwRHW23)^TK|sgq-iZm(b!a?CBM*X_mY zvg#ATm)Mt8aF2yshe>65JP9KQuqH?pyG`#P=FfY~8P)F>$A)8-nw6UJ$U3pC|1T{} z64h(GY+s|VrVF9siqdFV-H1DhudWCQFZK~7mrjWM$ds#%hTo&^~O z`mYyU!&<3pJy^?<)UOgLrhxFrfFK$P*fB6+r(d_={FXg=#$BoGH?m=D0OKm55Ye9r z<&r#J&N2a65xD4GR6_&oOeo)U*Csd#MHQza>sr^8{Oujks)DgGs^i9ZM^44nOGX>$ zrk5wTA-lE|ccun2XfVZa9~tw5#TwH0Zp<^J2nNx+XnUfzCg2p(Ml!oc$ z!=go^NjQ3VQ-N!!DQ)7EX3_S%S(sA;dO>$|xbueZcHZ7c5TQ*B%1KZS& zA-;WrP?a~>xb+*l22|Y3$J@*)sz)IS*VvJ*=Bf5yEyA&Eh*;k%Dh`aCo~Nj6jS(Md zM?A<}{lBEhh>}4s0nb(`K1PfIQX>03TIrYl*w)s>mA~Qfr6{m}zj)vUUZpOF5Lp$? zF8+~RMdH-qE7fNsz+8T9cly3xd3k30+Yo^ByY_y9+k%P^UQMmmf*sL>XoBk|@K$;J zgkr_M6r(4Ga$k{Ol630|7o{}QM}p{7kR2pkCW&XRC{RFC0w+K6R zOIeO!XfM}$deR`-y7>mY>tl!3B%(``C>6B(!~!W_RfC_1f26NW3Qst`pq@aqp%jDK z-56bn<Cb$Xa;G`cQf=PMB9`~JT5OFRK5x}}#M(BwaoQAwZm2+W%*Eqo*CvPwDYMzQ zE5y#oj-sM zK$m0`5Si(ZaNdjzKrzpV{EB@v>6gc1Q-g~k(_0h&8&qzo2$@I#56 zu@86Y)AvWei|S~?24UUS$7*aFxDjhqr`zGMUDOBay71>>A?S(U4_-t87)v4-pfmVN zTi_{_!C!)iS`I&tFdQmjN;r=yuD~D-NHd=Y9jLPiN6hosU3~Bhlr)kiZ)3i}2KP-D zH2rPbHCwNd5;zN#=zuA8a_y{>HL9*RX8|Qt`~SrSCrY|LGhVYh-xj8@T2#kExt8rE zvsdu(dzKD;cOX=&A_YjN3}a35(sRis+t_t?(|7fqXxu!lBUCeXaf?)$3fc7my4Pxy zxQ52Y&m2ZN7^t)^9Uu|j0UakA6w${>W)q~G(lWO8HBP;tm91^~izBluWW)Pk$};vc z`%}Azp;v>YIGLoJpi{RLHZxtUi(%$uPmnLJ%WP55UZ~pE?T5;ZBXF9sTKq1{X6Pr2GsPLj*Uzd(D4vEQFm{h#(vj$LXa z`^n9DeY5cFXHNO25bmzW+wOc#?!v9kJ!lMcIUm!c9Bz+wZ{9P86prph?x5X&!Zi|C zfYZDZ4T4=dm=wbUy#?`5AfMxuFGJwK(pWkO0>2;Muu;J#M#$n+k7qdHyjUBgBUS`6R zqA5TNho$I~Nf7j2vydShD}kvFjn!A^KP=nfW0V?Xitmf#jzPdN(i=r3B26KGH?S@O z3yai7&@6wppHo<4$WsMKP0nC5XcOiirH2e5=D`P>Lc4jB53pT|p5IKKK4zW1k_ux$ z*do0KZNFE_4=Oai8Qg|eKNncNlou0?LO?R$KXVDwijX@Uz1ho&9?Z6tFB?QtcR^Ct zq8Wn7ZQq5$Y;lB)9_&Z1#s-nnN_NCf@DhKh`fp3kFlj}9lYRrrh%++^vu#3gkHI=J_^`aW*j;B()<_x3pl4(82i{!{Npt)T?zue@O5YGhynO!RCCnk=mY@P;l3? zm<^gz?aGKsbi7|Ojs9DAd@Z|3yRfJ)NkKDoD4{d%>&9Pe-{E_w+5ADN8*M;U@|)gv z&Gum4b`!8`WVf*pGAjJcMii5f^fXYQ$dQ$6mSU=zYX1YhhdndT~uPD>)f-c+^i5By6 zn^jHAvVzaF1XnYGkT08sR`Oe2(XUV=3G?@Swe3y5>OwX6 zU&Ah*M@b;|)jnE>cXyITnXxhyZ`wA5pje>Q*HHbO1n>q(=do|eXTFQ^9UA!ZEqS4j z^MQ$!nOQOtIW)2h?Ql0@L*?vbKX2jX0DAq1{_n!jnZQn{zELuJ#eg+(NCtn`(sgm$ zv#(OupHjD^|LI;(b3c*`jeKXCagQ^3RTWch!D;1zE)D1ki1`-rs^!g0c1Om$2ORm8 z+%)%|A?isT0u>`>@}U=&nR9}w@}ak(RG?cM0{_ogAgNY-xXicL(>=vfz(meTmGFSn z(lrBG8(M|FTonuZ?WM9oo!X~*B2FztiR*!_``on;lCB(l-V4<`=pAJy9jD6}vC>|W z?0@>fXg#JMcwGu2$vFB)4PoZ{$&_Z0t_HEYHya+Dt#30fR7=vNKWMOXhk7Wz|us;xu>B9_yzg-&{XIWU_=%%2`2q5eq{4|l$cS1dzDYc{^-T^ zX}0}mXLuoxrxdZ3Wm`d$vyvHY2)Naq4lq$(=<^xR@zIk0dR`Xa>>U1+H&s09u>FH; zSQ90JI01WXKj?!tEAYoU50mX#pC$W;e#!!F4?!oGO8y)IJ!s5 z?g_dwD1OTH3ntl=*9H)_9ENuzm-IlsN$nchxF>6oKxH6H>gTLVjeW0i6PG{kleZ*^ zTjRNFzJhLr6?CKoCb_BiH-VEG9wO#JDlRHaCkmG2&KbePo6K|lUWrJQ*ncL(=-JVV z&;=n(Wl!#~LhnIOIHR!?7I~W^t=QCf?6cE7rrY41trPdtr>>tP*E0 zY4ukQub1T-Jv#f2cBmJj=m@dmT$LS_mFJ7vkg%mEG0D zB8)H3;kv){mYd$BHto378)t>y#cF%D01Q2F_qW7E&cN&SMQYC9Sd#0e61iQaOVz-@VufF6|yNkg0Li-?Qufv~r7fz+;z-ERbaRf5MIPirj!_0d1It0&?vS# zR`wSd*e)vEBILw&Z1zowuzc_K1M3UT&%1-)N`z4c$)lMbx4|XY-4C@AwG7>yCA>pb zL{%hj&3G-gtC?J%L}gQXNC7>G))_yB^DEF3Yu|#q+Gsl5dNhjPrDuTJkiqtfMdR%! zOu_xu$6@6M0fs$eS&q&XcGP!d5aqSLc-JUOxB6vUjwLn=s@p-az&V?A^`YKu_njSfad6-q+QHT_ zfq;ADb9w-ghOUc^l?*Iq zLZ6Ee$$Jp_FeB{9jm>#|f8tV>Gl+K!U;j}Xa9e`-y#dB|XumAMm|8>dW8oAoIEVdN zbz>Xm>%Aa^5>NXCxB_L?m?bd$1s+vFcQ)~J*1_X~W%7@Q~0 z>Hcuc8LiFT^6`26Ffi!ye6k0EXK!+1xK9_pd5|F_dx->X_;x0d-;Aq8yM;f%+z3_K zOg_PItm@%g2(8FgVc?JiSV>|WG?Bc=O6ax^Rw1ag7hZ0Db5U3QV^?Qyf=W7K3|nk( zhx3@3BZgD~nh6JWHq;GpAlXoLg?gnSli(jhe!pCbvEz*!7^)d?f;K2VMC3#&|^a{ZzK()t*P z4`Vlmzp=9RsHfx0E8t@byDiVe+~(bK{qHg_7*XATrys{%!m1j*vM7~{P%l)EHJJjp z$`pGWf#%t37OR*IM0x)bOq1z^>D1-5^fV4N+ni**plxuK{2R%1mTg%{j6p!*4$k;H zR)2v&xTNGbRC^nvDa(-->`WjsBqin%bNa8D6*suqI>2N=XP$$v;>uU?4bapm4@pPO>e*_Ko(^ z*yH9sl5Lb`bVDEySXW~fOD4Mh4uGti0BXiGBo|-1~rX`2`^ht;nPnMZe+L5e`AH* zIk++FoN)T!gpok*;8M`)TzBxxP|vvYU(_RPz=4utLN|o)=UoqfC0R!F6d zA|fRHZoeR&F&HlSMS`FstY2z`V(h30XcOfNf`jX-i}~JoOOO|-DAfKA+rd~`G`oPo z^cvEDRuhmGDGfLgA?cd;`_1_ea@s4Oyxij5%!Tv)-`0D`d@P&x#j6w-=3xBBP?)B*h@ z-{(D7+rvwdiriB$;|T}~D3Fp@H*E8Uh5>2JJ4ENLtq(*Iy|08bc-nljqy($HBCLuo4=Xs6P!kUmh5z~FjC1_?v9ze zfw$Ym(818u|0dmDU;4O`CVgLl5q&ZwOfZZLSl(1yEL~GCIep!tU7Wc*`k1q8>+V-& z6Q?5^7Y**1oSiE%`uO;;CjsAj_d%L!FL^xGz6;$BCbRDPip6+YUm>YXV-c$;KewYk zYyvVsstBT`cBAt*RLL?cPWPo+_iHO7$}1MXLP;Mbusrmk21Cx`63zwWG0N71Ah4#& zYMl-UbiI^B{{^9&HTbgX%Qo9CEEDe=WlDFVpCt)LiUClbPqWD&9A?^^s zDf7Kj?7?-1*YMFdL*56VB(KEXO`UrYyX1Aj8epExT{F5YMlinWR~F6?lE>uN18`Pm zA#Pyvf_a=)_u3)(AhN6TD62b+8^HqYvGqp0tL_Ds^={NeqZreIL-CB{1ad(3LORb-(Rtp>F3Ju|GnE1 zK{^^?1Vn|~R4g=(4t@@gU&LD~w`OLIn4HO5fMNZXdH@&uojIrsTKYV;D&bb!(*~^? zfr{#qX0a=a=$yWxR`-x-Pt5B;s4Z2Nf$jk|MJ(`I9pfTSHui9|J+Crqs;y1J%wh5v zIypCKH23xS{;UVgIg}LjglEFy|8NOlG8MxtrSu(s)M@~-=f*T z+skBW@i$595$|)_urh3AXlRV2WY=S>NRdSwAE(s9oT)W+5%08n?n0PKlYHSZYuP{U z!a3_jwu^vM|K~am$2~{;-=-uwFYnCmwIEJ~=F)oV`>+8ZJIO4)m$wXMPp(U>Z@gvE z${2egnyR9wa8z2aSHMq<`><29&?<57AYOu2KMd& zGU60`@C}vyA?=;_+m-ccECk8^Y;N4qM?m?x`}sbA*ZeQG)}fu4NIz5`KhHKUd(m#g z^fv+-qXj*{Td;?heZZ25b2f2|d2$T_(Y+d|TXxR#0fdy|R^4L{;1ecDCb%EojW<80 z=1HstZ3v4k2(nEZ9^_$z)cEIdlemsmq^{Rk#|cnylppM_VlYGg3_83(S2|x5-q2m+ z6B8B`bo_X345RxmW{Lm{(*$B%*d3r2;b31pb2=1~q*`klSNY4)ZHLWu;i zA%$%IsGB~F^Dp#`j5PW)Y(3M0!bjE-Jx-Ge#tlLmV}-Mp04vM_y>WCvBQO(z4lV3! zipA;P>J$-L_^_9VOTMP(iF}qhz8s|P>^ZbPdwjgA9^euvXzcBT(jaehwZGvg(I`9h zLaG6nER(X{8BydZC@3OoAkF%LE?r}_<)p8oQCrto#Wz0$hmFfe;&ln+<;1k54jiA1 zfSa+sCH+=+DQ<+WS%BMIFUuo6R;Il6*tj^@fam@j;9mfprnb+6D9vj*9N&iPZ{h!o z_sNnl8v2I`#{JmqT#Ot7ih$ z%C>O(b)mG^y%^c%!MDrjh6VcXCH8zW9EEE^THxzJm+KE@3P!u>Ng(*9vIOLHAO!EM z{;@W~F6aiHkEPk4%8T9^Ff2Yia)wrtqYm$@p?rJ`%MZ#5xu?P*BU1UXY1JwQ;I@js zQp20sG+?X{W?WD<3l7Xa;_zxyV?#g=vUiBHQ-|g^k1-xBDh=_&hI+?(P_(!D;-W(u z^vy&cjHGvx79zw<@z9F|GjcT^tw~>dc}=D{&TzqTIEDb!)39tx3ffo;o@Cx$P?m5n zIe zryc0atb?91p}NK--pAIcgKE<~N$xdZ5fGGqMxts=ePTf$TxoHb3RgJYh};+d^=AN6 zvMhfu(D?U?+hw$Sjx>!sE3_4QxyhdvSi&7eP1?X~p3kA(Kjz;(j7frpGS}oX5LdeLsdyFA&`iLrgYBB++R_L6wJ|Y$m>wv~z^2*02WL6m7*W)RiF4ekC)~Sd; z^B~J+y6~-(A3w{81bjXwO|U=Fg92c)>F$3{jASeS@(ByzYyV})ixOd0k{^ofG4=*K z;)h=FntI{*CI8j2J>rGBy@HvW^aKw@4S{>k#CPZX9(AB{Z^;1+9VG&EgPFOTJj@0%{*v8<^-i$$Ij&g=~}?gAc6ou4>X1wwryTp`YathG+DJOaijcs`s|y z3020~XrieWkcRKJkFR&*!Z;Bwf;jcCK(ZjHPcD@q`aFlwqsK^F2P|j^+)oAs zO(k@Mgo7ZU_^wXkkj=ay*u2FYcu9Zk=B+`?)UU1PsxJe0Rw(Qk(m7QkQV7A_!nqU) zH9Z{_bT6+~u7iagDB1^qA0*-VFQqX=`JvaWrA>Kw)CP5pE7sFYgnUho+~ssqC#@H- zd1Go3nkoys+DwqRZhxvT|4fleAeCm!udZyj9%hT8ka7tK$jBSFKOzX?s9CNMqXT(M z`Y%pc5t{?F$Vox<5C01z@wK$t(JMHo?nRHRKo0dClRAvPmT{ry$?b@tdwL$zRNCsQ z(_uzSbThmjA)#K#gk4#zTX%1UWE{riKYcY-jS&%>Q1!3aTylMsF}+6a<#b~f)aYjr z0y{$tDce*#7#%xn`J{-&sw=~fAr;$iR%NCYBCDX`fkVc?l5rsUl7s9gkLPqshZL*z`=yW?rqEwM|i-3OfJXhkp8>ht) zYf7q<_>f?--y?!0Brs18O?o2c{d+ovRYVe)>XR5VId=#?25Zx-W{Fw8eb1D%)nj@g zA&C&(AOE5?6yMH67KLtevy=dvzbt}3t`l;cAXkkNKxN|ih5!>X;LTeuU7tQp8)nd6 zWS)`f^|X*g$8wo9eV_#iMb070K4{Th1BYb2h{c(5@awsmqz2jy7b78nBH z6{(LCo2+w?l62|cC-1qjai-||^d+(%_j6+Sm8-Ndk)+&R^Rf(8B5Cz?`yHRbufbAK zqUZ+_j^k`!cc7vt)5xxqUZ{D1ssF>(Ikjg3Y*{#F$F@7RZQHhO@MH0j zs&**RkUom@CS|M+f=9==K+|5}M#9jdvziq+#d+jC(>N^Z=KWU9_9jCISESeS;32Ht zD#Pm(RrfGU1bTB>>m5`6C*L2q*duR>&-v_@b?n!bo2~E!B4}voHREwr6~ndoUnYye`kMY%eJpw8 z=FVEF9dA$9dgv*?$Ctl{f)^Yx8CqPTGvJ*r>Yfwd@VNA=m(|54)O7A z1%1WJDy>La0A~;yrvM+EN7t<*#o_v6(M3QA-Fh#0Ru4zNK1_^1)<^3b8pU06p?EBh zu|5yUnmINd>zQi0RrUAn{t%D%$1(5s57M{t5LKS2LBgkR{%lkMp_7tqg)He7WGh5Z z97<03Ss_1#%ZfpnTqojj>2O3-f8INAOXE0X-N7=8@3fJL2;hu`#UV=}D7LtPKx;us zejFJOUy9$OQ}8AQ^62Ot*eMXQZXRhwW5}3oAHKU}E1FzxI_M+wH7H*zQf>v|l!PH) z15L znl0{csaNyqbztxK3LTvPbndz^Xi!aJF&c)y!C&yMcviko*-Bi&;SY$0bIVbV+)m-$ zQo_@%g49}ZTQQiBRp8(W`aU1-6>)yPtmd60g~{KZv%l`NHSu@{to=3HuR@2?oeA@} zG%_J#as?R0!NwvM!|}jDEby*-I2Gig$|{K)%wo|<(HS`B6eAtLBn)nG4fwFd{UyNo zEhJq`*J*=A=v_AiBavuA9TlX#DT_FUAf>WE(s89}pZnEASlWW*{yCygMVfQp?fqc?D4RM&|v{p7B07Yk#-qAvcZ7{3D@E)uBP`s3Kf4>m9qi_CaJdqg$}1Ko{J|7 zpWg301{<-gbciZq!q}t6KU-uOGyXK|qj`udOpVz_-@OobvCArstI+ncv0YGXh>s>U zv`mS!AlW(75oxoj5&vLjHf&S+Y$fpE34j{W%u9(uIsDnsT8npAL@5cfia8{sS>$UV zC72i%GK=Ruw!t+X1AWHp8N6_qW3`@&2}F4$1#22rK(2iW9j0~rIm*fPLd6v**G0bJ z1p1K?kU%?eX(QXOY!k`kB4N#8GRBN7bOZzzPQx`wR?Mmi(Xg8%h>j0~o$Iko8-RGz z`(<7M$FoOedi1qI5dX%3!c_!ig#R0#E?hrSfQrkt<|^XPTXsWBRlW`zND%!@@ojEc+4ZYBI`N zvK}glr>J6lmu?tWv}4b_1#er`4Zxv9k?bk1!dU@d9s|Y37w`0-OFez)@KD4tnH@bL ze$iz6%I|(2qo>wl(CLm-lz0DZb&=jw+_{rBmJE7GWua)y*{Q)x?qFO$97%ON+z^m3 z-(Ug>ech~wA)Gi!W`xKU$CLzFoE?Scux(f|k(<6V<~yN{S?{Xrf;Qn-46q6jhca-Q z?U5N+_~iv`On~&K2~kbPRIoNlm3hv*7?|SRu{mWOV}g*KjU}_@%;kz_q{V zn04D%nAgwu5xxuv|Am`d1$d;?t#5VQ(mbT?KA!-+bd7ICTo|#}R;XIqx@Hh%~s8dqcCqcb*C9AKfd4c*$VmuCO)k5e5OV(5>>8>?3d z{?%UDuN9`=^Uw9(BrV>#M9?$IICu~v;86eK7>#+tMUq0?%eRja0jw>wBL|Mj=*9In z@lm!Q2w~Os-;yL~^!F z6u~Y^`p|gt^^q=$vP0};bojC%AwDiI1i#R{HF8LR(7mCs`#q;Q{c zk~8g-7n^&)1B^K$rBIgoU15D{l(t<5hPi#NcN{3)ocBDO#Fj-t7WvqX&tj|@X7>z) z2{kbKIFgwMAPK);?Gj-{wSn|{4Qh!Dv=LCaj}oA0Z%RLhyt_umw9>}Jcu?tUQ@hF3TNg;n8V zOs>lSfc@m@05j>J^v}NqqLJlj52=~)U~>-X9_pMkZIlt(CCkqUci?-`4tbLT<*4|B zMb3s_MN{J4e1nrNm+NQ>l`}8mO0;JOuk>L(b}+x(u;w*jjotXqIDz0>3kp-#lt=L66!ota;>LQez6?qE z?#V9e$2v(|K~9pPMBb`;oSQ~WdLe$_qUM)wsZjqsM-@aQ(>Py2ZwzFV+1MXw^#}-w zD$%NmFByLl6bC<|Uqj4%AZIbq>3C6%ZU>1?Qw-^JEkIX z05AegQV#`Oaav^ETIZ{5LbFyNRV5MrzvXm=)?~vuoeWrm?o|||W@Wh{lL5byrw9Bx ziE$uQVIv{5K|Q?cSZI#2p*%EQPW4y}HjVNjRV}oGqAitSUa0kGIx3!SnltpGvuqy{ z-5jUuc%&>6*!K>;j|{v5?%X5(D4Q}k016{cH|njL(0}&Y)m-U&&_mJ{`{!z73soXq z=A477{yfyft%$pT`6)_FOiNR{cxq~qBRih!WlTL2ADbQ3rmXLi0FCFD z1r6h+F|fAh9-hfr+0c64nGQikp-=$|p*0Y3-fC3l6nv0NNfsE(g-*)VRh|$RAT0db z(FBRv)LALOy=;QCAYCr5D)_ZSly-PlaS4&Xtvu|Nvz8e7@GvL%+TfyM_k`u6h@j#Q za_nY89lfR7Gq@Q7dUUrRM3A7dq5NqvN;TF_9E5WmRIu;hpYqwiiz4&LkoEJpGjzH) z1?iSOxl_UA1u^FDn3PN8>ITXMw3};hsxf7+nnRN8VDKG30PHAzHH2a-GHlS&S zE(fE#>btrmo_5fck0L&EO1{-J&vh{=6EpU5`(!`%Zl>mqZdMFpk&d|Rfnc`>*<+G$ z0$2Qc#*(>YTsn?S0nU*C4DwrK6w$pFCpR6(XCSiuMB2EIeWR6Bj6c0~X;?luN4{(} zx>>cc-Du8~j$tLwSeyE2)4o%%W2l8GuGTOhIfQq{_M|NKr|(89kCk+kxGg#`4K;?! zRdze7)Ah;j!Rg-bx+T(n=a`sW3s@ z18$N#u5PxS{KYTyJ&L27lEo1thk`}1Ggu4u+)$OGq}xjI$x=cnf_w<71uxvPl1Ig) z$0PE(+N1%m9E0+&dbqNT^=*&peE|h{F5VY65x*tGI-&glab5GMWV&a0z%&K_AY=MT zaPfpTIG;!C&QQp46<73qngTgb%lkwGXjO{lRCq-cOqa?GUNX!DEVC;wFv;@{UhrkDs7=M!d@m zlyN}DaDNT}LP%(2&0IrAK7+h}6JK-X`yx^^w>*bEoADYd;$`BjCPT?fCGJj@>FRid zk`0?<*_E_#0q$Tpzg6^Yf1T>W8g#LI4gMuu$jbuKbV(<)iyX@ol18R5@}H}MyzSZI z8pTEcVNCrHYA@rA<-2G~v!{=@CIF;BA(eGM35-Po&e{aHT@j9F?%HEc9)W6P;H0DS z`u0*pt}pa_b2z{c)qU9KKYmuyP`<9+<^S4~J4G41R_6Ip2LsSJRv#SOxL2zx(g7%J zNVb&GmK+a4*qB(DM|Ba%oa9tBHn?Z2V&uce>33rz-A`2`a7Ke4N=-us|BqZ)NQx9xPF5&Xh?A9A za@b!Cixfn%X5ZQCCv#6W$)Ukw)+y#@xs>r0Ae{+rMI$0 zDU)&;R6MY&O(rM0`aGIZF%^`L_q0_jsDbNpq5sQw_fl=Fmrt3%^wN&BIXAu6*m;}zFJV__mF9AtK z!2|Jf9t;8cC-3f@!k5-)NZsyK_tRBk?hw4>(1)>S2%MRowzJoi5{Aw2)KKMTps4pH zR*(Ze?UI*>i$kmDk+cd>Fv;|YZQRK-`?g& zg2ZuitE{~Xq2BfX+c?Kx0|(;(1q3vU^}jJlN`S8YK_`;$Y#m`YlohC6+o^8{gB@M{ zO4b#`xECn5B>|dNp)nhBMPf2ukp;keHa?kV&52L1v;TL4pUKyC45q+GKNz&;Og<3xEA|>7A4hJJ5 z55Q=mQ}-k{i-s>QPN-BE;)BQzJNb2{PTpUx1qN72`f0vygi9bn&ytI5qO-@!HQ^vjRp_ zCsIoX%d*SA@T+7vZY8nn>oMb%D#OaOA$hCpI)%w+&T@z;DU>ZCH(79EgkCBPG?F|* zl1yep9co5Xrzhotc0}K*&=(*caM5-CE0+xpFzz-(Z6JcCu2dbM*$7eEAHO40H~|P` z%l@Q(Z2Ig}aRHZsFM$49wp+}Rqx)x>SK9VR!B(V5w+0nV@)agly?j2#ya%X7pxl~PWG`}lFn0=PR9_#B52VJ%0E(7X&a zoL*biU`fYofwEeCS1Dc&LJNp|Kae^@x-Cy<3Y&0fpsJQoX~+&-|7HFd z;kyxWMkKFAxu*AOci0gekRYncpo&Iqn69TRflY}>v0PR-F2V-gz(?D$2MCc5qU^fy z>M1C!AaM`oRkmMwyz2`$RPopU9R`~FHI5SotGvzIil&JvG{c~%8=Tk3S8Bbvst}sP zQg6WCrWKNuGWl?26Y8<@M27vC0ybOK;Z!)jdu66HR(&WUrD9H_`RO*7qQnAJpd4{;A z2+{}2`JM7G$p|MLKmaL@TkB^DycT$lAI0bCA}QvA>Ox2oy`KD~Xb_u?neD8awX*9* z4_iRp=8`|l{K<$}&*mTk4u%bsY!wwfi#Q_En~SC!?+(=suPkbN15h3wP&;dKh>;;! zktwq@wV7JMa<3?3-kAx8vXmAtu|i$W-zlCJ7^LKSUtEZc77FP_^G;Dq-RtpMDfC0q)Opz7R)!{ctn1m06P9L4xTJ>j!p*}-K%Oi z5o$siT3dta?k3a~ejI~1&B^Ndp9Vh`x2=ltY`(Z>tHyta@sC~Bpu@Tg`QvLP=gdDQ zNhCCpcZ|?Q%2!NI_LP3d;@~XhX)TuFEarKDh>2-vj%R1BN)f|IB_11EQ1h!p-roq9Arb>?hy#G0L2?7_f=ZB~1`yK=XDF1CK`sVGup z%m2Yh&d$ul5DlQ4lb=>MumdhO=Eq7Mpo5~&P&L_d0VaNxcS|&+n(`{NRZIK{f%;DD z;s@FnTz|L9ZqnP}$#UI8Q-wwYCsXy0eI0#^x_gMxBN5USZcj8SsljK0#j1k`D2{#d zdXMn&ECjRPfK`_X?tfi3wKqC;_HU^ZAKp{Dcm3%gx$yzhHwgED6V6w&epAVa2WMJj z=@sn^01SY~C=s@l7rsnBWDyL&-TW%WUZcz0?h)CFcURcq$1nW(6D*}4wJpf8x(usc z$Oo%})@eGxyyLzUr*$VtE~1I2zK#IP6PJwkH0dSAztR-!l4aezl;VZHR?l1#qlr*5 z${bb-94kL$SqNv#L`9KF0j|$ch}XBtz4Tqs1mJB3Ajn%caR?t5*4aPyodGrZ^Uq2+ z`XoJ|Xc%kK<$>dbnu#~KN*Z8C%&RIiCD?W6-x?Wa>~&e}j4KmoJZ``NLnnZ;OA`5%3L?ItJ8Hj7Sfxt$KQ4H3;pFscA{8op2DWpw z0Z8XQmYt=>QOL^Of6m*lTRpx|+Fg783PB2y@fK=MR!!Fj=YODe5*q1`313 zPvDZGd~N^3_4en`Mgr{Zi+ADE0F?&1&dv~UnL8L(gvcd&NE$7-gUIu`$h%Km2jDNQ zd43d%;{H8gEQuu-^ToV6gFs8s9;-2f@uR~pdrt1bPlu75a*_n5uNZ4ssotwPg^Ydk zj?`&m`=CttE_Fb{E>+O$hG>Y18^r^1jT+n*;H@BbSv*<3iUgZCK*yJ0I3?jKS`?bc zcu}#10BlCEQ9_8=Uqe`jcJ~9Sfc;&dX_{$KzRRg_2V9*L$}EfqC&&` zhZUnUh1v@Ge?W)dW}n&xC_q3tLTQ9^|CEf5r#+5%>Q7!?p#TZuS;=|>-joSAgTML# zuEZr+YEw|im<4*4XhWeHds&q>GIRP3-%WW_7v)-#CUC+8m!4|R!AmTa>BgdW!pTPM z6?V#r&<%p?0!#;+>skxd$qmYe&Z22Wq}ob~qwGd4)p{qLudt@R{>8Z$(;D#^O&s8u zR|&QkWnBrISA9*lbJvB%X`$|fmm8H0+^ZG+%=d2(Q4_x!yUO?4#zpwX z_Jozm1*Z4jl_Wvs);jw=<(1?TJz;>nadH-rZQs&*g7xAKx9NI6+xxp%OP81NWqR!r zS>k<}h!ZEv@E4pNUwi<4(gf+Osb=7K+Wrt~#*3I*{g7EFqB57kJf=p1f>y)!~QfVla**H!kPs=;%^;tKAH5LGBOM?oq^e0k&E-Loc+m5K*^P zQN|AtBrY$W82-qCKw~UqmI1(V$!@rSui`0()R-h?bCyiTNOp|D{BlB)2b+S$>soIn znWk{HTUN!%)b3Gt#qe@i*=S6C+~ai*oi7*C$}nNER$9e~rl9Fz)hfEtOmlT)UN$_h zrBtC~&l1C8ZhXn7Ez%Xt47!%68~xB23H8<6fY6QD&&eF;;^11TA^|+iH8)Zvm$!j% zG1sR`UyCm@adewJjC3dh2s_hW#C~eUg1eNFU1sr(K#ibvIW?JI5VdT;T6QzP6cOeb z36+d!r{oNvB-+H0#0eF2{FkT#u5i|?D5MCvj0OcJ z!fQnR4W3O_vHl7UQ*teUa1Ch;EZYRHAt}Va1g6{y)IW&tzuU<&qbosIg zu6`qFr8St(4E{D(<_4KT9)Qj^Z&cJy7@}WGp>Z;2R^C*B&kHv*d!b<{-$~+Azi&b zy`91!s)`Ya0HOiqE>S!&;HYHkTxz2tks?eN10Gund=nvpZrmi8U|3^~foUupp-n^~ z;{lG8Q^VD5R|c5uht+T_=d>@FiSKVq&XMZb)wtcOfyUEjM-gf@+NdfMdBfZ`Il-OB zFsoB13ZoGxEKNEcf>bLeDlxodtUL#+?f8R~XSZ)uSb4y^;9TldGu0@v3F7heaNA~d zYjyA<7O7L4u=)^@$+^b3t>Pm{iEv+{w27Zu{-X|5NdORLq}_OsbhA1 z%Z7Wc6(`%z9NNJ}AlM_v2?WYqj4?Ym8&bcn%sCv`;vjv~wd8*ies!;;raa-TTG>N{ z08Mz<-2sZOt_6z(V&+Q6nLbAcMv{L2GiAbQEU`5*5kl;eyr*jk;J$Ke;r5VosHOFO7$(RVc7{C_U>;tk#|LZ*@3B;pb4bq#t52j z`U`L!!jums^O8n}m2I`SM6eS8XJ~vBQSl*M z0Sk9gR`q>lZ&LHD}gN;h}`jch^Z3vryBJ-G;Q@^ln*@+;2u#;H#6Vq@dLCXnwQsL z%;xH@Jh8qu6>jr$e~=`-D5d4e?^3wC^0s_4s@r4O&hhm(dKTf06)Fv@DlNY$QXj44v6X$Kh*N(&dbjv|?9eg5ohO zOvBd8aqnz3C%?Qv_4b8u8w-QY2;O#QQK+1VfrQghtu)a$Db9)Xf#+r*P|wgfGsBhO zD4mNq4O=vY8ebI0ac?BZ;{fe}eo0XoByS*bgdygfBKwUqnA%D6F9~ytz6r*|vw3!= zmRZY4c&Q|W>9E}y&^PIyZH+94Z8)ym5;4GTA-!!Ox&cK<1*@AonA6d2Y8BjxRa@8u z?t&4wfiP=9Q`w7b>lF`}uLlb*gcpqE2yE67`uN zaTmsD#=fW+5?4lO8RgUgb;z+mDtIO#D$nQ$!w4>f<47tkcNxhoDR76^r)C{c#elMl zP#YDeWd%ea{Q7c)Pr&RLhuak+t~;|#&U;X5nLkwn%krB#8E#A0Hrd)cJZaf(vUoW1 zz*ZOsiH8Vzm#7Fe?FJ!|g~f#!2Ahn_ogl?8PGf=kLh4F^>0>tkP&skNpNV1p1`80y z^D2Em2XI^sHFS$)w$agIjuCc5?V{U3GZfNflkQ$@{+6Q`O2E>_34+u55i=~Z)Uf&# z1nnlR?pzjPVatuf*{c^Bp0m?H*MJu~AUk*3=m7BEtp5cIHG;V+yr$u-e}h1q3fh1k zB}fPsX=6lD4_Az%@~G$?xuL*4CoNhoxa?C_fbu}!v9%ATn`1BS+hcw3ksPAoPJ2S= z_o*dH&U0ck3qVI9W?53oVQb%Y=A8;-esKWuJi_fY&w?Y+2$xRX71Cf9;`M@pT4lCBZI9H4tfSvKmGE1)-|y@O`K2}HHn2o~Y2gmfEKox3x4r81MXS5>c? zqP;|rxquY8F#OhIU8x7vPjF$p$pEGjCe*6oDbZfD05ECu_|adMu0wEi;rA=I!d}L) z2S4Skw);X^P9rTrXKXc@JKYR*?XNxBPCr>WD}-!Y5%S7j+M+r-8wuk(+M@gB=4Ixp zK+)O(@zpOsAp|5!AqcJv{MjDiNU4;oJva}Cy?aVSu!$nPEh_Q#O0QGf4+Exn@RWsQ3t#HGh@f+zKV5RuP`Cbbvx47@Kb{ssCToc+BIsw%yHv_+ z{V==bAl9PiL}d4KVW{&{U9sR7B&JdmEyXPCeTzXTMr2(g`{U=J5c|py;Z|gPF#L+) z*H!0XR7+hT{b44&2HjSeiE19Jfk(#co82oU1c-{OCEXrDZ;MwK{lV`w40t_Jb;%1l zm7Ww4-BkHO|Hh|)`|RP~Q#xx`LW&pHL$&`_Ui1vaH^LkbAV$KswG!R7qTeurq(lJ= z#FSbNE4LXkNyG&DunkRW;M$HIi0~n^pEgfCRrG!GiTJ30$Pi=ifSTqj>k(Jl7 z(?A<@Gav#o>>Ec2l;z!)Gl)DbyG#e9aG0I&|WUk z@Fm*!OUjXvazmLhuL~(Na+QCDouJQR?lk_my)$9~Kr3hRWEVX&lM&*V7ctxT0C{v0 zMaK;DQ7Mcz#MSRgE+^eNF&aPVdASZ$`=S&t9J&*ui1lEuVmvnJ@SX5zM+jf@soAj$ zG`$v3Q1QQ(F1Ovr92qz#cF|$C2*a1B4VjT2mRScLkQd^d9B^C8aWlJ}1+R*Cpompe{I2cs?P(HbBM`{sD@8~WKVR9iqcyOF6ZCv zq=M9|h6gWm5-(segow1->MDTcJB`MmsED*Ufxhtwh3r9__#Z;Ybvp;40k(>YZFwm;glH5)SWK3=M zf0ywnN}H^vPp1zV%cmiW0LnbWLkOXd?$W6@<)ceGRo4Q7rbSW_^moH`H-1KChZg%y zw~+33JDs!0`M02nTFiV1pAS)Kvl#o6YR=!uzA3&b%UxIVL{GNdK}tSvM}Ho9o}GXW zKejGj7D%s)!{nvs$o(n~^tcf?N@JvJ&E2K~^8^vjdtynS%uHlD0aima2r<{fPW#lD zuD2K~-fNq;EfVTj9VOhqcUgDq0WsI*{S0G+G==UR$|EtZ-Pe+8@M70XkoHn`);$Gn zWY>e0N>{pDn{(8tgQ|FGqmn@_&|-X92Pj|y96q8Uv#4*X$c?C7E8;S`hVd~3uW@pX zDv`rEmjN+_!EvUF(uZ&}OZjA&~XAf4d>%7xCYqR+!ubZ0LpWQAa#5H?N(K&5R3|tXsHJ^_GL77i5 z2%74F3r^w@)3BP_P3<4>w3mv5`;#_%ef?hd({QipxICo43+9ZUg(&dZe6pbdbOJ^@ zlNAKywnJ~A0BuRV!8IxL>zRz-;4;@UAhGN3+y=#voVKF$L&780(&W3`L|zA#@wn5) zrwV%{?0FIQO_UI1@0V@%3A%KX=_7}!-buwMaZlCY{ivif26U;LtfHB{X>ul86@jkz`uBodt?=x4} z$@BIxkNk?q+b;I;o@izre$G~4IB>r_FCq5U{-5oKg2M&{ige>Z6eUpeUj>w&3WwTB zVWK@}2foH}aplf_3BgT@EXZ!m_wWrT_n#X78)?WLsH1;W@gY(o&-~@a8V@O^ka;V> zZwfC7_~AJcPb_}*45FBtxLu%c_6V)oA9h!tSZ9IRTr5Z)SDtdeRnHU|Zq_kka%S&& z9x&&}Exs7s+ll%85vdk&pKOXCBczTml=jFCG{^sq6%OZm7UY{v;8f}ov%q{W*qXv3 zPJRl1x<&k{HTUZ2L5;zy*R&wd)AjMw8%V$h=wt{wjQjeU5a!j>AI@tiQ;kzaU6X=H z7$aDfM9iALD1zu}o4dV1<%2WHi_jVd|G>PHTM9%SrkBfj^TW?GCX$4Dq}yEL;)UNA zx~KLU7Va2$aeeGuO#vC6)j5wi8)f}?O87BY@!!GRN`#$1>tU~B>p@&7o6VIYkq+_! zKxaSX|4nrC4m4V1%8WQ9DBbCbjL5;9#hqr^T&(7{F{v^Of-G0F-E996xtmeFoZFhJ zJw7n)2%(R9iZWaaYN>b~j#D+u4Y#))FA+?hAh;%K?gtAm(Rlr&8|IaA&QC#Za&Mx0 zlop=0w{`iYSi}|NpIm4)j`7DhF0u0uOf~$rOxaPF z+Eup*tsV(B+V;kI*Q9xhwOltC71EXJYX^Kv$Ta%MY(>UM`{p7|5%22%tt;D34pA>4 z|8L$W+jWOajt2zPVbk`H4XpzVI0#A*@ywdKG5q%+rTQp}t2%?9(icB!%H#8!ijhBU zaD87Nq6B6=lzE_d&se9NnP!y|7A9*v*Bfyh#AceCB|R%B*kknuEZW-aJ-^!JmCH1B zCMPQGELk=88AQPsM(ryHis^n^rymahJD}5)9M*Y|owwbVQG_K)=GyoJD#RfnAs=We zs0d$~q^$;A=)*=XG5Q^cc^VLBjH1_#~O6oLZ1$q#TNbYb-0g_ay)G(F{W6)Cuk)jdB*6-{^f?-rp@PZPiEz zpc8$u-g5+#pABl1dM26zbJ$jv_dJF5m1uV~*ae7(tm%RsPA^RZuC@-hj=I#-*yo2*~U7w|j!a$_j{j-EQ0x?+-stJr_mguC@1E^4s`_ zR&y7AM%5q$C>)+!Bqo{G5X7HbT^$ezZxpa%7xfDKja7tSjY3yz7G&aadAyN7_Cf*s z_5#%fWlC2OR4e3O{Mpn2}J?NYredWD@a zdZ0nW@8@4wcWIhxm;R-anFD+1HHl6TWsb>H2|~~m7>b$V;4-DrY77FyCyr>r%RQ-` zqKRIC64x$G4zk<+)ma>c+B2L}f^l)5P!)JwzA?$a?5=_Up#3W6083GhBFrSE$fGH0 zFT7-yZmPCv^c0l24FAV@qM(gygd$RXk+97#2BpfRr3R^o4uS0r@g*+cSea(OU~m4| zYk%4cBUsGeZ$4L#BgfLK<=YPaLU8Lz=l!yzFrDss{*ROsy9Xq)Vd7{c{p@ zh#=6^>-{#%o~iT_&txrU&8-2wA8*g_a-}-S?Knw*QxMwjZobZBT9$HFO-w=|(N+V0 zO|5}g0SD)6RLXq9!dpj0BZOBF@i8A;RQ^pk?trWS#Yk4w!LScZiUvg0i)eiYN9x@@ zc@Kyx$RXKiw`n&H?D^|eLU=IZT7!Ns4on2GylDeLHOExln8&l%CcSU+y!G%w5Ji6y z5QA{Q$Q=0jU3PMR)OF1+#Wkb|o%!>v@*tRASV!eq+wYTl3RiB0ty`R2BTybwh??A1 zGc&H15gJJvIBT_5qK-!O!NeP$hv`*U3vDWD&vf*=CDzQe?dL(U_0-?^vP!!T>0ut= zgI;OLQRf!5aPFH5f2(<2AS29VWqE3*m(E;3A&!62I`2_^KwMtiI37^xfPn|n%pXy| zfPvCXpHN4D5!qi|iP=MjrmIt~e#SJ6a% zi}rJKtqa~42yLz}w2U|Q()#cU<3tb3Z`+s&s3ZEgqy~x*t{UCJ*kC{y2z{@A*0c>e7Yel;|MagiO6Ni~Pa^7F9aocVq4PE&M9B+2|( z9qhQ&X{e1&!4JaTU<%@&@)ZaH$eW(KzqIaZ$xEo4$d~DjCEK0+pq=P(L1DtQdL#@0 zVSpXk6flW=48W6eT1|&Ej0Ab4sj>hhooKzQI_TPnHvyl%ZkQQGTsyF&OHPcFKcw~kL|MV*E%V2lA7*J% z;{jNssIR70w#P}1Q20Yu47OD!>bjx>!haHi5lq7&JmZ=ML2!f<5szefKf&7J3dpFp zZXuE5vQ`rkpS7BRu%#@DPTl7vy(1zh$NP>*D?->w{UElTDAT?GgY`n`@)gcWN#gKt zddSwVRaPwFerTR%tzVY%valwc9Uj^?VFNB9KmCeyLuWA9Qq&3MSEK`R38#HAu|vf! zf?84w;9M@!H8qLKZKY^r;FU7A@=zMY4ov7ctEv`aaVZBHcKW}-B{&@75q|Uc{k*)a z5bWSIwy`z2tq{@!G$-qc)<_Qj0>$P?7NDg5E+ADO!6_%c5Y{RnMcPV05yV-a!R_U+{v znej#YHT>~sLmwDBt%6PLfwseQC^%Ee9RqOzCE;sQnW~c$I?mb?BniN)Jz}zf1kLX> zcJ>waq^LFky*+0$LwDz~iaGUG6#1J3Cdsc`PJv`-8ZaxHlU1fjH5I?h4%ac<4|V6W z)si~d)wsZijbJ4e#d&{YUv0u-)PIu%Y<83I96Qj-obz!0ee(3|4dmW$J1hFUq}h`A z^C_D6!c48OGdQoPHuax`zX4`)R6!|JJ8GDn&F%m|a?`20!=T}5Zw>pex#c}vY^-J3 z3(OX90H1A)OnV&e-tnz6VS_NaC>LCqZCIS9r;%x!=WN0~1dbG(YE7Hd8XD&mYt7VEPOuA?mQ>$FTkI@NeG)!PUNv}ul;VPHyUF(7J3O7&fy_C= zJ3fK_E{Fx%qhQl*yrlshX1U3Da)R>X*WS*6r!x06^Z6yA`0>pM;VIn?3_muI(XisU zN&2J#TD)frAk~1FmqLjBdzK>IM)5hqP=OX942TjL1+Ng3jMj`{rf~u{3!Oq^uIy2Y zh`AVq7z1}!LIE+s!qpLaV5D>8(nJ*C9<{~vP8#$6SavRJtH-cK?kR8;gQ}f2fkG;P za0BO~bYqvUF&E*r^aLMiSW(IKfmU?3Vw#U!5GP!jk{ zR?AX;+GxoQlTqT5Ayn5tgK|O`_}QuDAJ!VXYjBf;z0it2L9aCE=WYqdt3*bPY`xr> zbq#X(Q^&KnnJ&~>YBbaW{=!!m{e>71_E0@c0;7O|Ux{i6lDk3-@gmqm7llXIy-*62 zl+FeLT~`BHJdrYzVCIb>D{jGYq%g3LBm@PaS3FFOYc4!W#<7-LKM9`KA8e6KScD;a zHo&+)Eh=H92vK*-q`@}~*FQ$*0hV}^?UA;ImRARJ#%f)UPfKc)=p(P$k)8w)XM9H` zn}+|Ww+Gr(vlt@}#;!jD~h`68- zMJ(B8wom)t8IU7VE;9lRFKc&z=Uj2<{UJ&xpk!kCR7(So4hGYK$;EU8R@@DjQB&fB zVr?;7_|RPHPMG~#R7yBanPjV2Q)!>nbdfwcdwhUkd4{vhRb6DlD1kTyIVsKXUTT)X zds)zyi>y+n4Bly>qJ&{WMIb#}IwQ|u!7lS{-Dp_ro`o2lgq}kEG0+?!F9*f(bFIwr zyg8B^;W@}eqJ>&06wn6T1CRF?jgl>xa3%yqoU3ux>b-G-2{K!6Wtrz)X0(sq7L7ly zq*g1O1NCO8Xi#=mNmLAU0=_c-Sxc>u8^?Uhq=lYFmYq;a3%12ThmW+6MdLXB$}uFh zLe3~wmaFBxIGGCuY%IsJl^%Pp=3dLpY|PJ!trkayVH#)7GV*>qPRY>_>zH$>eJ+n} z!GbHL#S9&P$T~iZ4AS3V_YC!QzBslDVKi23fY!7m6EjM2*7B@DbhT`G(gF6c2OMA~~a-Yb+Uw{>jL%@TVRhkNqdhv9= zr+`oDmuvB&RZe+IE_uzywZVboMqL@7-S3vKv)j0XF^4P`k2UmKTDz#|KaO&5tWmL= z%shO4$Au=>nG=Czy1$amEPLXL;w*X}{eg2}06n(ZepnNvycN0m1N&v3!J2`F2^p2J z^ilAo-8L-Se5*9&c+R5pnE1)y-Rul;q(^h!5R2h*%(_&?SFn6T%pN2|6?zj9H|qZSxOi3a|&Ws%8h1QiTF^3*`Jc=7RO!wBD~*RfLjs z#B-`953v($8SVRT8#iBG1z91#sy*_Z0LvY&(=hNTSqsrtK?7E+Royznivg*|!jGWk zpl?6%G06K2^awNAm?<=8dE@NOE7baRB4)+Id5e?4s=5k$R*qe1=39GQ!qzQMpYX7ck5TpHLDcg3l;4`eGvLG9WicpgJ1cl*XG9l>~>|B+GO z#mYW(!*pJS-~IoGt9J|zq>H+RW7`wkwmB2qwrxz%$;7rfv2B|Z+n(6=H}Cu0s$2K# zU%Pgn^Q&ujowL{4YnffPRU;yJp%llLBLqwu$d{Njv7p)TrSjuIQerZzS(HxNVwbb8 zAsE>=CN)Rs-qa=p7@kZzMR2$+(ulXC%f2|Sg|mP*^}!O1WBavxYokE@7t;We<7oqB>b<<`=LsS3LVP|e>quTJDu z{wNXYCu^Y|#l~#PPzJekS}q@cipRWmXj8%tYK&|?M?-dQ{%Det>C6BNqTCWCbs)ZZ z$Lg+iO;3#!Jr#|3UKMf{Zsft2`-XUxuA>tXTe}I<5D*(!$a`rtwOYakzQ=|T0tERV zi>K%jaLT@-r7~-@E1&2B`t*alUkEWZ(!AZ#?%%iz+z$509DVxU%$q~4R8=+eZSRZH zla^|!T~iX6^!48A2kH~cR~7wbDKb*WVkUyFS+xJoOm}Z}hl?0OUOYEO4%d+{y+=(nM(YCxvfc0N zAnDVhd{1mKV7Fe`JQB(7ml8WTV=VXp^!qUVIcCAnEurtz`o|pfa+KI>ttHy0>2Z~Z z*jD$!398U?A5zHx{m^%bS%$S>R=g^b6A#VM2E&{f$t_Gw=m;kJt?qEsQPl&=a4@4_ z>QygnknAb$iS1X0%@^lyBA(rn^Af}Nx%j(jAFjVq*FAGu{6D(FJ`<@w3Z?pQL~?$n z9bftQf5dfXpnj#hEOQn_H+m1-oO}l1CsCDT-WR8ndpV^16OtS|_?nmcq^VxpB8Sc< z^d@tsC=OUiL6b~HAPrDvmwZ0u*SAd;o#<|bY8tH6EOI%b<}7wA)zmgieD%16o^vbNVuz2~WXV8b3=-6R?t zhJW9O7>Ie)^YRjq%JB0R+6_7KXexx4LD(*1hny2SnUYxc?%g~#COni|wH*X=8UKhf zn9xA+XoGKOK5J*#_`_cq3r!cTQzAP-s*?Ln_O<%~7#5%-xTr0{-I37SJ{i&tBtuJ+ z5T(~QeB{rXMbB#gUc`klAg4XMB{&Q0ggjV zrm9Y!FOjjgtSBq#amJ>ot|F0D9aW1su#x>C*c>P=7)}f+}}^3DHSwhQkE=-&XjJdL^GZ0tg5$T`E9?N!o&pi0OmyA3rws8|EG) z;{SLlA}1-K!C-)ZaJTpoVXmS97Lo;-8b88~YJY&aaXuwnV_1K{qbcluYaEKH(bXeKlLU^6a-JMDq=b@Ln-GpENl>#GAZ=`x0|U)SO^+`!Y{`Otu_V zLJsCXLl!IZn;1qNx{L2QM}-33rNwXsH|7#|lk|-|-aS1Qr%jAKU&kvyyoD9QmR3S z6Zyu2M_Z5}+wT2Oz(8pBYn4|XTz)fDI!srSti2YfAoxZJTzR;&+O{=PBPB_RFA zu^PdD4dQ(d;b{g{q{w|^PM6AWmy;J#H;tz{<1tVt@Q*VRE%^FbPUwE*BvrwvkZs-< zTXH*P^kJRzs#cH1b-5@`02u)VvIDALduGwMnVt2r2 zl>aizgW34)`WS)IJ}>Nb4c|q`g*olJ3nKZ7jGGg=F$@Bcp=_Ld$E z%pjQm3Pr*YQ}w?h$Th@7NBJ*ocEqeh{_nkwKW4&zNzedHWupI*8hM!V|0T=vFq6Sh z|EF@irFL`$K|w%j!9YOx{-dGC`eVYjI22%-gZ{U8wGa~<_P_AH3iI;+WdGJ++WZGr z-P3zBzyJH}H=zHy4NgO2LALm{U?TmWm2s_@!I1y$|JIFZ2l2mUoy@OE!i)w2qRsz* zH>ILnV8H-QI=(LJ!?RxoxqBh@;{GyyNy)N!@-GMRX1q%a;R0xECv4U5gkuF^xDcA1 z#}tH54IUm>A0VT0l(EBPiM^X!-S74u4o{6$;{r1CcI%DFk}4?|$YzVo-Q^RVcHe1x zh{{Ifnz3J9^tU!lhbCvSXeuZ8vCk;!BDE8#pY;LTjK?^59&(%Si%DkoQ0(sot?OoO zzo{SjCmvFz@yEQRNH3T7c4lK@aNc#3et7~T`ZrW?uUBYqoZKrMTdh=3qKe?``Ystt7# z@0l7Xr;I7Cl*DKgtZLSpF6Qi(JVrP!!;Ol$L-^Ih%u-`rG(N^N( z=-esIYM;bQ!HgQPh-2qzPXO1qa8pr7?hRP%Sy&n+V!>^ABGWX|u;1A)t#W=>$Xj^+ zZSOh1^jwCPSqa8b;??%oGI%zWEXgSQuH76cJSx@wKo=iWX`8VmCjzI9uydbRXJ_Ea zZ*l3~lFIq!fLkZTe$F`I(p(MU05Pf(#>b(j9K1Xk(*!*ew8C5q0mEYMCbb|eSBt>3 zB3+x|@Z%Gtab4SX!CI0U9KMVMuWk}9uir)!rrU9W^faddT-b#-x#7A*nax6aun7WK zKhI?8+{;{bc{i{&f0VN=zR36s;<5$WMC92wdmS++`$5DfBU#$#nUz9~Co!@;jXh%G z9)yW3KV1}&AyB(j?S5G9){5s{5QJXF zbTrM92>|@hovqv7)}%ofESV*&w$d{)Y_QJyy{P!Cg~tr=`O*~*2PuBBg<8d%KgLc! zcQB!aH2u%$@NyKQ;jo^QF)#cmXxml~`{l+wb5cEEb^L28zdeUGt%Mmfj4l9`L5p-N zW_Gg+;fu#jy_mx5LMf2cctRS+$ZY=WmBV_lF`;Bcoh!8r68e3~EQVRsxS|oP9kww} z0~<*cmM&!6%9T#2>%*G(hBQAv{&x+%V>WNsVA$XiY}`_e+1dCxvM z8(!z<93g){Lz@MVbM(5+Ux$9+OWo96K`OCO_jGe$&#tvEf<_MYzUEIF78;{8A)2is zQEZg7~kJDr$JA}a{?E(%<%=2+tjECzO2yIwAW%`YmZqnat;XM-e=#-!iloBsL!>dXSTcy%4KfOw#knj|M9 z^#xkv&iGjFmH`cS)@9zkMIZ)rm{+9#KnK)WEBsM8?Z{pCZZSIZ`vSh!vADsXTl#Tjt8Pqz<`+AmeP6w{2)bd$vaSi+;lnH zftOe(F$-{#H_+Z9)*tEPi)|>-?8%v}d(%|8FVp8VkvR<|*Kdh(N7U={`iE?MMkTx! zl#=LNX=YOMuMwgY3JEF;+@;3tc99RR=_o=npx9*vt&B(=6(u^Rk>V5iT8f zLTyY*Zhfu?82W5oNJl2_nPa+EF5RU^+%K-Q?0rV@pN8f=aJ}S>!jH`fBj!x_?y+Rf zCX&-W?f|l>2v=-fO+QLU$V&Dd+#@B^F}1;CFu=wQ!2^pIe%5Y6BW5&>K`tEXop~Qn zybv=S>blE~Aelg8lFEe8!wSnnIn!;&8U+*GgCB%OeFCiO(j z0uU?5l!FB!Uftr%a-~E%G;fH%G85LNJXAmGI8{)R)AD!g6&;=B^`((UH1~J_9e?Ja z&JQ;Z1KkgUpP$w&J<>JUN0GVJ^N}q~N6Rvef(O^&pi+ca7_m()sad_y#`CjI6|EK7 zi6qI5o&2~T(U2KKT6JT!ND#e$^)qPd0IO++xXB%2SIC5Fd|FN;q@3gO_#`{(u!e7} zFYsBcKhVG7UP;s(9Wm9(KYaKEe09Bre|qx(YzBXB=GQ$UCt8H`_eX{nUxs|{11QhR zhy44y7PkOjIIWxI=^lax2TBVf;X9Yqf- zH7W9I_`^TDM*odL096}IeCE9%PVTPV#oBG9Ns~E>FVO%3$cKoojNzFg3`@yjsQT*XTvicTAOG=)|6V3I`Df zY$7Q3`EL4|F+uZK`Om+R#WCFR-%V1_A#v_vG%{aJ^)8X)uqx~MZ3tyYivQT9#JGuU zk*85wp`~A7_`iw2{(f3wpx=c1_3dv#CG0*uB{POUO1u9aWOU^e04EG;8WWEipRm~4 zfP1PK?exYsJZb1maB{^$AnNGLhLQEdIvpw`zgl_HwdB<+(RQ%BD_k7g43tW%GSQM% zbv?blhSvR7=-T^WWlXCo5aKBN!Hg?k>fv($Lr!#v>x7P3CDVnK1h(30-5N zW9Iy~$XP!_?5~i?^}5Hzao#)Cvq}52($rH0qQ#Sny90iO6|PNC{%7C!rj_s2Z($~} zjvEc$pb_AmpOCEk`t+#?EWXWc8oN|7D2RSVfQ2cSReKR*&`;N?nZS~I8V;tBau~0 zDE$z4xid_bBpAEEV`n+xCpPCd<(C8M!Hl0r-i3n9V{G0#8Qmo@Rf>m~&Sx}KbhadO z_(N5^rYCOZlKWjL*>g=|<`~dNh}h*(R8@!}e(4xQ4AfzL z14?b`g~HigfBtTKQ?orIoCRrmSvcN$UI{ARH5sQQbl8EYYBcUFZ>2F4Eo3Mno|E}5 z25e2#g)GG`14UZV^NiC2`|Q*z+FBg-pMa=>7p}PO~OK4KCac+c1I5Lbi~d<#fplWTFR}_y|yJ&w0n{7D?Pox z1e_05Y5C?7X0yA$?^&~4qsJ0~n2~6dQ#z8jakJx+?|vTl>(qoc{LHF^hy)4|3{Q6` zCQldi1LIg!`=AB?>A5Vs*Y0>y#nicuHo!S&0_{a-$em7Cbhf<}1t-_Evf>)rymG$Q zj~3C@MHLlB#eGL~>!~x7?g8^o+XMr`^86;B9%u>Fs^yn$E&i$OrO!we8VlnfB(h?? z{d)Q*FirJnTp${5@!)Jzl`m?>;@J~%pV4F7DB1+>Qn{J|>iH8R0r%K^b)TAKt=t`; zKq96-*BY+W-*vnt!rJvZRA?nz$)u`HlyailsddCCRbQ8`miw`Pg4A8-wbT2+qbq9-)WBz&uhb&g{AcnQWGe_+8#whY7dq zjv+ZdC;Cr+=-2)7T~#fr;@rBW9iVa42Q2H74WJ3QYP_wg3!~-c$J_RcHo4J`&Gn}+ zObvKyE1UIK9x~i3Ypa6uEUM0#B7@fRChb?@YKuz7%*@0fdR%OE4BudNu@I8qhr~2R z!z7tjS_pXYjBx01Q?u)-esIDgfsgL4LwC)%5Wbdh=@{M-&ez9EWKTVVG-p340lD~M zRoGA0NA`sC$>)3?xniZgGPHL4x_R%6uD-o_o%1kGEY5II`eVMfbmxByXyx0W!a`x@ zdAu?Y)5K57Y6wt9NFp{`divXT`sT@^EMO&!+S7R#h!Ri`+ez$_pYA1O+bxJxdf{`5 zJO{XapvJWUTUzcuUI(y!y_05l;A_)?EMn#`T79#PI2##X0YdSQX4DI3n$VGT0R3^Ujax3; zBsna5)P;{#?hei1{;SB zz9tAex+ypGDWu=(Sx&gV$qLiaD~M%Xr20`gZBs+llRE9VLe`P7KfE-eevMs^)BSdb zcWBu0MC6TQW{c_O(n&2x0;*WP8~cdV7zxU&Tq``jDgMdc9?VG%zY3;YEON!H!{qS!bh zTJLPjo`h9W`if3wm55-m-whIm6vAbX)TiM(jyIi;(A~@S(SM#M199gmIx3TjVG|9p zo(vb6V-UJV!ueb;`v(Mv@napw;jtZZ_8Mwi26YtM(?FJio_^t7MMaB--r2pDV5iE3 z>~-f-0c8`dS^-}%!9T^1&G)_AWOLs53ns4EEXdAbf_{VM;)_0Sh8H2I^m@RAevXPO z?8)4qT+j;pSKWFzz)s`_jL}E?-r5sq2+VyE+WQL4J^XW_yhtnW*bSv1~GJ;O~DsYmD`LXg0S(Jdk zj>%98+MJgi-A){>%tb!@1^sK@Jj8&^wjhxTB)r0@HqQ}Q{q-m$TLE2Vm|i4W>YaT# zcw~RU!r0sFYmU0C7Y)5E_BJ{9Rhv*+1ey%Zc_ z@;kMnvot6x#jCwq)wWvav6(i4-UAy?%aqrfcJslQ2K}jPBc*C7%TvLPa^kzqh}Um@ z6@l%?L0+K20C7_^B~n#^VAc82S0M@hCFV=u>od>{yDD;Fc4Omf{q5Ok0bNKCA*4W| z;D&p+3i)Q|^mI4Y^PeE~DTh*p^pVzyc+5zy_>XvO0jI=d+P=9f6|KoTGTm71pur6+okcU%9Rk+%<7VQ5`IEnOguX{N>nS>8yXQhj4e;DGpt>i88NO3%4tY>SJa}2 z%!yn5Q>uL6scq|8mLF0WOuI~TfnC`JJ_hjC)5%K>PBpHZ!D$9bdgl`deC2Bppb29I zZ~Vfbd(z0`l7?CNd{8dj6Z&CPLhAGpmAc1p@2%MKPf1g)zB~enM^&LQb9%kY;asX^ zu{^@gAPoIR^4${A)Y*k%?4QZY$f|vMhFgNwe*fk+hBIcW*KK8a4o(aq;jY}*>ml&h z$ki=wBb~RnGlimUs;4n(J{+&u(1HzDd#t{a!qwhGyIM8>i1#G&&92EG(cn7~(v;hm z=NpEQA1+?SjYsWx>K#0Ft%!>(3R>UQ>Z}&MLZvmZx6RBGkB`2yKH%iF#X8Pg z8rkvo{5XYh0f~)$Y3%v*@(F5m^B1^$EX9qv>D_QJ*zP)1KsK13TsD;L%??k`|KVgq zEUSnaMvMkUw7bP^fDM~ZnZD0D!j?TdEQ6%^TyRMF6HzQ>V(@-SsUR@52x`)YvIl71jO%~s;iYyZ9PbmsDFHRs>BdZ!N zToX26%9T^4W;S2DIC?kIt~jTlh&K`PSQ&-Ultm>8R=!1Z;zV3dK_;h%e~7bnoiD%4jbK z3BV^b5)bTENYfh@WN+o0`tzqDr~G@hjI`SRP?v&>`zILPI(u z1x52ZQ?4Lvn>fgHEut-hz|G64_l*}bz4x9qKW9LW7(aZGow&!+U?kv}Knga2Hp{jr zWq(B|;oIElF*`IBqX;)(9e-l6l1*wL#K8SBM|k6ItP$BJi=mKl2qIAIxDb5`#^s9@GeSzMcAq_X^om@|%Dra~H~tx*sg$dpUCzdQNya2&8F+_4?=nRHe; zfb@JN=-=q|))NTz`wnn-c>28l>ECnLvYR+?KT;Y#EpkidGI!zIe?2we>1bHlg}3#Z zUAXD6q2%ph2p?^u8PxR|tNuh+#|C0MDwcbfF6uWtIglQyMNZ?a!CafDK$Gv<6F)Z9 z<%&>hoP9zY!&fAIB=E~xE$6^W)(K*mUbZQJ`%Y!lJa zXfNfS3zdJRkU+0`i_dghKYpO>h0!h%8XmB^Pk{kNO3iNU#^X9&<`qa++NNtw56j#>9%Lz|Ux*oHLWvcoWifDUQEDG!#6g$M>ia6hUk zl?dPy&yk#|di_rRrdh3VfE=dZ+wTSEQTM3V+%Z{{49Cln;Q_x_kw$jb_v6_YjwVwV zT++IY*T*`cmP@aK%ew`Fz137@D}6<+2G#fE+^SFjL>SPmV3x&k@QA1^;7Aa-Bzfy1 zW=hKMnuh0~lU|44j|91L`3SNNx{Y#d)9owM2o|T5ZONidai)`P=I@Pk$9o(X>!Vc( zzad@-bdkge&%NUiw=nMdNlTuU1V1EeS8D{lvdS%LmV&5}CvowW-|8MUI0EkZj|rg2 z4V`oTiwyXl{cUcYUSVAF$byznED7SBH?aX*6s=+2EgWIu_za{2y{_Lq_`A}Ge?a; z+e`t%!+jk(DO4IxR{<9ZQ#qqwKRpFzs6dqrA60C;g_(X`{J4NVMaEC@?Y)+=z&b_; zcB!bqQI*+1;Ms&20xA{Lo5{!gx4x2}%{kTEhUzz67z9O4>aYvL&XXm}Udi4o*3Mre zmCAtsIMOwt^p`uAw2PeXx@2m%cR+1<~F7d027-@`&=IeD_eaxwBzT=VN8pf*oLJ;G=qrZmFnYSPT%$$qe zqT<43Jo9l@gChQs36Tdcv(YGpZ-Tqviy?LNeqYbBOu4_Tao>|DRd@C>dSd%@S?6t<8$y)t;P{u3ApmAA)~+aGcbz!qJVSM1|aYvTR0n?c0&D z&0Tfhmk!I#FC{5$67)IKL^9U1Q$)ZqcusXV0#+mq_Pn4}qfW^k)?R>yV!28yd=SH_<#B73C+nS&9lB%%b)oDWpr0?vMZ<;Zzh^hvLL2gDWcw zfA0iW^EQATo;l8mDL<5KB>r(k0I~E~hT0AGWE2!!3nHfYoYPPcg1D&3TB+byG~)E-?3YDvo*o=B+-4b|;$CQCo25(<)9CIbu?uK7s@3n%ED zMa!YX9=nPKoL4TKNQ(XMT&y77clHhPoWG0xcg9U=(Nr$KyVAWZ^inFK^{sU5 zHRTz4+G9Hr?g0Vrt~A-7d@9gT!J*Nah~QS`gV`braJ&3#w#(qJg~ES#p%gbO=i0NF zZdk<$o2vlOZWWcI485A)$U~61awWjD zbd^!%M5h1EBOPCOfab6>|F@C#!eFw5_3jT=DDU=UznKY-_bHv%tJ0|Gm;A{ z-$8^zHjFS9r{0I!INe?j482Ki7$D~nPSC5sE>TA^#P$LQY;ya*ry!bymSmvnCb9&^ zoMY+9;MRle?p^ivYeW1#Ptfia(N+a5Y+VWqCdRq=8JN!0%{JL0A=FyDpaSd1Xk?#+ zh<9C1n2`%CC;yBnH_Lc`{|=HZ91`T!Ye>)5VkOim^yPgO8-`GQ#i=KhJUc%69lA)? zKt=4A{LW7x)F*aoyxGij8AoMa;r*`Y*f7`cIQ&V^CG9Y7&t4hYwlF&OV|b*I>q37s z_lnT|J6{JcGcKVllNb9%jThW(&{m`L^oo=={0jeZZ9T^z>o32%kD!_Dx({KRB)>bk zrIiK3KU7l7Y!T^qwcx#>zpRQP5L}sP4gZ>ot>GO3pX92U+#MzLHTWCclJOy_k9_`mwvt#fWi6B5{FIh==+3RvF`KbsTlFc*`Te%!Gu)R=kBg{mZggVpj`EBz|Adi~gc!J2pZ?X{1#aU#?Lt)< zQw+A3QZhg!BM8McFs{OaQ>}R?lVjPhmG&9x78fE~Jye!+JcX@MIuRVklc2x(Atso9 zvu!D5Q`CB^WtUi0O9~Z$H7wAe>EqiAtrP(S7193OY@D*yoh(r#a20VAAU%)T<&0Co zmC{%61jA=oa2!9Z#USOvx#OL|O?K+9Y>rckKaF-_98Hn%w2%+ELpo)CT13!A~ zao!p<`YA&zt8OB+hzH_*A1%a4T5z-5p3p8^+hps+ea|KXk3-EfOICA`GI)0CyIPqc zik@Kt`!4;+kBunVe$bZN#-I?l;oSj&{sCn(e;(EE+e`f7Y0_VL2QC|qoXc6`BlXFv zQCBZ<8J@Q5ha-=FMH`kk`-es!8b_*{nu9IvGR+=8+Pl6zPog_6Zfaz$dL*BE9a9s^ zCZK@4^H~OZtUU!ilh@+$qRIw=;lvv)cIO*Qdr;OZT~p9MP-Rcv%F*yvGjjp7c_DLt z-e$mFOwBHoT2TsJOctBk&F{yoM`*)vk0YAtqXh=>{P`8gMAdUmY=z>8jpxKo4##YLDIp-n1+!{OfP*Z#9e7FJwv4=WFlb@1F zb=VaRU$`S%9Y~asAjw^dNh5&2c;$JxBX7lv7GD?`7U3crPW;p0yEHY-me?u)UgVCn z)BZ(~s4qt90K?UJu>|Fg0z<@Vy7yOqbTvv^ZjE)G3mmr&fw^tG6{blf!-t62zo1PP zO?G(lmoC2#zP``bC-^DmyjEA(mKLF4zlFn}SU684$DM>RVxpf1+pPc!%r^uG%eV@R z&CYji$l+1jj`(%uKT8|z2q{h=*Ip_W@S)&qjt`*gczV4D_v7^!=LpAZ&d`Y$JqO#h zm`{)FP9Niy9RzPEYZ4t2_iqkE=ix`IzK3#YkHqN9v9V7koIcj#$}%S9hR_f=-ks=6 zq~Aw6qv`CWuK)fMox}rFFDWP8z%%>06|=kF#1V&h<#*`t9t!l_5qM9RO*8bkPb1?b z20WF19zyO4xx%mG_9)-DhIO#(M(WtpR8jUaUHh|e?7n1=WUsg3 zf-O}-K&3`%X2%sOF{{C5L?6wDNYSGnrl@-0&Gp|9Z-6(@AFB-uK3w5jPvWW zd=t^bDdWg$>?INurdik-)Shjw@KgNYr?@;@Z;WzfZ%)N&5_v-J4(Xu!X zcIevc4gc~8_te^5{%26=59LsKXGOC=nZIwp`;6aN6t^+sm!u6~EnX|KFC}|1vm_=OB=R;6XrQQ%*1$0Q>dPhfM>P zS|d%c*2WI2_NsP9PPuw3|8q*=tcwD6Qi(ZsjL<`bs#4^)3-76PcnisKr#URk2b4S3 zBR`=(#cJNoy7s*DO~!4e&fBF+%-u`nr%{?~Zw(Fb?k(t*7gfdZDomv?Wm(&&Yk!Ghm~#q=0op{3#Hug)i{qu* zShDswJxBF>XVM22KbD(&C()2Wuhl^+inDj^hNr+6yv%2Jgu>cNTbJ}Z(N zetlejr!=YBIlS$ZzIA6Pt&s#u&Z$Er~KqgRzu z(iA(A{d#k|J!i$FtbitfG|LdCU^shijT*LbK@L;)XyZs$VKaig?S@0d^RVJMf@Buv0<4*5IJp7;Co8+aT6<_qb2gL zS~!9;9rAwFF+e6@f&ntRGx|mZB3gZq#EM+|jWsMWlq(MJNBR?|8&9BZjJrz>*54JF z5>wSQ|Jt#YV&x4K9Z&YU&_vqiFhlQ8sml(5eecBptc77~CrXF|NqEua+K` z#3~Tqv8W=(&Oc#D6Tm{fw** z=7CWnlL9=Kzj-m`7lJ625F0t`&~Z&I>XpOnnqBygk6Lw#56kDjDq$g&D$9I1XmQt( ze>*Z_`^$4+OSXrPL~%XJ*~whqq!!@7iGj$sJ1=Fe-57PotQcSA&&U8bmGNc zo22CjA)LCv_86n;T(laQyS;CuW`vUpm%!l&^8rL~htNl!BE8V(sWfrqs}Xs_bJ?K; z-P+J2O6}ROjFFt>pN?-$@wIK%9bE}B&)}KLwJ$<%tw6wa*A>AWpJqgmuYk)F?gXn= zu}e@xKIM=9eAF%uD{5M~@#ZcdQxlfkF{7DXY}gWD3Dpr7vr^`0-Pd=+2lZ#g{6*Q0QM@_@WX5#4a0ZK@G^!b0sltBPTuQ+%R6@3UpCY)D=)9K z`G}Uzv9IV@ENP9w$8mUpUK13J2=EtqLI4P)ulGLkN*u+HW@nkcFg2pEa-=L;b>eLH zcas{9Xm*i1Z>@n!F|!pLPWL=SzVd1_9Y~2HfyLk1!nk1;u{jR4w@#UYzi5zGb}=zM zC6rrOrT@%iHX{gNWpDiJbR%zI?EE?E?VKz`6(}Y_BCS9_*=YGlIg0$jzq>LE5(9AV zklj0GHV$mDSfY_W_Z31`?U#LviUB9ZA!boyOl4yzmoxuZ(Y&fg7b_|6v8=;Vo(pbt*{L7=o4(n4w6 zQv;zcwsS2n690!Wf11hd_>f7bgcRtk&FHi}Iyz671jA`VT_A~MG+?wT9h)#q!I!+} zd5B)@>^FCFUgZ$Jk-J%Ch(pCMqkM|y4SlLH6m^lt!d^b_`1IIPYK{p09Y!l zB12=yZ}lg;!G7(9ga=K#wgCLF)Hr8$_pq4kszKKu^@Ezs5;l+Ug2i1!VDoW>?~_`a z7eDCWO9J51gp-#vp-IRL@fu&Gl3z8iac%cweRoMnahl zkS^^ustUD*irpGeu%#=+xh+>WR6FmRqh)ujfGWB9pYSN|kcXflKS*6uyCWOt?$I54 z(Z_#l&=N##k^LUB;uu;Sd0Eg~7=2-I-nMwelesdP@m)4v@uUFk)uK`N5lI_fjb~Bvoga2J z_#QU^t4$JpCF%%pgn8Fe@Eo;2;rB;{?g?jRvoch>Rd z&h1=MIGyWU@#IO&0x}6)(rK+Wxo^O~3|_&Rc&|N9SNY{%X}=r?E`h;Q|0w~5kMz@o z564@#ZCO%2*0#Z|zaelh!IbvpU%it<rJ0`-L z*N{oW8)^Xu`L_{d#s;Fd{$2i|>E`(uQ6yAzCE3tW0*2ZR?C$3Z;dbd^q9*uVcvPFD zl-7!?^=ieR-mFr=*^7JKUn}g$Ci>5+4%k;F<9%GYCEKRMf~!vf-*k3X@U4d(m35+V z{b`o#Y*MUZ!vncl6!yHqYsAV6u2P)OMQV&nM}fbWtMVSlb*i9N6(Uzr_K+J z#NUC!*&*>nrpnbqMa-%k! zIS7KvC^fD!U^N>>VpJW^hD?S~0A|WW=uJ({L#8T}q>b;(ymq5pLqlV^pn^?qkH=-x zD(4W^Ll5f@wo?L&L)NfSj+4gw<>+pZM{yW)_&}UOJ#mb3Fshf!rNs;B0RgDV`nz90 zHfA2s;JLTktHUJqLM*lSy^pbTOyVj9JI=~+`^5E@+_j5dM%jI|I@*yKCcV5rsJ=9E{`w*q;K=#Rt(Zn)I*L~JwqNG%L17bXNj7pN%Z zN19RdKandH6B8|egNGo5@KAQ$aH2f4P~><37#9wH^cg3l@&v~}{IO*AB%3T24fHzy zc)nZ%%Oe&gS24NSh#QedHBdFs*vy#oz02&N&+@wgib{j~jz})X`Z)ETfD#u{r$L;03jE7ifMBfWKfzLjPX}oW_X?7g`IpXmw~O_C+lnd-DEAV=qJ_;^51yy zncP^e?dSt8Lp$3TKlkoOhTcxx9L^bD1VON6Tajkab>~Vlv3^j^9tVBkn5e1`-tPSs zJlfLnD%P+T%I%;soipZr=s29k-XI&u6$D&Z4GnHa#xf`N8yfVXv3Bn-uDmbT_hpi> zS!$#p*Sj_yuI$bxE?aI}X1zF`Qz1AUaqc0t2U5MSZ_kZAB)TAZ4b0y^GoRlcWNKU2 z-^{-~V#qPG8C@&RowE3Nlor?_U=Wmuy7Wlh zwTmN`ML|qka6=wF_DRr+7m3NLq?{dEdnFq zpP*rNuedY$$bN{QGzVBUTYr9pu{$|EoIju5E@tkY91T)b-x!=(z%(1% zw(V?e+s?+=*mj=S-fV2!wr$(CjhpxTZr!@?kExnEr+;^y(=*fU6C8Glwav}cuR*T& z52=rLP_zco@4E#D?wg88A1+qEYiL6j-rO1K5{ijCQ|hEJE{-DiH^oj7aJRpCJfC(F zDXS?IqT8McAg<9=iodraTSux76Z#-c2}87*26BjZ*;Ip?EL{)A!?q8Y*T_vT1r=r1 zvB-nf!4@NBw!PFJrk{?EeVXG3?7BD@j$ve^)?&{5;^=Y zN#|6K)Pe9=BOy~h@7oN+Jxk2{T*zg)eomQOUtrW`zyKB&P?W^S-*XtR-f1#fuR%oO zE#jlCL!u;%M&iUy_8@QxpAjn}Wo%_!74&d+It@sH-o%r*u{_RvLf148sU)LL!+=cl znF#u~7k*EWkKFkLSfm0`I4<@0!*>z2vmoX~tQ^5dy(;%Kkx7F9rAI~oq)o+g<;sG2 zQu-%JfCJy0TCC_fbo2uZIU3kO8lNs1bIn-NAPfm~gEhV;OT(;a;B{dMr2Tp!0fZW~+17@CoCIiU2zQSPjf@b6eJCV8b)$A zo_p8PozuKMtuxH%MiNsbAEtSMmf_kXqQNbklPH?)Y+%4Ggyb`vY8+0)2rV`Z$lz8d zK<&=`X6|2N-jj4KP3^BIG2JV6I5WqT0bft+b{8-e%}5g$d!wKPyaTs3lEmEt&jB^t zjcH-*W%`7=;Tr>L6>WS=lPXy`vGy29u)T^tc%m{wFgG86$~A}$*4fXW9O{XQY*4)w z$r%A5q7ro-t?FvIot4~gUHZn!gnIZt< z;|Jssq<`BHhD)sU4L+DWCKC51zyheX4mx+^*pNxVDwXsCkB~(y40OW{ugT{60@jt0 zSR*opaxz>Pq##~s2-ObHk#~YDfYZ+d>XEH=s8A<@f#J?0t zNn)Zk*?;pDCj{xpSz4MbfiGwQn;2S^CHf%Oxs`?$7G!MS;tOFjrYi3Wz#8*z%*ch~ zl|Ac&_lU?wDN*g9890-VKuK4dT3o;(}<$1>@PMcXY=Z$FY{+3A?Y4+~7u>7S3(rc0a>YtZ0 zjV3j=JEbp$OyI7#v&G>lSNV6W`|LQ)YZUZi;26>Leh`sx=pvg_UDwB zSIFIUQ>4eZU_#Ti(s>R)rQN8mBTl8YETV{=KrE#MgcCw_Q?5LdcX0%VLMpSFJz!*$ z!HP~6fR;sJ3g~kW0J}6_?iBj$Iv1>j5+=~-p7*ua(6L8hjPDpIQ^Bp^uOlF^Oy$KE z7!CzfM1^irf^g^P*$V35Xkwi)Q zLD*qL&XzYxX+NfepZ_i~f{=2&NW^6ID_$)^ znQPl}5FgW{1H9j(E!bV5shj;qmslpFr!1TpRA!J@MPZF&8>RjG=0YjhK3ss=hhb|HAYSLz_cws$E&^+0 zrIvS~2N=k^uN6-VN`f2&<6iAHCt4vhN~X-r*L|`fg=okpNOJaet5FacW7HlwYo!Ho znxM9#7FdeKP)`B}p+72Tn70<#izMI_Ud>YYml~|P`biYX$tsfD5K(7UHH)u(C8O*c znkVFrvqoLV;a$L-^m6cqNk&RPcxM~BiX3AX0)nh)^oK8jhzQ0}N?IHWXvb~Ypf#nK z!BYa|B$jF})Kzp^Pl7AXT8bIHG(jrtQ3gF~B26-=75q!m5*tjgHMz*(iKu!S@}V`b z;xwWHM`V(0n{;l{FbjXxC3qWbhUTk3=Ez~RBU`n%DiuQe6KihZ1FcG14HwPOTWIVQ z17HfJAq9d!6UX>tGlf5_3rQ`)MRRW<1pXkV{4!ESO%-jsA#rM#f)e;its~Mf$&2fv zu!fA2$W*uAp=YLX?d+;&q}QGmnfA-S6jtXNFFw~bTY#DDPyB|;yhL}FmPCeJpSOoz zv~u=XL#Lw8XgH3O7e6Dz*Q83q1pz`^2av3vy;=<54&Q^YAPrVsc%3~h7nDT&I}

  • Y&k&+ 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 Date: Mon, 5 Oct 2020 02:58:43 +0530 Subject: [PATCH 409/486] Typo fix (GH-22496) Multiple typo fixes in code comments Automerge-Triggered-By: @Mariatta --- setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 04b1358bc916e11..476f8c414978ead 100644 --- a/setup.py +++ b/setup.py @@ -1881,9 +1881,9 @@ def detect_tkinter_darwin(self): # you want to build and link with a framework build of Tcl and Tk # that is not in /Library/Frameworks, say, in your private # $HOME/Library/Frameworks directory or elsewhere. It turns - # out to be difficult to make that work automtically here + # out to be difficult to make that work automatically here # without bringing into play more tools and magic. That case - # can be hamdled using a recipe with the right arguments + # can be handled using a recipe with the right arguments # to detect_tkinter_explicitly(). # # Note also that the fallback case here is to try to use the @@ -1891,7 +1891,7 @@ def detect_tkinter_darwin(self): # be forewarned that they are deprecated by Apple and typically # out-of-date and buggy; their use should be avoided if at # all possible by installing a newer version of Tcl and Tk in - # /Library/Frameworks before bwfore building Python without + # /Library/Frameworks before building Python without # an explicit SDK or by configuring build arguments explicitly. from os.path import join, exists @@ -1908,7 +1908,7 @@ def detect_tkinter_darwin(self): else: # Use case #1: no explicit SDK selected. # Search the local system-wide /Library/Frameworks, - # not the one in the default SDK, othewise fall back to + # not the one in the default SDK, otherwise fall back to # /System/Library/Frameworks whose header files may be in # the default SDK or, on older systems, actually installed. framework_dirs = [ @@ -1924,7 +1924,7 @@ def detect_tkinter_darwin(self): if not exists(join(F, fw + '.framework')): break else: - # ok, F is now directory with both frameworks. Continure + # ok, F is now directory with both frameworks. Continue # building break else: From 256604fed295d5f435bddd6ab29d7b1fe0a3a964 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Oct 2020 00:55:57 +0300 Subject: [PATCH 410/486] bpo-41909: Enable previously disabled recursion checks. (GH-22536) Enable recursion checks which were disabled when get __bases__ of non-type objects in issubclass() and isinstance() and when intern strings. It fixes a stack overflow when getting __bases__ leads to infinite recursion. Originally recursion checks was disabled for PyDict_GetItem() which silences all errors including the one raised in case of detected recursion and can return incorrect result. But now the code uses PyDict_GetItemWithError() and PyDict_SetDefault() instead. --- Lib/test/test_isinstance.py | 10 ++++++++++ .../2020-10-04-10-55-12.bpo-41909.BqHPcm.rst | 2 ++ Objects/abstract.c | 2 -- Objects/unicodeobject.c | 2 -- 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 91e79c295481db8..109c3f84a5c426d 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -303,6 +303,16 @@ def __bases__(self): self.assertEqual(True, issubclass(B(), int)) + def test_infinite_recursion_in_bases(self): + class X: + @property + def __bases__(self): + return self.__bases__ + + self.assertRaises(RecursionError, issubclass, X(), int) + self.assertRaises(RecursionError, issubclass, int, X()) + self.assertRaises(RecursionError, isinstance, 1, X()) + def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst new file mode 100644 index 000000000000000..388cfea065eedcb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst @@ -0,0 +1,2 @@ +Fixed stack overflow in :func:`issubclass` and :func:`isinstance` when +getting the ``__bases__`` attribute leads to infinite recursion. diff --git a/Objects/abstract.c b/Objects/abstract.c index c471f184f6c8487..c30fb4eb6a604e2 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2336,9 +2336,7 @@ abstract_get_bases(PyObject *cls) _Py_IDENTIFIER(__bases__); PyObject *bases; - Py_ALLOW_RECURSION (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases); - Py_END_ALLOW_RECURSION if (bases != NULL && !PyTuple_Check(bases)) { Py_DECREF(bases); return NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index cf72238a8d05854..6ae06a508c6140a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15734,9 +15734,7 @@ PyUnicode_InternInPlace(PyObject **p) } PyObject *t; - Py_ALLOW_RECURSION t = PyDict_SetDefault(interned, s, s); - Py_END_ALLOW_RECURSION if (t == NULL) { PyErr_Clear(); From 245022ffbec4aa24190f83ae5ed59c3ff7518cef Mon Sep 17 00:00:00 2001 From: scoder Date: Mon, 5 Oct 2020 01:13:46 +0200 Subject: [PATCH 411/486] bpo-41892: Clarify that an example in the ElementTree docs explicitly avoids modifying an XML tree while iterating over it. (GH-22464) --- Doc/library/xml.etree.elementtree.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 7725e4d158d429e..f4bccf6609810ee 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -251,12 +251,18 @@ We can remove elements using :meth:`Element.remove`. Let's say we want to remove all countries with a rank higher than 50:: >>> for country in root.findall('country'): + ... # using root.findall() to avoid removal during traversal ... rank = int(country.find('rank').text) ... if rank > 50: ... root.remove(country) ... >>> tree.write('output.xml') +Note that concurrent modification while iterating can lead to problems, +just like when iterating and modifying Python lists or dicts. +Therefore, the example first collects all matching elements with +``root.findall()``, and only then iterates over the list of matches. + Our XML now looks like this: .. code-block:: xml From d1e50f9ef035218f2b35149599748517b1997358 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Mon, 5 Oct 2020 12:40:52 +0800 Subject: [PATCH 412/486] bpo-41428: Documentation for PEP 604 (gh-22517) --- Doc/library/stdtypes.rst | 122 ++++++++++++++++++ Doc/library/types.rst | 5 + Doc/library/typing.rst | 4 + Doc/whatsnew/3.10.rst | 23 ++++ Misc/ACKS | 1 + .../2020-10-03-18-20-46.bpo-41428._ju1NE.rst | 1 + 6 files changed, 156 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 62f39da2a72a2d1..04dfea276d2b1e5 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4743,6 +4743,128 @@ define these methods must provide them as a normal Python accessible method. Compared to the overhead of setting up the runtime context, the overhead of a single class dictionary lookup is negligible. +.. _types-union: + +Union Type +========== + +.. index:: + object: Union + pair: union; type + +A union object holds the value of the ``|`` (bitwise or) operation on +multiple :ref:`type objects`. These types are intended +primarily for type annotations. The union type expression enables cleaner +type hinting syntax compared to :data:`typing.Union`. + +.. describe:: X | Y | ... + + Defines a union object which holds types *X*, *Y*, and so forth. ``X | Y`` + means either X or Y. It is equivalent to ``typing.Union[X, Y]``. + Example:: + + def square(number: int | float) -> int | float: + return number ** 2 + +.. describe:: union_object == other + + Union objects can be tested for equality with other union objects. Details: + + * Unions of unions are flattened, e.g.:: + + (int | str) | float == int | str | float + + * Redundant types are removed, e.g.:: + + int | str | int == int | str + + * When comparing unions, the order is ignored, e.g.:: + + int | str == str | int + + * It is compatible with :data:`typing.Union`:: + + int | str == typing.Union[int, str] + + * Optional types can be spelled as a union with ``None``:: + + str | None == typing.Optional[str] + +.. describe:: isinstance(obj, union_object) + + Calls to :func:`isinstance` are also supported with a Union object:: + + >>> isinstance("", int | str) + True + + .. + At the time of writing this, there is no documentation for parameterized + generics or PEP 585. Thus the link currently points to PEP 585 itself. + Please change the link for parameterized generics to reference the correct + documentation once documentation for PEP 585 becomes available. + + However, union objects containing `parameterized generics + `_ cannot be used:: + + >>> isinstance(1, int | list[int]) + Traceback (most recent call last): + File "", line 1, in + TypeError: isinstance() argument 2 cannot contain a parameterized generic + +.. describe:: issubclass(obj, union_object) + + Calls to :func:`issubclass` are also supported with a Union Object.:: + + >>> issubclass(bool, int | str) + True + + .. + Once again, please change the link below for parameterized generics to + reference the correct documentation once documentation for PEP 585 + becomes available. + + However, union objects containing `parameterized generics + `_ cannot be used:: + + >>> issubclass(bool, bool | list[str]) + Traceback (most recent call last): + File "", line 1, in + TypeError: issubclass() argument 2 cannot contain a parameterized generic + +The type for the Union object is :data:`types.Union`. An object cannot be +instantiated from the type:: + + >>> import types + >>> isinstance(int | str, types.Union) + True + >>> types.Union() + Traceback (most recent call last): + File "", line 1, in + TypeError: cannot create 'types.Union' instances + +.. note:: + The :meth:`__or__` method for type objects was added to support the syntax + ``X | Y``. If a metaclass implements :meth:`__or__`, the Union may + override it:: + + >>> class M(type): + ... def __or__(self, other): + ... return "Hello" + ... + >>> class C(metaclass=M): + ... pass + ... + >>> C | int + 'Hello' + >>> int | C + int | __main__.C + +.. seealso:: + + :pep:`604` -- PEP proposing the ``X | Y`` syntax and the Union type. + +.. versionadded:: 3.10 + .. _typesother: diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 25fa750f2ccacf1..e4a8dec5cb95a1c 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -256,6 +256,11 @@ Standard names are defined for the following types: .. versionadded:: 3.10 +.. data:: Union + + The type of :ref:`union type expressions`. + + .. versionadded:: 3.10 .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index f712dfea13f2c91..a72632e61b07307 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -544,6 +544,10 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. versionchanged:: 3.7 Don't remove explicit subclasses from unions at runtime. + .. versionchanged:: 3.10 + Unions can now be written as ``X | Y``. See + :ref:`union type expressions`. + .. data:: Optional Optional type. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 957a3e791ecb69a..9c3a0287d550955 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -82,6 +82,29 @@ New Features * :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used to require that all the iterables have an equal length. +PEP604: New Type Operator +------------------------- + +A new type union operator was introduced which enables the syntax ``X | Y``. +This provides a cleaner way of expressing 'either type X or type Y' instead of +using :data:`typing.Union`, especially in type hints (annotations). + +In previous versions of Python, to apply a type hint for functions accepting +arguments of multiple types, :data:`typing.Union` was used:: + + def square(number: Union[int, float]) -> Union[int, float]: + return number ** 2 + + +Now, type hints can be written in a more succinct manner:: + + def square(number: int | float) -> int | float: + return number ** 2 + + +See :pep:`604` for more details. + +(Contributed by Maggie Moss and Philippe Prados in :issue:`41428`.) Other Language Changes ====================== diff --git a/Misc/ACKS b/Misc/ACKS index 9be0e777ca29427..08449fe08269bdb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1257,6 +1257,7 @@ Grant Olson Furkan Onder Koray Oner Ethan Onstott +Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup Jason Orendorff diff --git a/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst b/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst new file mode 100644 index 000000000000000..2c3339345601977 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst @@ -0,0 +1 @@ +Add documentation for :pep:`604` (Allow writing union types as ``X | Y``). From 295532cf454b756b972737bc727ccb3ec6586046 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 5 Oct 2020 10:09:16 +0200 Subject: [PATCH 413/486] bpo-41557: Update macOS installer to use SQLite 3.33.0 (GH-21959) https://sqlite.org/releaselog/3_33_0.html --- Mac/BuildScript/build-installer.py | 6 +++--- .../next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index a58b922ce30b836..2548b212d9ea424 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -307,9 +307,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.32.3", - url="https://sqlite.org/2020/sqlite-autoconf-3320300.tar.gz", - checksum='2e3911a3c15e85c2f2d040154bbe5ce3', + name="SQLite 3.33.0", + url="https://sqlite.org/2020/sqlite-autoconf-3330000.tar.gz", + checksum='842a8a100d7b01b09e543deb2b7951dd', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' diff --git a/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst b/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst new file mode 100644 index 000000000000000..5f2d9937c0606dc --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst @@ -0,0 +1 @@ +Update macOS installer to use SQLite 3.33.0. From bdbf07006e50a3889472317b9faf213ceb5a1344 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Oct 2020 12:32:00 +0300 Subject: [PATCH 414/486] bpo-41936. Remove macros Py_ALLOW_RECURSION/Py_END_ALLOW_RECURSION (GH-22552) --- Doc/whatsnew/3.10.rst | 5 +++++ Include/ceval.h | 8 -------- Include/cpython/pystate.h | 2 -- .../next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst | 3 +++ Python/ceval.c | 3 --- Python/pystate.c | 1 - 6 files changed, 8 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 9c3a0287d550955..1ea5aeac8a3c623 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -365,3 +365,8 @@ Removed * Removed ``_Py_CheckRecursionLimit`` variable: it has been replaced by ``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` structure. (Contributed by Victor Stinner in :issue:`41834`.) + +* Removed undocumented macros ``Py_ALLOW_RECURSION`` and + ``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the + :c:type:`PyInterpreterState` structure. + (Contributed by Serhiy Storchaka in :issue:`41936`.) diff --git a/Include/ceval.h b/Include/ceval.h index 0f372e2044a1c8a..0f687666e2bccf5 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -67,14 +67,6 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); -#define Py_ALLOW_RECURSION \ - do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ - PyThreadState_GET()->recursion_critical = 1; - -#define Py_END_ALLOW_RECURSION \ - PyThreadState_GET()->recursion_critical = _old; \ - } while(0); - PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 42a7fc163064dc8..5d5e4e331978ac1 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -56,8 +56,6 @@ struct _ts { int recursion_depth; char overflowed; /* The stack has overflowed. Allow 50 more calls to handle the runtime error. */ - char recursion_critical; /* The current calls must not cause - a stack overflow. */ int stackcheck_counter; /* 'tracing' keeps track of the execution depth when tracing/profiling. diff --git a/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst b/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst new file mode 100644 index 000000000000000..646135330861675 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst @@ -0,0 +1,3 @@ +Removed undocumented macros ``Py_ALLOW_RECURSION`` and +``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the +:c:type:`PyInterpreterState` structure. diff --git a/Python/ceval.c b/Python/ceval.c index 7c6cf83bc9ac012..500c588e3c2afb7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -814,9 +814,6 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) return -1; } #endif - if (tstate->recursion_critical) - /* Somebody asked that we don't check for recursion. */ - return 0; if (tstate->overflowed) { if (tstate->recursion_depth > recursion_limit + 50) { /* Overflowing while handling an overflow. Give up. */ diff --git a/Python/pystate.c b/Python/pystate.c index f6d1956e9dce9ae..eb24f2b800607fd 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -581,7 +581,6 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->frame = NULL; tstate->recursion_depth = 0; tstate->overflowed = 0; - tstate->recursion_critical = 0; tstate->stackcheck_counter = 0; tstate->tracing = 0; tstate->use_tracing = 0; From c8c029bbcc86452df401efe87fbdbe914473af73 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 5 Oct 2020 10:31:44 -0400 Subject: [PATCH 415/486] bpo-41774: Tweak new programming FAQ entry (GH-22562) Remove mention of space in "remove multiple items from list". --- Doc/faq/programming.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 0b486d7e7e254ac..7bcedb0b5d75b46 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1176,7 +1176,7 @@ Here are three variations.:: mylist[:] = (x for x in mylist if keep_condition) mylist[:] = [x for x in mylist if keep_condition] -If space is not an issue, the list comprehension may be fastest. +The list comprehension may be fastest. How do you make an array in Python? From 99dda04c95591a7abc254f4d1777010dabec4704 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 5 Oct 2020 18:24:00 +0200 Subject: [PATCH 416/486] bpo-41939: Fix test_site.test_license_exists_at_url() (#22559) Call urllib.request.urlcleanup() to reset the global urllib.request._opener. --- Lib/test/test_site.py | 2 ++ .../NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index d3ee68facdbc3de..a475ed1ab4c469a 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -525,6 +525,8 @@ def test_license_exists_at_url(self): # string displayed by license in the absence of a LICENSE file. url = license._Printer__data.split()[1] req = urllib.request.Request(url, method='HEAD') + # Reset global urllib.request._opener + self.addCleanup(urllib.request.urlcleanup) try: with socket_helper.transient_internet(url): with urllib.request.urlopen(req) as data: diff --git a/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst b/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst new file mode 100644 index 000000000000000..e58ad2616da1ba4 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst @@ -0,0 +1,3 @@ +Fix test_site.test_license_exists_at_url(): call +``urllib.request.urlcleanup()`` to reset the global +``urllib.request._opener``. Patch by Victor Stinner. From 1708e1a3e3f9c330300bc26bf976f8c1e2b39387 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 5 Oct 2020 09:42:21 -0700 Subject: [PATCH 417/486] bpo-41584: clarify when the reflected method of a binary arithemtic operator is called (#22505) --- Doc/reference/datamodel.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index a817408c3b1ef55..4396f1b9b729975 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2376,10 +2376,11 @@ left undefined. .. note:: - If the right operand's type is a subclass of the left operand's type and that - subclass provides the reflected method for the operation, this method will be - called before the left operand's non-reflected method. This behavior allows - subclasses to override their ancestors' operations. + If the right operand's type is a subclass of the left operand's type and + that subclass provides a different implementation of the reflected method + for the operation, this method will be called before the left operand's + non-reflected method. This behavior allows subclasses to override their + ancestors' operations. .. method:: object.__iadd__(self, other) @@ -2771,6 +2772,6 @@ An example of an asynchronous context manager class:: method—that will instead have the opposite effect of explicitly *blocking* such fallback. -.. [#] For operands of the same type, it is assumed that if the non-reflected method - (such as :meth:`__add__`) fails the operation is not supported, which is why the - reflected method is not called. +.. [#] For operands of the same type, it is assumed that if the non-reflected + method -- such as :meth:`__add__` -- fails then the overall operation is not + supported, which is why the reflected method is not called. From be2420a484ee6bd29e72e042550506ac6fb48b87 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 5 Oct 2020 18:24:54 +0100 Subject: [PATCH 418/486] Python 3.10.0a1 --- Include/patchlevel.h | 4 +- Lib/pydoc_data/topics.py | 1134 +++--- Misc/NEWS.d/3.10.0a1.rst | 3519 +++++++++++++++++ .../2020-05-19-10-54-08.bpo-40683.W8JHrr.rst | 2 - .../2020-06-08-19-57-05.bpo-40684.WIY2-i.rst | 2 - .../2020-06-15-22-14-25.bpo-36020.wbiv0P.rst | 2 - .../2020-06-25-06-59-13.bpo-40204.GpD04D.rst | 1 - .../2020-08-24-18-34-01.bpo-41617.sKKXz7.rst | 2 - .../2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst | 2 - .../2020-02-08-08-01-35.bpo-39583.qURKSl.rst | 1 - .../2020-05-20-19-11-12.bpo-40703.qQXfW8.rst | 2 - .../2020-05-26-16-21-47.bpo-39573.depAgq.rst | 5 - .../2020-05-27-11-02-15.bpo-40792.pBw2Bb.rst | 2 - .../2020-06-01-16-12-37.bpo-40826.zQzFoK.rst | 2 - .../2020-06-01-20-47-49.bpo-40839.bAi52Z.rst | 2 - .../2020-06-03-17-48-13.bpo-40679.3sgWma.rst | 1 - .../2020-06-04-08-01-23.bpo-40724.qIIdSi.rst | 1 - .../2020-06-08-15-59-06.bpo-40910.L56oI0.rst | 3 - .../2020-06-10-18-37-26.bpo-40943.i4q7rK.rst | 5 - .../2020-06-15-16-46-01.bpo-36020.djI6jw.rst | 2 - .../2020-06-15-23-17-51.bpo-40989.tlzG3r.rst | 3 - .../2020-06-17-11-24-00.bpo-36346.fTMr3S.rst | 4 - .../2020-06-17-20-31-12.bpo-36346.mwIyxi.rst | 2 - .../2020-06-24-22-57-07.bpo-41103.doojgE.rst | 4 - .../2020-06-26-13-29-25.bpo-41123.bRa1oy.rst | 1 - .../2020-06-28-11-39-22.bpo-41123.sjJWjQ.rst | 1 - .../2020-06-29-11-33-49.bpo-41123.qFevek.rst | 1 - .../2020-06-29-15-49-36.bpo-41123.wYY4E1.rst | 1 - .../2020-07-08-10-14-52.bpo-40170.N6Qx1i.rst | 4 - .../2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst | 3 - .../2020-08-10-16-05-08.bpo-41324.waZD35.rst | 3 - .../2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst | 2 - .../2020-09-01-23-39-45.bpo-41689.zxHbLB.rst | 2 - .../2020-09-22-14-47-12.bpo-41834.nrOrDU.rst | 3 - .../2020-09-27-20-43-16.bpo-41842.bCakAj.rst | 2 - .../2020-10-02-00-57-34.bpo-41692.fDScsF.rst | 3 - .../2020-10-05-01-25-23.bpo-41936.1gb5ra.rst | 3 - .../2018-03-15-11-51-36.bpo-26680.wOWYps.rst | 2 - .../2018-08-29-15-57-07.bpo-19569.RGu2Kb.rst | 2 - .../2019-05-25-05-27-39.bpo-36982.0UHgfB.rst | 1 - .../2019-06-02-11-29-15.bpo-29882.AkRzjb.rst | 2 - .../2019-09-01-14-26-02.bpo-37999.XPl6dn.rst | 5 - ...2020-04-05-02-35-08.bpo-1635741.Kfe9fT.rst | 1 - ...2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst | 1 - .../2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst | 1 - .../2020-05-03-22-26-00.bpo-29590.aRz3l7.rst | 2 - .../2020-05-19-19-39-49.bpo-40679.SVzz9p.rst | 2 - .../2020-05-20-01-17-34.bpo-40521.wvAehI.rst | 9 - .../2020-05-21-01-54-00.bpo-40696.u3n8Wx.rst | 2 - .../2020-05-22-00-34-34.bpo-39573.QO2QHj.rst | 2 - .../2020-05-23-01-15-51.bpo-40217.jZsHTc.rst | 4 - .../2020-05-24-02-42-26.bpo-40750.ZmO9Ev.rst | 1 - .../2020-05-25-21-49-11.bpo-38964.lrml90.rst | 1 - .../2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst | 2 - .../2020-05-27-22-37-58.bpo-40792.WEDqqU.rst | 3 - .../2020-05-30-14-37-18.bpo-40824.XR3V5s.rst | 4 - .../2020-05-30-23-18-35.bpo-19468.S-TA7p.rst | 2 - ...2020-05-30-23-23-35.bpo-1635741.0D-laM.rst | 1 - .../2020-06-01-20-31-07.bpo-40826.XCI4M2.rst | 2 - .../2020-06-03-13-53-24.bpo-40854.O6vfQU.rst | 1 - .../2020-06-05-12-48-28.bpo-40870.9cd2sk.rst | 2 - .../2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst | 1 - .../2020-06-06-00-23-19.bpo-40880.fjdzSh.rst | 2 - .../2020-06-07-22-50-10.bpo-40903.7dWejS.rst | 1 - .../2020-06-08-01-08-57.bpo-40904.76qQzo.rst | 2 - .../2020-06-08-22-46-33.bpo-40889.vIBl-W.rst | 1 - .../2020-06-09-00-20-13.bpo-40890.LoRV-g.rst | 1 - .../2020-06-09-23-52-32.bpo-40847.4XAACw.rst | 4 - .../2020-06-10-11-27-15.bpo-40939.DO-wAI.rst | 1 - .../2020-06-11-16-06-49.bpo-40947.72cZcR.rst | 2 - .../2020-06-12-00-12-28.bpo-40950.tzMy7m.rst | 2 - .../2020-06-12-12-21-54.bpo-40957.Z8n6I6.rst | 1 - ...2020-06-12-22-56-17.bpo-1635741.mmlp3Q.rst | 1 - .../2020-06-15-01-20-44.bpo-40958.7O2Wh1.rst | 2 - .../2020-06-15-16-29-55.bpo-40985.IIN_xX.rst | 1 - ...2020-06-17-00-52-21.bpo-1635741.61iyYh.rst | 1 - .../2020-06-17-10-27-17.bpo-40636.MYaCIe.rst | 3 - .../2020-06-18-00-07-09.bpo-41006.H-wN-d.rst | 2 - .../2020-06-18-19-04-30.bpo-40077._yI-ax.rst | 1 - .../2020-06-20-16-59-02.bpo-40939.6810Ak.rst | 1 - .../2020-06-20-17-00-44.bpo-35975.UDHCHp.rst | 3 - .../2020-06-20-19-27-47.bpo-40939.jxJ4yn.rst | 1 - .../2020-06-20-22-46-18.bpo-41052.46MPeF.rst | 1 - .../2020-06-21-10-54-02.bpo-41061.AHf9MU.rst | 1 - .../2020-06-21-19-53-33.bpo-41056.IDu_EK.rst | 1 - .../2020-06-22-13-22-30.bpo-41076.eWYw2N.rst | 1 - .../2020-06-23-07-35-11.bpo-40521.dMNA6k.rst | 1 - .../2020-06-23-15-10-19.bpo-41084.pt3y7F.rst | 1 - .../2020-06-23-18-32-41.bpo-39960.Kez3fP.rst | 2 - .../2020-06-23-23-26-42.bpo-41094.zEIJse.rst | 2 - .../2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 - .../2020-06-30-20-17-31.bpo-41175.acJoXB.rst | 2 - ...2020-07-01-20-17-38.bpo-1635741.-AtPYu.rst | 1 - ...2020-07-03-23-10-02.bpo-1635741.F5coWe.rst | 1 - .../2020-07-06-13-35-17.bpo-41218.oKnSr2.rst | 4 - .../2020-07-06-18-36-33.bpo-41215.vFGFIz.rst | 2 - ...2020-07-06-20-43-19.bpo-1635741.LYhsni.rst | 1 - ...2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst | 1 - .../2020-07-08-21-55-23.bpo-41252.nBWL-Y.rst | 1 - .../2020-07-08-22-03-54.bpo-41247.PndYIk.rst | 2 - .../2020-07-17-11-31-54.bpo-41323.ChbZHh.rst | 3 - .../2020-07-18-08-15-32.bpo-41295.pu8Ezo.rst | 3 - .../2020-07-18-18-01-10.bpo-41334.t5xMGp.rst | 2 - .../2020-07-19-15-40-52.bpo-41342.RRk_m_.rst | 1 - .../2020-07-20-17-01-17.bpo-38156.ptcdRy.rst | 1 - .../2020-07-27-01-50-06.bpo-41340.pZXfcF.rst | 1 - .../2020-07-28-22-43-27.bpo-41428.FM6xsI.rst | 1 - .../2020-08-02-15-53-12.bpo-41431.TblUBT.rst | 2 - ...2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst | 2 - .../2020-08-12-07-35-07.bpo-41525.d9q3XL.rst | 1 - .../2020-08-12-19-32-15.bpo-41531.WgPzjT.rst | 2 - .../2020-08-12-20-29-57.bpo-41533.4pcVAc.rst | 2 - ...2020-08-13-07-18-05.bpo-1635741.FC13e7.rst | 1 - ...2020-08-13-07-19-21.bpo-1653741.fubBkb.rst | 1 - .../2020-08-25-22-43-33.bpo-40077.vcxSUa.rst | 1 - .../2020-08-26-11-23-31.bpo-41631.3jZcd9.rst | 5 - ...2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst | 1 - .../2020-08-30-20-38-33.bpo-41654.HtnhAM.rst | 2 - .../2020-08-31-11-37-59.bpo-41670.vmRJRx.rst | 4 - .../2020-08-31-14-53-17.bpo-41675.VSoqWU.rst | 3 - .../2020-08-31-17-49-02.bpo-41681.3-VJiH.rst | 2 - ...2020-09-01-17-06-02.bpo-1635741.5jZymK.rst | 2 - ...2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst | 2 - ...2020-09-01-17-22-35.bpo-1635741.CnRME3.rst | 2 - .../2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst | 2 - ...2020-09-07-09-45-47.bpo-1635741.QuDIut.rst | 1 - ...2020-09-07-11-35-02.bpo-1635741.rvIexb.rst | 2 - ...2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst | 2 - ...2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst | 2 - .../2020-09-12-12-55-45.bpo-41756.1h0tbV.rst | 2 - ...2020-09-12-18-34-34.bpo-1635741.lh335O.rst | 2 - .../2020-09-15-23-29-49.bpo-41780.bOBUIH.rst | 2 - .../2020-09-24-12-15-45.bpo-39934.YVHTCF.rst | 3 - ...2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst | 1 - .../2020-09-27-22-23-14.bpo-41870.2v6_v4.rst | 2 - .../2020-09-28-08-58-28.bpo-41873.VzEDhA.rst | 1 - .../2020-10-04-01-02-58.bpo-41922.kHGT8I.rst | 2 - .../2020-10-04-10-55-12.bpo-41909.BqHPcm.rst | 2 - .../2019-08-16-20-25-42.bpo-37703.Qm_l_H.rst | 2 - .../2020-03-07-03-53-39.bpo-39883.1tnb4-.rst | 1 - .../2020-05-09-12-10-31.bpo-40552._0uB73.rst | 2 - .../2020-07-21-15-23-30.bpo-40979.pLA8rO.rst | 1 - .../2020-07-25-14-20-00.bpo-41314.yrjko0.rst | 1 - .../2020-07-27-20-46-17.bpo-41045.GFF6Ul.rst | 1 - .../2020-08-12-18-35-40.bpo-40204.C8A_pe.rst | 3 - .../2020-08-25-15-11-23.bpo-41624.ddjJlN.rst | 1 - .../2020-09-08-16-57-09.bpo-41726.g0UXrn.rst | 1 - .../2020-09-10-07-48-02.bpo-37149.VD0rCv.rst | 1 - .../2020-09-12-17-37-13.bpo-35293._cOwPD.rst | 1 - .../2020-09-24-15-35-13.bpo-41774.5IqdGP.rst | 2 - .../2020-10-03-18-20-46.bpo-41428._ju1NE.rst | 1 - .../2020-05-24-06-19-43.bpo-40723.AJLd4U.rst | 1 - .../2020-05-29-18-21-58.bpo-39885.zB_-bN.rst | 2 - .../2020-06-27-17-02-00.bpo-41144.JoFGIX.rst | 1 - .../2020-06-29-14-51-15.bpo-41152.d6mV0C.rst | 2 - .../2020-07-07-18-44-30.bpo-37765.umc1o8.rst | 2 - .../2020-07-16-17-39-06.bpo-41300.wRixNb.rst | 2 - .../2020-07-24-17-49-58.bpo-41373.YQIPu_.rst | 3 - .../2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst | 1 - .../2020-09-22-00-45-40.bpo-40181.hhQi3z.rst | 2 - .../2020-09-22-11-13-45.bpo-35764.VoNa8y.rst | 1 - .../2020-09-24-14-31-16.bpo-41775.sB8Vre.rst | 1 - .../2018-03-15-11-55-04.bpo-26680.eKAi85.rst | 3 - .../2018-03-15-11-56-48.bpo-26680.Udkhn4.rst | 2 - .../2018-06-07-22-04-01.bpo-28557.ViNJnK.rst | 1 - .../2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst | 2 - .../2018-07-29-12-14-54.bpo-34226.BE7zbu.rst | 1 - .../2018-07-30-12-48-17.bpo-31844.0_GKsD.rst | 4 - .../2018-08-21-16-20-33.bpo-29620.xxx666.rst | 3 - .../2018-10-27-09-37-03.bpo-35078.kweA3R.rst | 3 - .../2019-03-01-01-56-23.bpo-33944.-82Pkt.rst | 1 - .../2019-03-17-19-01-53.bpo-36290.7VXo_K.rst | 2 - .../2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst | 3 - .../2019-08-11-16-28-03.bpo-26543.X-TJZO.rst | 1 - .../2019-09-12-21-34-03.bpo-38144.8uQCdd.rst | 1 - .../2019-10-25-23-45-49.bpo-35714.fw3xb7.rst | 2 - .../2019-11-13-07-37-11.bpo-38731.9qmcSx.rst | 2 - .../2019-12-15-18-47-20.bpo-39040.tKa0Qs.rst | 2 - .../2020-02-23-15-09-47.bpo-39244.aBK5IM.rst | 2 - .../2020-02-24-10-58-34.bpo-39728.kOOaHn.rst | 1 - .../2020-03-11-07-44-06.bpo-31122.zIQ80l.rst | 1 - .../2020-03-29-21-32-00.bpo-40084.MCYwcv.rst | 1 - .../2020-04-03-16-13-59.bpo-40105.hfM2c0.rst | 2 - .../2020-04-18-14-16-02.bpo-40318.K2UdRx.rst | 1 - .../2020-04-20-22-08-36.bpo-23082.iX90Id.rst | 1 - .../2020-04-23-18-21-19.bpo-39385.MIAyS7.rst | 3 - .../2020-05-06-02-01-25.bpo-13097.Wh5xSK.rst | 1 - .../2020-05-07-22-00-12.bpo-39881.E1xsNv.rst | 2 - .../2020-05-13-16-28-33.bpo-40611.ZCk0_c.rst | 1 - .../2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst | 1 - .../2020-05-17-02-03-09.bpo-32309.KM9psl.rst | 4 - .../2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst | 1 - .../2020-05-18-15-38-25.bpo-25920.PxrLY8.rst | 7 - .../2020-05-18-17-29-30.bpo-40626.NeZufF.rst | 1 - .../2020-05-18-22-41-02.bpo-40614.8j3kmq.rst | 1 - .../2020-05-20-12-53-20.bpo-9216.ps7Yf1.rst | 3 - .../2020-05-20-13-03-28.bpo-40695.lr4aIS.rst | 3 - .../2020-05-20-14-38-04.bpo-40698.zwl5Hc.rst | 2 - .../2020-05-22-12-45-58.bpo-40726.7oBdMw.rst | 2 - .../2020-05-23-00-22-11.bpo-40737.iph-CM.rst | 1 - .../2020-05-23-04-18-00.bpo-37129.YoYoYo.rst | 1 - .../2020-05-24-11-06-37.bpo-40756.7ZH83z.rst | 2 - .../2020-05-24-23-52-35.bpo-40759.DdZdaw.rst | 1 - .../2020-05-25-11-52-23.bpo-30064.6CICsH.rst | 1 - .../2020-05-25-22-18-38.bpo-30008.CKC3td.rst | 2 - .../2020-05-27-00-09-52.bpo-16995.4niOT7.rst | 2 - .../2020-05-27-17-00-18.bpo-40795.eZSnHA.rst | 4 - .../2020-05-27-18-04-52.bpo-40791.IzpNor.rst | 2 - .../2020-05-27-21-27-01.bpo-40767.L5MnVV.rst | 3 - .../2020-05-27-22-19-42.bpo-40792.87Yx01.rst | 2 - .../2020-05-28-16-51-00.bpo-38488.hFQNgA.rst | 1 - .../2020-05-28-17-32-29.bpo-40777.1kJU6N.rst | 2 - .../2020-05-30-08-10-23.bpo-40744.jKURVV.rst | 4 - .../2020-05-30-12-44-29.bpo-39384.Iqxy3q.rst | 1 - .../2020-05-30-14-19-47.bpo-26407.MjWLO1.rst | 3 - .../2020-05-30-18-48-58.bpo-40755.IyOe2J.rst | 1 - .../2020-05-31-15-52-18.bpo-40834.MO9_hb.rst | 1 - .../2020-05-31-23-32-36.bpo-17005.JlRUGB.rst | 4 - .../2020-06-01-02-16-29.bpo-39314.0T9hlA.rst | 3 - .../2020-06-02-02-16-02.bpo-39791.StCJlA.rst | 1 - .../2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst | 2 - .../2020-06-04-16-25-15.bpo-40807.yYyLWx.rst | 2 - .../2020-06-05-19-29-10.bpo-39791._CcO3d.rst | 1 - .../2020-06-05-20-00-18.bpo-40876.zDhiZj.rst | 1 - .../2020-06-06-02-42-26.bpo-40884.n7fOwS.rst | 3 - .../2020-06-06-14-09-55.bpo-33689.EFUDH7.rst | 4 - .../2020-06-08-18-59-16.bpo-23427.ilg1Cz.rst | 2 - .../2020-06-11-11-07-10.bpo-40939.-D5Asl.rst | 1 - .../2020-06-12-10-44-15.bpo-40855.jSot83.rst | 2 - .../2020-06-12-11-55-30.bpo-40955.huixCg.rst | 1 - .../2020-06-13-12-04-50.bpo-40924.SM_luS.rst | 3 - .../2020-06-15-00-13-57.bpo-40967._dx3OO.rst | 2 - .../2020-06-15-12-22-53.bpo-40448.1dk8Bu.rst | 2 - .../2020-06-17-17-26-24.bpo-41002.NPBItE.rst | 1 - .../2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst | 2 - .../2020-06-18-10-34-59.bpo-41025.elf_nz.rst | 2 - .../2020-06-20-00-19-30.bpo-41043.p-Pk-H.rst | 2 - .../2020-06-20-10-16-57.bpo-41048.hEXB-B.rst | 2 - .../2020-06-20-18-33-03.bpo-41056.gTH4Bq.rst | 1 - .../2020-06-20-18-35-43.bpo-41056.Garcle.rst | 1 - .../2020-06-20-18-37-29.bpo-41056.d9v_uL.rst | 1 - .../2020-06-20-21-03-55.bpo-41058.gztdZy.rst | 1 - .../2020-06-22-10-25-39.bpo-41068._bX2BW.rst | 2 - .../2020-06-22-20-08-40.bpo-31938.EVuko9.rst | 1 - .../2020-06-23-06-09-59.bpo-40521.HUfxP7.rst | 1 - .../2020-06-25-10-11-47.bpo-31082.HsgDkx.rst | 1 - .../2020-06-27-13-51-36.bpo-41138.bIpf7g.rst | 2 - .../2020-06-28-21-16-51.bpo-40874.YImvzA.rst | 1 - .../2020-06-30-20-50-51.bpo-41161.QTdJjz.rst | 2 - .../2020-07-01-17-33-50.bpo-41182.FPFI0N.rst | 1 - .../2020-07-02-11-53-45.bpo-41193.8-Tnql.rst | 4 - .../2020-07-02-15-03-04.bpo-41195.cEnpO3.rst | 2 - .../2020-07-03-13-15-08.bpo-41194.djrKjs.rst | 2 - .../2020-07-04-21-56-46.bpo-39168.DQWsXj.rst | 1 - .../2020-07-05-19-16-02.bpo-29727.Q6Z2rg.rst | 2 - .../2020-07-06-16-58-53.bpo-41207.Emw7Nk.rst | 1 - .../2020-07-07-21-56-26.bpo-41235.H2csMU.rst | 1 - .../2020-07-11-00-15-01.bpo-41273.SVrsJh.rst | 3 - .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst | 1 - .../2020-07-13-15-06-35.bpo-41288.8mn5P-.rst | 2 - .../2020-07-18-18-07-40.bpo-41333.upkHIm.rst | 1 - .../2020-07-20-13-27-48.bpo-41344.iKipNd.rst | 1 - .../2020-07-20-19-13-17.bpo-41341.wqrj8C.rst | 1 - .../2020-07-21-16-20-55.bpo-35328.jXovHb.rst | 2 - .../2020-07-21-21-45-55.bpo-41364.5O-k7A.rst | 1 - .../2020-07-23-01-18-34.bpo-41317.O17Z6x.rst | 2 - .../2020-07-26-21-18-43.bpo-41384.MlzIgV.rst | 2 - .../2020-07-28-12-08-58.bpo-41316.bSCbK4.rst | 1 - .../2020-07-30-14-56-58.bpo-41440.rju34k.rst | 1 - .../2020-08-01-00-51-15.bpo-41421.dHKRVB.rst | 3 - .../2020-08-03-01-59-48.bpo-41425.KJo6zF.rst | 1 - .../2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst | 3 - .../2020-08-07-06-06-29.bpo-41497.aBtsWz.rst | 1 - .../2020-08-07-15-18-16.bpo-41503.IYftcu.rst | 1 - .../2020-08-09-18-16-05.bpo-41513.e6K6EK.rst | 2 - .../2020-08-12-07-43-31.bpo-41528.bu83oD.rst | 1 - .../2020-08-12-13-25-16.bpo-41520.BEUWa4.rst | 1 - .../2020-08-13-08-07-25.bpo-40782.aGZqmB.rst | 1 - .../2020-08-15-15-21-40.bpo-37658.f9nivB.rst | 2 - .../2020-08-15-15-50-12.bpo-32751.85je5X.rst | 3 - .../2020-08-15-18-17-21.bpo-39994.dOgPOh.rst | 1 - .../2020-08-21-15-51-15.bpo-41609.JmiUKG.rst | 1 - .../2020-08-23-14-23-18.bpo-41513.DGqc_I.rst | 3 - .../2020-08-29-16-07-36.bpo-41662.Mn79zh.rst | 1 - .../2020-08-29-16-45-12.bpo-41638.iZfW5N.rst | 3 - .../2020-08-30-10-24-26.bpo-39010._mzXJW.rst | 2 - .../2020-08-30-21-38-57.bpo-41662.6e9iZn.rst | 2 - .../2020-09-01-15-57-51.bpo-41687.m1b1KA.rst | 1 - .../2020-09-03-01-35-32.bpo-41696.zkYGre.rst | 1 - .../2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst | 2 - .../2020-09-06-20-27-10.bpo-41732.1SKv26.rst | 1 - ...2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst | 2 - ...2020-09-08-13-55-34.bpo-1635741.56MLP-.rst | 2 - .../2020-09-11-12-38-55.bpo-39651.JMp9l2.rst | 3 - .../2020-09-12-16-18-42.bpo-32218.IpYkEe.rst | 1 - .../2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst | 2 - .../2020-09-15-07-55-35.bpo-41792.qMpSlU.rst | 6 - .../2020-09-15-14-56-13.bpo-39587.69xzuh.rst | 1 - .../2020-09-15-22-43-30.bpo-41517.sLBH7g.rst | 1 - .../2020-09-19-12-22-08.bpo-41816.ynynXJ.rst | 2 - .../2020-09-19-23-14-54.bpo-41815.RNpuX3.rst | 2 - .../2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 3 - .../2020-09-22-00-23-30.bpo-41817.bnh-VG.rst | 1 - .../2020-09-22-13-51-14.bpo-41833.6HVDjT.rst | 2 - .../2020-09-22-14-55-34.bpo-40670.R5sm68.rst | 3 - .../2020-09-23-03-33-37.bpo-40564.iXQqMq.rst | 1 - .../2020-09-23-22-52-24.bpo-41842.lIuhC9.rst | 1 - .../2020-09-23-23-17-59.bpo-41840.QRFr4L.rst | 3 - .../2020-09-28-23-22-25.bpo-41773.oKkus0.rst | 2 - .../2020-09-30-23-49-42.bpo-41887.-ee2S-.rst | 2 - .../2020-10-01-10-50-12.bpo-41900.Cho7oh.rst | 2 - .../2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | 2 - .../2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst | 1 - .../2020-07-03-17-21-37.bpo-29778.cR_fGS.rst | 2 - .../2020-07-03-20-41-29.bpo-41162.tb8pVj.rst | 1 - .../2020-07-15-20-15-08.bpo-41304.vNEeYA.rst | 1 - .../2018-08-20-09-38-52.bpo-34401.eGxMPm.rst | 1 - .../2019-09-14-13-20-27.bpo-38169.hurq4B.rst | 1 - .../2020-04-09-15-40-03.bpo-31904.TJ4k3d.rst | 1 - .../2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst | 1 - .../2020-06-09-18-48-18.bpo-40927.67ylLg.rst | 2 - .../2020-06-12-20-46-23.bpo-40964.OBzf2c.rst | 2 - .../2020-06-17-15-07-14.bpo-41003.tiH_Fy.rst | 3 - .../2020-06-17-17-27-07.bpo-41009.Rvn6OQ.rst | 2 - .../2020-06-17-18-00-21.bpo-38377.jfg4TH.rst | 4 - .../2020-06-22-00-21-12.bpo-41069.bLZkX-.rst | 2 - .../2020-06-23-12-02-45.bpo-41085.JZKsyz.rst | 2 - .../2020-08-07-17-28-49.bpo-41477.GrFexU.rst | 1 - .../2020-08-11-14-59-13.bpo-41521.w2UYK7.rst | 2 - .../2020-08-25-19-25-36.bpo-41602.Z64s0I.rst | 1 - .../2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst | 1 - .../2020-10-05-09-37-43.bpo-41939.P4OlbA.rst | 3 - .../2019-07-11-06-11-09.bpo-37556.sygMUU.rst | 1 - .../2020-05-19-04-11-12.bpo-40677.qQbLW8.rst | 1 - .../2020-05-19-14-43-33.bpo-39631.Z5yXam.rst | 2 - .../2020-06-12-13-13-44.bpo-40164.SPrSn5.rst | 1 - .../2020-06-23-03-12-57.bpo-41039.0hgd0s.rst | 2 - .../2020-06-24-21-30-42.bpo-41074.gaQc3C.rst | 3 - .../2020-06-28-12-40-41.bpo-41142.jpZzzh.rst | 2 - .../2020-07-20-23-26-26.bpo-40741.C9sc_d.rst | 1 - .../2020-07-28-11-55-43.bpo-41412.ME20KB.rst | 2 - .../2020-07-28-12-39-32.bpo-40948.ISUFO6.rst | 1 - .../2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst | 1 - .../2020-08-13-22-40-58.bpo-41526.-i2bwb.rst | 2 - .../2020-09-04-21-35-28.bpo-41627.sx2KN1.rst | 2 - .../2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst | 1 - .../2020-06-07-20-10-56.bpo-40741.80A2BW.rst | 1 - .../2020-06-17-13-45-15.bpo-41005.zZegdV.rst | 1 - .../2020-06-19-14-19-08.bpo-40741.L7yTbm.rst | 1 - .../2020-06-24-13-51-57.bpo-41100.mcHdc5.rst | 7 - .../2020-06-25-06-09-00.bpo-39580.N_vJ9h.rst | 2 - .../2020-08-26-09-31-37.bpo-41557.mcQ75z.rst | 1 - README.rst | 2 +- 353 files changed, 4132 insertions(+), 1177 deletions(-) create mode 100644 Misc/NEWS.d/3.10.0a1.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-05-19-10-54-08.bpo-40683.W8JHrr.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-06-15-22-14-25.bpo-36020.wbiv0P.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-06-25-06-59-13.bpo-40204.GpD04D.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst delete mode 100644 Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-05-26-16-21-47.bpo-39573.depAgq.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-05-27-11-02-15.bpo-40792.pBw2Bb.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-10-18-37-26.bpo-40943.i4q7rK.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-15-16-46-01.bpo-36020.djI6jw.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-17-11-24-00.bpo-36346.fTMr3S.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-17-20-31-12.bpo-36346.mwIyxi.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-24-22-57-07.bpo-41103.doojgE.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-26-13-29-25.bpo-41123.bRa1oy.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-28-11-39-22.bpo-41123.sjJWjQ.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-29-11-33-49.bpo-41123.qFevek.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-06-29-15-49-36.bpo-41123.wYY4E1.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-07-08-10-14-52.bpo-40170.N6Qx1i.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst delete mode 100644 Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-08-29-15-57-07.bpo-19569.RGu2Kb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-02-11-29-15.bpo-29882.AkRzjb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-09-01-14-26-02.bpo-37999.XPl6dn.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-04-05-02-35-08.bpo-1635741.Kfe9fT.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-03-22-26-00.bpo-29590.aRz3l7.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-19-19-39-49.bpo-40679.SVzz9p.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-21-01-54-00.bpo-40696.u3n8Wx.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-22-00-34-34.bpo-39573.QO2QHj.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-23-01-15-51.bpo-40217.jZsHTc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-24-02-42-26.bpo-40750.ZmO9Ev.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-27-22-37-58.bpo-40792.WEDqqU.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-18-35.bpo-19468.S-TA7p.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-09-00-20-13.bpo-40890.LoRV-g.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-09-23-52-32.bpo-40847.4XAACw.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-10-11-27-15.bpo-40939.DO-wAI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-11-16-06-49.bpo-40947.72cZcR.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-12-12-21-54.bpo-40957.Z8n6I6.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-12-22-56-17.bpo-1635741.mmlp3Q.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-15-01-20-44.bpo-40958.7O2Wh1.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-17-00-52-21.bpo-1635741.61iyYh.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-17-10-27-17.bpo-40636.MYaCIe.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-18-00-07-09.bpo-41006.H-wN-d.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-18-19-04-30.bpo-40077._yI-ax.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-20-16-59-02.bpo-40939.6810Ak.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-00-44.bpo-35975.UDHCHp.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-20-19-27-47.bpo-40939.jxJ4yn.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-20-22-46-18.bpo-41052.46MPeF.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-21-10-54-02.bpo-41061.AHf9MU.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-21-19-53-33.bpo-41056.IDu_EK.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-22-13-22-30.bpo-41076.eWYw2N.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-23-18-32-41.bpo-39960.Kez3fP.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-23-23-26-42.bpo-41094.zEIJse.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-20-17-31.bpo-41175.acJoXB.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-01-20-17-38.bpo-1635741.-AtPYu.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-03-23-10-02.bpo-1635741.F5coWe.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-06-13-35-17.bpo-41218.oKnSr2.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-06-18-36-33.bpo-41215.vFGFIz.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-08-21-55-23.bpo-41252.nBWL-Y.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-17-11-31-54.bpo-41323.ChbZHh.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-18-08-15-32.bpo-41295.pu8Ezo.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-18-18-01-10.bpo-41334.t5xMGp.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-20-17-01-17.bpo-38156.ptcdRy.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-27-01-50-06.bpo-41340.pZXfcF.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-08-16-20-25-42.bpo-37703.Qm_l_H.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-05-09-12-10-31.bpo-40552._0uB73.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-07-25-14-20-00.bpo-41314.yrjko0.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-07-27-20-46-17.bpo-41045.GFF6Ul.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-05-24-06-19-43.bpo-40723.AJLd4U.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-05-29-18-21-58.bpo-39885.zB_-bN.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-06-27-17-02-00.bpo-41144.JoFGIX.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-06-29-14-51-15.bpo-41152.d6mV0C.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-07-16-17-39-06.bpo-41300.wRixNb.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-07-24-17-49-58.bpo-41373.YQIPu_.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-06-07-22-04-01.bpo-28557.ViNJnK.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-07-30-12-48-17.bpo-31844.0_GKsD.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-08-21-16-20-33.bpo-29620.xxx666.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-01-01-56-23.bpo-33944.-82Pkt.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-17-19-01-53.bpo-36290.7VXo_K.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-09-12-21-34-03.bpo-38144.8uQCdd.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-10-25-23-45-49.bpo-35714.fw3xb7.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-11-13-07-37-11.bpo-38731.9qmcSx.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-12-15-18-47-20.bpo-39040.tKa0Qs.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-02-23-15-09-47.bpo-39244.aBK5IM.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-20-22-08-36.bpo-23082.iX90Id.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-23-18-21-19.bpo-39385.MIAyS7.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-06-02-01-25.bpo-13097.Wh5xSK.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-13-16-28-33.bpo-40611.ZCk0_c.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-17-02-03-09.bpo-32309.KM9psl.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-18-15-38-25.bpo-25920.PxrLY8.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-18-17-29-30.bpo-40626.NeZufF.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-20-12-53-20.bpo-9216.ps7Yf1.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-20-13-03-28.bpo-40695.lr4aIS.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-20-14-38-04.bpo-40698.zwl5Hc.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-23-00-22-11.bpo-40737.iph-CM.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-23-04-18-00.bpo-37129.YoYoYo.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-24-11-06-37.bpo-40756.7ZH83z.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-24-23-52-35.bpo-40759.DdZdaw.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-25-11-52-23.bpo-30064.6CICsH.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-17-00-18.bpo-40795.eZSnHA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-18-04-52.bpo-40791.IzpNor.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-27-22-19-42.bpo-40792.87Yx01.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-28-16-51-00.bpo-38488.hFQNgA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-28-17-32-29.bpo-40777.1kJU6N.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-30-12-44-29.bpo-39384.Iqxy3q.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-30-14-19-47.bpo-26407.MjWLO1.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-30-18-48-58.bpo-40755.IyOe2J.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-31-15-52-18.bpo-40834.MO9_hb.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-05-31-23-32-36.bpo-17005.JlRUGB.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-01-02-16-29.bpo-39314.0T9hlA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-06-02-42-26.bpo-40884.n7fOwS.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-08-18-59-16.bpo-23427.ilg1Cz.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-11-11-07-10.bpo-40939.-D5Asl.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-12-10-44-15.bpo-40855.jSot83.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-12-11-55-30.bpo-40955.huixCg.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-13-12-04-50.bpo-40924.SM_luS.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-15-00-13-57.bpo-40967._dx3OO.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-15-12-22-53.bpo-40448.1dk8Bu.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-17-17-26-24.bpo-41002.NPBItE.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-00-19-30.bpo-41043.p-Pk-H.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-10-16-57.bpo-41048.hEXB-B.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-18-33-03.bpo-41056.gTH4Bq.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-18-35-43.bpo-41056.Garcle.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-18-37-29.bpo-41056.d9v_uL.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-20-21-03-55.bpo-41058.gztdZy.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-22-10-25-39.bpo-41068._bX2BW.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-22-20-08-40.bpo-31938.EVuko9.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-23-06-09-59.bpo-40521.HUfxP7.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-25-10-11-47.bpo-31082.HsgDkx.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-27-13-51-36.bpo-41138.bIpf7g.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-28-21-16-51.bpo-40874.YImvzA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-06-30-20-50-51.bpo-41161.QTdJjz.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-01-17-33-50.bpo-41182.FPFI0N.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-02-11-53-45.bpo-41193.8-Tnql.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-02-15-03-04.bpo-41195.cEnpO3.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-03-13-15-08.bpo-41194.djrKjs.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-04-21-56-46.bpo-39168.DQWsXj.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-05-19-16-02.bpo-29727.Q6Z2rg.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-06-16-58-53.bpo-41207.Emw7Nk.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-18-18-07-40.bpo-41333.upkHIm.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-20-19-13-17.bpo-41341.wqrj8C.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-21-16-20-55.bpo-35328.jXovHb.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-21-21-45-55.bpo-41364.5O-k7A.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-23-01-18-34.bpo-41317.O17Z6x.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-26-21-18-43.bpo-41384.MlzIgV.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst delete mode 100644 Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst delete mode 100644 Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst delete mode 100644 Misc/NEWS.d/next/Security/2020-07-03-17-21-37.bpo-29778.cR_fGS.rst delete mode 100644 Misc/NEWS.d/next/Security/2020-07-03-20-41-29.bpo-41162.tb8pVj.rst delete mode 100644 Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst delete mode 100644 Misc/NEWS.d/next/Tests/2018-08-20-09-38-52.bpo-34401.eGxMPm.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-09-14-13-20-27.bpo-38169.hurq4B.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-04-09-15-40-03.bpo-31904.TJ4k3d.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-09-18-48-18.bpo-40927.67ylLg.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-12-20-46-23.bpo-40964.OBzf2c.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-17-15-07-14.bpo-41003.tiH_Fy.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-17-17-27-07.bpo-41009.Rvn6OQ.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-22-00-21-12.bpo-41069.bLZkX-.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-06-23-12-02-45.bpo-41085.JZKsyz.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst delete mode 100644 Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst delete mode 100644 Misc/NEWS.d/next/Windows/2019-07-11-06-11-09.bpo-37556.sygMUU.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-05-19-04-11-12.bpo-40677.qQbLW8.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-05-19-14-43-33.bpo-39631.Z5yXam.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-06-12-13-13-44.bpo-40164.SPrSn5.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-06-23-03-12-57.bpo-41039.0hgd0s.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-06-24-21-30-42.bpo-41074.gaQc3C.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-06-28-12-40-41.bpo-41142.jpZzzh.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-07-20-23-26-26.bpo-40741.C9sc_d.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-07-28-11-55-43.bpo-41412.ME20KB.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-07-28-12-39-32.bpo-40948.ISUFO6.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst delete mode 100644 Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-06-17-13-45-15.bpo-41005.zZegdV.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-06-19-14-19-08.bpo-40741.L7yTbm.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-06-25-06-09-00.bpo-39580.N_vJ9h.rst delete mode 100644 Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 8578b6597f60239..c4468ad3f2223b6 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 10 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 0 +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.10.0a0" +#define PY_VERSION "3.10.0a1" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 8aca5c0cb88e38d..1fdb1ae859e3e05 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon Apr 27 22:35:16 2020 +# Autogenerated by Sphinx on Mon Oct 5 18:27:28 2020 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -99,27 +99,26 @@ 'assigned,\n' ' from left to right, to the corresponding targets.\n' '\n' - ' * If the target list contains one target prefixed with an\n' - ' asterisk, called a “starred” target: The object must be ' - 'an\n' - ' iterable with at least as many items as there are targets ' - 'in the\n' - ' target list, minus one. The first items of the iterable ' - 'are\n' - ' assigned, from left to right, to the targets before the ' + ' * If the target list contains one target prefixed with an ' + 'asterisk,\n' + ' called a “starred” target: The object must be an iterable ' + 'with at\n' + ' least as many items as there are targets in the target ' + 'list, minus\n' + ' one. The first items of the iterable are assigned, from ' + 'left to\n' + ' right, to the targets before the starred target. The ' + 'final items\n' + ' of the iterable are assigned to the targets after the ' 'starred\n' - ' target. The final items of the iterable are assigned to ' - 'the\n' - ' targets after the starred target. A list of the remaining ' - 'items\n' - ' in the iterable is then assigned to the starred target ' - '(the list\n' - ' can be empty).\n' + ' target. A list of the remaining items in the iterable is ' + 'then\n' + ' assigned to the starred target (the list can be empty).\n' '\n' ' * Else: The object must be an iterable with the same number ' - 'of\n' - ' items as there are targets in the target list, and the ' - 'items are\n' + 'of items\n' + ' as there are targets in the target list, and the items ' + 'are\n' ' assigned, from left to right, to the corresponding ' 'targets.\n' '\n' @@ -135,10 +134,10 @@ 'in the\n' ' current local namespace.\n' '\n' - ' * Otherwise: the name is bound to the object in the global\n' - ' namespace or the outer namespace determined by ' - '"nonlocal",\n' - ' respectively.\n' + ' * Otherwise: the name is bound to the object in the global ' + 'namespace\n' + ' or the outer namespace determined by "nonlocal", ' + 'respectively.\n' '\n' ' The name is rebound if it was already bound. This may cause ' 'the\n' @@ -225,26 +224,27 @@ 'called with\n' ' appropriate arguments.\n' '\n' - '* If the target is a slicing: The primary expression in the\n' - ' reference is evaluated. It should yield a mutable sequence ' - 'object\n' - ' (such as a list). The assigned object should be a sequence ' - 'object\n' - ' of the same type. Next, the lower and upper bound ' - 'expressions are\n' - ' evaluated, insofar they are present; defaults are zero and ' - 'the\n' - ' sequence’s length. The bounds should evaluate to integers. ' - 'If\n' - ' either bound is negative, the sequence’s length is added to ' - 'it. The\n' - ' resulting bounds are clipped to lie between zero and the ' + '* If the target is a slicing: The primary expression in the ' + 'reference\n' + ' is evaluated. It should yield a mutable sequence object ' + '(such as a\n' + ' list). The assigned object should be a sequence object of ' + 'the same\n' + ' type. Next, the lower and upper bound expressions are ' + 'evaluated,\n' + ' insofar they are present; defaults are zero and the ' 'sequence’s\n' - ' length, inclusive. Finally, the sequence object is asked to ' - 'replace\n' - ' the slice with the items of the assigned sequence. The ' - 'length of\n' - ' the slice may be different from the length of the assigned ' + ' length. The bounds should evaluate to integers. If either ' + 'bound is\n' + ' negative, the sequence’s length is added to it. The ' + 'resulting\n' + ' bounds are clipped to lie between zero and the sequence’s ' + 'length,\n' + ' inclusive. Finally, the sequence object is asked to replace ' + 'the\n' + ' slice with the items of the assigned sequence. The length ' + 'of the\n' + ' slice may be different from the length of the assigned ' 'sequence,\n' ' thus changing the length of the target sequence, if the ' 'target\n' @@ -544,13 +544,17 @@ '\n' '-[ Footnotes ]-\n' '\n' - '[1] The exception is propagated to the invocation stack unless\n' - ' there is a "finally" clause which happens to raise another\n' - ' exception. That new exception causes the old one to be lost.\n' + '[1] The exception is propagated to the invocation stack unless ' + 'there\n' + ' is a "finally" clause which happens to raise another ' + 'exception.\n' + ' That new exception causes the old one to be lost.\n' '\n' - '[2] A string literal appearing as the first statement in the\n' - ' function body is transformed into the function’s "__doc__"\n' - ' attribute and therefore the function’s *docstring*.\n' + '[2] A string literal appearing as the first statement in the ' + 'function\n' + ' body is transformed into the function’s "__doc__" attribute ' + 'and\n' + ' therefore the function’s *docstring*.\n' '\n' '[3] A string literal appearing as the first statement in the class\n' ' body is transformed into the namespace’s "__doc__" item and\n' @@ -688,11 +692,13 @@ 'needs, for\n' ' example, "object.__getattribute__(self, name)".\n' '\n' - ' Note: This method may still be bypassed when looking ' - 'up special\n' - ' methods as the result of implicit invocation via ' - 'language syntax\n' - ' or built-in functions. See Special method lookup.\n' + ' Note:\n' + '\n' + ' This method may still be bypassed when looking up ' + 'special methods\n' + ' as the result of implicit invocation via language ' + 'syntax or\n' + ' built-in functions. See Special method lookup.\n' '\n' 'object.__setattr__(self, name, value)\n' '\n' @@ -776,15 +782,16 @@ '\n' ' sys.modules[__name__].__class__ = VerboseModule\n' '\n' - 'Note: Defining module "__getattr__" and setting module ' - '"__class__"\n' - ' only affect lookups made using the attribute access ' - 'syntax –\n' - ' directly accessing the module globals (whether by code ' - 'within the\n' - ' module, or via a reference to the module’s globals ' - 'dictionary) is\n' - ' unaffected.\n' + 'Note:\n' + '\n' + ' Defining module "__getattr__" and setting module ' + '"__class__" only\n' + ' affect lookups made using the attribute access syntax ' + '– directly\n' + ' accessing the module globals (whether by code within ' + 'the module, or\n' + ' via a reference to the module’s globals dictionary) is ' + 'unaffected.\n' '\n' 'Changed in version 3.5: "__class__" module attribute is ' 'now writable.\n' @@ -867,12 +874,14 @@ 'created. The\n' ' descriptor has been assigned to *name*.\n' '\n' - ' Note: "__set_name__()" is only called implicitly as ' - 'part of the\n' - ' "type" constructor, so it will need to be called ' - 'explicitly with\n' - ' the appropriate parameters when a descriptor is ' - 'added to a class\n' + ' Note:\n' + '\n' + ' "__set_name__()" is only called implicitly as part ' + 'of the "type"\n' + ' constructor, so it will need to be called ' + 'explicitly with the\n' + ' appropriate parameters when a descriptor is added ' + 'to a class\n' ' after initial creation:\n' '\n' ' class A:\n' @@ -1033,10 +1042,9 @@ '--------------------------\n' '\n' '* When inheriting from a class without *__slots__*, the ' - '*__dict__*\n' - ' and *__weakref__* attribute of the instances will ' - 'always be\n' - ' accessible.\n' + '*__dict__* and\n' + ' *__weakref__* attribute of the instances will always ' + 'be accessible.\n' '\n' '* Without a *__dict__* variable, instances cannot be ' 'assigned new\n' @@ -1051,14 +1059,12 @@ ' declaration.\n' '\n' '* Without a *__weakref__* variable for each instance, ' - 'classes\n' - ' defining *__slots__* do not support weak references to ' - 'its\n' - ' instances. If weak reference support is needed, then ' - 'add\n' - ' "\'__weakref__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' + 'classes defining\n' + ' *__slots__* do not support weak references to its ' + 'instances. If weak\n' + ' reference support is needed, then add ' + '"\'__weakref__\'" to the\n' + ' sequence of strings in the *__slots__* declaration.\n' '\n' '* *__slots__* are implemented at the class level by ' 'creating\n' @@ -1071,24 +1077,23 @@ ' attribute would overwrite the descriptor assignment.\n' '\n' '* The action of a *__slots__* declaration is not limited ' - 'to the\n' - ' class where it is defined. *__slots__* declared in ' - 'parents are\n' - ' available in child classes. However, child subclasses ' - 'will get a\n' - ' *__dict__* and *__weakref__* unless they also define ' - '*__slots__*\n' - ' (which should only contain names of any *additional* ' - 'slots).\n' + 'to the class\n' + ' where it is defined. *__slots__* declared in parents ' + 'are available\n' + ' in child classes. However, child subclasses will get a ' + '*__dict__*\n' + ' and *__weakref__* unless they also define *__slots__* ' + '(which should\n' + ' only contain names of any *additional* slots).\n' '\n' '* If a class defines a slot also defined in a base ' - 'class, the\n' - ' instance variable defined by the base class slot is ' - 'inaccessible\n' - ' (except by retrieving its descriptor directly from the ' - 'base class).\n' - ' This renders the meaning of the program undefined. In ' - 'the future, a\n' + 'class, the instance\n' + ' variable defined by the base class slot is ' + 'inaccessible (except by\n' + ' retrieving its descriptor directly from the base ' + 'class). This\n' + ' renders the meaning of the program undefined. In the ' + 'future, a\n' ' check may be added to prevent this.\n' '\n' '* Nonempty *__slots__* does not work for classes derived ' @@ -1097,9 +1102,9 @@ '"bytes" and "tuple".\n' '\n' '* Any non-string iterable may be assigned to ' - '*__slots__*. Mappings\n' - ' may also be used; however, in the future, special ' - 'meaning may be\n' + '*__slots__*. Mappings may\n' + ' also be used; however, in the future, special meaning ' + 'may be\n' ' assigned to the values corresponding to each key.\n' '\n' '* *__class__* assignment works only if both classes have ' @@ -1115,9 +1120,9 @@ ' raise "TypeError".\n' '\n' '* If an iterator is used for *__slots__* then a ' - 'descriptor is\n' - ' created for each of the iterator’s values. However, ' - 'the *__slots__*\n' + 'descriptor is created\n' + ' for each of the iterator’s values. However, the ' + '*__slots__*\n' ' attribute will be an empty iterator.\n', 'attribute-references': 'Attribute references\n' '********************\n' @@ -1882,10 +1887,10 @@ ' != x" is true. This behavior is compliant with IEEE 754.\n' '\n' '* "None" and "NotImplemented" are singletons. **PEP 8** ' - 'advises\n' - ' that comparisons for singletons should always be done with ' - '"is" or\n' - ' "is not", never the equality operators.\n' + 'advises that\n' + ' comparisons for singletons should always be done with "is" ' + 'or "is\n' + ' not", never the equality operators.\n' '\n' '* Binary sequences (instances of "bytes" or "bytearray") can ' 'be\n' @@ -1901,15 +1906,15 @@ '\n' ' Strings and binary sequences cannot be directly compared.\n' '\n' - '* Sequences (instances of "tuple", "list", or "range") can ' - 'be\n' - ' compared only within each of their types, with the ' - 'restriction that\n' - ' ranges do not support order comparison. Equality ' - 'comparison across\n' - ' these types results in inequality, and ordering comparison ' - 'across\n' - ' these types raises "TypeError".\n' + '* Sequences (instances of "tuple", "list", or "range") can be ' + 'compared\n' + ' only within each of their types, with the restriction that ' + 'ranges do\n' + ' not support order comparison. Equality comparison across ' + 'these\n' + ' types results in inequality, and ordering comparison across ' + 'these\n' + ' types raises "TypeError".\n' '\n' ' Sequences compare lexicographically using comparison of\n' ' corresponding elements. The built-in containers typically ' @@ -1933,8 +1938,8 @@ ' false because the type is not the same).\n' '\n' ' * Collections that support order comparison are ordered the ' - 'same\n' - ' as their first unequal elements (for example, "[1,2,x] <= ' + 'same as\n' + ' their first unequal elements (for example, "[1,2,x] <= ' '[1,2,y]"\n' ' has the same value as "x <= y"). If a corresponding ' 'element does\n' @@ -1952,8 +1957,8 @@ '"TypeError".\n' '\n' '* Sets (instances of "set" or "frozenset") can be compared ' - 'within\n' - ' and across their types.\n' + 'within and\n' + ' across their types.\n' '\n' ' They define order comparison operators to mean subset and ' 'superset\n' @@ -1972,8 +1977,8 @@ ' Comparison of sets enforces reflexivity of its elements.\n' '\n' '* Most other built-in types have no comparison methods ' - 'implemented,\n' - ' so they inherit the default comparison behavior.\n' + 'implemented, so\n' + ' they inherit the default comparison behavior.\n' '\n' 'User-defined classes that customize their comparison behavior ' 'should\n' @@ -2022,10 +2027,10 @@ ' "total_ordering()" decorator.\n' '\n' '* The "hash()" result should be consistent with equality. ' - 'Objects\n' - ' that are equal should either have the same hash value, or ' - 'be marked\n' - ' as unhashable.\n' + 'Objects that\n' + ' are equal should either have the same hash value, or be ' + 'marked as\n' + ' unhashable.\n' '\n' 'Python does not enforce these consistency rules. In fact, ' 'the\n' @@ -2299,10 +2304,11 @@ ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' '2]".\n' '\n' - 'Note: There is a subtlety when the sequence is being modified by ' - 'the\n' - ' loop (this can only occur for mutable sequences, e.g. lists). ' - 'An\n' + 'Note:\n' + '\n' + ' There is a subtlety when the sequence is being modified by the ' + 'loop\n' + ' (this can only occur for mutable sequences, e.g. lists). An\n' ' internal counter is used to keep track of which item is used ' 'next,\n' ' and this is incremented on each iteration. When this counter ' @@ -2525,8 +2531,8 @@ 'follows:\n' '\n' '1. The context expression (the expression given in the ' - '"with_item")\n' - ' is evaluated to obtain a context manager.\n' + '"with_item") is\n' + ' evaluated to obtain a context manager.\n' '\n' '2. The context manager’s "__enter__()" is loaded for later use.\n' '\n' @@ -2534,13 +2540,15 @@ '\n' '4. The context manager’s "__enter__()" method is invoked.\n' '\n' - '5. If a target was included in the "with" statement, the return\n' - ' value from "__enter__()" is assigned to it.\n' + '5. If a target was included in the "with" statement, the return ' + 'value\n' + ' from "__enter__()" is assigned to it.\n' + '\n' + ' Note:\n' '\n' - ' Note: The "with" statement guarantees that if the ' - '"__enter__()"\n' - ' method returns without an error, then "__exit__()" will ' - 'always be\n' + ' The "with" statement guarantees that if the "__enter__()" ' + 'method\n' + ' returns without an error, then "__exit__()" will always be\n' ' called. Thus, if an error occurs during the assignment to ' 'the\n' ' target list, it will be treated the same as an error ' @@ -2710,17 +2718,17 @@ '“pre-\n' 'computed” value is used for each call. This is especially ' 'important\n' - 'to understand when a default parameter is a mutable object, such ' - 'as a\n' - 'list or a dictionary: if the function modifies the object (e.g. ' - 'by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body of ' - 'the\n' - 'function, e.g.:\n' + 'to understand when a default parameter value is a mutable ' + 'object, such\n' + 'as a list or a dictionary: if the function modifies the object ' + '(e.g.\n' + 'by appending an item to a list), the default parameter value is ' + 'in\n' + 'effect modified. This is generally not what was intended. A ' + 'way\n' + 'around this is to use "None" as the default, and explicitly test ' + 'for\n' + 'it in the body of the function, e.g.:\n' '\n' ' def whats_on_the_telly(penguin=None):\n' ' if penguin is None:\n' @@ -3054,14 +3062,17 @@ '\n' '-[ Footnotes ]-\n' '\n' - '[1] The exception is propagated to the invocation stack unless\n' - ' there is a "finally" clause which happens to raise another\n' - ' exception. That new exception causes the old one to be ' - 'lost.\n' + '[1] The exception is propagated to the invocation stack unless ' + 'there\n' + ' is a "finally" clause which happens to raise another ' + 'exception.\n' + ' That new exception causes the old one to be lost.\n' '\n' - '[2] A string literal appearing as the first statement in the\n' - ' function body is transformed into the function’s "__doc__"\n' - ' attribute and therefore the function’s *docstring*.\n' + '[2] A string literal appearing as the first statement in the ' + 'function\n' + ' body is transformed into the function’s "__doc__" attribute ' + 'and\n' + ' therefore the function’s *docstring*.\n' '\n' '[3] A string literal appearing as the first statement in the ' 'class\n' @@ -3160,8 +3171,8 @@ ' complex;\n' '\n' '* otherwise, if either argument is a floating point number, ' - 'the\n' - ' other is converted to floating point;\n' + 'the other\n' + ' is converted to floating point;\n' '\n' '* otherwise, both must be integers and no conversion is ' 'necessary.\n' @@ -3271,7 +3282,9 @@ 'for\n' ' objects that still exist when the interpreter exits.\n' '\n' - ' Note: "del x" doesn’t directly call "x.__del__()" — the ' + ' Note:\n' + '\n' + ' "del x" doesn’t directly call "x.__del__()" — the ' 'former\n' ' decrements the reference count for "x" by one, and the ' 'latter is\n' @@ -3295,13 +3308,15 @@ '\n' ' See also: Documentation for the "gc" module.\n' '\n' - ' Warning: Due to the precarious circumstances under ' - 'which\n' - ' "__del__()" methods are invoked, exceptions that occur ' - 'during\n' - ' their execution are ignored, and a warning is printed ' - 'to\n' - ' "sys.stderr" instead. In particular:\n' + ' Warning:\n' + '\n' + ' Due to the precarious circumstances under which ' + '"__del__()"\n' + ' methods are invoked, exceptions that occur during ' + 'their execution\n' + ' are ignored, and a warning is printed to "sys.stderr" ' + 'instead.\n' + ' In particular:\n' '\n' ' * "__del__()" can be invoked when arbitrary code is ' 'being\n' @@ -3314,22 +3329,20 @@ ' that gets interrupted to execute "__del__()".\n' '\n' ' * "__del__()" can be executed during interpreter ' - 'shutdown. As\n' - ' a consequence, the global variables it needs to ' - 'access\n' - ' (including other modules) may already have been ' - 'deleted or set\n' - ' to "None". Python guarantees that globals whose name ' - 'begins\n' - ' with a single underscore are deleted from their ' - 'module before\n' - ' other globals are deleted; if no other references to ' - 'such\n' - ' globals exist, this may help in assuring that ' - 'imported modules\n' - ' are still available at the time when the "__del__()" ' - 'method is\n' - ' called.\n' + 'shutdown. As a\n' + ' consequence, the global variables it needs to access ' + '(including\n' + ' other modules) may already have been deleted or set ' + 'to "None".\n' + ' Python guarantees that globals whose name begins ' + 'with a single\n' + ' underscore are deleted from their module before ' + 'other globals\n' + ' are deleted; if no other references to such globals ' + 'exist, this\n' + ' may help in assuring that imported modules are still ' + 'available\n' + ' at the time when the "__del__()" method is called.\n' '\n' 'object.__repr__(self)\n' '\n' @@ -3505,19 +3518,21 @@ ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' '\n' - ' Note: "hash()" truncates the value returned from an ' - 'object’s\n' - ' custom "__hash__()" method to the size of a ' - '"Py_ssize_t". This\n' - ' is typically 8 bytes on 64-bit builds and 4 bytes on ' - '32-bit\n' - ' builds. If an object’s "__hash__()" must ' - 'interoperate on builds\n' - ' of different bit sizes, be sure to check the width on ' - 'all\n' - ' supported builds. An easy way to do this is with ' - '"python -c\n' - ' "import sys; print(sys.hash_info.width)"".\n' + ' Note:\n' + '\n' + ' "hash()" truncates the value returned from an object’s ' + 'custom\n' + ' "__hash__()" method to the size of a "Py_ssize_t". ' + 'This is\n' + ' typically 8 bytes on 64-bit builds and 4 bytes on ' + '32-bit builds.\n' + ' If an object’s "__hash__()" must interoperate on ' + 'builds of\n' + ' different bit sizes, be sure to check the width on all ' + 'supported\n' + ' builds. An easy way to do this is with "python -c ' + '"import sys;\n' + ' print(sys.hash_info.width)"".\n' '\n' ' If a class does not define an "__eq__()" method it ' 'should not\n' @@ -3575,22 +3590,24 @@ ' hashable by an "isinstance(obj, ' 'collections.abc.Hashable)" call.\n' '\n' - ' Note: By default, the "__hash__()" values of str and ' - 'bytes\n' - ' objects are “salted” with an unpredictable random ' - 'value.\n' - ' Although they remain constant within an individual ' - 'Python\n' - ' process, they are not predictable between repeated ' - 'invocations of\n' - ' Python.This is intended to provide protection against ' - 'a denial-\n' - ' of-service caused by carefully-chosen inputs that ' - 'exploit the\n' - ' worst case performance of a dict insertion, O(n^2) ' - 'complexity.\n' - ' See ' - 'http://www.ocert.org/advisories/ocert-2011-003.html for\n' + ' Note:\n' + '\n' + ' By default, the "__hash__()" values of str and bytes ' + 'objects are\n' + ' “salted” with an unpredictable random value. Although ' + 'they\n' + ' remain constant within an individual Python process, ' + 'they are not\n' + ' predictable between repeated invocations of ' + 'Python.This is\n' + ' intended to provide protection against a ' + 'denial-of-service caused\n' + ' by carefully-chosen inputs that exploit the worst ' + 'case\n' + ' performance of a dict insertion, O(n^2) complexity. ' + 'See\n' + ' http://www.ocert.org/advisories/ocert-2011-003.html ' + 'for\n' ' details.Changing hash values affects the iteration ' 'order of sets.\n' ' Python has never made guarantees about this ordering ' @@ -4170,9 +4187,11 @@ 'its\n' ' value.\n' '\n' - ' Note: "print()" can also be used, but is not a debugger ' - 'command —\n' - ' this executes the Python "print()" function.\n' + ' Note:\n' + '\n' + ' "print()" can also be used, but is not a debugger command — ' + 'this\n' + ' executes the Python "print()" function.\n' '\n' 'pp expression\n' '\n' @@ -4298,13 +4317,14 @@ ' the current environment).\n' '\n' 'retval\n' - 'Print the return value for the last return of a function.\n' + '\n' + ' Print the return value for the last return of a function.\n' '\n' '-[ Footnotes ]-\n' '\n' '[1] Whether a frame is considered to originate in a certain ' - 'module\n' - ' is determined by the "__name__" in the frame globals.\n', + 'module is\n' + ' determined by the "__name__" in the frame globals.\n', 'del': 'The "del" statement\n' '*******************\n' '\n' @@ -4484,13 +4504,15 @@ 'about the\n' 'exceptional condition.\n' '\n' - 'Note: Exception messages are not part of the Python API. ' - 'Their\n' - ' contents may change from one version of Python to the next ' - 'without\n' - ' warning and should not be relied on by code which will run ' - 'under\n' - ' multiple versions of the interpreter.\n' + 'Note:\n' + '\n' + ' Exception messages are not part of the Python API. Their ' + 'contents\n' + ' may change from one version of Python to the next without ' + 'warning\n' + ' and should not be relied on by code which will run under ' + 'multiple\n' + ' versions of the interpreter.\n' '\n' 'See also the description of the "try" statement in section The ' 'try\n' @@ -4500,10 +4522,9 @@ '-[ Footnotes ]-\n' '\n' '[1] This limitation occurs because the code that is executed ' - 'by\n' - ' these operations is not available at the time the module ' - 'is\n' - ' compiled.\n', + 'by these\n' + ' operations is not available at the time the module is ' + 'compiled.\n', 'execmodel': 'Execution model\n' '***************\n' '\n' @@ -4809,13 +4830,15 @@ 'about the\n' 'exceptional condition.\n' '\n' - 'Note: Exception messages are not part of the Python API. ' - 'Their\n' - ' contents may change from one version of Python to the next ' - 'without\n' - ' warning and should not be relied on by code which will run ' - 'under\n' - ' multiple versions of the interpreter.\n' + 'Note:\n' + '\n' + ' Exception messages are not part of the Python API. Their ' + 'contents\n' + ' may change from one version of Python to the next without ' + 'warning\n' + ' and should not be relied on by code which will run under ' + 'multiple\n' + ' versions of the interpreter.\n' '\n' 'See also the description of the "try" statement in section The ' 'try\n' @@ -4824,11 +4847,10 @@ '\n' '-[ Footnotes ]-\n' '\n' - '[1] This limitation occurs because the code that is executed ' - 'by\n' - ' these operations is not available at the time the module ' - 'is\n' - ' compiled.\n', + '[1] This limitation occurs because the code that is executed by ' + 'these\n' + ' operations is not available at the time the module is ' + 'compiled.\n', 'exprlists': 'Expression lists\n' '****************\n' '\n' @@ -4947,8 +4969,11 @@ 'i\n' ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n' '\n' - 'Note: There is a subtlety when the sequence is being modified by the\n' - ' loop (this can only occur for mutable sequences, e.g. lists). An\n' + 'Note:\n' + '\n' + ' There is a subtlety when the sequence is being modified by the ' + 'loop\n' + ' (this can only occur for mutable sequences, e.g. lists). An\n' ' internal counter is used to keep track of which item is used next,\n' ' and this is incremented on each iteration. When this counter has\n' ' reached the length of the sequence the loop terminates. This ' @@ -5786,17 +5811,17 @@ '“pre-\n' 'computed” value is used for each call. This is especially ' 'important\n' - 'to understand when a default parameter is a mutable object, such ' - 'as a\n' - 'list or a dictionary: if the function modifies the object (e.g. ' - 'by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body of ' - 'the\n' - 'function, e.g.:\n' + 'to understand when a default parameter value is a mutable ' + 'object, such\n' + 'as a list or a dictionary: if the function modifies the object ' + '(e.g.\n' + 'by appending an item to a list), the default parameter value is ' + 'in\n' + 'effect modified. This is generally not what was intended. A ' + 'way\n' + 'around this is to use "None" as the default, and explicitly test ' + 'for\n' + 'it in the body of the function, e.g.:\n' '\n' ' def whats_on_the_telly(penguin=None):\n' ' if penguin is None:\n' @@ -5956,7 +5981,9 @@ 'defined.\n' ' See section The import statement.\n' '\n' - ' Note: The name "_" is often used in conjunction with\n' + ' Note:\n' + '\n' + ' The name "_" is often used in conjunction with\n' ' internationalization; refer to the documentation for the\n' ' "gettext" module for more information on this ' 'convention.\n' @@ -6060,8 +6087,8 @@ '\n' 'A non-normative HTML file listing all valid identifier ' 'characters for\n' - 'Unicode 4.1 can be found at https://www.dcl.hpi.uni-\n' - 'potsdam.de/home/loewis/table-3131.html.\n' + 'Unicode 4.1 can be found at\n' + 'https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txt\n' '\n' '\n' 'Keywords\n' @@ -6102,7 +6129,9 @@ 'defined.\n' ' See section The import statement.\n' '\n' - ' Note: The name "_" is often used in conjunction with\n' + ' Note:\n' + '\n' + ' The name "_" is often used in conjunction with\n' ' internationalization; refer to the documentation for ' 'the\n' ' "gettext" module for more information on this ' @@ -6187,8 +6216,9 @@ '\n' '1. find a module, loading and initializing it if necessary\n' '\n' - '2. define a name or names in the local namespace for the scope\n' - ' where the "import" statement occurs.\n' + '2. define a name or names in the local namespace for the scope ' + 'where\n' + ' the "import" statement occurs.\n' '\n' 'When the statement contains multiple clauses (separated by commas) ' 'the\n' @@ -6214,8 +6244,9 @@ 'made\n' 'available in the local namespace in one of three ways:\n' '\n' - '* If the module name is followed by "as", then the name following\n' - ' "as" is bound directly to the imported module.\n' + '* If the module name is followed by "as", then the name following ' + '"as"\n' + ' is bound directly to the imported module.\n' '\n' '* If no other name is specified, and the module being imported is ' 'a\n' @@ -6893,15 +6924,18 @@ '"__rpow__()" (the\n' ' coercion rules would become too complicated).\n' '\n' - ' Note: If the right operand’s type is a subclass of the ' - 'left\n' - ' operand’s type and that subclass provides the ' - 'reflected method\n' - ' for the operation, this method will be called before ' - 'the left\n' - ' operand’s non-reflected method. This behavior allows ' - 'subclasses\n' - ' to override their ancestors’ operations.\n' + ' Note:\n' + '\n' + ' If the right operand’s type is a subclass of the left ' + 'operand’s\n' + ' type and that subclass provides a different ' + 'implementation of the\n' + ' reflected method for the operation, this method will ' + 'be called\n' + ' before the left operand’s non-reflected method. This ' + 'behavior\n' + ' allows subclasses to override their ancestors’ ' + 'operations.\n' '\n' 'object.__iadd__(self, other)\n' 'object.__isub__(self, other)\n' @@ -7221,8 +7255,8 @@ '-[ Footnotes ]-\n' '\n' '[1] While "abs(x%y) < abs(y)" is true mathematically, ' - 'for floats\n' - ' it may not be true numerically due to roundoff. For ' + 'for floats it\n' + ' may not be true numerically due to roundoff. For ' 'example, and\n' ' assuming a platform on which a Python float is an ' 'IEEE 754 double-\n' @@ -7287,22 +7321,22 @@ '"unicodedata.normalize()".\n' '\n' '[4] Due to automatic garbage-collection, free lists, and ' - 'the\n' - ' dynamic nature of descriptors, you may notice ' - 'seemingly unusual\n' - ' behaviour in certain uses of the "is" operator, like ' - 'those\n' - ' involving comparisons between instance methods, or ' - 'constants.\n' - ' Check their documentation for more info.\n' + 'the dynamic\n' + ' nature of descriptors, you may notice seemingly ' + 'unusual behaviour\n' + ' in certain uses of the "is" operator, like those ' + 'involving\n' + ' comparisons between instance methods, or constants. ' + 'Check their\n' + ' documentation for more info.\n' '\n' '[5] The "%" operator is also used for string formatting; ' 'the same\n' ' precedence applies.\n' '\n' '[6] The power operator "**" binds less tightly than an ' - 'arithmetic\n' - ' or bitwise unary operator on its right, that is, ' + 'arithmetic or\n' + ' bitwise unary operator on its right, that is, ' '"2**-1" is "0.5".\n', 'pass': 'The "pass" statement\n' '********************\n' @@ -7592,9 +7626,11 @@ '\n' ' New in version 3.4.\n' '\n' - 'Note: Slicing is done exclusively with the following three ' - 'methods.\n' - ' A call like\n' + 'Note:\n' + '\n' + ' Slicing is done exclusively with the following three ' + 'methods. A\n' + ' call like\n' '\n' ' a[1:2] = b\n' '\n' @@ -7625,7 +7661,9 @@ 'the\n' ' container), "KeyError" should be raised.\n' '\n' - ' Note: "for" loops expect that an "IndexError" will be ' + ' Note:\n' + '\n' + ' "for" loops expect that an "IndexError" will be ' 'raised for\n' ' illegal indexes to allow proper detection of the end ' 'of the\n' @@ -7861,26 +7899,26 @@ '-[ Footnotes ]-\n' '\n' '[1] Additional information on these special methods may be ' - 'found\n' - ' in the Python Reference Manual (Basic customization).\n' + 'found in\n' + ' the Python Reference Manual (Basic customization).\n' '\n' '[2] As a consequence, the list "[1, 2]" is considered equal ' - 'to\n' - ' "[1.0, 2.0]", and similarly for tuples.\n' + 'to "[1.0,\n' + ' 2.0]", and similarly for tuples.\n' '\n' '[3] They must have since the parser can’t tell the type of ' 'the\n' ' operands.\n' '\n' '[4] Cased characters are those with general category ' - 'property\n' - ' being one of “Lu” (Letter, uppercase), “Ll” (Letter, ' - 'lowercase),\n' - ' or “Lt” (Letter, titlecase).\n' - '\n' - '[5] To format only a tuple you should therefore provide a\n' - ' singleton tuple whose only element is the tuple to be ' - 'formatted.\n', + 'property being\n' + ' one of “Lu” (Letter, uppercase), “Ll” (Letter, ' + 'lowercase), or “Lt”\n' + ' (Letter, titlecase).\n' + '\n' + '[5] To format only a tuple you should therefore provide a ' + 'singleton\n' + ' tuple whose only element is the tuple to be formatted.\n', 'specialnames': 'Special method names\n' '********************\n' '\n' @@ -8025,7 +8063,9 @@ 'for\n' ' objects that still exist when the interpreter exits.\n' '\n' - ' Note: "del x" doesn’t directly call "x.__del__()" — the ' + ' Note:\n' + '\n' + ' "del x" doesn’t directly call "x.__del__()" — the ' 'former\n' ' decrements the reference count for "x" by one, and the ' 'latter is\n' @@ -8049,12 +8089,15 @@ '\n' ' See also: Documentation for the "gc" module.\n' '\n' - ' Warning: Due to the precarious circumstances under which\n' - ' "__del__()" methods are invoked, exceptions that occur ' - 'during\n' - ' their execution are ignored, and a warning is printed ' - 'to\n' - ' "sys.stderr" instead. In particular:\n' + ' Warning:\n' + '\n' + ' Due to the precarious circumstances under which ' + '"__del__()"\n' + ' methods are invoked, exceptions that occur during their ' + 'execution\n' + ' are ignored, and a warning is printed to "sys.stderr" ' + 'instead.\n' + ' In particular:\n' '\n' ' * "__del__()" can be invoked when arbitrary code is ' 'being\n' @@ -8067,22 +8110,20 @@ ' that gets interrupted to execute "__del__()".\n' '\n' ' * "__del__()" can be executed during interpreter ' - 'shutdown. As\n' - ' a consequence, the global variables it needs to ' - 'access\n' - ' (including other modules) may already have been ' - 'deleted or set\n' - ' to "None". Python guarantees that globals whose name ' - 'begins\n' - ' with a single underscore are deleted from their ' - 'module before\n' - ' other globals are deleted; if no other references to ' - 'such\n' - ' globals exist, this may help in assuring that ' - 'imported modules\n' - ' are still available at the time when the "__del__()" ' - 'method is\n' - ' called.\n' + 'shutdown. As a\n' + ' consequence, the global variables it needs to access ' + '(including\n' + ' other modules) may already have been deleted or set ' + 'to "None".\n' + ' Python guarantees that globals whose name begins with ' + 'a single\n' + ' underscore are deleted from their module before other ' + 'globals\n' + ' are deleted; if no other references to such globals ' + 'exist, this\n' + ' may help in assuring that imported modules are still ' + 'available\n' + ' at the time when the "__del__()" method is called.\n' '\n' 'object.__repr__(self)\n' '\n' @@ -8258,19 +8299,21 @@ ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' '\n' - ' Note: "hash()" truncates the value returned from an ' - 'object’s\n' - ' custom "__hash__()" method to the size of a ' - '"Py_ssize_t". This\n' - ' is typically 8 bytes on 64-bit builds and 4 bytes on ' - '32-bit\n' - ' builds. If an object’s "__hash__()" must interoperate ' - 'on builds\n' - ' of different bit sizes, be sure to check the width on ' - 'all\n' - ' supported builds. An easy way to do this is with ' - '"python -c\n' - ' "import sys; print(sys.hash_info.width)"".\n' + ' Note:\n' + '\n' + ' "hash()" truncates the value returned from an object’s ' + 'custom\n' + ' "__hash__()" method to the size of a "Py_ssize_t". ' + 'This is\n' + ' typically 8 bytes on 64-bit builds and 4 bytes on ' + '32-bit builds.\n' + ' If an object’s "__hash__()" must interoperate on ' + 'builds of\n' + ' different bit sizes, be sure to check the width on all ' + 'supported\n' + ' builds. An easy way to do this is with "python -c ' + '"import sys;\n' + ' print(sys.hash_info.width)"".\n' '\n' ' If a class does not define an "__eq__()" method it should ' 'not\n' @@ -8326,21 +8369,22 @@ ' hashable by an "isinstance(obj, ' 'collections.abc.Hashable)" call.\n' '\n' - ' Note: By default, the "__hash__()" values of str and ' - 'bytes\n' - ' objects are “salted” with an unpredictable random ' - 'value.\n' - ' Although they remain constant within an individual ' - 'Python\n' - ' process, they are not predictable between repeated ' - 'invocations of\n' - ' Python.This is intended to provide protection against a ' - 'denial-\n' - ' of-service caused by carefully-chosen inputs that ' - 'exploit the\n' - ' worst case performance of a dict insertion, O(n^2) ' - 'complexity.\n' - ' See http://www.ocert.org/advisories/ocert-2011-003.html ' + ' Note:\n' + '\n' + ' By default, the "__hash__()" values of str and bytes ' + 'objects are\n' + ' “salted” with an unpredictable random value. Although ' + 'they\n' + ' remain constant within an individual Python process, ' + 'they are not\n' + ' predictable between repeated invocations of Python.This ' + 'is\n' + ' intended to provide protection against a ' + 'denial-of-service caused\n' + ' by carefully-chosen inputs that exploit the worst case\n' + ' performance of a dict insertion, O(n^2) complexity. ' + 'See\n' + ' http://www.ocert.org/advisories/ocert-2011-003.html ' 'for\n' ' details.Changing hash values affects the iteration ' 'order of sets.\n' @@ -8429,11 +8473,13 @@ 'needs, for\n' ' example, "object.__getattribute__(self, name)".\n' '\n' - ' Note: This method may still be bypassed when looking up ' - 'special\n' - ' methods as the result of implicit invocation via ' - 'language syntax\n' - ' or built-in functions. See Special method lookup.\n' + ' Note:\n' + '\n' + ' This method may still be bypassed when looking up ' + 'special methods\n' + ' as the result of implicit invocation via language ' + 'syntax or\n' + ' built-in functions. See Special method lookup.\n' '\n' 'object.__setattr__(self, name, value)\n' '\n' @@ -8517,15 +8563,16 @@ '\n' ' sys.modules[__name__].__class__ = VerboseModule\n' '\n' - 'Note: Defining module "__getattr__" and setting module ' - '"__class__"\n' - ' only affect lookups made using the attribute access syntax ' - '–\n' - ' directly accessing the module globals (whether by code ' - 'within the\n' - ' module, or via a reference to the module’s globals ' - 'dictionary) is\n' - ' unaffected.\n' + 'Note:\n' + '\n' + ' Defining module "__getattr__" and setting module ' + '"__class__" only\n' + ' affect lookups made using the attribute access syntax – ' + 'directly\n' + ' accessing the module globals (whether by code within the ' + 'module, or\n' + ' via a reference to the module’s globals dictionary) is ' + 'unaffected.\n' '\n' 'Changed in version 3.5: "__class__" module attribute is now ' 'writable.\n' @@ -8608,12 +8655,14 @@ 'The\n' ' descriptor has been assigned to *name*.\n' '\n' - ' Note: "__set_name__()" is only called implicitly as part ' - 'of the\n' - ' "type" constructor, so it will need to be called ' - 'explicitly with\n' - ' the appropriate parameters when a descriptor is added ' - 'to a class\n' + ' Note:\n' + '\n' + ' "__set_name__()" is only called implicitly as part of ' + 'the "type"\n' + ' constructor, so it will need to be called explicitly ' + 'with the\n' + ' appropriate parameters when a descriptor is added to a ' + 'class\n' ' after initial creation:\n' '\n' ' class A:\n' @@ -8772,10 +8821,9 @@ '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' '\n' '* When inheriting from a class without *__slots__*, the ' - '*__dict__*\n' - ' and *__weakref__* attribute of the instances will always ' - 'be\n' - ' accessible.\n' + '*__dict__* and\n' + ' *__weakref__* attribute of the instances will always be ' + 'accessible.\n' '\n' '* Without a *__dict__* variable, instances cannot be ' 'assigned new\n' @@ -8789,13 +8837,12 @@ ' declaration.\n' '\n' '* Without a *__weakref__* variable for each instance, ' - 'classes\n' - ' defining *__slots__* do not support weak references to ' - 'its\n' - ' instances. If weak reference support is needed, then add\n' - ' "\'__weakref__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' + 'classes defining\n' + ' *__slots__* do not support weak references to its ' + 'instances. If weak\n' + ' reference support is needed, then add "\'__weakref__\'" to ' + 'the\n' + ' sequence of strings in the *__slots__* declaration.\n' '\n' '* *__slots__* are implemented at the class level by ' 'creating\n' @@ -8808,23 +8855,22 @@ ' attribute would overwrite the descriptor assignment.\n' '\n' '* The action of a *__slots__* declaration is not limited to ' - 'the\n' - ' class where it is defined. *__slots__* declared in ' - 'parents are\n' - ' available in child classes. However, child subclasses will ' - 'get a\n' - ' *__dict__* and *__weakref__* unless they also define ' - '*__slots__*\n' - ' (which should only contain names of any *additional* ' - 'slots).\n' + 'the class\n' + ' where it is defined. *__slots__* declared in parents are ' + 'available\n' + ' in child classes. However, child subclasses will get a ' + '*__dict__*\n' + ' and *__weakref__* unless they also define *__slots__* ' + '(which should\n' + ' only contain names of any *additional* slots).\n' '\n' '* If a class defines a slot also defined in a base class, ' - 'the\n' - ' instance variable defined by the base class slot is ' - 'inaccessible\n' - ' (except by retrieving its descriptor directly from the ' - 'base class).\n' - ' This renders the meaning of the program undefined. In the ' + 'the instance\n' + ' variable defined by the base class slot is inaccessible ' + '(except by\n' + ' retrieving its descriptor directly from the base class). ' + 'This\n' + ' renders the meaning of the program undefined. In the ' 'future, a\n' ' check may be added to prevent this.\n' '\n' @@ -8834,9 +8880,9 @@ 'and "tuple".\n' '\n' '* Any non-string iterable may be assigned to *__slots__*. ' - 'Mappings\n' - ' may also be used; however, in the future, special meaning ' - 'may be\n' + 'Mappings may\n' + ' also be used; however, in the future, special meaning may ' + 'be\n' ' assigned to the values corresponding to each key.\n' '\n' '* *__class__* assignment works only if both classes have the ' @@ -8852,8 +8898,8 @@ ' raise "TypeError".\n' '\n' '* If an iterator is used for *__slots__* then a descriptor ' - 'is\n' - ' created for each of the iterator’s values. However, the ' + 'is created\n' + ' for each of the iterator’s values. However, the ' '*__slots__*\n' ' attribute will be an empty iterator.\n' '\n' @@ -8906,9 +8952,11 @@ 'does nothing,\n' ' but raises an error if it is called with any arguments.\n' '\n' - ' Note: The metaclass hint "metaclass" is consumed by the ' - 'rest of\n' - ' the type machinery, and is never passed to ' + ' Note:\n' + '\n' + ' The metaclass hint "metaclass" is consumed by the rest ' + 'of the\n' + ' type machinery, and is never passed to ' '"__init_subclass__"\n' ' implementations. The actual metaclass (rather than the ' 'explicit\n' @@ -8976,9 +9024,10 @@ 'tuple may\n' 'be empty, in such case the original base is ignored.\n' '\n' - 'See also: **PEP 560** - Core support for typing module and ' - 'generic\n' - ' types\n' + 'See also:\n' + '\n' + ' **PEP 560** - Core support for typing module and generic ' + 'types\n' '\n' '\n' 'Determining the appropriate metaclass\n' @@ -9236,9 +9285,10 @@ 'type hints,\n' 'other usage is discouraged.\n' '\n' - 'See also: **PEP 560** - Core support for typing module and ' - 'generic\n' - ' types\n' + 'See also:\n' + '\n' + ' **PEP 560** - Core support for typing module and generic ' + 'types\n' '\n' '\n' 'Emulating callable objects\n' @@ -9350,9 +9400,11 @@ '\n' ' New in version 3.4.\n' '\n' - 'Note: Slicing is done exclusively with the following three ' - 'methods.\n' - ' A call like\n' + 'Note:\n' + '\n' + ' Slicing is done exclusively with the following three ' + 'methods. A\n' + ' call like\n' '\n' ' a[1:2] = b\n' '\n' @@ -9383,8 +9435,10 @@ 'the\n' ' container), "KeyError" should be raised.\n' '\n' - ' Note: "for" loops expect that an "IndexError" will be ' - 'raised for\n' + ' Note:\n' + '\n' + ' "for" loops expect that an "IndexError" will be raised ' + 'for\n' ' illegal indexes to allow proper detection of the end of ' 'the\n' ' sequence.\n' @@ -9574,15 +9628,18 @@ '"__rpow__()" (the\n' ' coercion rules would become too complicated).\n' '\n' - ' Note: If the right operand’s type is a subclass of the ' - 'left\n' - ' operand’s type and that subclass provides the reflected ' - 'method\n' - ' for the operation, this method will be called before ' - 'the left\n' - ' operand’s non-reflected method. This behavior allows ' - 'subclasses\n' - ' to override their ancestors’ operations.\n' + ' Note:\n' + '\n' + ' If the right operand’s type is a subclass of the left ' + 'operand’s\n' + ' type and that subclass provides a different ' + 'implementation of the\n' + ' reflected method for the operation, this method will be ' + 'called\n' + ' before the left operand’s non-reflected method. This ' + 'behavior\n' + ' allows subclasses to override their ancestors’ ' + 'operations.\n' '\n' 'object.__iadd__(self, other)\n' 'object.__isub__(self, other)\n' @@ -9914,36 +9971,7 @@ '*start* and\n' ' *end* are interpreted as in slice notation.\n' '\n' - 'str.removeprefix(prefix, /)\n' - '\n' - ' If the string starts with the *prefix* string, return\n' - ' "string[len(prefix):]". Otherwise, return a copy of the ' - 'original\n' - ' string:\n' - '\n' - " >>> 'TestHook'.removeprefix('Test')\n" - " 'Hook'\n" - " >>> 'BaseTestCase'.removeprefix('Test')\n" - " 'BaseTestCase'\n" - '\n' - ' New in version 3.9.\n' - '\n' - 'str.removesuffix(suffix, /)\n' - '\n' - ' If the string ends with the *suffix* string and that ' - '*suffix* is\n' - ' not empty, return "string[:-len(suffix)]". Otherwise, ' - 'return a copy\n' - ' of the original string:\n' - '\n' - " >>> 'MiscTests'.removesuffix('Tests')\n" - " 'Misc'\n" - " >>> 'TmpDirMixin'.removesuffix('Tests')\n" - " 'TmpDirMixin'\n" - '\n' - ' New in version 3.9.\n' - '\n' - 'str.encode(encoding="utf-8", errors="strict")\n' + "str.encode(encoding='utf-8', errors='strict')\n" '\n' ' Return an encoded version of the string as a bytes ' 'object. Default\n' @@ -10029,11 +10057,13 @@ '"-1" if\n' ' *sub* is not found.\n' '\n' - ' Note: The "find()" method should be used only if you ' - 'need to know\n' - ' the position of *sub*. To check if *sub* is a ' - 'substring or not,\n' - ' use the "in" operator:\n' + ' Note:\n' + '\n' + ' The "find()" method should be used only if you need ' + 'to know the\n' + ' position of *sub*. To check if *sub* is a substring ' + 'or not, use\n' + ' the "in" operator:\n' '\n' " >>> 'Py' in 'Python'\n" ' True\n' @@ -10062,8 +10092,9 @@ ' formatting options that can be specified in format ' 'strings.\n' '\n' - ' Note: When formatting a number ("int", "float", ' - '"complex",\n' + ' Note:\n' + '\n' + ' When formatting a number ("int", "float", "complex",\n' ' "decimal.Decimal" and subclasses) with the "n" type ' '(ex:\n' ' "\'{:n}\'.format(1234)"), the function temporarily ' @@ -10371,6 +10402,35 @@ 'followed by\n' ' two empty strings.\n' '\n' + 'str.removeprefix(prefix, /)\n' + '\n' + ' If the string starts with the *prefix* string, return\n' + ' "string[len(prefix):]". Otherwise, return a copy of the ' + 'original\n' + ' string:\n' + '\n' + " >>> 'TestHook'.removeprefix('Test')\n" + " 'Hook'\n" + " >>> 'BaseTestCase'.removeprefix('Test')\n" + " 'BaseTestCase'\n" + '\n' + ' New in version 3.9.\n' + '\n' + 'str.removesuffix(suffix, /)\n' + '\n' + ' If the string ends with the *suffix* string and that ' + '*suffix* is\n' + ' not empty, return "string[:-len(suffix)]". Otherwise, ' + 'return a copy\n' + ' of the original string:\n' + '\n' + " >>> 'MiscTests'.removesuffix('Tests')\n" + " 'Misc'\n" + " >>> 'TmpDirMixin'.removesuffix('Tests')\n" + " 'TmpDirMixin'\n" + '\n' + ' New in version 3.9.\n' + '\n' 'str.replace(old, new[, count])\n' '\n' ' Return a copy of the string with all occurrences of ' @@ -10417,7 +10477,7 @@ 'followed by\n' ' the string itself.\n' '\n' - 'str.rsplit(sep=None, maxsplit=-1)\n' + 'str.rsplit(sep=None, maxsplit=- 1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -10458,7 +10518,7 @@ " >>> 'Monty Python'.removesuffix(' Python')\n" " 'Monty'\n" '\n' - 'str.split(sep=None, maxsplit=-1)\n' + 'str.split(sep=None, maxsplit=- 1)\n' '\n' ' Return a list of the words in the string, using *sep* ' 'as the\n' @@ -10939,17 +10999,20 @@ '\n' '2. Unlike in Standard C, exactly two hex digits are required.\n' '\n' - '3. In a bytes literal, hexadecimal and octal escapes denote the\n' - ' byte with the given value. In a string literal, these escapes\n' - ' denote a Unicode character with the given value.\n' + '3. In a bytes literal, hexadecimal and octal escapes denote the ' + 'byte\n' + ' with the given value. In a string literal, these escapes ' + 'denote a\n' + ' Unicode character with the given value.\n' '\n' '4. Changed in version 3.3: Support for name aliases [1] has been\n' ' added.\n' '\n' '5. Exactly four hex digits are required.\n' '\n' - '6. Any Unicode character can be encoded this way. Exactly eight\n' - ' hex digits are required.\n' + '6. Any Unicode character can be encoded this way. Exactly eight ' + 'hex\n' + ' digits are required.\n' '\n' 'Unlike Standard C, all unrecognized escape sequences are left in ' 'the\n' @@ -11399,7 +11462,7 @@ ' points. All the code points in the range "U+0000 - ' 'U+10FFFF"\n' ' can be represented in a string. Python doesn’t have a ' - '"char"\n' + '*char*\n' ' type; instead, every code point in the string is ' 'represented\n' ' as a string object with length "1". The built-in ' @@ -12647,9 +12710,11 @@ '\n' ' Changed in version 3.8: Dictionaries are now reversible.\n' '\n' - 'See also: "types.MappingProxyType" can be used to create a ' - 'read-only\n' - ' view of a "dict".\n' + 'See also:\n' + '\n' + ' "types.MappingProxyType" can be used to create a read-only ' + 'view of a\n' + ' "dict".\n' '\n' '\n' 'Dictionary view objects\n' @@ -12712,6 +12777,14 @@ ' Changed in version 3.8: Dictionary views are now ' 'reversible.\n' '\n' + 'dictview.mapping\n' + '\n' + ' Return a "types.MappingProxyType" that wraps the ' + 'original\n' + ' dictionary to which the view refers.\n' + '\n' + ' New in version 3.10.\n' + '\n' 'Keys views are set-like since their entries are unique and ' 'hashable.\n' 'If all values are hashable, so that "(key, value)" pairs are ' @@ -12757,7 +12830,15 @@ " >>> keys & {'eggs', 'bacon', 'salad'}\n" " {'bacon'}\n" " >>> keys ^ {'sausage', 'juice'}\n" - " {'juice', 'sausage', 'bacon', 'spam'}\n", + " {'juice', 'sausage', 'bacon', 'spam'}\n" + '\n' + ' >>> # get back a read-only proxy for the original ' + 'dictionary\n' + ' >>> values.mapping\n' + " mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, " + "'spam': 500})\n" + " >>> values.mapping['spam']\n" + ' 500\n', 'typesmethods': 'Methods\n' '*******\n' '\n' @@ -13033,13 +13114,14 @@ '"None", it\n' ' is treated like "1".\n' '\n' - '6. Concatenating immutable sequences always results in a new\n' - ' object. This means that building up a sequence by repeated\n' - ' concatenation will have a quadratic runtime cost in the ' - 'total\n' - ' sequence length. To get a linear runtime cost, you must ' - 'switch to\n' - ' one of the alternatives below:\n' + '6. Concatenating immutable sequences always results in a new ' + 'object.\n' + ' This means that building up a sequence by repeated ' + 'concatenation\n' + ' will have a quadratic runtime cost in the total sequence ' + 'length.\n' + ' To get a linear runtime cost, you must switch to one of the\n' + ' alternatives below:\n' '\n' ' * if concatenating "str" objects, you can build a list and ' 'use\n' @@ -13057,24 +13139,25 @@ ' * for other types, investigate the relevant class ' 'documentation\n' '\n' - '7. Some sequence types (such as "range") only support item\n' - ' sequences that follow specific patterns, and hence don’t ' - 'support\n' - ' sequence concatenation or repetition.\n' - '\n' - '8. "index" raises "ValueError" when *x* is not found in *s*. ' - 'Not\n' - ' all implementations support passing the additional arguments ' - '*i*\n' - ' and *j*. These arguments allow efficient searching of ' - 'subsections\n' - ' of the sequence. Passing the extra arguments is roughly ' - 'equivalent\n' - ' to using "s[i:j].index(x)", only without copying any data and ' - 'with\n' - ' the returned index being relative to the start of the ' + '7. Some sequence types (such as "range") only support item ' + 'sequences\n' + ' that follow specific patterns, and hence don’t support ' 'sequence\n' - ' rather than the start of the slice.\n' + ' concatenation or repetition.\n' + '\n' + '8. "index" raises "ValueError" when *x* is not found in *s*. Not ' + 'all\n' + ' implementations support passing the additional arguments *i* ' + 'and\n' + ' *j*. These arguments allow efficient searching of subsections ' + 'of\n' + ' the sequence. Passing the extra arguments is roughly ' + 'equivalent to\n' + ' using "s[i:j].index(x)", only without copying any data and ' + 'with the\n' + ' returned index being relative to the start of the sequence ' + 'rather\n' + ' than the start of the slice.\n' '\n' '\n' 'Immutable Sequence Types\n' @@ -13202,17 +13285,17 @@ '1. *t* must have the same length as the slice it is replacing.\n' '\n' '2. The optional argument *i* defaults to "-1", so that by ' - 'default\n' - ' the last item is removed and returned.\n' + 'default the\n' + ' last item is removed and returned.\n' '\n' '3. "remove()" raises "ValueError" when *x* is not found in *s*.\n' '\n' - '4. The "reverse()" method modifies the sequence in place for\n' - ' economy of space when reversing a large sequence. To remind ' - 'users\n' - ' that it operates by side effect, it does not return the ' - 'reversed\n' - ' sequence.\n' + '4. The "reverse()" method modifies the sequence in place for ' + 'economy\n' + ' of space when reversing a large sequence. To remind users ' + 'that it\n' + ' operates by side effect, it does not return the reversed ' + 'sequence.\n' '\n' '5. "clear()" and "copy()" are included for consistency with the\n' ' interfaces of mutable containers that don’t support slicing\n' @@ -13249,9 +13332,9 @@ ' * Using a pair of square brackets to denote the empty list: ' '"[]"\n' '\n' - ' * Using square brackets, separating items with commas: ' - '"[a]",\n' - ' "[a, b, c]"\n' + ' * Using square brackets, separating items with commas: "[a]", ' + '"[a,\n' + ' b, c]"\n' '\n' ' * Using a list comprehension: "[x for x in iterable]"\n' '\n' @@ -13554,9 +13637,9 @@ '\n' 'See also:\n' '\n' - ' * The linspace recipe shows how to implement a lazy version ' - 'of\n' - ' range suitable for floating point applications.\n', + ' * The linspace recipe shows how to implement a lazy version of ' + 'range\n' + ' suitable for floating point applications.\n', 'typesseq-mutable': 'Mutable Sequence Types\n' '**********************\n' '\n' @@ -13667,19 +13750,18 @@ 'replacing.\n' '\n' '2. The optional argument *i* defaults to "-1", so that ' - 'by default\n' - ' the last item is removed and returned.\n' + 'by default the\n' + ' last item is removed and returned.\n' '\n' '3. "remove()" raises "ValueError" when *x* is not found ' 'in *s*.\n' '\n' '4. The "reverse()" method modifies the sequence in place ' - 'for\n' - ' economy of space when reversing a large sequence. To ' - 'remind users\n' - ' that it operates by side effect, it does not return ' - 'the reversed\n' - ' sequence.\n' + 'for economy\n' + ' of space when reversing a large sequence. To remind ' + 'users that it\n' + ' operates by side effect, it does not return the ' + 'reversed sequence.\n' '\n' '5. "clear()" and "copy()" are included for consistency ' 'with the\n' @@ -13762,8 +13844,9 @@ 'The execution of the "with" statement with one “item” proceeds as\n' 'follows:\n' '\n' - '1. The context expression (the expression given in the "with_item")\n' - ' is evaluated to obtain a context manager.\n' + '1. The context expression (the expression given in the "with_item") ' + 'is\n' + ' evaluated to obtain a context manager.\n' '\n' '2. The context manager’s "__enter__()" is loaded for later use.\n' '\n' @@ -13771,12 +13854,15 @@ '\n' '4. The context manager’s "__enter__()" method is invoked.\n' '\n' - '5. If a target was included in the "with" statement, the return\n' - ' value from "__enter__()" is assigned to it.\n' + '5. If a target was included in the "with" statement, the return ' + 'value\n' + ' from "__enter__()" is assigned to it.\n' + '\n' + ' Note:\n' '\n' - ' Note: The "with" statement guarantees that if the "__enter__()"\n' - ' method returns without an error, then "__exit__()" will always ' - 'be\n' + ' The "with" statement guarantees that if the "__enter__()" ' + 'method\n' + ' returns without an error, then "__exit__()" will always be\n' ' called. Thus, if an error occurs during the assignment to the\n' ' target list, it will be treated the same as an error occurring\n' ' within the suite would be. See step 6 below.\n' diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst new file mode 100644 index 000000000000000..725dfd16b180a77 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -0,0 +1,3519 @@ +.. bpo: 41304 +.. date: 2020-07-15-20-15-08 +.. nonce: vNEeYA +.. release date: 2020-10-05 +.. section: Security + +Fixes `python3x._pth` being ignored on Windows, caused by the fix for +:issue:`29778` (CVE-2020-15801). + +.. + +.. bpo: 41162 +.. date: 2020-07-03-20-41-29 +.. nonce: tb8pVj +.. section: Security + +Audit hooks are now cleared later during finalization to avoid missing +events. + +.. + +.. bpo: 29778 +.. date: 2020-07-03-17-21-37 +.. nonce: cR_fGS +.. section: Security + +Ensure :file:`python3.dll` is loaded from correct locations when Python is +embedded (CVE-2020-15523). + +.. + +.. bpo: 41004 +.. date: 2020-06-29-16-02-29 +.. nonce: ovF0KZ +.. section: Security + +The __hash__() methods of ipaddress.IPv4Interface and +ipaddress.IPv6Interface incorrectly generated constant hash values of 32 and +128 respectively. This resulted in always causing hash collisions. The fix +uses hash() to generate hash values for the tuple of (address, mask length, +network address). + +.. + +.. bpo: 39603 +.. date: 2020-02-12-14-17-39 +.. nonce: Gt3RSg +.. section: Security + +Prevent http header injection by rejecting control characters in +http.client.putrequest(...). + +.. + +.. bpo: 41909 +.. date: 2020-10-04-10-55-12 +.. nonce: BqHPcm +.. section: Core and Builtins + +Fixed stack overflow in :func:`issubclass` and :func:`isinstance` when +getting the ``__bases__`` attribute leads to infinite recursion. + +.. + +.. bpo: 41922 +.. date: 2020-10-04-01-02-58 +.. nonce: kHGT8I +.. section: Core and Builtins + +Speed up calls to ``reversed()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Dong-hee Na. + +.. + +.. bpo: 41873 +.. date: 2020-09-28-08-58-28 +.. nonce: VzEDhA +.. section: Core and Builtins + +Calls to ``float()`` are now faster due to the ``vectorcall`` calling +convention. Patch by Dennis Sweeney. + +.. + +.. bpo: 41870 +.. date: 2020-09-27-22-23-14 +.. nonce: 2v6_v4 +.. section: Core and Builtins + +Speed up calls to ``bool()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Dong-hee Na. + +.. + +.. bpo: 1635741 +.. date: 2020-09-26-14-43-30 +.. nonce: aJS9B3 +.. section: Core and Builtins + +Port the :mod:`_bisect` module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 39934 +.. date: 2020-09-24-12-15-45 +.. nonce: YVHTCF +.. section: Core and Builtins + +Correctly count control blocks in 'except' in compiler. Ensures that a +syntax error, rather a fatal error, occurs for deeply nested, named +exception handlers. + +.. + +.. bpo: 41780 +.. date: 2020-09-15-23-29-49 +.. nonce: bOBUIH +.. section: Core and Builtins + +Fix :meth:`__dir__` of :class:`types.GenericAlias`. Patch by Batuhan +Taskaya. + +.. + +.. bpo: 1635741 +.. date: 2020-09-12-18-34-34 +.. nonce: lh335O +.. section: Core and Builtins + +Port the :mod:`_lsprof` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 41756 +.. date: 2020-09-12-12-55-45 +.. nonce: 1h0tbV +.. section: Core and Builtins + +Add PyGen_Send function to allow sending value into generator/coroutine +without raising StopIteration exception to signal return + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-21-58-47 +.. nonce: vdjSLH +.. section: Core and Builtins + +Port the :mod:`cmath` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-20-39-43 +.. nonce: jiXmyT +.. section: Core and Builtins + +Port the :mod:`_scproxy` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-07-11-35-02 +.. nonce: rvIexb +.. section: Core and Builtins + +Port the :mod:`termios` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-07-09-45-47 +.. nonce: QuDIut +.. section: Core and Builtins + +Convert the :mod:`_sha256` extension module types to heap types. + +.. + +.. bpo: 41690 +.. date: 2020-09-02-12-00-57 +.. nonce: Ny-Sfy +.. section: Core and Builtins + +Fix a possible stack overflow in the parser when parsing functions and +classes with a huge ammount of arguments. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-22-35 +.. nonce: CnRME3 +.. section: Core and Builtins + +Port the :mod:`_overlapped` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-08-07 +.. nonce: X9CZgo +.. section: Core and Builtins + +Port the :mod:`_curses_panel` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-06-02 +.. nonce: 5jZymK +.. section: Core and Builtins + +Port the :mod:`_opcode` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 41681 +.. date: 2020-08-31-17-49-02 +.. nonce: 3-VJiH +.. section: Core and Builtins + +Fixes the wrong error description in the error raised by using 2 `,` in +format string in f-string and :meth:`str.format`. + +.. + +.. bpo: 41675 +.. date: 2020-08-31-14-53-17 +.. nonce: VSoqWU +.. section: Core and Builtins + +The implementation of :func:`signal.siginterrupt` now uses +:c:func:`sigaction` (if it is available in the system) instead of the +deprecated :c:func:`siginterrupt`. Patch by Pablo Galindo. + +.. + +.. bpo: 41670 +.. date: 2020-08-31-11-37-59 +.. nonce: vmRJRx +.. section: Core and Builtins + +Prevent line trace being skipped on platforms not compiled with +``USE_COMPUTED_GOTOS``. Fixes issue where some lines nested within a +try-except block were not being traced on Windows. + +.. + +.. bpo: 41654 +.. date: 2020-08-30-20-38-33 +.. nonce: HtnhAM +.. section: Core and Builtins + +Fix a crash that occurred when destroying subclasses of +:class:`MemoryError`. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-08-28-20-54-04 +.. nonce: 7ijlcI +.. section: Core and Builtins + +Port the :mod:`zlib` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 41631 +.. date: 2020-08-26-11-23-31 +.. nonce: 3jZcd9 +.. section: Core and Builtins + +The ``_ast`` module uses again a global state. Using a module state per +module instance is causing subtle practical problems. For example, the +Mercurial project replaces the ``__import__()`` function to implement lazy +import, whereas Python expected that ``import _ast`` always return a fully +initialized ``_ast`` module. + +.. + +.. bpo: 40077 +.. date: 2020-08-25-22-43-33 +.. nonce: vcxSUa +.. section: Core and Builtins + +Convert :mod:`_operator` to use :c:func:`PyType_FromSpec`. + +.. + +.. bpo: 1653741 +.. date: 2020-08-13-07-19-21 +.. nonce: fubBkb +.. section: Core and Builtins + +Port :mod:`_sha3` to multi-phase init. Convert static types to heap types. + +.. + +.. bpo: 1635741 +.. date: 2020-08-13-07-18-05 +.. nonce: FC13e7 +.. section: Core and Builtins + +Port the :mod:`_blake2` extension module to the multi-phase initialization +API (:pep:`489`). + +.. + +.. bpo: 41533 +.. date: 2020-08-12-20-29-57 +.. nonce: 4pcVAc +.. section: Core and Builtins + +Free the stack allocated in ``va_build_stack`` if ``do_mkstack`` fails and +the stack is not a ``small_stack``. + +.. + +.. bpo: 41531 +.. date: 2020-08-12-19-32-15 +.. nonce: WgPzjT +.. section: Core and Builtins + +Fix a bug that was dropping keys when compiling dict literals with more than +0xFFFF elements. Patch by Pablo Galindo. + +.. + +.. bpo: 41525 +.. date: 2020-08-12-07-35-07 +.. nonce: d9q3XL +.. section: Core and Builtins + +The output of ``python --help`` contains now only ASCII characters. + +.. + +.. bpo: 1635741 +.. date: 2020-08-10-16-11-32 +.. nonce: O0d3ym +.. section: Core and Builtins + +Port the :mod:`_sha1`, :mod:`_sha512`, and :mod:`_md5` extension modules to +multi-phase initialization API (:pep:`489`). + +.. + +.. bpo: 41431 +.. date: 2020-08-02-15-53-12 +.. nonce: TblUBT +.. section: Core and Builtins + +Optimize ``dict_merge()`` for copying dict (e.g. ``dict(d)`` and +``{}.update(d)``). + +.. + +.. bpo: 41428 +.. date: 2020-07-28-22-43-27 +.. nonce: FM6xsI +.. section: Core and Builtins + +Implement PEP 604. This supports (int | str) etc. in place of Union[str, +int]. + +.. + +.. bpo: 41340 +.. date: 2020-07-27-01-50-06 +.. nonce: pZXfcF +.. section: Core and Builtins + +Removed fallback implementation for ``strdup``. + +.. + +.. bpo: 38156 +.. date: 2020-07-20-17-01-17 +.. nonce: ptcdRy +.. section: Core and Builtins + +Handle interrupts that come after EOF correctly in ``PyOS_StdioReadline``. + +.. + +.. bpo: 41342 +.. date: 2020-07-19-15-40-52 +.. nonce: RRk_m_ +.. section: Core and Builtins + +:func:`round` with integer argument is now faster (9--60%). + +.. + +.. bpo: 41334 +.. date: 2020-07-18-18-01-10 +.. nonce: t5xMGp +.. section: Core and Builtins + +Constructors :func:`str`, :func:`bytes` and :func:`bytearray` are now faster +(around 30--40% for small objects). + +.. + +.. bpo: 41295 +.. date: 2020-07-18-08-15-32 +.. nonce: pu8Ezo +.. section: Core and Builtins + +Resolve a regression in CPython 3.8.4 where defining "__setattr__" in a +multi-inheritance setup and calling up the hierarchy chain could fail if +builtins/extension types were involved in the base types. + +.. + +.. bpo: 41323 +.. date: 2020-07-17-11-31-54 +.. nonce: ChbZHh +.. section: Core and Builtins + +Bytecode optimizations are performed directly on the control flow graph. +This will result in slightly more compact code objects in some +circumstances. + +.. + +.. bpo: 41247 +.. date: 2020-07-08-22-03-54 +.. nonce: PndYIk +.. section: Core and Builtins + +Always cache the running loop holder when running +``asyncio.set_running_loop``. + +.. + +.. bpo: 41252 +.. date: 2020-07-08-21-55-23 +.. nonce: nBWL-Y +.. section: Core and Builtins + +Fix incorrect refcounting in _ssl.c's ``_servername_callback()``. + +.. + +.. bpo: 1635741 +.. date: 2020-07-07-16-10-52 +.. nonce: zU-H_n +.. section: Core and Builtins + +Port :mod:`multiprocessing` to multi-phase initialization + +.. + +.. bpo: 1635741 +.. date: 2020-07-06-20-43-19 +.. nonce: LYhsni +.. section: Core and Builtins + +Port :mod:`winapi` to multiphase initialization + +.. + +.. bpo: 41215 +.. date: 2020-07-06-18-36-33 +.. nonce: vFGFIz +.. section: Core and Builtins + +Use non-NULL default values in the PEG parser keyword list to overcome a bug +that was preventing Python from being properly compiled when using the XLC +compiler. Patch by Pablo Galindo. + +.. + +.. bpo: 41218 +.. date: 2020-07-06-13-35-17 +.. nonce: oKnSr2 +.. section: Core and Builtins + +Python 3.8.3 had a regression where compiling with +ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension +with CO_COROUTINE. Now only list comprehension making use of async/await +will tagged as so. + +.. + +.. bpo: 1635741 +.. date: 2020-07-03-23-10-02 +.. nonce: F5coWe +.. section: Core and Builtins + +Port :mod:`faulthandler` to multiphase initialization. + +.. + +.. bpo: 1635741 +.. date: 2020-07-01-20-17-38 +.. nonce: -AtPYu +.. section: Core and Builtins + +Port :mod:`sha256` to multiphase initialization + +.. + +.. bpo: 41175 +.. date: 2020-06-30-20-17-31 +.. nonce: acJoXB +.. section: Core and Builtins + +Guard against a NULL pointer dereference within bytearrayobject triggered by +the ``bytearray() + bytearray()`` operation. + +.. + +.. bpo: 41100 +.. date: 2020-06-30-04-44-29 +.. nonce: PJwA6F +.. section: Core and Builtins + +add arm64 to the allowable Mac OS arches in mpdecimal.h + +.. + +.. bpo: 41094 +.. date: 2020-06-23-23-26-42 +.. nonce: zEIJse +.. section: Core and Builtins + +Fix decoding errors with audit when open files with non-ASCII names on +non-UTF-8 locale. + +.. + +.. bpo: 39960 +.. date: 2020-06-23-18-32-41 +.. nonce: Kez3fP +.. section: Core and Builtins + +The "hackcheck" that prevents sneaking around a type's __setattr__() by +calling the superclass method was rewritten to allow C implemented heap +types. + +.. + +.. bpo: 41084 +.. date: 2020-06-23-15-10-19 +.. nonce: pt3y7F +.. section: Core and Builtins + +Prefix the error message with 'f-string: ', when parsing an f-string +expression which throws a :exc:`SyntaxError`. + +.. + +.. bpo: 40521 +.. date: 2020-06-23-07-35-11 +.. nonce: dMNA6k +.. section: Core and Builtins + +Empty frozensets are no longer singletons. + +.. + +.. bpo: 41076 +.. date: 2020-06-22-13-22-30 +.. nonce: eWYw2N +.. section: Core and Builtins + +Pre-feed the parser with the location of the f-string expression, not the +f-string itself, which allows us to skip the shifting of the AST node +locations after the parsing is completed. + +.. + +.. bpo: 41056 +.. date: 2020-06-21-19-53-33 +.. nonce: IDu_EK +.. section: Core and Builtins + +Fixes a reference to deallocated stack space during startup when +constructing sys.path involving a relative symlink when code was supplied +via -c. (discovered via Coverity) + +.. + +.. bpo: 41061 +.. date: 2020-06-21-10-54-02 +.. nonce: AHf9MU +.. section: Core and Builtins + +Fix incorrect expressions and asserts in hashtable code and tests. + +.. + +.. bpo: 41052 +.. date: 2020-06-20-22-46-18 +.. nonce: 46MPeF +.. section: Core and Builtins + +Opt out serialization/deserialization for _random.Random + +.. + +.. bpo: 40939 +.. date: 2020-06-20-19-27-47 +.. nonce: jxJ4yn +.. section: Core and Builtins + +Rename `PyPegen*` functions to `PyParser*`, so that we can remove the old +set of `PyParser*` functions that were using the old parser, but keep +everything backwards-compatible. + +.. + +.. bpo: 35975 +.. date: 2020-06-20-17-00-44 +.. nonce: UDHCHp +.. section: Core and Builtins + +Stefan Behnel reported that cf_feature_version is used even when +PyCF_ONLY_AST is not set. This is against the intention and against the +documented behavior, so it's been fixed. + +.. + +.. bpo: 40939 +.. date: 2020-06-20-16-59-02 +.. nonce: 6810Ak +.. section: Core and Builtins + +Remove the remaining files from the old parser and the :mod:`symbol` module. + +.. + +.. bpo: 40077 +.. date: 2020-06-18-19-04-30 +.. nonce: _yI-ax +.. section: Core and Builtins + +Convert :mod:`_bz2` to use :c:func:`PyType_FromSpec`. + +.. + +.. bpo: 41006 +.. date: 2020-06-18-00-07-09 +.. nonce: H-wN-d +.. section: Core and Builtins + +The ``encodings.latin_1`` module is no longer imported at startup. Now it is +only imported when it is the filesystem encoding or the stdio encoding. + +.. + +.. bpo: 40636 +.. date: 2020-06-17-10-27-17 +.. nonce: MYaCIe +.. section: Core and Builtins + +:func:`zip` now supports :pep:`618`'s ``strict`` parameter, which raises a +:exc:`ValueError` if the arguments are exhausted at different lengths. Patch +by Brandt Bucher. + +.. + +.. bpo: 1635741 +.. date: 2020-06-17-00-52-21 +.. nonce: 61iyYh +.. section: Core and Builtins + +Port :mod:`_gdbm` to multiphase initialization. + +.. + +.. bpo: 40985 +.. date: 2020-06-15-16-29-55 +.. nonce: IIN_xX +.. section: Core and Builtins + +Fix a bug that caused the :exc:`SyntaxError` text to be empty when a file +ends with a line ending in a line continuation character (i.e. backslash). +The error text should contain the text of the last line. + +.. + +.. bpo: 40958 +.. date: 2020-06-15-01-20-44 +.. nonce: 7O2Wh1 +.. section: Core and Builtins + +Fix a possible buffer overflow in the PEG parser when gathering information +for emitting syntax errors. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-06-12-22-56-17 +.. nonce: mmlp3Q +.. section: Core and Builtins + +Port :mod:`_dbm` to multiphase initialization. + +.. + +.. bpo: 40957 +.. date: 2020-06-12-12-21-54 +.. nonce: Z8n6I6 +.. section: Core and Builtins + +Fix refleak in _Py_fopen_obj() when PySys_Audit() fails + +.. + +.. bpo: 40950 +.. date: 2020-06-12-00-12-28 +.. nonce: tzMy7m +.. section: Core and Builtins + +Add a state to the :mod:`nis` module (:pep:`3121`) and apply the multiphase +initialization. Patch by Dong-hee Na. + +.. + +.. bpo: 40947 +.. date: 2020-06-11-16-06-49 +.. nonce: 72cZcR +.. section: Core and Builtins + +The Python :ref:`Path Configuration ` now takes +:c:member:`PyConfig.platlibdir` in account. + +.. + +.. bpo: 40939 +.. date: 2020-06-10-11-27-15 +.. nonce: DO-wAI +.. section: Core and Builtins + +Remove the old parser, the :mod:`parser` module and all associated support +code, command-line options and environment variables. Patch by Pablo +Galindo. + +.. + +.. bpo: 40847 +.. date: 2020-06-09-23-52-32 +.. nonce: 4XAACw +.. section: Core and Builtins + +Fix a bug where a line with only a line continuation character is not +considered a blank line at tokenizer level. In such cases, more than a +single `NEWLINE` token was emitted. The old parser was working around the +issue, but the new parser threw a :exc:`SyntaxError` for valid input due to +this. For example, an empty line following a line continuation character was +interpreted as a :exc:`SyntaxError`. + +.. + +.. bpo: 40890 +.. date: 2020-06-09-00-20-13 +.. nonce: LoRV-g +.. section: Core and Builtins + +Each dictionary view now has a ``mapping`` attribute that provides a +:class:`types.MappingProxyType` wrapping the original dictionary. Patch +contributed by Dennis Sweeney. + +.. + +.. bpo: 40889 +.. date: 2020-06-08-22-46-33 +.. nonce: vIBl-W +.. section: Core and Builtins + +Improved the performance of symmetric difference operations on dictionary +item views. Patch by Dennis Sweeney. + +.. + +.. bpo: 40904 +.. date: 2020-06-08-01-08-57 +.. nonce: 76qQzo +.. section: Core and Builtins + +Fix possible segfault in the new PEG parser when parsing f-string containing +yield statements with no value (:code:`f"{yield}"`). Patch by Pablo Galindo + +.. + +.. bpo: 40903 +.. date: 2020-06-07-22-50-10 +.. nonce: 7dWejS +.. section: Core and Builtins + +Fixed a possible segfault in the new PEG parser when producing error +messages for invalid assignments of the form :code:`p=p=`. Patch by Pablo +Galindo + +.. + +.. bpo: 40880 +.. date: 2020-06-06-00-23-19 +.. nonce: fjdzSh +.. section: Core and Builtins + +Fix invalid memory read in the new parser when checking newlines in string +literals. Patch by Pablo Galindo. + +.. + +.. bpo: 40883 +.. date: 2020-06-05-23-25-00 +.. nonce: M6sQ-Q +.. section: Core and Builtins + +Fix memory leak in when parsing f-strings in the new parser. Patch by Pablo +Galindo + +.. + +.. bpo: 40870 +.. date: 2020-06-05-12-48-28 +.. nonce: 9cd2sk +.. section: Core and Builtins + +Raise :exc:`ValueError` when validating custom AST's where the constants +``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. + +.. + +.. bpo: 40854 +.. date: 2020-06-03-13-53-24 +.. nonce: O6vfQU +.. section: Core and Builtins + +Allow overriding :data:`sys.platlibdir` via a new :envvar:`PYTHONPLATLIBDIR` +environment variable. + +.. + +.. bpo: 40826 +.. date: 2020-06-01-20-31-07 +.. nonce: XCI4M2 +.. section: Core and Builtins + +Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception +and pass the Python thread state when checking if there is a pending signal. + +.. + +.. bpo: 1635741 +.. date: 2020-05-30-23-23-35 +.. nonce: 0D-laM +.. section: Core and Builtins + +Port :mod:`fcntl` to multiphase initialization. + +.. + +.. bpo: 19468 +.. date: 2020-05-30-23-18-35 +.. nonce: S-TA7p +.. section: Core and Builtins + +Delete unnecessary instance check in importlib.reload(). Patch by Furkan +Önder. + +.. + +.. bpo: 40824 +.. date: 2020-05-30-14-37-18 +.. nonce: XR3V5s +.. section: Core and Builtins + +Unexpected errors in calling the ``__iter__`` method are no longer masked by +``TypeError`` in the :keyword:`in` operator and functions +:func:`~operator.contains`, :func:`~operator.indexOf` and +:func:`~operator.countOf` of the :mod:`operator` module. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-22-37-58 +.. nonce: WEDqqU +.. section: Core and Builtins + +Attributes ``start``, ``stop`` and ``step`` of the :class:`range` object now +always has exact type :class:`int`. Previously, they could have been an +instance of a subclass of ``int``. + +.. + +.. bpo: 40780 +.. date: 2020-05-26-17-43-58 +.. nonce: 3Ckdgm +.. section: Core and Builtins + +Fix a corner case where g-style string formatting of a float failed to +remove trailing zeros. + +.. + +.. bpo: 38964 +.. date: 2020-05-25-21-49-11 +.. nonce: lrml90 +.. section: Core and Builtins + +When there's a :exc:`SyntaxError` in the expression part of an fstring, the +filename attribute of the :exc:`SyntaxError` gets correctly set to the name +of the file the fstring resides in. + +.. + +.. bpo: 40750 +.. date: 2020-05-24-02-42-26 +.. nonce: ZmO9Ev +.. section: Core and Builtins + +Support the "-d" debug flag in the new PEG parser. Patch by Pablo Galindo + +.. + +.. bpo: 40217 +.. date: 2020-05-23-01-15-51 +.. nonce: jZsHTc +.. section: Core and Builtins + +Instances of types created with :c:func:`PyType_FromSpecWithBases` will no +longer automatically visit their class object when traversing references in +the garbage collector. The user is expected to manually visit the object's +class. Patch by Pablo Galindo. + +.. + +.. bpo: 39573 +.. date: 2020-05-22-00-34-34 +.. nonce: QO2QHj +.. section: Core and Builtins + +:c:func:`Py_TYPE()` is changed to the inline static function. Patch by +Dong-hee Na. + +.. + +.. bpo: 40696 +.. date: 2020-05-21-01-54-00 +.. nonce: u3n8Wx +.. section: Core and Builtins + +Fix a hang that can arise after :meth:`generator.throw` due to a cycle in +the exception context chain. + +.. + +.. bpo: 40521 +.. date: 2020-05-20-01-17-34 +.. nonce: wvAehI +.. section: Core and Builtins + +Each interpreter now its has own free lists, singletons and caches: + +* Free lists: float, tuple, list, dict, frame, context, + asynchronous generator, MemoryError. +* Singletons: empty tuple, empty bytes string, empty Unicode string, + single byte character, single Unicode (latin1) character. +* Slice cache. + +They are no longer shared by all interpreters. + +.. + +.. bpo: 40679 +.. date: 2020-05-19-19-39-49 +.. nonce: SVzz9p +.. section: Core and Builtins + +Certain :exc:`TypeError` messages about missing or extra arguments now +include the function's :term:`qualified name`. Patch by Dennis Sweeney. + +.. + +.. bpo: 29590 +.. date: 2020-05-03-22-26-00 +.. nonce: aRz3l7 +.. section: Core and Builtins + +Make the stack trace correct after calling :meth:`generator.throw` on a +generator that has yielded from a ``yield from``. + +.. + +.. bpo: 4022 +.. date: 2020-04-11-13-07-49 +.. nonce: Ctpn_F +.. section: Core and Builtins + +Improve performance of generators by not raising internal StopIteration. + +.. + +.. bpo: 1635741 +.. date: 2020-04-10-23-54-57 +.. nonce: ZURqoN +.. section: Core and Builtins + +Port :mod:`mmap` to multiphase initialization. + +.. + +.. bpo: 1635741 +.. date: 2020-04-05-02-35-08 +.. nonce: Kfe9fT +.. section: Core and Builtins + +Port :mod:`_lzma` to multiphase initialization. + +.. + +.. bpo: 37999 +.. date: 2019-09-01-14-26-02 +.. nonce: XPl6dn +.. section: Core and Builtins + +Builtin and extension functions that take integer arguments no longer accept +:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other +objects that can be converted to integers only with a loss (e.g. that have +the :meth:`~object.__int__` method but do not have the +:meth:`~object.__index__` method). + +.. + +.. bpo: 29882 +.. date: 2019-06-02-11-29-15 +.. nonce: AkRzjb +.. section: Core and Builtins + +Add :meth:`int.bit_count()`, counting the number of ones in the binary +representation of an integer. Patch by Niklas Fiekas. + +.. + +.. bpo: 36982 +.. date: 2019-05-25-05-27-39 +.. nonce: 0UHgfB +.. section: Core and Builtins + +Use ncurses extended color functions when available to support terminals +with 256 colors, and add the new function +:func:`curses.has_extended_color_support` to indicate whether extended color +support is provided by the underlying ncurses library. + +.. + +.. bpo: 19569 +.. date: 2018-08-29-15-57-07 +.. nonce: RGu2Kb +.. section: Core and Builtins + +Add the private macros ``_Py_COMP_DIAG_PUSH``, +``_Py_COMP_DIAG_IGNORE_DEPR_DECLS``, and ``_Py_COMP_DIAG_POP``. + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-51-36 +.. nonce: wOWYps +.. section: Core and Builtins + +The int type now supports the x.is_integer() method for compatibility with +float. + +.. + +.. bpo: 41900 +.. date: 2020-10-01-10-50-12 +.. nonce: Cho7oh +.. section: Library + +C14N 2.0 serialisation in xml.etree.ElementTree failed for unprefixed +attributes when a default namespace was defined. + +.. + +.. bpo: 41887 +.. date: 2020-09-30-23-49-42 +.. nonce: -ee2S- +.. section: Library + +Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document +stripping of spaces and tabs for :func:`eval`. + +.. + +.. bpo: 41773 +.. date: 2020-09-28-23-22-25 +.. nonce: oKkus0 +.. section: Library + +Note in documentation that :func:`random.choices` doesn't support non-finite +weights, raise :exc:`ValueError` when given non-finite weights. + +.. + +.. bpo: 41840 +.. date: 2020-09-23-23-17-59 +.. nonce: QRFr4L +.. section: Library + +Fix a bug in the :mod:`symtable` module that was causing module-scope global +variables to not be reported as both local and global. Patch by Pablo +Galindo. + +.. + +.. bpo: 41842 +.. date: 2020-09-23-22-52-24 +.. nonce: lIuhC9 +.. section: Library + +Add :func:`codecs.unregister` function to unregister a codec search +function. + +.. + +.. bpo: 40564 +.. date: 2020-09-23-03-33-37 +.. nonce: iXQqMq +.. section: Library + +In ``zipfile.Path``, mutate the passed ZipFile object type instead of making +a copy. Prevents issues when both the local copy and the caller’s copy +attempt to close the same file handle. + +.. + +.. bpo: 40670 +.. date: 2020-09-22-14-55-34 +.. nonce: R5sm68 +.. section: Library + +More reliable validation of statements in :class:`timeit.Timer`. It now +accepts "empty" statements (only whitespaces and comments) and rejects +misindentent statements. + +.. + +.. bpo: 41833 +.. date: 2020-09-22-13-51-14 +.. nonce: 6HVDjT +.. section: Library + +The :class:`threading.Thread` constructor now uses the target name if the +*target* argument is specified but the *name* argument is omitted. + +.. + +.. bpo: 41817 +.. date: 2020-09-22-00-23-30 +.. nonce: bnh-VG +.. section: Library + +fix `tkinter.EventType` Enum so all members are strings, and none are tuples + +.. + +.. bpo: 41810 +.. date: 2020-09-20-15-14-05 +.. nonce: 7l8lyV +.. section: Library + +:data:`types.EllipsisType`, :data:`types.NotImplementedType` and +:data:`types.NoneType` have been reintroduced, providing a new set of types +readily interpretable by static type checkers. + +.. + +.. bpo: 41815 +.. date: 2020-09-19-23-14-54 +.. nonce: RNpuX3 +.. section: Library + +Fix SQLite3 segfault when backing up closed database. Patch contributed by +Peter David McCormick. + +.. + +.. bpo: 41816 +.. date: 2020-09-19-12-22-08 +.. nonce: ynynXJ +.. section: Library + +StrEnum added: it ensures that all members are already strings or string +candidates + +.. + +.. bpo: 41517 +.. date: 2020-09-15-22-43-30 +.. nonce: sLBH7g +.. section: Library + +fix bug allowing Enums to be extended via multiple inheritance + +.. + +.. bpo: 39587 +.. date: 2020-09-15-14-56-13 +.. nonce: 69xzuh +.. section: Library + +use the correct mix-in data type when constructing Enums + +.. + +.. bpo: 41792 +.. date: 2020-09-15-07-55-35 +.. nonce: qMpSlU +.. section: Library + +Add is_typeddict function to typing.py to check if a type is a TypedDict +class + +Previously there was no way to check that without using private API. See the +`relevant issue in python/typing +` + +.. + +.. bpo: 41789 +.. date: 2020-09-14-19-27-46 +.. nonce: pI_uZQ +.. section: Library + +Honor `object` overrides in `Enum` class creation (specifically, `__str__`, +`__repr__`, `__format__`, and `__reduce_ex__`). + +.. + +.. bpo: 32218 +.. date: 2020-09-12-16-18-42 +.. nonce: IpYkEe +.. section: Library + +`enum.Flag` and `enum.IntFlag` members are now iterable + +.. + +.. bpo: 39651 +.. date: 2020-09-11-12-38-55 +.. nonce: JMp9l2 +.. section: Library + +Fix a race condition in the ``call_soon_threadsafe()`` method of +``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has been +closed. + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-13-55-34 +.. nonce: 56MLP- +.. section: Library + +Port the ``mashal`` extension module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-13-51-16 +.. nonce: wkPeoT +.. section: Library + +Port the ``_string`` extension module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 41732 +.. date: 2020-09-06-20-27-10 +.. nonce: 1SKv26 +.. section: Library + +Added an :term:`iterator` to :class:`memoryview`. + +.. + +.. bpo: 41720 +.. date: 2020-09-04-20-45-38 +.. nonce: PW9MzZ +.. section: Library + +Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not int or +float. + +.. + +.. bpo: 41696 +.. date: 2020-09-03-01-35-32 +.. nonce: zkYGre +.. section: Library + +Fix handling of debug mode in :func:`asyncio.run`. This allows setting +``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode when using +:func:`asyncio.run`. + +.. + +.. bpo: 41687 +.. date: 2020-09-01-15-57-51 +.. nonce: m1b1KA +.. section: Library + +Fix implementation of sendfile to be compatible with Solaris. + +.. + +.. bpo: 41662 +.. date: 2020-08-30-21-38-57 +.. nonce: 6e9iZn +.. section: Library + +No longer override exceptions raised in ``__len__()`` of a sequence of +parameters in :mod:`sqlite3` with :exc:`~sqlite3.ProgrammingError`. + +.. + +.. bpo: 39010 +.. date: 2020-08-30-10-24-26 +.. nonce: _mzXJW +.. section: Library + +Restarting a ``ProactorEventLoop`` on Windows no longer logs spurious +``ConnectionResetErrors``. + +.. + +.. bpo: 41638 +.. date: 2020-08-29-16-45-12 +.. nonce: iZfW5N +.. section: Library + +:exc:`~sqlite3.ProgrammingError` message for absent parameter in +:mod:`sqlite3` contains now the name of the parameter instead of its index +when parameters are supplied as a dict. + +.. + +.. bpo: 41662 +.. date: 2020-08-29-16-07-36 +.. nonce: Mn79zh +.. section: Library + +Fixed crash when mutate list of parameters during iteration in +:mod:`sqlite3`. + +.. + +.. bpo: 41513 +.. date: 2020-08-23-14-23-18 +.. nonce: DGqc_I +.. section: Library + +Improved the accuracy of math.hypot(). Internally, each step is computed +with extra precision so that the result is now almost always correctly +rounded. + +.. + +.. bpo: 41609 +.. date: 2020-08-21-15-51-15 +.. nonce: JmiUKG +.. section: Library + +The pdb whatis command correctly reports instance methods as 'Method' rather +than 'Function'. + +.. + +.. bpo: 39994 +.. date: 2020-08-15-18-17-21 +.. nonce: dOgPOh +.. section: Library + +Fixed pprint's handling of dict subclasses that override __repr__. + +.. + +.. bpo: 32751 +.. date: 2020-08-15-15-50-12 +.. nonce: 85je5X +.. section: Library + +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete also in the case when *timeout* is +<= 0, like it does with positive timeouts. + +.. + +.. bpo: 37658 +.. date: 2020-08-15-15-21-40 +.. nonce: f9nivB +.. section: Library + +:meth:`asyncio.wait_for` now properly handles races between cancellation of +itself and the completion of the wrapped awaitable. + +.. + +.. bpo: 40782 +.. date: 2020-08-13-08-07-25 +.. nonce: aGZqmB +.. section: Library + +Change the method asyncio.AbstractEventLoop.run_in_executor to not be a +coroutine. + +.. + +.. bpo: 41520 +.. date: 2020-08-12-13-25-16 +.. nonce: BEUWa4 +.. section: Library + +Fix :mod:`codeop` regression that prevented turning compile warnings into +errors. + +.. + +.. bpo: 41528 +.. date: 2020-08-12-07-43-31 +.. nonce: bu83oD +.. section: Library + +turtle uses math module functions to convert degrees to radians and vice +versa and to calculate vector norm + +.. + +.. bpo: 41513 +.. date: 2020-08-09-18-16-05 +.. nonce: e6K6EK +.. section: Library + +Minor algorithmic improvement to math.hypot() and math.dist() giving small +gains in speed and accuracy. + +.. + +.. bpo: 41503 +.. date: 2020-08-07-15-18-16 +.. nonce: IYftcu +.. section: Library + +Fixed a race between setTarget and flush in logging.handlers.MemoryHandler. + +.. + +.. bpo: 41497 +.. date: 2020-08-07-06-06-29 +.. nonce: aBtsWz +.. section: Library + +Fix potential UnicodeDecodeError in dis module. + +.. + +.. bpo: 41467 +.. date: 2020-08-04-00-20-30 +.. nonce: Z8DgTL +.. section: Library + +On Windows, fix asyncio ``recv_into()`` return value when the socket/pipe is +closed (:exc:`BrokenPipeError`): return ``0`` rather than an empty byte +string (``b''``). + +.. + +.. bpo: 41425 +.. date: 2020-08-03-01-59-48 +.. nonce: KJo6zF +.. section: Library + +Make tkinter doc example runnable. + +.. + +.. bpo: 41421 +.. date: 2020-08-01-00-51-15 +.. nonce: dHKRVB +.. section: Library + +Make an algebraic simplification to random.paretovariate(). It now is +slightly less subject to round-off error and is slightly faster. Inputs that +used to cause ZeroDivisionError now cause an OverflowError instead. + +.. + +.. bpo: 41440 +.. date: 2020-07-30-14-56-58 +.. nonce: rju34k +.. section: Library + +Add :func:`os.cpu_count()` support for VxWorks RTOS. + +.. + +.. bpo: 41316 +.. date: 2020-07-28-12-08-58 +.. nonce: bSCbK4 +.. section: Library + +Fix the :mod:`tarfile` module to write only basename of TAR file to GZIP +compression header. + +.. + +.. bpo: 41384 +.. date: 2020-07-26-21-18-43 +.. nonce: MlzIgV +.. section: Library + +Raise TclError instead of TypeError when an unknown option is passed to +tkinter.OptionMenu. + +.. + +.. bpo: 41317 +.. date: 2020-07-23-01-18-34 +.. nonce: O17Z6x +.. section: Library + +Use add_done_callback() in asyncio.loop.sock_accept() to unsubscribe reader +early on cancellation. + +.. + +.. bpo: 41364 +.. date: 2020-07-21-21-45-55 +.. nonce: 5O-k7A +.. section: Library + +Reduce import overhead of :mod:`uuid`. + +.. + +.. bpo: 35328 +.. date: 2020-07-21-16-20-55 +.. nonce: jXovHb +.. section: Library + +Set the environment variable ``VIRTUAL_ENV_PROMPT`` at :mod:`venv` +activation. + +.. + +.. bpo: 41341 +.. date: 2020-07-20-19-13-17 +.. nonce: wqrj8C +.. section: Library + +Recursive evaluation of `typing.ForwardRef` in `get_type_hints`. + +.. + +.. bpo: 41344 +.. date: 2020-07-20-13-27-48 +.. nonce: iKipNd +.. section: Library + +Prevent creating :class:`shared_memory.SharedMemory` objects with +:code:`size=0`. + +.. + +.. bpo: 41333 +.. date: 2020-07-18-18-07-40 +.. nonce: upkHIm +.. section: Library + +:meth:`collections.OrderedDict.pop` is now 2 times faster. + +.. + +.. bpo: 41288 +.. date: 2020-07-13-15-06-35 +.. nonce: 8mn5P- +.. section: Library + +Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now +UnpicklingError instead of crashing. + +.. + +.. bpo: 39017 +.. date: 2020-07-12-22-16-58 +.. nonce: x3Cg-9 +.. section: Library + +Avoid infinite loop when reading specially crafted TAR files using the +tarfile module (CVE-2019-20907). + +.. + +.. bpo: 41273 +.. date: 2020-07-11-00-15-01 +.. nonce: SVrsJh +.. section: Library + +Speed up any transport using ``_ProactorReadPipeTransport`` by calling +``recv_into`` instead of ``recv``, thus not creating a new buffer for each +``recv`` call in the transport's read loop. + +.. + +.. bpo: 41235 +.. date: 2020-07-07-21-56-26 +.. nonce: H2csMU +.. section: Library + +Fix the error handling in :meth:`ssl.SSLContext.load_dh_params`. + +.. + +.. bpo: 41207 +.. date: 2020-07-06-16-58-53 +.. nonce: Emw7Nk +.. section: Library + +In distutils.spawn, restore expectation that DistutilsExecError is raised +when the command is not found. + +.. + +.. bpo: 29727 +.. date: 2020-07-05-19-16-02 +.. nonce: Q6Z2rg +.. section: Library + +Register :class:`array.array` as a +:class:`~collections.abc.MutableSequence`. Patch by Pablo Galindo. + +.. + +.. bpo: 39168 +.. date: 2020-07-04-21-56-46 +.. nonce: DQWsXj +.. section: Library + +Remove the ``__new__`` method of :class:`typing.Generic`. + +.. + +.. bpo: 41194 +.. date: 2020-07-03-13-15-08 +.. nonce: djrKjs +.. section: Library + +Fix a crash in the ``_ast`` module: it can no longer be loaded more than +once. It now uses a global state rather than a module state. + +.. + +.. bpo: 41195 +.. date: 2020-07-02-15-03-04 +.. nonce: cEnpO3 +.. section: Library + +Add read-only ssl.SSLContext.security_level attribute to retrieve the +context's security level. + +.. + +.. bpo: 41193 +.. date: 2020-07-02-11-53-45 +.. nonce: 8-Tnql +.. section: Library + +The ``write_history()`` atexit function of the readline completer now +ignores any :exc:`OSError` to ignore error if the filesystem is read-only, +instead of only ignoring :exc:`FileNotFoundError` and +:exc:`PermissionError`. + +.. + +.. bpo: 41182 +.. date: 2020-07-01-17-33-50 +.. nonce: FPFI0N +.. section: Library + +selector: use DefaultSelector based upon implementation + +.. + +.. bpo: 41161 +.. date: 2020-06-30-20-50-51 +.. nonce: QTdJjz +.. section: Library + +The decimal module now requires libmpdec-2.5.0. Users of +--with-system-libmpdec should update their system library. + +.. + +.. bpo: 40874 +.. date: 2020-06-28-21-16-51 +.. nonce: YImvzA +.. section: Library + +The decimal module now requires libmpdec-2.5.0. + +.. + +.. bpo: 41138 +.. date: 2020-06-27-13-51-36 +.. nonce: bIpf7g +.. section: Library + +Fixed the :mod:`trace` module CLI for Python source files with non-UTF-8 +encoding. + +.. + +.. bpo: 31082 +.. date: 2020-06-25-10-11-47 +.. nonce: HsgDkx +.. section: Library + +Use the term "iterable" in the docstring for :func:`functools.reduce`. + +.. + +.. bpo: 40521 +.. date: 2020-06-23-06-09-59 +.. nonce: HUfxP7 +.. section: Library + +Remove freelist from collections.deque(). + +.. + +.. bpo: 31938 +.. date: 2020-06-22-20-08-40 +.. nonce: EVuko9 +.. section: Library + +Fix default-value signatures of several functions in the :mod:`select` +module - by Anthony Sottile. + +.. + +.. bpo: 41068 +.. date: 2020-06-22-10-25-39 +.. nonce: _bX2BW +.. section: Library + +Fixed reading files with non-ASCII names from ZIP archive directly after +writing them. + +.. + +.. bpo: 41058 +.. date: 2020-06-20-21-03-55 +.. nonce: gztdZy +.. section: Library + +:func:`pdb.find_function` now correctly determines the source file encoding. + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-37-29 +.. nonce: d9v_uL +.. section: Library + +Invalid file descriptor values are now prevented from being passed to +os.fpathconf. (discovered by Coverity) + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-35-43 +.. nonce: Garcle +.. section: Library + +Fix a NULL pointer dereference within the ssl module during a MemoryError in +the keylog callback. (discovered by Coverity) + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-33-03 +.. nonce: gTH4Bq +.. section: Library + +Fixed an instance where a MemoryError within the zoneinfo module might not +be reported or not reported at its source. (found by Coverity) + +.. + +.. bpo: 41048 +.. date: 2020-06-20-10-16-57 +.. nonce: hEXB-B +.. section: Library + +:func:`mimetypes.read_mime_types` function reads the rule file using UTF-8 +encoding, not the locale encoding. Patch by Srinivas Reddy Thatiparthy. + +.. + +.. bpo: 41043 +.. date: 2020-06-20-00-19-30 +.. nonce: p-Pk-H +.. section: Library + +Fixed the use of :func:`~glob.glob` in the stdlib: literal part of the path +is now always correctly escaped. + +.. + +.. bpo: 41025 +.. date: 2020-06-18-10-34-59 +.. nonce: elf_nz +.. section: Library + +Fixed an issue preventing the C implementation of :class:`zoneinfo.ZoneInfo` +from being subclassed. + +.. + +.. bpo: 35018 +.. date: 2020-06-17-23-49-45 +.. nonce: NP5_Qk +.. section: Library + +Add the :class:`xml.sax.handler.LexicalHandler` class that is present in +other SAX XML implementations. + +.. + +.. bpo: 41002 +.. date: 2020-06-17-17-26-24 +.. nonce: NPBItE +.. section: Library + +Improve performance of HTTPResponse.read with a given amount. Patch by Bruce +Merry. + +.. + +.. bpo: 40448 +.. date: 2020-06-15-12-22-53 +.. nonce: 1dk8Bu +.. section: Library + +:mod:`ensurepip` now disables the use of `pip` cache when installing the +bundled versions of `pip` and `setuptools`. Patch by Krzysztof Konopko. + +.. + +.. bpo: 40967 +.. date: 2020-06-15-00-13-57 +.. nonce: _dx3OO +.. section: Library + +Removed :meth:`asyncio.Task.current_task` and +:meth:`asyncio.Task.all_tasks`. Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 40924 +.. date: 2020-06-13-12-04-50 +.. nonce: SM_luS +.. section: Library + +Ensure ``importlib.resources.path`` returns an extant path for the +SourceFileLoader's resource reader. Avoids the regression identified in +master while a long-term solution is devised. + +.. + +.. bpo: 40955 +.. date: 2020-06-12-11-55-30 +.. nonce: huixCg +.. section: Library + +Fix a minor memory leak in :mod:`subprocess` module when extra_groups was +specified. + +.. + +.. bpo: 40855 +.. date: 2020-06-12-10-44-15 +.. nonce: jSot83 +.. section: Library + +The standard deviation and variance functions in the statistics module were +ignoring their mu and xbar arguments. + +.. + +.. bpo: 40939 +.. date: 2020-06-11-11-07-10 +.. nonce: -D5Asl +.. section: Library + +Use the new PEG parser when generating the stdlib :mod:`keyword` module. + +.. + +.. bpo: 23427 +.. date: 2020-06-08-18-59-16 +.. nonce: ilg1Cz +.. section: Library + +Add :data:`sys.orig_argv` attribute: the list of the original command line +arguments passed to the Python executable. + +.. + +.. bpo: 33689 +.. date: 2020-06-06-14-09-55 +.. nonce: EFUDH7 +.. section: Library + +Ignore empty or whitespace-only lines in .pth files. This matches the +documentated behavior. Before, empty lines caused the site-packages dir to +appear multiple times in sys.path. By Ido Michael, contributors Malcolm +Smith and Tal Einat. + +.. + +.. bpo: 40884 +.. date: 2020-06-06-02-42-26 +.. nonce: n7fOwS +.. section: Library + +Added a `defaults` parameter to :class:`logging.Formatter`, to allow +specifying default values for custom fields. Patch by Asaf Alon and Bar +Harel. + +.. + +.. bpo: 40876 +.. date: 2020-06-05-20-00-18 +.. nonce: zDhiZj +.. section: Library + +Clarify error message in the :mod:`csv` module. + +.. + +.. bpo: 39791 +.. date: 2020-06-05-19-29-10 +.. nonce: _CcO3d +.. section: Library + +Refresh importlib.metadata from importlib_metadata 1.6.1. + +.. + +.. bpo: 40807 +.. date: 2020-06-04-16-25-15 +.. nonce: yYyLWx +.. section: Library + +Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). +from emitting each warning three times. + +.. + +.. bpo: 32604 +.. date: 2020-06-02-23-49-07 +.. nonce: ZN4V4l +.. section: Library + +Fix reference leak in the :mod:`select` module when the module is imported +in a subinterpreter. + +.. + +.. bpo: 39791 +.. date: 2020-06-02-02-16-02 +.. nonce: StCJlA +.. section: Library + +Built-in loaders (SourceFileLoader and ZipImporter) now supply +``TraversableResources`` implementations for ``ResourceReader``, and the +fallback function has been removed. + +.. + +.. bpo: 39314 +.. date: 2020-06-01-02-16-29 +.. nonce: 0T9hlA +.. section: Library + +:class:`rlcompleter.Completer` and the standard Python shell now close the +parenthesis for functions that take no arguments. Patch contributed by Rémi +Lapeyre. + +.. + +.. bpo: 17005 +.. date: 2020-05-31-23-32-36 +.. nonce: JlRUGB +.. section: Library + +The topological sort functionality that was introduced initially in the +:mod:`functools` module has been moved to a new :mod:`graphlib` module to +better accommodate the new tools and keep the original scope of the +:mod:`functools` module. Patch by Pablo Galindo + +.. + +.. bpo: 40834 +.. date: 2020-05-31-15-52-18 +.. nonce: MO9_hb +.. section: Library + +Fix truncate when sending str object with_xxsubinterpreters.channel_send. + +.. + +.. bpo: 40755 +.. date: 2020-05-30-18-48-58 +.. nonce: IyOe2J +.. section: Library + +Add rich comparisons to collections.Counter(). + +.. + +.. bpo: 26407 +.. date: 2020-05-30-14-19-47 +.. nonce: MjWLO1 +.. section: Library + +Unexpected errors in calling the ``__iter__`` method are no longer masked by +``TypeError`` in :func:`csv.reader`, :func:`csv.writer.writerow` and +:meth:`csv.writer.writerows`. + +.. + +.. bpo: 39384 +.. date: 2020-05-30-12-44-29 +.. nonce: Iqxy3q +.. section: Library + +Fixed email.contentmanager to allow set_content() to set a null string. + +.. + +.. bpo: 40744 +.. date: 2020-05-30-08-10-23 +.. nonce: jKURVV +.. section: Library + +The :mod:`sqlite3` module uses SQLite API functions that require SQLite +v3.7.3 or higher. This patch removes support for older SQLite versions, and +explicitly requires SQLite 3.7.3 both at build, compile and runtime. Patch +by Sergey Fedoseev and Erlend E. Aasland. + +.. + +.. bpo: 40777 +.. date: 2020-05-28-17-32-29 +.. nonce: 1kJU6N +.. section: Library + +Initialize PyDateTime_IsoCalendarDateType.tp_base at run-time to avoid +errors on some compilers. + +.. + +.. bpo: 38488 +.. date: 2020-05-28-16-51-00 +.. nonce: hFQNgA +.. section: Library + +Update ensurepip to install pip 20.1.1 and setuptools 47.1.0. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-22-19-42 +.. nonce: 87Yx01 +.. section: Library + +The result of :func:`operator.index` now always has exact type :class:`int`. +Previously, the result could have been an instance of a subclass of ``int``. + +.. + +.. bpo: 40767 +.. date: 2020-05-27-21-27-01 +.. nonce: L5MnVV +.. section: Library + +:mod:`webbrowser` now properly finds the default browser in pure Wayland +systems by checking the WAYLAND_DISPLAY environment variable. Patch +contributed by Jérémy Attali. + +.. + +.. bpo: 40791 +.. date: 2020-05-27-18-04-52 +.. nonce: IzpNor +.. section: Library + +:func:`hashlib.compare_digest` uses OpenSSL's ``CRYPTO_memcmp()`` function +when OpenSSL is available. + +.. + +.. bpo: 40795 +.. date: 2020-05-27-17-00-18 +.. nonce: eZSnHA +.. section: Library + +:mod:`ctypes` module: If ctypes fails to convert the result of a callback or +if a ctypes callback function raises an exception, sys.unraisablehook is now +called with an exception set. Previously, the error was logged into stderr +by :c:func:`PyErr_Print`. + +.. + +.. bpo: 16995 +.. date: 2020-05-27-00-09-52 +.. nonce: 4niOT7 +.. section: Library + +Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support +the Base32 Encoding with Extended Hex Alphabet. + +.. + +.. bpo: 30008 +.. date: 2020-05-25-22-18-38 +.. nonce: CKC3td +.. section: Library + +Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use +``no-deprecated`` and ``--api=1.1.0``. + +.. + +.. bpo: 30064 +.. date: 2020-05-25-11-52-23 +.. nonce: 6CICsH +.. section: Library + +Fix asyncio ``loop.sock_*`` race condition issue + +.. + +.. bpo: 40759 +.. date: 2020-05-24-23-52-35 +.. nonce: DdZdaw +.. section: Library + +Deprecate the :mod:`symbol` module. + +.. + +.. bpo: 40756 +.. date: 2020-05-24-11-06-37 +.. nonce: 7ZH83z +.. section: Library + +The second argument (extra) of ``LoggerAdapter.__init__`` now defaults to +None. + +.. + +.. bpo: 37129 +.. date: 2020-05-23-04-18-00 +.. nonce: YoYoYo +.. section: Library + +Add a new :data:`os.RWF_APPEND` flag for :func:`os.pwritev`. + +.. + +.. bpo: 40737 +.. date: 2020-05-23-00-22-11 +.. nonce: iph-CM +.. section: Library + +Fix possible reference leak for :mod:`sqlite3` initialization. + +.. + +.. bpo: 40726 +.. date: 2020-05-22-12-45-58 +.. nonce: 7oBdMw +.. section: Library + +Handle cases where the ``end_lineno`` is ``None`` on +:func:`ast.increment_lineno`. + +.. + +.. bpo: 40698 +.. date: 2020-05-20-14-38-04 +.. nonce: zwl5Hc +.. section: Library + +:mod:`distutils` upload creates SHA2-256 and Blake2b-256 digests. MD5 +digests is skipped if platform blocks MD5. + +.. + +.. bpo: 40695 +.. date: 2020-05-20-13-03-28 +.. nonce: lr4aIS +.. section: Library + +:mod:`hashlib` no longer falls back to builtin hash implementations when +OpenSSL provides a hash digest and the algorithm is blocked by security +policy. + +.. + +.. bpo: 9216 +.. date: 2020-05-20-12-53-20 +.. nonce: ps7Yf1 +.. section: Library + +func:`hashlib.new` passed ``usedforsecurity`` to OpenSSL EVP constructor +``_hashlib.new()``. test_hashlib and test_smtplib handle strict security +policy better. + +.. + +.. bpo: 40614 +.. date: 2020-05-18-22-41-02 +.. nonce: 8j3kmq +.. section: Library + +:func:`ast.parse` will not parse self documenting expressions in f-strings +when passed ``feature_version`` is less than ``(3, 8)``. + +.. + +.. bpo: 40626 +.. date: 2020-05-18-17-29-30 +.. nonce: NeZufF +.. section: Library + +Add h5 file extension as MIME Type application/x-hdf5, as per HDF Group +recommendation for HDF5 formatted data files. Patch contributed by Mark +Schwab. + +.. + +.. bpo: 25920 +.. date: 2020-05-18-15-38-25 +.. nonce: PxrLY8 +.. section: Library + +On macOS, when building Python for macOS 10.4 and older, which wasn't the +case for python.org macOS installer, :func:`socket.getaddrinfo` no longer +uses an internal lock to prevent race conditions when calling +``getaddrinfo()`` which is thread-safe since macOS 10.5. Python 3.9 requires +macOS 10.6 or newer. The internal lock caused random hang on fork when +another thread was calling :func:`socket.getaddrinfo`. The lock was also +used on FreeBSD older than 5.3, OpenBSD older than 201311 and NetBSD older +than 4. + +.. + +.. bpo: 40671 +.. date: 2020-05-18-15-26-31 +.. nonce: NeZ9Cy +.. section: Library + +Prepare ``_hashlib`` for :pep:`489` and use :c:func:`PyModule_AddType`. + +.. + +.. bpo: 32309 +.. date: 2020-05-17-02-03-09 +.. nonce: KM9psl +.. section: Library + +Added a new :term:`coroutine` :func:`asyncio.to_thread`. It is mainly used +for running IO-bound functions in a separate thread to avoid blocking the +event loop, and essentially works as a high-level version of +:meth:`~asyncio.loop.run_in_executor` that can directly take keyword +arguments. + +.. + +.. bpo: 36543 +.. date: 2020-05-15-21-14-45 +.. nonce: Jt-eSX +.. section: Library + +Restored the deprecated :mod:`xml.etree.cElementTree` module. + +.. + +.. bpo: 40611 +.. date: 2020-05-13-16-28-33 +.. nonce: ZCk0_c +.. section: Library + +:data:`~mmap.MAP_POPULATE` constant has now been added to the list of +exported :mod:`mmap` module flags. + +.. + +.. bpo: 39881 +.. date: 2020-05-07-22-00-12 +.. nonce: E1xsNv +.. section: Library + +PEP 554 for use in the test suite. (Patch By Joannah Nanjekye) + +.. + +.. bpo: 13097 +.. date: 2020-05-06-02-01-25 +.. nonce: Wh5xSK +.. section: Library + +``ctypes`` now raises an ``ArgumentError`` when a callback is invoked with +more than 1024 arguments. + +.. + +.. bpo: 39385 +.. date: 2020-04-23-18-21-19 +.. nonce: MIAyS7 +.. section: Library + +A new test assertion context-manager, :func:`unittest.assertNoLogs` will +ensure a given block of code emits no log messages using the logging module. +Contributed by Kit Yan Choi. + +.. + +.. bpo: 23082 +.. date: 2020-04-20-22-08-36 +.. nonce: iX90Id +.. section: Library + +Updated the error message and docs of PurePath.relative_to() to better +reflect the function behaviour. + +.. + +.. bpo: 40318 +.. date: 2020-04-18-14-16-02 +.. nonce: K2UdRx +.. section: Library + +Use SQLite3 trace v2 API, if it is available. + +.. + +.. bpo: 40105 +.. date: 2020-04-03-16-13-59 +.. nonce: hfM2c0 +.. section: Library + +ZipFile truncates files to avoid corruption when a shorter comment is +provided in append ("a") mode. Patch by Jan Mazur. + +.. + +.. bpo: 40084 +.. date: 2020-03-29-21-32-00 +.. nonce: MCYwcv +.. section: Library + +Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes as well as +methods. + +.. + +.. bpo: 31122 +.. date: 2020-03-11-07-44-06 +.. nonce: zIQ80l +.. section: Library + +ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer +closes connection during TLS negotiation + +.. + +.. bpo: 39728 +.. date: 2020-02-24-10-58-34 +.. nonce: kOOaHn +.. section: Library + +fix default `_missing_` so a duplicate `ValueError` is not set as the +`__context__` of the original `ValueError` + +.. + +.. bpo: 39244 +.. date: 2020-02-23-15-09-47 +.. nonce: aBK5IM +.. section: Library + +Fixed :class:`multiprocessing.context.get_all_start_methods` to properly +return the default method first on macOS. + +.. + +.. bpo: 39040 +.. date: 2019-12-15-18-47-20 +.. nonce: tKa0Qs +.. section: Library + +Fix parsing of invalid mime headers parameters by collapsing whitespace +between encoded words in a bare-quote-string. + +.. + +.. bpo: 38731 +.. date: 2019-11-13-07-37-11 +.. nonce: 9qmcSx +.. section: Library + +Add ``--quiet`` option to command-line interface of :mod:`py_compile`. Patch +by Gregory Schevchenko. + +.. + +.. bpo: 35714 +.. date: 2019-10-25-23-45-49 +.. nonce: fw3xb7 +.. section: Library + +:exc:`struct.error` is now raised if there is a null character in a +:mod:`struct` format string. + +.. + +.. bpo: 38144 +.. date: 2019-09-12-21-34-03 +.. nonce: 8uQCdd +.. section: Library + +Added the *root_dir* and *dir_fd* parameters in :func:`glob.glob`. + +.. + +.. bpo: 26543 +.. date: 2019-08-11-16-28-03 +.. nonce: X-TJZO +.. section: Library + +Fix :meth:`IMAP4.noop()` when debug mode is enabled (ex: ``imaplib.Debug = +3``). + +.. + +.. bpo: 12178 +.. date: 2019-05-31-23-54-28 +.. nonce: N6FLCZ +.. section: Library + +:func:`csv.writer` now correctly escapes *escapechar* when input contains +*escapechar*. Patch by Catalin Iacob, Berker Peksag, and Itay Elbirt. + +.. + +.. bpo: 36290 +.. date: 2019-03-17-19-01-53 +.. nonce: 7VXo_K +.. section: Library + +AST nodes are now raising :exc:`TypeError` on conflicting keyword arguments. +Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 33944 +.. date: 2019-03-01-01-56-23 +.. nonce: -82Pkt +.. section: Library + +Added site.py site-packages tracing in verbose mode. + +.. + +.. bpo: 35078 +.. date: 2018-10-27-09-37-03 +.. nonce: kweA3R +.. section: Library + +Refactor formatweekday, formatmonthname methods in LocaleHTMLCalendar and +LocaleTextCalendar classes in calendar module to call the base class +methods.This enables customizable CSS classes for LocaleHTMLCalendar. Patch +by Srinivas Reddy Thatiparthy + +.. + +.. bpo: 29620 +.. date: 2018-08-21-16-20-33 +.. nonce: xxx666 +.. section: Library + +:func:`~unittest.TestCase.assertWarns` no longer raises a +``RuntimeException`` when accessing a module's ``__warningregistry__`` +causes importation of a new module, or when a new module is imported in +another thread. Patch by Kernc. + +.. + +.. bpo: 31844 +.. date: 2018-07-30-12-48-17 +.. nonce: 0_GKsD +.. section: Library + +Remove ``ParserBase.error()`` method from the private and undocumented +``_markupbase`` module. :class:`html.parser.HTMLParser` is the only +subclass of ``ParserBase`` and its ``error()`` implementation was deprecated +in Python 3.4 and removed in Python 3.5. + +.. + +.. bpo: 34226 +.. date: 2018-07-29-12-14-54 +.. nonce: BE7zbu +.. section: Library + +Fix `cgi.parse_multipart` without content_length. Patch by Roger Duran + +.. + +.. bpo: 33660 +.. date: 2018-06-12-23-30-41 +.. nonce: AdDn5Z +.. section: Library + +Fix pathlib.PosixPath to resolve a relative path located on the root +directory properly. + +.. + +.. bpo: 28557 +.. date: 2018-06-07-22-04-01 +.. nonce: ViNJnK +.. section: Library + +Improve the error message for a misbehaving ``rawio.readinto`` + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-56-48 +.. nonce: Udkhn4 +.. section: Library + +The d.is_integer() method is added to the Decimal type, for compatibility +with other number types. + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-55-04 +.. nonce: eKAi85 +.. section: Library + +The x.is_integer() method is incorporated into the abstract types of the +numeric tower, Real, Rational and Integral, with appropriate default +implementations. + +.. + +.. bpo: 41428 +.. date: 2020-10-03-18-20-46 +.. nonce: _ju1NE +.. section: Documentation + +Add documentation for :pep:`604` (Allow writing union types as ``X | Y``). + +.. + +.. bpo: 41774 +.. date: 2020-09-24-15-35-13 +.. nonce: 5IqdGP +.. section: Documentation + +In Programming FAQ "Sequences (Tuples/Lists)" section, add "How do you +remove multiple items from a list". + +.. + +.. bpo: 35293 +.. date: 2020-09-12-17-37-13 +.. nonce: _cOwPD +.. section: Documentation + +Fix RemovedInSphinx40Warning when building the documentation. Patch by +Dong-hee Na. + +.. + +.. bpo: 37149 +.. date: 2020-09-10-07-48-02 +.. nonce: VD0rCv +.. section: Documentation + +Change Shipman tkinter doc link from archive.org to TkDocs. (The doc has +been removed from the NMT server.) The new link responds much faster and +includes a short explanatory note. + +.. + +.. bpo: 41726 +.. date: 2020-09-08-16-57-09 +.. nonce: g0UXrn +.. section: Documentation + +Update the refcounts info of ``PyType_FromModuleAndSpec``. + +.. + +.. bpo: 41624 +.. date: 2020-08-25-15-11-23 +.. nonce: ddjJlN +.. section: Documentation + +Fix the signature of :class:`typing.Coroutine`. + +.. + +.. bpo: 40204 +.. date: 2020-08-12-18-35-40 +.. nonce: C8A_pe +.. section: Documentation + +Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable +``c_warn_on_allowed_pre_v3`` option to make the documentation compatible +with Sphinx 2 and Sphinx 3. + +.. + +.. bpo: 41045 +.. date: 2020-07-27-20-46-17 +.. nonce: GFF6Ul +.. section: Documentation + +Add documentation for debug feature of f-strings. + +.. + +.. bpo: 41314 +.. date: 2020-07-25-14-20-00 +.. nonce: yrjko0 +.. section: Documentation + +Changed the release when ``from __future__ import annotations`` becomes the +default from ``4.0`` to ``3.10`` (following a change in PEP 563). + +.. + +.. bpo: 40979 +.. date: 2020-07-21-15-23-30 +.. nonce: pLA8rO +.. section: Documentation + +Refactored typing.rst, arranging more than 70 classes, functions, and +decorators into new sub-sections. + +.. + +.. bpo: 40552 +.. date: 2020-05-09-12-10-31 +.. nonce: _0uB73 +.. section: Documentation + +Fix in tutorial section 4.2. Code snippet is now correct. + +.. + +.. bpo: 39883 +.. date: 2020-03-07-03-53-39 +.. nonce: 1tnb4- +.. section: Documentation + +Make code, examples, and recipes in the Python documentation be licensed +under the more permissive BSD0 license in addition to the existing Python +2.0 license. + +.. + +.. bpo: 37703 +.. date: 2019-08-16-20-25-42 +.. nonce: Qm_l_H +.. section: Documentation + +Updated Documentation to comprehensively elaborate on the behaviour of +gather.cancel() + +.. + +.. bpo: 41939 +.. date: 2020-10-05-09-37-43 +.. nonce: P4OlbA +.. section: Tests + +Fix test_site.test_license_exists_at_url(): call +``urllib.request.urlcleanup()`` to reset the global +``urllib.request._opener``. Patch by Victor Stinner. + +.. + +.. bpo: 41731 +.. date: 2020-09-11-19-12-31 +.. nonce: Ivxh4U +.. section: Tests + +Make test_cmd_line_script pass with option '-vv'. + +.. + +.. bpo: 41602 +.. date: 2020-08-25-19-25-36 +.. nonce: Z64s0I +.. section: Tests + +Add tests for SIGINT handling in the runpy module. + +.. + +.. bpo: 41521 +.. date: 2020-08-11-14-59-13 +.. nonce: w2UYK7 +.. section: Tests + +:mod:`test.support`: Rename ``blacklist`` parameter of +:func:`~test.support.check__all__` to ``not_exported``. + +.. + +.. bpo: 41477 +.. date: 2020-08-07-17-28-49 +.. nonce: GrFexU +.. section: Tests + +Make ctypes optional in test_genericalias. + +.. + +.. bpo: 41085 +.. date: 2020-06-23-12-02-45 +.. nonce: JZKsyz +.. section: Tests + +Fix integer overflow in the :meth:`array.array.index` method on 64-bit +Windows for index larger than ``2**31``. + +.. + +.. bpo: 41069 +.. date: 2020-06-22-00-21-12 +.. nonce: bLZkX- +.. section: Tests + +:data:`test.support.TESTFN` and the current directory for tests when run via +``test.regrtest`` contain now non-ascii characters if possible. + +.. + +.. bpo: 38377 +.. date: 2020-06-17-18-00-21 +.. nonce: jfg4TH +.. section: Tests + +On Linux, skip tests using multiprocessing if the current user cannot create +a file in ``/dev/shm/`` directory. Add the +:func:`~test.support.skip_if_broken_multiprocessing_synchronize` function to +the :mod:`test.support` module. + +.. + +.. bpo: 41009 +.. date: 2020-06-17-17-27-07 +.. nonce: Rvn6OQ +.. section: Tests + +Fix use of ``support.require_{linux|mac|freebsd}_version()`` decorators as +class decorator. + +.. + +.. bpo: 41003 +.. date: 2020-06-17-15-07-14 +.. nonce: tiH_Fy +.. section: Tests + +Fix ``test_copyreg`` when ``numpy`` is installed: ``test.pickletester`` now +saves/restores warnings filters when importing ``numpy``, to ignore filters +installed by ``numpy``. + +.. + +.. bpo: 40964 +.. date: 2020-06-12-20-46-23 +.. nonce: OBzf2c +.. section: Tests + +Disable remote :mod:`imaplib` tests, host cyrus.andrew.cmu.edu is blocking +incoming connections. + +.. + +.. bpo: 40927 +.. date: 2020-06-09-18-48-18 +.. nonce: 67ylLg +.. section: Tests + +Fix test_binhex when run twice: it now uses import_fresh_module() to ensure +that it raises DeprecationWarning each time. + +.. + +.. bpo: 17258 +.. date: 2020-05-26-07-53-31 +.. nonce: X_IKTQ +.. section: Tests + +Skip some :mod:`multiprocessing` tests when MD5 hash digest is blocked. + +.. + +.. bpo: 31904 +.. date: 2020-04-09-15-40-03 +.. nonce: TJ4k3d +.. section: Tests + +Increase LOOPBACK_TIMEOUT to 10 for VxWorks RTOS. + +.. + +.. bpo: 38169 +.. date: 2019-09-14-13-20-27 +.. nonce: hurq4B +.. section: Tests + +Increase code coverage for SharedMemory and ShareableList + +.. + +.. bpo: 34401 +.. date: 2018-08-20-09-38-52 +.. nonce: eGxMPm +.. section: Tests + +Make test_gdb properly run on HP-UX. Patch by Michael Osipov. + +.. + +.. bpo: 38249 +.. date: 2020-09-28-21-56-51 +.. nonce: uzMCaZ +.. section: Build + +Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() if only the +compiler is able to use it. Patch by Dong-hee Na. + +.. + +.. bpo: 41617 +.. date: 2020-08-24-18-34-01 +.. nonce: sKKXz7 +.. section: Build + +Fix ``pycore_bitutils.h`` header file to support old clang versions: +``__builtin_bswap16()`` is not available in LLVM clang 3.0. + +.. + +.. bpo: 40204 +.. date: 2020-06-25-06-59-13 +.. nonce: GpD04D +.. section: Build + +Pin Sphinx version to 2.3.1 in ``Doc/Makefile``. + +.. + +.. bpo: 36020 +.. date: 2020-06-15-22-14-25 +.. nonce: wbiv0P +.. section: Build + +The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now +required to build Python. + +.. + +.. bpo: 40684 +.. date: 2020-06-08-19-57-05 +.. nonce: WIY2-i +.. section: Build + +``make install`` now uses the ``PLATLIBDIR`` variable for the destination +``lib-dynload/`` directory when ``./configure --with-platlibdir`` is used. + +.. + +.. bpo: 40683 +.. date: 2020-05-19-10-54-08 +.. nonce: W8JHrr +.. section: Build + +Fixed an issue where the :mod:`zoneinfo` module and its tests were not +included when Python is installed with ``make``. + +.. + +.. bpo: 41744 +.. date: 2020-09-11-17-59-33 +.. nonce: e_ugDQ +.. section: Windows + +Fixes automatic import of props file when using the Nuget package. + +.. + +.. bpo: 41627 +.. date: 2020-09-04-21-35-28 +.. nonce: sx2KN1 +.. section: Windows + +The user site directory for 32-bit now includes a ``-32`` suffix to +distinguish it from the 64-bit interpreter's directory. + +.. + +.. bpo: 41526 +.. date: 2020-08-13-22-40-58 +.. nonce: -i2bwb +.. section: Windows + +Fixed layout of final page of the installer by removing the special thanks +to Mark Hammond (with his permission). + +.. + +.. bpo: 41492 +.. date: 2020-08-06-16-59-10 +.. nonce: 2FQ9cM +.. section: Windows + +Fixes the description that appears in UAC prompts. + +.. + +.. bpo: 40948 +.. date: 2020-07-28-12-39-32 +.. nonce: ISUFO6 +.. section: Windows + +Improve post-install message to direct people to the "py" command. + +.. + +.. bpo: 41412 +.. date: 2020-07-28-11-55-43 +.. nonce: ME20KB +.. section: Windows + +The installer will now fail to install on Windows 7 and Windows 8. Further, +the UCRT dependency is now always downloaded on demand. + +.. + +.. bpo: 40741 +.. date: 2020-07-20-23-26-26 +.. nonce: C9sc_d +.. section: Windows + +Update Windows release to include SQLite 3.32.3. + +.. + +.. bpo: 41142 +.. date: 2020-06-28-12-40-41 +.. nonce: jpZzzh +.. section: Windows + +:mod:`msilib` now supports creating CAB files with non-ASCII file path and +adding files with non-ASCII file path to them. + +.. + +.. bpo: 41074 +.. date: 2020-06-24-21-30-42 +.. nonce: gaQc3C +.. section: Windows + +Fixed support of non-ASCII names in functions :func:`msilib.OpenDatabase` +and :func:`msilib.init_database` and non-ASCII SQL in method +:meth:`msilib.Database.OpenView`. + +.. + +.. bpo: 41039 +.. date: 2020-06-23-03-12-57 +.. nonce: 0hgd0s +.. section: Windows + +Stable ABI redirection DLL (python3.dll) now uses ``#pragma +comment(linker)`` for re-exporting. + +.. + +.. bpo: 40164 +.. date: 2020-06-12-13-13-44 +.. nonce: SPrSn5 +.. section: Windows + +Updates Windows OpenSSL to 1.1.1g + +.. + +.. bpo: 39631 +.. date: 2020-05-19-14-43-33 +.. nonce: Z5yXam +.. section: Windows + +Changes the registered MIME type for ``.py`` files on Windows to +``text/x-python`` instead of ``text/plain``. + +.. + +.. bpo: 40677 +.. date: 2020-05-19-04-11-12 +.. nonce: qQbLW8 +.. section: Windows + +Manually define IO_REPARSE_TAG_APPEXECLINK in case some old Windows SDK +doesn't have it. + +.. + +.. bpo: 37556 +.. date: 2019-07-11-06-11-09 +.. nonce: sygMUU +.. section: Windows + +Extend py.exe help to mention overrides via venv, shebang, environmental +variables & ini files. + +.. + +.. bpo: 41557 +.. date: 2020-08-26-09-31-37 +.. nonce: mcQ75z +.. section: macOS + +Update macOS installer to use SQLite 3.33.0. + +.. + +.. bpo: 39580 +.. date: 2020-06-25-06-09-00 +.. nonce: N_vJ9h +.. section: macOS + +Avoid opening Finder window if running installer from the command line. +Patch contributed by Rick Heil. + +.. + +.. bpo: 41100 +.. date: 2020-06-24-13-51-57 +.. nonce: mcHdc5 +.. section: macOS + +Fix configure error when building on macOS 11. Note that the current Python +release was released shortly after the first developer preview of macOS 11 +(Big Sur); there are other known issues with building and running on the +developer preview. Big Sur is expected to be fully supported in a future +bugfix release of Python 3.8.x and with 3.9.0. + +.. + +.. bpo: 40741 +.. date: 2020-06-19-14-19-08 +.. nonce: L7yTbm +.. section: macOS + +Update macOS installer to use SQLite 3.32.3. + +.. + +.. bpo: 41005 +.. date: 2020-06-17-13-45-15 +.. nonce: zZegdV +.. section: macOS + +fixed an XDG settings issue not allowing macos to open browser in +webbrowser.py + +.. + +.. bpo: 40741 +.. date: 2020-06-07-20-10-56 +.. nonce: 80A2BW +.. section: macOS + +Update macOS installer to use SQLite 3.32.2. + +.. + +.. bpo: 41775 +.. date: 2020-09-24-14-31-16 +.. nonce: sB8Vre +.. section: IDLE + +Use 'IDLE Shell' as shell title + +.. + +.. bpo: 35764 +.. date: 2020-09-22-11-13-45 +.. nonce: VoNa8y +.. section: IDLE + +Rewrite the Calltips doc section. + +.. + +.. bpo: 40181 +.. date: 2020-09-22-00-45-40 +.. nonce: hhQi3z +.. section: IDLE + +In calltips, stop reminding that '/' marks the end of positional-only +arguments. + +.. + +.. bpo: 41468 +.. date: 2020-08-09-13-42-55 +.. nonce: zkP0_Y +.. section: IDLE + +Improve IDLE run crash error message (which users should never see). + +.. + +.. bpo: 41373 +.. date: 2020-07-24-17-49-58 +.. nonce: YQIPu_ +.. section: IDLE + +Save files loaded with no line ending, as when blank, or different line +endings, by setting its line ending to the system default. Fix regression in +3.8.4 and 3.9.0b4. + +.. + +.. bpo: 41300 +.. date: 2020-07-16-17-39-06 +.. nonce: wRixNb +.. section: IDLE + +Save files with non-ascii chars. Fix regression released in 3.9.0b4 and +3.8.4. + +.. + +.. bpo: 37765 +.. date: 2020-07-07-18-44-30 +.. nonce: umc1o8 +.. section: IDLE + +Add keywords to module name completion list. Rewrite Completions section of +IDLE doc. + +.. + +.. bpo: 41152 +.. date: 2020-06-29-14-51-15 +.. nonce: d6mV0C +.. section: IDLE + +The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE is now always +UTF-8. + +.. + +.. bpo: 41144 +.. date: 2020-06-27-17-02-00 +.. nonce: JoFGIX +.. section: IDLE + +Make Open Module open a special module such as os.path. + +.. + +.. bpo: 39885 +.. date: 2020-05-29-18-21-58 +.. nonce: zB_-bN +.. section: IDLE + +Make context menu Cut and Copy work again when right-clicking within a +selection. + +.. + +.. bpo: 40723 +.. date: 2020-05-24-06-19-43 +.. nonce: AJLd4U +.. section: IDLE + +Make test_idle pass when run after import. + +.. + +.. bpo: 41936 +.. date: 2020-10-05-01-25-23 +.. nonce: 1gb5ra +.. section: C API + +Removed undocumented macros ``Py_ALLOW_RECURSION`` and +``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the +:c:type:`PyInterpreterState` structure. + +.. + +.. bpo: 41692 +.. date: 2020-10-02-00-57-34 +.. nonce: fDScsF +.. section: C API + +The ``PyUnicode_InternImmortal()`` function is now deprecated and will be +removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` instead. Patch +by Victor Stinner. + +.. + +.. bpo: 41842 +.. date: 2020-09-27-20-43-16 +.. nonce: bCakAj +.. section: C API + +Add :c:func:`PyCodec_Unregister` function to unregister a codec search +function. + +.. + +.. bpo: 41834 +.. date: 2020-09-22-14-47-12 +.. nonce: nrOrDU +.. section: C API + +Remove the ``_Py_CheckRecursionLimit`` variable: it has been replaced by +``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` structure. +Patch by Victor Stinner. + +.. + +.. bpo: 41689 +.. date: 2020-09-01-23-39-45 +.. nonce: zxHbLB +.. section: C API + +Types created with :c:func:`PyType_FromSpec` now make any signature in their +``tp_doc`` slot accessible from ``__text_signature__``. + +.. + +.. bpo: 41524 +.. date: 2020-08-12-17-09-06 +.. nonce: u6Xfr2 +.. section: C API + +Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented pointers +beyond the end of a string. + +.. + +.. bpo: 41324 +.. date: 2020-08-10-16-05-08 +.. nonce: waZD35 +.. section: C API + +Add a minimal decimal capsule API. The API supports fast conversions +between Decimals up to 38 digits and their triple representation as a C +struct. + +.. + +.. bpo: 30155 +.. date: 2020-07-26-19-39-45 +.. nonce: rHZRJ_ +.. section: C API + +Add :c:func:`PyDateTime_DATE_GET_TZINFO` and +:c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo`` +attributes of :class:`datetime.datetime` and :class:`datetime.time` objects. + +.. + +.. bpo: 40170 +.. date: 2020-07-08-10-14-52 +.. nonce: N6Qx1i +.. section: C API + +Revert :c:func:`PyType_HasFeature` change: it reads again directly the +:c:member:`PyTypeObject.tp_flags` member when the limited C API is not used, +rather than always calling :c:func:`PyType_GetFlags` which hides +implementation details. + +.. + +.. bpo: 41123 +.. date: 2020-06-29-15-49-36 +.. nonce: wYY4E1 +.. section: C API + +Remove ``PyUnicode_AsUnicodeCopy``. + +.. + +.. bpo: 41123 +.. date: 2020-06-29-11-33-49 +.. nonce: qFevek +.. section: C API + +Removed ``PyLong_FromUnicode()``. + +.. + +.. bpo: 41123 +.. date: 2020-06-28-11-39-22 +.. nonce: sjJWjQ +.. section: C API + +Removed ``PyUnicode_GetMax()``. + +.. + +.. bpo: 41123 +.. date: 2020-06-26-13-29-25 +.. nonce: bRa1oy +.. section: C API + +Removed ``Py_UNICODE_str*`` functions manipulating ``Py_UNICODE*`` strings. + +.. + +.. bpo: 41103 +.. date: 2020-06-24-22-57-07 +.. nonce: doojgE +.. section: C API + +``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, +``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are +removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer` +and :c:func:`PyBuffer_Release`. + +.. + +.. bpo: 36346 +.. date: 2020-06-17-20-31-12 +.. nonce: mwIyxi +.. section: C API + +Raises DeprecationWarning for ``PyUnicode_FromUnicode(NULL, size)`` and +``PyUnicode_FromStringAndSize(NULL, size)`` with ``size > 0``. + +.. + +.. bpo: 36346 +.. date: 2020-06-17-11-24-00 +.. nonce: fTMr3S +.. section: C API + +Mark ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``, +``PyUnicode_FromUnicode``, ``PyUnicode_AsUnicode``, and +``PyUnicode_AsUnicodeAndSize`` as deprecated in C. Remove +``Py_UNICODE_MATCH`` which was deprecated and broken since Python 3.3. + +.. + +.. bpo: 40989 +.. date: 2020-06-15-23-17-51 +.. nonce: tlzG3r +.. section: C API + +The :c:func:`PyObject_INIT` and :c:func:`PyObject_INIT_VAR` macros become +aliases to, respectively, :c:func:`PyObject_Init` and +:c:func:`PyObject_InitVar` functions. + +.. + +.. bpo: 36020 +.. date: 2020-06-15-16-46-01 +.. nonce: djI6jw +.. section: C API + +On Windows, ``#include "pyerrors.h"`` no longer defines ``snprintf`` and +``vsnprintf`` macros. + +.. + +.. bpo: 40943 +.. date: 2020-06-10-18-37-26 +.. nonce: i4q7rK +.. section: C API + +The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use +:c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use +``#``: ``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and ``Z#``. +See :ref:`Parsing arguments and building values ` and the +:pep:`353`. + +.. + +.. bpo: 40910 +.. date: 2020-06-08-15-59-06 +.. nonce: L56oI0 +.. section: C API + +Export explicitly the :c:func:`Py_GetArgcArgv` function to the C API and +document the function. Previously, it was exported implicitly which no +longer works since Python is built with ``-fvisibility=hidden``. + +.. + +.. bpo: 40724 +.. date: 2020-06-04-08-01-23 +.. nonce: qIIdSi +.. section: C API + +Allow defining buffer slots in type specs. + +.. + +.. bpo: 40679 +.. date: 2020-06-03-17-48-13 +.. nonce: 3sgWma +.. section: C API + +Fix a ``_PyEval_EvalCode()`` crash if *qualname* argument is NULL. + +.. + +.. bpo: 40839 +.. date: 2020-06-01-20-47-49 +.. nonce: bAi52Z +.. section: C API + +Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed +for historical reason. It is no longer allowed. + +.. + +.. bpo: 40826 +.. date: 2020-06-01-16-12-37 +.. nonce: zQzFoK +.. section: C API + +:c:func:`PyOS_InterruptOccurred` now fails with a fatal error if it is +called with the GIL released. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-11-02-15 +.. nonce: pBw2Bb +.. section: C API + +The result of :c:func:`PyNumber_Index` now always has exact type +:class:`int`. Previously, the result could have been an instance of a +subclass of ``int``. + +.. + +.. bpo: 39573 +.. date: 2020-05-26-16-21-47 +.. nonce: depAgq +.. section: C API + +Convert :c:func:`Py_REFCNT` and :c:func:`Py_SIZE` macros to static inline +functions. They cannot be used as l-value anymore: use +:c:func:`Py_SET_REFCNT` and :c:func:`Py_SET_SIZE` to set an object reference +count and size. This change is backward incompatible on purpose, to prepare +the C API for an opaque :c:type:`PyObject` structure. + +.. + +.. bpo: 40703 +.. date: 2020-05-20-19-11-12 +.. nonce: qQXfW8 +.. section: C API + +The PyType_FromSpec*() functions no longer overwrite the type's "__module__" +attribute if it is set via "Py_tp_members" or "Py_tp_getset". + +.. + +.. bpo: 39583 +.. date: 2020-02-08-08-01-35 +.. nonce: qURKSl +.. section: C API + +Remove superfluous "extern C" declarations from ``Include/cpython/*.h``. diff --git a/Misc/NEWS.d/next/Build/2020-05-19-10-54-08.bpo-40683.W8JHrr.rst b/Misc/NEWS.d/next/Build/2020-05-19-10-54-08.bpo-40683.W8JHrr.rst deleted file mode 100644 index d57e064c03d61e6..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-05-19-10-54-08.bpo-40683.W8JHrr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed an issue where the :mod:`zoneinfo` module and its tests were not -included when Python is installed with ``make``. diff --git a/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst b/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst deleted file mode 100644 index 0495e5e413622e7..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst +++ /dev/null @@ -1,2 +0,0 @@ -``make install`` now uses the ``PLATLIBDIR`` variable for the destination -``lib-dynload/`` directory when ``./configure --with-platlibdir`` is used. diff --git a/Misc/NEWS.d/next/Build/2020-06-15-22-14-25.bpo-36020.wbiv0P.rst b/Misc/NEWS.d/next/Build/2020-06-15-22-14-25.bpo-36020.wbiv0P.rst deleted file mode 100644 index de50dff3b1d27f7..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-06-15-22-14-25.bpo-36020.wbiv0P.rst +++ /dev/null @@ -1,2 +0,0 @@ -The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now required -to build Python. diff --git a/Misc/NEWS.d/next/Build/2020-06-25-06-59-13.bpo-40204.GpD04D.rst b/Misc/NEWS.d/next/Build/2020-06-25-06-59-13.bpo-40204.GpD04D.rst deleted file mode 100644 index 25a6d751e5f45c3..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-06-25-06-59-13.bpo-40204.GpD04D.rst +++ /dev/null @@ -1 +0,0 @@ -Pin Sphinx version to 2.3.1 in ``Doc/Makefile``. diff --git a/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst b/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst deleted file mode 100644 index 715eadbee896f1d..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-08-24-18-34-01.bpo-41617.sKKXz7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``pycore_bitutils.h`` header file to support old clang versions: -``__builtin_bswap16()`` is not available in LLVM clang 3.0. diff --git a/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst b/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst deleted file mode 100644 index 3e409ec2e7c2024..000000000000000 --- a/Misc/NEWS.d/next/Build/2020-09-28-21-56-51.bpo-38249.uzMCaZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() if only the -compiler is able to use it. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst b/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst deleted file mode 100644 index 1c9f44f7443c14a..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst +++ /dev/null @@ -1 +0,0 @@ -Remove superfluous "extern C" declarations from ``Include/cpython/*.h``. diff --git a/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst b/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst deleted file mode 100644 index 5385a2d8dce4546..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst +++ /dev/null @@ -1,2 +0,0 @@ -The PyType_FromSpec*() functions no longer overwrite the type's "__module__" attribute -if it is set via "Py_tp_members" or "Py_tp_getset". diff --git a/Misc/NEWS.d/next/C API/2020-05-26-16-21-47.bpo-39573.depAgq.rst b/Misc/NEWS.d/next/C API/2020-05-26-16-21-47.bpo-39573.depAgq.rst deleted file mode 100644 index f8f675cebcac7ad..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-05-26-16-21-47.bpo-39573.depAgq.rst +++ /dev/null @@ -1,5 +0,0 @@ -Convert :c:func:`Py_REFCNT` and :c:func:`Py_SIZE` macros to static inline -functions. They cannot be used as l-value anymore: use -:c:func:`Py_SET_REFCNT` and :c:func:`Py_SET_SIZE` to set an object reference -count and size. This change is backward incompatible on purpose, to prepare -the C API for an opaque :c:type:`PyObject` structure. diff --git a/Misc/NEWS.d/next/C API/2020-05-27-11-02-15.bpo-40792.pBw2Bb.rst b/Misc/NEWS.d/next/C API/2020-05-27-11-02-15.bpo-40792.pBw2Bb.rst deleted file mode 100644 index 4cfe09bc774aff8..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-05-27-11-02-15.bpo-40792.pBw2Bb.rst +++ /dev/null @@ -1,2 +0,0 @@ -The result of :c:func:`PyNumber_Index` now always has exact type :class:`int`. -Previously, the result could have been an instance of a subclass of ``int``. diff --git a/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst b/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst deleted file mode 100644 index 0d7a36c3eb401c0..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`PyOS_InterruptOccurred` now fails with a fatal error if it is -called with the GIL released. diff --git a/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst b/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst deleted file mode 100644 index 5de2f40c14eca02..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed for -historical reason. It is no longer allowed. diff --git a/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst b/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst deleted file mode 100644 index ccf908cef19142c..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a ``_PyEval_EvalCode()`` crash if *qualname* argument is NULL. diff --git a/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst b/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst deleted file mode 100644 index 82793dbf7ad5f12..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst +++ /dev/null @@ -1 +0,0 @@ -Allow defining buffer slots in type specs. diff --git a/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst b/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst deleted file mode 100644 index 1d0cb0b0235bf50..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst +++ /dev/null @@ -1,3 +0,0 @@ -Export explicitly the :c:func:`Py_GetArgcArgv` function to the C API and -document the function. Previously, it was exported implicitly which no -longer works since Python is built with ``-fvisibility=hidden``. diff --git a/Misc/NEWS.d/next/C API/2020-06-10-18-37-26.bpo-40943.i4q7rK.rst b/Misc/NEWS.d/next/C API/2020-06-10-18-37-26.bpo-40943.i4q7rK.rst deleted file mode 100644 index 360ddae34cb9607..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-10-18-37-26.bpo-40943.i4q7rK.rst +++ /dev/null @@ -1,5 +0,0 @@ -The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use -:c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use ``#``: -``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and ``Z#``. -See :ref:`Parsing arguments and building values ` and the -:pep:`353`. diff --git a/Misc/NEWS.d/next/C API/2020-06-15-16-46-01.bpo-36020.djI6jw.rst b/Misc/NEWS.d/next/C API/2020-06-15-16-46-01.bpo-36020.djI6jw.rst deleted file mode 100644 index 1f91dce4608d349..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-15-16-46-01.bpo-36020.djI6jw.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, ``#include "pyerrors.h"`` no longer defines ``snprintf`` and -``vsnprintf`` macros. diff --git a/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst b/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst deleted file mode 100644 index 1be473d142760e4..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :c:func:`PyObject_INIT` and :c:func:`PyObject_INIT_VAR` macros become -aliases to, respectively, :c:func:`PyObject_Init` and -:c:func:`PyObject_InitVar` functions. diff --git a/Misc/NEWS.d/next/C API/2020-06-17-11-24-00.bpo-36346.fTMr3S.rst b/Misc/NEWS.d/next/C API/2020-06-17-11-24-00.bpo-36346.fTMr3S.rst deleted file mode 100644 index 1e448303a853cff..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-17-11-24-00.bpo-36346.fTMr3S.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mark ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``, -``PyUnicode_FromUnicode``, ``PyUnicode_AsUnicode``, -and ``PyUnicode_AsUnicodeAndSize`` as deprecated in C. Remove ``Py_UNICODE_MATCH`` -which was deprecated and broken since Python 3.3. diff --git a/Misc/NEWS.d/next/C API/2020-06-17-20-31-12.bpo-36346.mwIyxi.rst b/Misc/NEWS.d/next/C API/2020-06-17-20-31-12.bpo-36346.mwIyxi.rst deleted file mode 100644 index 9b0400399beb998..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-17-20-31-12.bpo-36346.mwIyxi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raises DeprecationWarning for ``PyUnicode_FromUnicode(NULL, size)`` and -``PyUnicode_FromStringAndSize(NULL, size)`` with ``size > 0``. diff --git a/Misc/NEWS.d/next/C API/2020-06-24-22-57-07.bpo-41103.doojgE.rst b/Misc/NEWS.d/next/C API/2020-06-24-22-57-07.bpo-41103.doojgE.rst deleted file mode 100644 index 082b77b9035cbee..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-24-22-57-07.bpo-41103.doojgE.rst +++ /dev/null @@ -1,4 +0,0 @@ -``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, -``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are -removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer` -and :c:func:`PyBuffer_Release`. diff --git a/Misc/NEWS.d/next/C API/2020-06-26-13-29-25.bpo-41123.bRa1oy.rst b/Misc/NEWS.d/next/C API/2020-06-26-13-29-25.bpo-41123.bRa1oy.rst deleted file mode 100644 index 1261a8708d6c9fe..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-26-13-29-25.bpo-41123.bRa1oy.rst +++ /dev/null @@ -1 +0,0 @@ -Removed ``Py_UNICODE_str*`` functions manipulating ``Py_UNICODE*`` strings. diff --git a/Misc/NEWS.d/next/C API/2020-06-28-11-39-22.bpo-41123.sjJWjQ.rst b/Misc/NEWS.d/next/C API/2020-06-28-11-39-22.bpo-41123.sjJWjQ.rst deleted file mode 100644 index 97331458c6ab9a1..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-28-11-39-22.bpo-41123.sjJWjQ.rst +++ /dev/null @@ -1 +0,0 @@ -Removed ``PyUnicode_GetMax()``. diff --git a/Misc/NEWS.d/next/C API/2020-06-29-11-33-49.bpo-41123.qFevek.rst b/Misc/NEWS.d/next/C API/2020-06-29-11-33-49.bpo-41123.qFevek.rst deleted file mode 100644 index 1f5813594b0ec59..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-29-11-33-49.bpo-41123.qFevek.rst +++ /dev/null @@ -1 +0,0 @@ -Removed ``PyLong_FromUnicode()``. diff --git a/Misc/NEWS.d/next/C API/2020-06-29-15-49-36.bpo-41123.wYY4E1.rst b/Misc/NEWS.d/next/C API/2020-06-29-15-49-36.bpo-41123.wYY4E1.rst deleted file mode 100644 index 74ac45462773eca..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-06-29-15-49-36.bpo-41123.wYY4E1.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``PyUnicode_AsUnicodeCopy``. diff --git a/Misc/NEWS.d/next/C API/2020-07-08-10-14-52.bpo-40170.N6Qx1i.rst b/Misc/NEWS.d/next/C API/2020-07-08-10-14-52.bpo-40170.N6Qx1i.rst deleted file mode 100644 index 760a3ff4d17b44f..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-07-08-10-14-52.bpo-40170.N6Qx1i.rst +++ /dev/null @@ -1,4 +0,0 @@ -Revert :c:func:`PyType_HasFeature` change: it reads again directly the -:c:member:`PyTypeObject.tp_flags` member when the limited C API is not used, -rather than always calling :c:func:`PyType_GetFlags` which hides implementation -details. diff --git a/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst b/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst deleted file mode 100644 index a276759da793388..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-07-26-19-39-45.bpo-30155.rHZRJ_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :c:func:`PyDateTime_DATE_GET_TZINFO` and -:c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo`` -attributes of :class:`datetime.datetime` and :class:`datetime.time` objects. diff --git a/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst b/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst deleted file mode 100644 index e09332ab11e1d7f..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-08-10-16-05-08.bpo-41324.waZD35.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add a minimal decimal capsule API. The API supports fast conversions -between Decimals up to 38 digits and their triple representation as a C -struct. diff --git a/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst b/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst deleted file mode 100644 index 4704e29be29bb03..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-08-12-17-09-06.bpo-41524.u6Xfr2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented -pointers beyond the end of a string. \ No newline at end of file diff --git a/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst b/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst deleted file mode 100644 index 44cf58a4b063889..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-09-01-23-39-45.bpo-41689.zxHbLB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Types created with :c:func:`PyType_FromSpec` now make any signature in their -``tp_doc`` slot accessible from ``__text_signature__``. diff --git a/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst b/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst deleted file mode 100644 index 07043dce5a6274e..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-09-22-14-47-12.bpo-41834.nrOrDU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the ``_Py_CheckRecursionLimit`` variable: it has been replaced by -``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` -structure. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst b/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst deleted file mode 100644 index 116d08f49085961..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-09-27-20-43-16.bpo-41842.bCakAj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`PyCodec_Unregister` function to unregister a codec search -function. diff --git a/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst b/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst deleted file mode 100644 index 1be37c6572271bd..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-10-02-00-57-34.bpo-41692.fDScsF.rst +++ /dev/null @@ -1,3 +0,0 @@ -The ``PyUnicode_InternImmortal()`` function is now deprecated and will be -removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` instead. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst b/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst deleted file mode 100644 index 646135330861675..000000000000000 --- a/Misc/NEWS.d/next/C API/2020-10-05-01-25-23.bpo-41936.1gb5ra.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed undocumented macros ``Py_ALLOW_RECURSION`` and -``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the -:c:type:`PyInterpreterState` structure. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst deleted file mode 100644 index 93325ffffcbfc68..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-03-15-11-51-36.bpo-26680.wOWYps.rst +++ /dev/null @@ -1,2 +0,0 @@ -The int type now supports the x.is_integer() method for compatibility with -float. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-08-29-15-57-07.bpo-19569.RGu2Kb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-08-29-15-57-07.bpo-19569.RGu2Kb.rst deleted file mode 100644 index 1b76bd8e247fc6f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-08-29-15-57-07.bpo-19569.RGu2Kb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add the private macros ``_Py_COMP_DIAG_PUSH``, -``_Py_COMP_DIAG_IGNORE_DEPR_DECLS``, and ``_Py_COMP_DIAG_POP``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst deleted file mode 100644 index f105f1857d487f2..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-05-27-39.bpo-36982.0UHgfB.rst +++ /dev/null @@ -1 +0,0 @@ -Use ncurses extended color functions when available to support terminals with 256 colors, and add the new function :func:`curses.has_extended_color_support` to indicate whether extended color support is provided by the underlying ncurses library. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-02-11-29-15.bpo-29882.AkRzjb.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-02-11-29-15.bpo-29882.AkRzjb.rst deleted file mode 100644 index 240b5680b36a2aa..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-02-11-29-15.bpo-29882.AkRzjb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :meth:`int.bit_count()`, counting the number of ones in the binary -representation of an integer. Patch by Niklas Fiekas. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-01-14-26-02.bpo-37999.XPl6dn.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-01-14-26-02.bpo-37999.XPl6dn.rst deleted file mode 100644 index 8d7e9369af4c6d3..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-01-14-26-02.bpo-37999.XPl6dn.rst +++ /dev/null @@ -1,5 +0,0 @@ -Builtin and extension functions that take integer arguments no longer accept -:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other -objects that can be converted to integers only with a loss (e.g. that have -the :meth:`~object.__int__` method but do not have the -:meth:`~object.__index__` method). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-05-02-35-08.bpo-1635741.Kfe9fT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-05-02-35-08.bpo-1635741.Kfe9fT.rst deleted file mode 100644 index 956d0b68a8dfb1b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-04-05-02-35-08.bpo-1635741.Kfe9fT.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`_lzma` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst deleted file mode 100644 index cb849fb9b44308c..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`mmap` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst deleted file mode 100644 index a13a8e88226830c..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of generators by not raising internal StopIteration. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-03-22-26-00.bpo-29590.aRz3l7.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-03-22-26-00.bpo-29590.aRz3l7.rst deleted file mode 100644 index 2570c4f2c7c0fd9..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-03-22-26-00.bpo-29590.aRz3l7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make the stack trace correct after calling :meth:`generator.throw` -on a generator that has yielded from a ``yield from``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-19-19-39-49.bpo-40679.SVzz9p.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-19-19-39-49.bpo-40679.SVzz9p.rst deleted file mode 100644 index 2d0a432b6fa69ae..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-19-19-39-49.bpo-40679.SVzz9p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Certain :exc:`TypeError` messages about missing or extra arguments now include the function's -:term:`qualified name`. Patch by Dennis Sweeney. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst deleted file mode 100644 index 43226931ccc88dd..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ /dev/null @@ -1,9 +0,0 @@ -Each interpreter now its has own free lists, singletons and caches: - -* Free lists: float, tuple, list, dict, frame, context, - asynchronous generator, MemoryError. -* Singletons: empty tuple, empty bytes string, empty Unicode string, - single byte character, single Unicode (latin1) character. -* Slice cache. - -They are no longer shared by all interpreters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-21-01-54-00.bpo-40696.u3n8Wx.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-21-01-54-00.bpo-40696.u3n8Wx.rst deleted file mode 100644 index f99bdea2e3177b0..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-21-01-54-00.bpo-40696.u3n8Wx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a hang that can arise after :meth:`generator.throw` due to a cycle -in the exception context chain. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-22-00-34-34.bpo-39573.QO2QHj.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-22-00-34-34.bpo-39573.QO2QHj.rst deleted file mode 100644 index 243003030426794..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-22-00-34-34.bpo-39573.QO2QHj.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`Py_TYPE()` is changed to the inline static function. Patch by -Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-23-01-15-51.bpo-40217.jZsHTc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-23-01-15-51.bpo-40217.jZsHTc.rst deleted file mode 100644 index b13e8eeb0634fad..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-23-01-15-51.bpo-40217.jZsHTc.rst +++ /dev/null @@ -1,4 +0,0 @@ -Instances of types created with :c:func:`PyType_FromSpecWithBases` will no -longer automatically visit their class object when traversing references in -the garbage collector. The user is expected to manually visit the object's -class. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-24-02-42-26.bpo-40750.ZmO9Ev.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-24-02-42-26.bpo-40750.ZmO9Ev.rst deleted file mode 100644 index 4032b8016903515..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-24-02-42-26.bpo-40750.ZmO9Ev.rst +++ /dev/null @@ -1 +0,0 @@ -Support the "-d" debug flag in the new PEG parser. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst deleted file mode 100644 index 120076430694662..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst +++ /dev/null @@ -1 +0,0 @@ -When there's a :exc:`SyntaxError` in the expression part of an fstring, the filename attribute of the :exc:`SyntaxError` gets correctly set to the name of the file the fstring resides in. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst deleted file mode 100644 index ed6020c2e235501..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a corner case where g-style string formatting of a float failed to -remove trailing zeros. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-27-22-37-58.bpo-40792.WEDqqU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-27-22-37-58.bpo-40792.WEDqqU.rst deleted file mode 100644 index 5986a221f5b37eb..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-27-22-37-58.bpo-40792.WEDqqU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Attributes ``start``, ``stop`` and ``step`` of the :class:`range` object now -always has exact type :class:`int`. Previously, they could have been an -instance of a subclass of ``int``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst deleted file mode 100644 index 73c593c04a0dad6..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-14-37-18.bpo-40824.XR3V5s.rst +++ /dev/null @@ -1,4 +0,0 @@ -Unexpected errors in calling the ``__iter__`` method are no longer masked by -``TypeError`` in the :keyword:`in` operator and functions -:func:`~operator.contains`, :func:`~operator.indexOf` and -:func:`~operator.countOf` of the :mod:`operator` module. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-18-35.bpo-19468.S-TA7p.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-18-35.bpo-19468.S-TA7p.rst deleted file mode 100644 index e35750e37f4da39..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-18-35.bpo-19468.S-TA7p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Delete unnecessary instance check in importlib.reload(). -Patch by Furkan Önder. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst deleted file mode 100644 index cd2bcb6e60877a1..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`fcntl` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst deleted file mode 100644 index a03ed180eb952b7..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception -and pass the Python thread state when checking if there is a pending signal. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst deleted file mode 100644 index 6ef4ed5af731862..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst +++ /dev/null @@ -1 +0,0 @@ -Allow overriding :data:`sys.platlibdir` via a new :envvar:`PYTHONPLATLIBDIR` environment variable. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst deleted file mode 100644 index 8e943a29f337fe0..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`ValueError` when validating custom AST's where the constants -``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst deleted file mode 100644 index ebeb0cc60d16bb4..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in when parsing f-strings in the new parser. Patch by Pablo Galindo \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst deleted file mode 100644 index ab42f5c205f81b4..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix invalid memory read in the new parser when checking newlines in string -literals. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst deleted file mode 100644 index 5ee72c14ad352b3..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a possible segfault in the new PEG parser when producing error messages for invalid assignments of the form :code:`p=p=`. Patch by Pablo Galindo \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst deleted file mode 100644 index 09009b18c63a341..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible segfault in the new PEG parser when parsing f-string containing -yield statements with no value (:code:`f"{yield}"`). Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst deleted file mode 100644 index 0ab1a261e3e6eec..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst +++ /dev/null @@ -1 +0,0 @@ -Improved the performance of symmetric difference operations on dictionary item views. Patch by Dennis Sweeney. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-09-00-20-13.bpo-40890.LoRV-g.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-09-00-20-13.bpo-40890.LoRV-g.rst deleted file mode 100644 index eaefc894a13a510..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-09-00-20-13.bpo-40890.LoRV-g.rst +++ /dev/null @@ -1 +0,0 @@ -Each dictionary view now has a ``mapping`` attribute that provides a :class:`types.MappingProxyType` wrapping the original dictionary. Patch contributed by Dennis Sweeney. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-09-23-52-32.bpo-40847.4XAACw.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-09-23-52-32.bpo-40847.4XAACw.rst deleted file mode 100644 index 0b489f248321593..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-09-23-52-32.bpo-40847.4XAACw.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix a bug where a line with only a line continuation character is not considered a blank line at tokenizer level. -In such cases, more than a single `NEWLINE` token was emitted. The old parser was working around the issue, -but the new parser threw a :exc:`SyntaxError` for valid input due to this. For example, an empty line following -a line continuation character was interpreted as a :exc:`SyntaxError`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-10-11-27-15.bpo-40939.DO-wAI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-10-11-27-15.bpo-40939.DO-wAI.rst deleted file mode 100644 index b12985d0816040a..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-10-11-27-15.bpo-40939.DO-wAI.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the old parser, the :mod:`parser` module and all associated support code, command-line options and environment variables. Patch by Pablo Galindo. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-11-16-06-49.bpo-40947.72cZcR.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-11-16-06-49.bpo-40947.72cZcR.rst deleted file mode 100644 index e7dfe06531a4d94..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-11-16-06-49.bpo-40947.72cZcR.rst +++ /dev/null @@ -1,2 +0,0 @@ -The Python :ref:`Path Configuration ` now takes -:c:member:`PyConfig.platlibdir` in account. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst deleted file mode 100644 index 925b5790f73f3de..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a state to the :mod:`nis` module (:pep:`3121`) and apply -the multiphase initialization. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-12-21-54.bpo-40957.Z8n6I6.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-12-21-54.bpo-40957.Z8n6I6.rst deleted file mode 100644 index f99c374f94aac94..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-12-21-54.bpo-40957.Z8n6I6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix refleak in _Py_fopen_obj() when PySys_Audit() fails diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-22-56-17.bpo-1635741.mmlp3Q.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-22-56-17.bpo-1635741.mmlp3Q.rst deleted file mode 100644 index ae12d25baa3adea..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-22-56-17.bpo-1635741.mmlp3Q.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`_dbm` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-15-01-20-44.bpo-40958.7O2Wh1.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-15-01-20-44.bpo-40958.7O2Wh1.rst deleted file mode 100644 index 8e36897948f9b47..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-15-01-20-44.bpo-40958.7O2Wh1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a possible buffer overflow in the PEG parser when gathering information -for emitting syntax errors. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst deleted file mode 100644 index e07134c7166adc1..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug that caused the :exc:`SyntaxError` text to be empty when a file ends with a line ending in a line continuation character (i.e. backslash). The error text should contain the text of the last line. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-17-00-52-21.bpo-1635741.61iyYh.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-17-00-52-21.bpo-1635741.61iyYh.rst deleted file mode 100644 index cffe70dd71eaf22..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-17-00-52-21.bpo-1635741.61iyYh.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`_gdbm` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-17-10-27-17.bpo-40636.MYaCIe.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-17-10-27-17.bpo-40636.MYaCIe.rst deleted file mode 100644 index ba26ad9373ce38e..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-17-10-27-17.bpo-40636.MYaCIe.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`zip` now supports :pep:`618`'s ``strict`` parameter, which raises a -:exc:`ValueError` if the arguments are exhausted at different lengths. -Patch by Brandt Bucher. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-18-00-07-09.bpo-41006.H-wN-d.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-18-00-07-09.bpo-41006.H-wN-d.rst deleted file mode 100644 index 4593e6bb89a9e9e..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-18-00-07-09.bpo-41006.H-wN-d.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``encodings.latin_1`` module is no longer imported at startup. Now it is -only imported when it is the filesystem encoding or the stdio encoding. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-18-19-04-30.bpo-40077._yI-ax.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-18-19-04-30.bpo-40077._yI-ax.rst deleted file mode 100644 index 2e0258a7b369d2f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-18-19-04-30.bpo-40077._yI-ax.rst +++ /dev/null @@ -1 +0,0 @@ -Convert :mod:`_bz2` to use :c:func:`PyType_FromSpec`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-16-59-02.bpo-40939.6810Ak.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-16-59-02.bpo-40939.6810Ak.rst deleted file mode 100644 index 8a626d479a91c54..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-16-59-02.bpo-40939.6810Ak.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the remaining files from the old parser and the :mod:`symbol` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-00-44.bpo-35975.UDHCHp.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-00-44.bpo-35975.UDHCHp.rst deleted file mode 100644 index 73f4a6da2e5c0a2..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-17-00-44.bpo-35975.UDHCHp.rst +++ /dev/null @@ -1,3 +0,0 @@ -Stefan Behnel reported that cf_feature_version is used even when -PyCF_ONLY_AST is not set. This is against the intention and against the -documented behavior, so it's been fixed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-19-27-47.bpo-40939.jxJ4yn.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-19-27-47.bpo-40939.jxJ4yn.rst deleted file mode 100644 index 7024dfe47ae1c73..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-19-27-47.bpo-40939.jxJ4yn.rst +++ /dev/null @@ -1 +0,0 @@ -Rename `PyPegen*` functions to `PyParser*`, so that we can remove the old set of `PyParser*` functions that were using the old parser, but keep everything backwards-compatible. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-22-46-18.bpo-41052.46MPeF.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-20-22-46-18.bpo-41052.46MPeF.rst deleted file mode 100644 index 82969bf4a789412..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-20-22-46-18.bpo-41052.46MPeF.rst +++ /dev/null @@ -1 +0,0 @@ -Opt out serialization/deserialization for _random.Random diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-21-10-54-02.bpo-41061.AHf9MU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-21-10-54-02.bpo-41061.AHf9MU.rst deleted file mode 100644 index b5bb81621b7f294..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-21-10-54-02.bpo-41061.AHf9MU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix incorrect expressions and asserts in hashtable code and tests. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-21-19-53-33.bpo-41056.IDu_EK.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-21-19-53-33.bpo-41056.IDu_EK.rst deleted file mode 100644 index 25f93c9da31051d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-21-19-53-33.bpo-41056.IDu_EK.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes a reference to deallocated stack space during startup when constructing sys.path involving a relative symlink when code was supplied via -c. (discovered via Coverity) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-22-13-22-30.bpo-41076.eWYw2N.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-22-13-22-30.bpo-41076.eWYw2N.rst deleted file mode 100644 index f13560ad9d26976..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-22-13-22-30.bpo-41076.eWYw2N.rst +++ /dev/null @@ -1 +0,0 @@ -Pre-feed the parser with the location of the f-string expression, not the f-string itself, which allows us to skip the shifting of the AST node locations after the parsing is completed. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst deleted file mode 100644 index 25f146e35ef439a..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst +++ /dev/null @@ -1 +0,0 @@ -Empty frozensets are no longer singletons. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst deleted file mode 100644 index cd349af770bd078..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst +++ /dev/null @@ -1 +0,0 @@ -Prefix the error message with 'f-string: ', when parsing an f-string expression which throws a :exc:`SyntaxError`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-18-32-41.bpo-39960.Kez3fP.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-18-32-41.bpo-39960.Kez3fP.rst deleted file mode 100644 index f69fccfa4db6949..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-18-32-41.bpo-39960.Kez3fP.rst +++ /dev/null @@ -1,2 +0,0 @@ -The "hackcheck" that prevents sneaking around a type's __setattr__() by calling the -superclass method was rewritten to allow C implemented heap types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-23-26-42.bpo-41094.zEIJse.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-23-26-42.bpo-41094.zEIJse.rst deleted file mode 100644 index 6dd45e21d17587d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-23-26-42.bpo-41094.zEIJse.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix decoding errors with audit when open files with non-ASCII names on non-UTF-8 -locale. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst deleted file mode 100644 index d6176d69f0eb0a4..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst +++ /dev/null @@ -1 +0,0 @@ -add arm64 to the allowable Mac OS arches in mpdecimal.h \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-20-17-31.bpo-41175.acJoXB.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-20-17-31.bpo-41175.acJoXB.rst deleted file mode 100644 index 844fb804c0c8d4d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-20-17-31.bpo-41175.acJoXB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Guard against a NULL pointer dereference within bytearrayobject triggered by -the ``bytearray() + bytearray()`` operation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-01-20-17-38.bpo-1635741.-AtPYu.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-01-20-17-38.bpo-1635741.-AtPYu.rst deleted file mode 100644 index c529923779fa84f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-01-20-17-38.bpo-1635741.-AtPYu.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`sha256` to multiphase initialization diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-03-23-10-02.bpo-1635741.F5coWe.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-03-23-10-02.bpo-1635741.F5coWe.rst deleted file mode 100644 index 927c8e5b7083fa3..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-03-23-10-02.bpo-1635741.F5coWe.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`faulthandler` to multiphase initialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-13-35-17.bpo-41218.oKnSr2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-06-13-35-17.bpo-41218.oKnSr2.rst deleted file mode 100644 index d98b3433ef05f76..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-13-35-17.bpo-41218.oKnSr2.rst +++ /dev/null @@ -1,4 +0,0 @@ -Python 3.8.3 had a regression where compiling with -ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension -with CO_COROUTINE. Now only list comprehension making use of async/await -will tagged as so. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-18-36-33.bpo-41215.vFGFIz.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-06-18-36-33.bpo-41215.vFGFIz.rst deleted file mode 100644 index 7343da31e94f78d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-18-36-33.bpo-41215.vFGFIz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use non-NULL default values in the PEG parser keyword list to overcome a bug that was preventing -Python from being properly compiled when using the XLC compiler. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst deleted file mode 100644 index 956fcd5d1ee29e0..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-06-20-43-19.bpo-1635741.LYhsni.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`winapi` to multiphase initialization diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst deleted file mode 100644 index 52e184dc3170741..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-07-16-10-52.bpo-1635741.zU-H_n.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`multiprocessing` to multi-phase initialization diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-08-21-55-23.bpo-41252.nBWL-Y.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-08-21-55-23.bpo-41252.nBWL-Y.rst deleted file mode 100644 index 65f3189c83ec64c..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-08-21-55-23.bpo-41252.nBWL-Y.rst +++ /dev/null @@ -1 +0,0 @@ -Fix incorrect refcounting in _ssl.c's ``_servername_callback()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst deleted file mode 100644 index 08699b6e4a1f017..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-08-22-03-54.bpo-41247.PndYIk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Always cache the running loop holder when running -``asyncio.set_running_loop``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-17-11-31-54.bpo-41323.ChbZHh.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-17-11-31-54.bpo-41323.ChbZHh.rst deleted file mode 100644 index 671d874b535afd7..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-17-11-31-54.bpo-41323.ChbZHh.rst +++ /dev/null @@ -1,3 +0,0 @@ -Bytecode optimizations are performed directly on the control flow graph. -This will result in slightly more compact code objects in some -circumstances. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-18-08-15-32.bpo-41295.pu8Ezo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-18-08-15-32.bpo-41295.pu8Ezo.rst deleted file mode 100644 index d61fd8f0a296837..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-18-08-15-32.bpo-41295.pu8Ezo.rst +++ /dev/null @@ -1,3 +0,0 @@ -Resolve a regression in CPython 3.8.4 where defining "__setattr__" in a -multi-inheritance setup and calling up the hierarchy chain could fail -if builtins/extension types were involved in the base types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-18-18-01-10.bpo-41334.t5xMGp.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-18-18-01-10.bpo-41334.t5xMGp.rst deleted file mode 100644 index 5d44527a561a118..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-18-18-01-10.bpo-41334.t5xMGp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Constructors :func:`str`, :func:`bytes` and :func:`bytearray` are now faster -(around 30--40% for small objects). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst deleted file mode 100644 index 38851a7f7fc0f40..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`round` with integer argument is now faster (9--60%). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-20-17-01-17.bpo-38156.ptcdRy.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-20-17-01-17.bpo-38156.ptcdRy.rst deleted file mode 100644 index 254d13cf3ed3a7f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-20-17-01-17.bpo-38156.ptcdRy.rst +++ /dev/null @@ -1 +0,0 @@ -Handle interrupts that come after EOF correctly in ``PyOS_StdioReadline``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-27-01-50-06.bpo-41340.pZXfcF.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-27-01-50-06.bpo-41340.pZXfcF.rst deleted file mode 100644 index 3a93a5769310703..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-27-01-50-06.bpo-41340.pZXfcF.rst +++ /dev/null @@ -1 +0,0 @@ -Removed fallback implementation for ``strdup``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst deleted file mode 100644 index a6652de92751177..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-07-28-22-43-27.bpo-41428.FM6xsI.rst +++ /dev/null @@ -1 +0,0 @@ -Implement PEP 604. This supports (int | str) etc. in place of Union[str, int]. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst deleted file mode 100644 index fa9d047edc39459..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-02-15-53-12.bpo-41431.TblUBT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize ``dict_merge()`` for copying dict (e.g. ``dict(d)`` and -``{}.update(d)``). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst deleted file mode 100644 index 12af3d01ed8eff4..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-10-16-11-32.bpo-1635741.O0d3ym.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_sha1`, :mod:`_sha512`, and :mod:`_md5` extension modules -to multi-phase initialization API (:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst deleted file mode 100644 index acc00f8b992c916..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-07-35-07.bpo-41525.d9q3XL.rst +++ /dev/null @@ -1 +0,0 @@ -The output of ``python --help`` contains now only ASCII characters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst deleted file mode 100644 index 8544664f39335d6..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-19-32-15.bpo-41531.WgPzjT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that was dropping keys when compiling dict literals with more than -0xFFFF elements. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst deleted file mode 100644 index e166f0c0b621a42..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-12-20-29-57.bpo-41533.4pcVAc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Free the stack allocated in ``va_build_stack`` if ``do_mkstack`` fails and -the stack is not a ``small_stack``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst deleted file mode 100644 index cdfee874095fe5c..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst +++ /dev/null @@ -1 +0,0 @@ -Port the :mod:`_blake2` extension module to the multi-phase initialization API (:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst deleted file mode 100644 index 73a4fdbac48a24d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-19-21.bpo-1653741.fubBkb.rst +++ /dev/null @@ -1 +0,0 @@ -Port :mod:`_sha3` to multi-phase init. Convert static types to heap types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst deleted file mode 100644 index ee950010e6d13f2..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-25-22-43-33.bpo-40077.vcxSUa.rst +++ /dev/null @@ -1 +0,0 @@ -Convert :mod:`_operator` to use :c:func:`PyType_FromSpec`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst deleted file mode 100644 index 68bb51024d9e705..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-26-11-23-31.bpo-41631.3jZcd9.rst +++ /dev/null @@ -1,5 +0,0 @@ -The ``_ast`` module uses again a global state. Using a module state per module -instance is causing subtle practical problems. For example, the Mercurial -project replaces the ``__import__()`` function to implement lazy import, -whereas Python expected that ``import _ast`` always return a fully initialized -``_ast`` module. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst deleted file mode 100644 index 4d6ce1185ed936c..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-28-20-54-04.bpo-1635741.7ijlcI.rst +++ /dev/null @@ -1 +0,0 @@ -Port the :mod:`zlib` extension module to multi-phase initialization (:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst deleted file mode 100644 index e05c3133e12625b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-30-20-38-33.bpo-41654.HtnhAM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash that occurred when destroying subclasses of -:class:`MemoryError`. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst deleted file mode 100644 index 6ad5fb6dc9bb403..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-11-37-59.bpo-41670.vmRJRx.rst +++ /dev/null @@ -1,4 +0,0 @@ -Prevent line trace being skipped on platforms not compiled -with ``USE_COMPUTED_GOTOS``. -Fixes issue where some lines nested within a try-except block -were not being traced on Windows. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst deleted file mode 100644 index aa102f8fe438458..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-14-53-17.bpo-41675.VSoqWU.rst +++ /dev/null @@ -1,3 +0,0 @@ -The implementation of :func:`signal.siginterrupt` now uses :c:func:`sigaction` -(if it is available in the system) instead of the deprecated :c:func:`siginterrupt`. -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst deleted file mode 100644 index ed557f92d85cac0..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-08-31-17-49-02.bpo-41681.3-VJiH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes the wrong error description in the error raised by using 2 `,` in -format string in f-string and :meth:`str.format`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst deleted file mode 100644 index c3bc9a78a2e054b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-06-02.bpo-1635741.5jZymK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_opcode` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst deleted file mode 100644 index a39673a26307a93..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-08-07.bpo-1635741.X9CZgo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_curses_panel` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst deleted file mode 100644 index 76f985bb87b4e9f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-22-35.bpo-1635741.CnRME3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_overlapped` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst deleted file mode 100644 index 5711aa5a55f0708..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-02-12-00-57.bpo-41690.Ny-Sfy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a possible stack overflow in the parser when parsing functions and -classes with a huge ammount of arguments. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst deleted file mode 100644 index 90e56542d1e97a2..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-09-45-47.bpo-1635741.QuDIut.rst +++ /dev/null @@ -1 +0,0 @@ -Convert the :mod:`_sha256` extension module types to heap types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst deleted file mode 100644 index 1e19b34b372d895..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-07-11-35-02.bpo-1635741.rvIexb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`termios` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst deleted file mode 100644 index 17752b2ccd3fad9..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-20-39-43.bpo-1635741.jiXmyT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_scproxy` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst deleted file mode 100644 index bc1a6c888e33bd1..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-08-21-58-47.bpo-1635741.vdjSLH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`cmath` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst deleted file mode 100644 index b387cfd94033c9b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-12-55-45.bpo-41756.1h0tbV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add PyGen_Send function to allow sending value into generator/coroutine -without raising StopIteration exception to signal return diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst deleted file mode 100644 index ba61819df9e082f..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-12-18-34-34.bpo-1635741.lh335O.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the :mod:`_lsprof` extension module to multi-phase initialization -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst deleted file mode 100644 index 9a7594fc453381b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-15-23-29-49.bpo-41780.bOBUIH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :meth:`__dir__` of :class:`types.GenericAlias`. Patch by Batuhan -Taskaya. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst deleted file mode 100644 index 92cd1ba234d215d..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-24-12-15-45.bpo-39934.YVHTCF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Correctly count control blocks in 'except' in compiler. Ensures that a -syntax error, rather a fatal error, occurs for deeply nested, named -exception handlers. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst deleted file mode 100644 index 252dab35a1368a0..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst +++ /dev/null @@ -1 +0,0 @@ -Port the :mod:`_bisect` module to the multi-phase initialization API (:pep:`489`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst deleted file mode 100644 index 13a6bb04a28fd0b..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-27-22-23-14.bpo-41870.2v6_v4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speed up calls to ``bool()`` by using the :pep:`590` ``vectorcall`` calling -convention. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst deleted file mode 100644 index ee2636704c29920..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-09-28-08-58-28.bpo-41873.VzEDhA.rst +++ /dev/null @@ -1 +0,0 @@ -Calls to ``float()`` are now faster due to the ``vectorcall`` calling convention. Patch by Dennis Sweeney. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst deleted file mode 100644 index 3c4de2c93555f20..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-01-02-58.bpo-41922.kHGT8I.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speed up calls to ``reversed()`` by using the :pep:`590` ``vectorcall`` -calling convention. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst deleted file mode 100644 index 388cfea065eedcb..000000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2020-10-04-10-55-12.bpo-41909.BqHPcm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed stack overflow in :func:`issubclass` and :func:`isinstance` when -getting the ``__bases__`` attribute leads to infinite recursion. diff --git a/Misc/NEWS.d/next/Documentation/2019-08-16-20-25-42.bpo-37703.Qm_l_H.rst b/Misc/NEWS.d/next/Documentation/2019-08-16-20-25-42.bpo-37703.Qm_l_H.rst deleted file mode 100644 index a1a1c354b1688b0..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-16-20-25-42.bpo-37703.Qm_l_H.rst +++ /dev/null @@ -1,2 +0,0 @@ -Updated Documentation to comprehensively elaborate on the behaviour of -gather.cancel() diff --git a/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst b/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst deleted file mode 100644 index 4941d50a560e2e5..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-03-07-03-53-39.bpo-39883.1tnb4-.rst +++ /dev/null @@ -1 +0,0 @@ -Make code, examples, and recipes in the Python documentation be licensed under the more permissive BSD0 license in addition to the existing Python 2.0 license. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-05-09-12-10-31.bpo-40552._0uB73.rst b/Misc/NEWS.d/next/Documentation/2020-05-09-12-10-31.bpo-40552._0uB73.rst deleted file mode 100644 index 5ed9c31834ac288..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-05-09-12-10-31.bpo-40552._0uB73.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix in tutorial section 4.2. -Code snippet is now correct. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst b/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst deleted file mode 100644 index b0ca4327ad61a42..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-07-21-15-23-30.bpo-40979.pLA8rO.rst +++ /dev/null @@ -1 +0,0 @@ -Refactored typing.rst, arranging more than 70 classes, functions, and decorators into new sub-sections. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-07-25-14-20-00.bpo-41314.yrjko0.rst b/Misc/NEWS.d/next/Documentation/2020-07-25-14-20-00.bpo-41314.yrjko0.rst deleted file mode 100644 index 48f9c933828b0d5..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-07-25-14-20-00.bpo-41314.yrjko0.rst +++ /dev/null @@ -1 +0,0 @@ -Changed the release when ``from __future__ import annotations`` becomes the default from ``4.0`` to ``3.10`` (following a change in PEP 563). diff --git a/Misc/NEWS.d/next/Documentation/2020-07-27-20-46-17.bpo-41045.GFF6Ul.rst b/Misc/NEWS.d/next/Documentation/2020-07-27-20-46-17.bpo-41045.GFF6Ul.rst deleted file mode 100644 index dfc9891bb89f278..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-07-27-20-46-17.bpo-41045.GFF6Ul.rst +++ /dev/null @@ -1 +0,0 @@ -Add documentation for debug feature of f-strings. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst b/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst deleted file mode 100644 index 152f6c98b900484..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-08-12-18-35-40.bpo-40204.C8A_pe.rst +++ /dev/null @@ -1,3 +0,0 @@ -Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable -``c_warn_on_allowed_pre_v3`` option to make the documentation compatible -with Sphinx 2 and Sphinx 3. diff --git a/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst b/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst deleted file mode 100644 index bdbc5a445f3390e..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-08-25-15-11-23.bpo-41624.ddjJlN.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the signature of :class:`typing.Coroutine`. diff --git a/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst b/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst deleted file mode 100644 index 1079a757c054ac9..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-09-08-16-57-09.bpo-41726.g0UXrn.rst +++ /dev/null @@ -1 +0,0 @@ -Update the refcounts info of ``PyType_FromModuleAndSpec``. diff --git a/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst b/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst deleted file mode 100644 index aeca652b4ed970b..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-09-10-07-48-02.bpo-37149.VD0rCv.rst +++ /dev/null @@ -1 +0,0 @@ -Change Shipman tkinter doc link from archive.org to TkDocs. (The doc has been removed from the NMT server.) The new link responds much faster and includes a short explanatory note. diff --git a/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst b/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst deleted file mode 100644 index 089d44e35d2baa5..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-09-12-17-37-13.bpo-35293._cOwPD.rst +++ /dev/null @@ -1 +0,0 @@ -Fix RemovedInSphinx40Warning when building the documentation. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst b/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst deleted file mode 100644 index af8e02437cb2b56..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst +++ /dev/null @@ -1,2 +0,0 @@ -In Programming FAQ "Sequences (Tuples/Lists)" section, add "How do you -remove multiple items from a list". diff --git a/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst b/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst deleted file mode 100644 index 2c3339345601977..000000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-10-03-18-20-46.bpo-41428._ju1NE.rst +++ /dev/null @@ -1 +0,0 @@ -Add documentation for :pep:`604` (Allow writing union types as ``X | Y``). diff --git a/Misc/NEWS.d/next/IDLE/2020-05-24-06-19-43.bpo-40723.AJLd4U.rst b/Misc/NEWS.d/next/IDLE/2020-05-24-06-19-43.bpo-40723.AJLd4U.rst deleted file mode 100644 index e0de2f9d836688c..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-05-24-06-19-43.bpo-40723.AJLd4U.rst +++ /dev/null @@ -1 +0,0 @@ -Make test_idle pass when run after import. diff --git a/Misc/NEWS.d/next/IDLE/2020-05-29-18-21-58.bpo-39885.zB_-bN.rst b/Misc/NEWS.d/next/IDLE/2020-05-29-18-21-58.bpo-39885.zB_-bN.rst deleted file mode 100644 index a847b75997117dc..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-05-29-18-21-58.bpo-39885.zB_-bN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make context menu Cut and Copy work again when right-clicking within a -selection. diff --git a/Misc/NEWS.d/next/IDLE/2020-06-27-17-02-00.bpo-41144.JoFGIX.rst b/Misc/NEWS.d/next/IDLE/2020-06-27-17-02-00.bpo-41144.JoFGIX.rst deleted file mode 100644 index ed558d3e7ded10d..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-06-27-17-02-00.bpo-41144.JoFGIX.rst +++ /dev/null @@ -1 +0,0 @@ -Make Open Module open a special module such as os.path. diff --git a/Misc/NEWS.d/next/IDLE/2020-06-29-14-51-15.bpo-41152.d6mV0C.rst b/Misc/NEWS.d/next/IDLE/2020-06-29-14-51-15.bpo-41152.d6mV0C.rst deleted file mode 100644 index 434be10b5309cf5..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-06-29-14-51-15.bpo-41152.d6mV0C.rst +++ /dev/null @@ -1,2 +0,0 @@ -The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE is now always -UTF-8. diff --git a/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst b/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst deleted file mode 100644 index f8b53ca482a21e8..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-07-07-18-44-30.bpo-37765.umc1o8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add keywords to module name completion list. Rewrite Completions -section of IDLE doc. diff --git a/Misc/NEWS.d/next/IDLE/2020-07-16-17-39-06.bpo-41300.wRixNb.rst b/Misc/NEWS.d/next/IDLE/2020-07-16-17-39-06.bpo-41300.wRixNb.rst deleted file mode 100644 index 080775f7d7ab44c..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-07-16-17-39-06.bpo-41300.wRixNb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Save files with non-ascii chars. Fix regression released in 3.9.0b4 and -3.8.4. diff --git a/Misc/NEWS.d/next/IDLE/2020-07-24-17-49-58.bpo-41373.YQIPu_.rst b/Misc/NEWS.d/next/IDLE/2020-07-24-17-49-58.bpo-41373.YQIPu_.rst deleted file mode 100644 index b50a72fe676a826..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-07-24-17-49-58.bpo-41373.YQIPu_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Save files loaded with no line ending, as when blank, or different line -endings, by setting its line ending to the system default. Fix regression in -3.8.4 and 3.9.0b4. diff --git a/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst b/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst deleted file mode 100644 index e41c7d574905cd5..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst +++ /dev/null @@ -1 +0,0 @@ -Improve IDLE run crash error message (which users should never see). diff --git a/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst b/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst deleted file mode 100644 index b6866e19c4d41ac..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-09-22-00-45-40.bpo-40181.hhQi3z.rst +++ /dev/null @@ -1,2 +0,0 @@ -In calltips, stop reminding that '/' marks the end of positional-only -arguments. diff --git a/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst b/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst deleted file mode 100644 index eb62d3699d5febb..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-09-22-11-13-45.bpo-35764.VoNa8y.rst +++ /dev/null @@ -1 +0,0 @@ -Rewrite the Calltips doc section. diff --git a/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst b/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst deleted file mode 100644 index 59605fa40235fb6..000000000000000 --- a/Misc/NEWS.d/next/IDLE/2020-09-24-14-31-16.bpo-41775.sB8Vre.rst +++ /dev/null @@ -1 +0,0 @@ -Use 'IDLE Shell' as shell title diff --git a/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst b/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst deleted file mode 100644 index 8b2e818383041a5..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-15-11-55-04.bpo-26680.eKAi85.rst +++ /dev/null @@ -1,3 +0,0 @@ -The x.is_integer() method is incorporated into the abstract types of the -numeric tower, Real, Rational and Integral, with appropriate default -implementations. diff --git a/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst b/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst deleted file mode 100644 index df75e080fa6ee09..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-15-11-56-48.bpo-26680.Udkhn4.rst +++ /dev/null @@ -1,2 +0,0 @@ -The d.is_integer() method is added to the Decimal type, for compatibility -with other number types. diff --git a/Misc/NEWS.d/next/Library/2018-06-07-22-04-01.bpo-28557.ViNJnK.rst b/Misc/NEWS.d/next/Library/2018-06-07-22-04-01.bpo-28557.ViNJnK.rst deleted file mode 100644 index 4137e2ff89beb11..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-06-07-22-04-01.bpo-28557.ViNJnK.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the error message for a misbehaving ``rawio.readinto`` diff --git a/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst b/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst deleted file mode 100644 index cce3dbb1c6ea5ba..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-06-12-23-30-41.bpo-33660.AdDn5Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix pathlib.PosixPath to resolve a relative path located on the root -directory properly. diff --git a/Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst b/Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst deleted file mode 100644 index 2656b4bf22ae4a1..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst +++ /dev/null @@ -1 +0,0 @@ -Fix `cgi.parse_multipart` without content_length. Patch by Roger Duran diff --git a/Misc/NEWS.d/next/Library/2018-07-30-12-48-17.bpo-31844.0_GKsD.rst b/Misc/NEWS.d/next/Library/2018-07-30-12-48-17.bpo-31844.0_GKsD.rst deleted file mode 100644 index 9034afd3284c4fb..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-07-30-12-48-17.bpo-31844.0_GKsD.rst +++ /dev/null @@ -1,4 +0,0 @@ -Remove ``ParserBase.error()`` method from the private and undocumented -``_markupbase`` module. :class:`html.parser.HTMLParser` is the only -subclass of ``ParserBase`` and its ``error()`` implementation was deprecated -in Python 3.4 and removed in Python 3.5. diff --git a/Misc/NEWS.d/next/Library/2018-08-21-16-20-33.bpo-29620.xxx666.rst b/Misc/NEWS.d/next/Library/2018-08-21-16-20-33.bpo-29620.xxx666.rst deleted file mode 100644 index d781919504e68e8..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-21-16-20-33.bpo-29620.xxx666.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`~unittest.TestCase.assertWarns` no longer raises a ``RuntimeException`` -when accessing a module's ``__warningregistry__`` causes importation of a new -module, or when a new module is imported in another thread. Patch by Kernc. diff --git a/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst b/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst deleted file mode 100644 index 123f9dabde91365..000000000000000 --- a/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst +++ /dev/null @@ -1,3 +0,0 @@ -Refactor formatweekday, formatmonthname methods in LocaleHTMLCalendar and LocaleTextCalendar classes in calendar module to call the base class methods.This enables customizable CSS classes for LocaleHTMLCalendar. -Patch by Srinivas Reddy Thatiparthy - diff --git a/Misc/NEWS.d/next/Library/2019-03-01-01-56-23.bpo-33944.-82Pkt.rst b/Misc/NEWS.d/next/Library/2019-03-01-01-56-23.bpo-33944.-82Pkt.rst deleted file mode 100644 index b0c953dd6752e95..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-01-01-56-23.bpo-33944.-82Pkt.rst +++ /dev/null @@ -1 +0,0 @@ -Added site.py site-packages tracing in verbose mode. diff --git a/Misc/NEWS.d/next/Library/2019-03-17-19-01-53.bpo-36290.7VXo_K.rst b/Misc/NEWS.d/next/Library/2019-03-17-19-01-53.bpo-36290.7VXo_K.rst deleted file mode 100644 index a9afe62b0c46e01..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-17-19-01-53.bpo-36290.7VXo_K.rst +++ /dev/null @@ -1,2 +0,0 @@ -AST nodes are now raising :exc:`TypeError` on conflicting keyword arguments. -Patch contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst b/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst deleted file mode 100644 index 80e2a7b5fbb2c08..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-31-23-54-28.bpo-12178.N6FLCZ.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`csv.writer` now correctly escapes *escapechar* when input -contains *escapechar*. Patch by Catalin Iacob, Berker Peksag, -and Itay Elbirt. diff --git a/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst b/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst deleted file mode 100644 index 8715b8d79cace1b..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`IMAP4.noop()` when debug mode is enabled (ex: ``imaplib.Debug = 3``). diff --git a/Misc/NEWS.d/next/Library/2019-09-12-21-34-03.bpo-38144.8uQCdd.rst b/Misc/NEWS.d/next/Library/2019-09-12-21-34-03.bpo-38144.8uQCdd.rst deleted file mode 100644 index 2c335bf29cfb395..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-21-34-03.bpo-38144.8uQCdd.rst +++ /dev/null @@ -1 +0,0 @@ -Added the *root_dir* and *dir_fd* parameters in :func:`glob.glob`. diff --git a/Misc/NEWS.d/next/Library/2019-10-25-23-45-49.bpo-35714.fw3xb7.rst b/Misc/NEWS.d/next/Library/2019-10-25-23-45-49.bpo-35714.fw3xb7.rst deleted file mode 100644 index 39102065ca7b516..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-25-23-45-49.bpo-35714.fw3xb7.rst +++ /dev/null @@ -1,2 +0,0 @@ -:exc:`struct.error` is now raised if there is a null character in a -:mod:`struct` format string. diff --git a/Misc/NEWS.d/next/Library/2019-11-13-07-37-11.bpo-38731.9qmcSx.rst b/Misc/NEWS.d/next/Library/2019-11-13-07-37-11.bpo-38731.9qmcSx.rst deleted file mode 100644 index ba9e522ecfcbf69..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-13-07-37-11.bpo-38731.9qmcSx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ``--quiet`` option to command-line interface of :mod:`py_compile`. -Patch by Gregory Schevchenko. diff --git a/Misc/NEWS.d/next/Library/2019-12-15-18-47-20.bpo-39040.tKa0Qs.rst b/Misc/NEWS.d/next/Library/2019-12-15-18-47-20.bpo-39040.tKa0Qs.rst deleted file mode 100644 index 078bce22be30f0d..000000000000000 --- a/Misc/NEWS.d/next/Library/2019-12-15-18-47-20.bpo-39040.tKa0Qs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix parsing of invalid mime headers parameters by collapsing whitespace between -encoded words in a bare-quote-string. diff --git a/Misc/NEWS.d/next/Library/2020-02-23-15-09-47.bpo-39244.aBK5IM.rst b/Misc/NEWS.d/next/Library/2020-02-23-15-09-47.bpo-39244.aBK5IM.rst deleted file mode 100644 index c7d8e0de676b5c0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-23-15-09-47.bpo-39244.aBK5IM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :class:`multiprocessing.context.get_all_start_methods` -to properly return the default method first on macOS. diff --git a/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst b/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst deleted file mode 100644 index beb2016a85ba682..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-02-24-10-58-34.bpo-39728.kOOaHn.rst +++ /dev/null @@ -1 +0,0 @@ -fix default `_missing_` so a duplicate `ValueError` is not set as the `__context__` of the original `ValueError` diff --git a/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst b/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst deleted file mode 100644 index 2e70f7aee65c835..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-03-11-07-44-06.bpo-31122.zIQ80l.rst +++ /dev/null @@ -1 +0,0 @@ -ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer closes connection during TLS negotiation \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst b/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst deleted file mode 100644 index 65ff4ce36e82eab..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-03-29-21-32-00.bpo-40084.MCYwcv.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes as well as methods. diff --git a/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst b/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst deleted file mode 100644 index f71a7a1e697a48e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-03-16-13-59.bpo-40105.hfM2c0.rst +++ /dev/null @@ -1,2 +0,0 @@ -ZipFile truncates files to avoid corruption when a shorter comment is provided -in append ("a") mode. Patch by Jan Mazur. diff --git a/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst b/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst deleted file mode 100644 index 3d5fcfb74a0fe58..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-18-14-16-02.bpo-40318.K2UdRx.rst +++ /dev/null @@ -1 +0,0 @@ -Use SQLite3 trace v2 API, if it is available. diff --git a/Misc/NEWS.d/next/Library/2020-04-20-22-08-36.bpo-23082.iX90Id.rst b/Misc/NEWS.d/next/Library/2020-04-20-22-08-36.bpo-23082.iX90Id.rst deleted file mode 100644 index 13ed0defe529cf2..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-20-22-08-36.bpo-23082.iX90Id.rst +++ /dev/null @@ -1 +0,0 @@ -Updated the error message and docs of PurePath.relative_to() to better reflect the function behaviour. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-04-23-18-21-19.bpo-39385.MIAyS7.rst b/Misc/NEWS.d/next/Library/2020-04-23-18-21-19.bpo-39385.MIAyS7.rst deleted file mode 100644 index e6c5c0dd4380b12..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-23-18-21-19.bpo-39385.MIAyS7.rst +++ /dev/null @@ -1,3 +0,0 @@ -A new test assertion context-manager, :func:`unittest.assertNoLogs` will -ensure a given block of code emits no log messages using the logging module. -Contributed by Kit Yan Choi. diff --git a/Misc/NEWS.d/next/Library/2020-05-06-02-01-25.bpo-13097.Wh5xSK.rst b/Misc/NEWS.d/next/Library/2020-05-06-02-01-25.bpo-13097.Wh5xSK.rst deleted file mode 100644 index a7f5f5882891746..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-06-02-01-25.bpo-13097.Wh5xSK.rst +++ /dev/null @@ -1 +0,0 @@ -``ctypes`` now raises an ``ArgumentError`` when a callback is invoked with more than 1024 arguments. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst b/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst deleted file mode 100644 index 1129cd7649b96a6..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst +++ /dev/null @@ -1,2 +0,0 @@ -PEP 554 for use in the test suite. -(Patch By Joannah Nanjekye) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-05-13-16-28-33.bpo-40611.ZCk0_c.rst b/Misc/NEWS.d/next/Library/2020-05-13-16-28-33.bpo-40611.ZCk0_c.rst deleted file mode 100644 index 50ef3ad200a5e00..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-13-16-28-33.bpo-40611.ZCk0_c.rst +++ /dev/null @@ -1 +0,0 @@ -:data:`~mmap.MAP_POPULATE` constant has now been added to the list of exported :mod:`mmap` module flags. diff --git a/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst b/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst deleted file mode 100644 index 468c1ac9eee17c3..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst +++ /dev/null @@ -1 +0,0 @@ -Restored the deprecated :mod:`xml.etree.cElementTree` module. diff --git a/Misc/NEWS.d/next/Library/2020-05-17-02-03-09.bpo-32309.KM9psl.rst b/Misc/NEWS.d/next/Library/2020-05-17-02-03-09.bpo-32309.KM9psl.rst deleted file mode 100644 index 6272c35edf4d573..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-17-02-03-09.bpo-32309.KM9psl.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added a new :term:`coroutine` :func:`asyncio.to_thread`. It is mainly used for -running IO-bound functions in a separate thread to avoid blocking the event -loop, and essentially works as a high-level version of -:meth:`~asyncio.loop.run_in_executor` that can directly take keyword arguments. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst b/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst deleted file mode 100644 index d38b88dbf356d2c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst +++ /dev/null @@ -1 +0,0 @@ -Prepare ``_hashlib`` for :pep:`489` and use :c:func:`PyModule_AddType`. diff --git a/Misc/NEWS.d/next/Library/2020-05-18-15-38-25.bpo-25920.PxrLY8.rst b/Misc/NEWS.d/next/Library/2020-05-18-15-38-25.bpo-25920.PxrLY8.rst deleted file mode 100644 index cc60e976286c33c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-18-15-38-25.bpo-25920.PxrLY8.rst +++ /dev/null @@ -1,7 +0,0 @@ -On macOS, when building Python for macOS 10.4 and older, which wasn't the case -for python.org macOS installer, :func:`socket.getaddrinfo` no longer uses an -internal lock to prevent race conditions when calling ``getaddrinfo()`` which -is thread-safe since macOS 10.5. Python 3.9 requires macOS 10.6 or newer. The -internal lock caused random hang on fork when another thread was calling -:func:`socket.getaddrinfo`. The lock was also used on FreeBSD older than 5.3, -OpenBSD older than 201311 and NetBSD older than 4. diff --git a/Misc/NEWS.d/next/Library/2020-05-18-17-29-30.bpo-40626.NeZufF.rst b/Misc/NEWS.d/next/Library/2020-05-18-17-29-30.bpo-40626.NeZufF.rst deleted file mode 100644 index fe652cd7ee39d61..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-18-17-29-30.bpo-40626.NeZufF.rst +++ /dev/null @@ -1 +0,0 @@ -Add h5 file extension as MIME Type application/x-hdf5, as per HDF Group recommendation for HDF5 formatted data files. Patch contributed by Mark Schwab. diff --git a/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst b/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst deleted file mode 100644 index 238b98c14a32692..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`ast.parse` will not parse self documenting expressions in f-strings when passed ``feature_version`` is less than ``(3, 8)``. diff --git a/Misc/NEWS.d/next/Library/2020-05-20-12-53-20.bpo-9216.ps7Yf1.rst b/Misc/NEWS.d/next/Library/2020-05-20-12-53-20.bpo-9216.ps7Yf1.rst deleted file mode 100644 index 37542e8caffd4dd..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-20-12-53-20.bpo-9216.ps7Yf1.rst +++ /dev/null @@ -1,3 +0,0 @@ -func:`hashlib.new` passed ``usedforsecurity`` to OpenSSL EVP constructor -``_hashlib.new()``. test_hashlib and test_smtplib handle strict security -policy better. diff --git a/Misc/NEWS.d/next/Library/2020-05-20-13-03-28.bpo-40695.lr4aIS.rst b/Misc/NEWS.d/next/Library/2020-05-20-13-03-28.bpo-40695.lr4aIS.rst deleted file mode 100644 index 643779bab494830..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-20-13-03-28.bpo-40695.lr4aIS.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`hashlib` no longer falls back to builtin hash implementations when -OpenSSL provides a hash digest and the algorithm is blocked by security -policy. diff --git a/Misc/NEWS.d/next/Library/2020-05-20-14-38-04.bpo-40698.zwl5Hc.rst b/Misc/NEWS.d/next/Library/2020-05-20-14-38-04.bpo-40698.zwl5Hc.rst deleted file mode 100644 index e57624819d54a77..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-20-14-38-04.bpo-40698.zwl5Hc.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`distutils` upload creates SHA2-256 and Blake2b-256 digests. MD5 -digests is skipped if platform blocks MD5. diff --git a/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst b/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst deleted file mode 100644 index 7409eb3d80df644..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-22-12-45-58.bpo-40726.7oBdMw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Handle cases where the ``end_lineno`` is ``None`` on -:func:`ast.increment_lineno`. diff --git a/Misc/NEWS.d/next/Library/2020-05-23-00-22-11.bpo-40737.iph-CM.rst b/Misc/NEWS.d/next/Library/2020-05-23-00-22-11.bpo-40737.iph-CM.rst deleted file mode 100644 index f068d3a091a03b0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-23-00-22-11.bpo-40737.iph-CM.rst +++ /dev/null @@ -1 +0,0 @@ -Fix possible reference leak for :mod:`sqlite3` initialization. diff --git a/Misc/NEWS.d/next/Library/2020-05-23-04-18-00.bpo-37129.YoYoYo.rst b/Misc/NEWS.d/next/Library/2020-05-23-04-18-00.bpo-37129.YoYoYo.rst deleted file mode 100644 index e025e96f4f1c05e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-23-04-18-00.bpo-37129.YoYoYo.rst +++ /dev/null @@ -1 +0,0 @@ -Add a new :data:`os.RWF_APPEND` flag for :func:`os.pwritev`. diff --git a/Misc/NEWS.d/next/Library/2020-05-24-11-06-37.bpo-40756.7ZH83z.rst b/Misc/NEWS.d/next/Library/2020-05-24-11-06-37.bpo-40756.7ZH83z.rst deleted file mode 100644 index a970f5be156f532..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-24-11-06-37.bpo-40756.7ZH83z.rst +++ /dev/null @@ -1,2 +0,0 @@ -The second argument (extra) of ``LoggerAdapter.__init__`` now defaults to -None. diff --git a/Misc/NEWS.d/next/Library/2020-05-24-23-52-35.bpo-40759.DdZdaw.rst b/Misc/NEWS.d/next/Library/2020-05-24-23-52-35.bpo-40759.DdZdaw.rst deleted file mode 100644 index e77da3ac3dfa93a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-24-23-52-35.bpo-40759.DdZdaw.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate the :mod:`symbol` module. diff --git a/Misc/NEWS.d/next/Library/2020-05-25-11-52-23.bpo-30064.6CICsH.rst b/Misc/NEWS.d/next/Library/2020-05-25-11-52-23.bpo-30064.6CICsH.rst deleted file mode 100644 index 904991dca16d88a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-25-11-52-23.bpo-30064.6CICsH.rst +++ /dev/null @@ -1 +0,0 @@ -Fix asyncio ``loop.sock_*`` race condition issue diff --git a/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst deleted file mode 100644 index c4cfa56ce02c585..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use -``no-deprecated`` and ``--api=1.1.0``. diff --git a/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst b/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst deleted file mode 100644 index 88b95998d085f67..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-00-09-52.bpo-16995.4niOT7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support the -Base32 Encoding with Extended Hex Alphabet. diff --git a/Misc/NEWS.d/next/Library/2020-05-27-17-00-18.bpo-40795.eZSnHA.rst b/Misc/NEWS.d/next/Library/2020-05-27-17-00-18.bpo-40795.eZSnHA.rst deleted file mode 100644 index dd02fb05cab5e7a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-17-00-18.bpo-40795.eZSnHA.rst +++ /dev/null @@ -1,4 +0,0 @@ -:mod:`ctypes` module: If ctypes fails to convert the result of a callback or -if a ctypes callback function raises an exception, sys.unraisablehook is now -called with an exception set. Previously, the error was logged into stderr -by :c:func:`PyErr_Print`. diff --git a/Misc/NEWS.d/next/Library/2020-05-27-18-04-52.bpo-40791.IzpNor.rst b/Misc/NEWS.d/next/Library/2020-05-27-18-04-52.bpo-40791.IzpNor.rst deleted file mode 100644 index b88f308ec3b5224..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-18-04-52.bpo-40791.IzpNor.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`hashlib.compare_digest` uses OpenSSL's ``CRYPTO_memcmp()`` function -when OpenSSL is available. diff --git a/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst deleted file mode 100644 index 4bebb311b4d546f..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`webbrowser` now properly finds the default browser in pure Wayland -systems by checking the WAYLAND_DISPLAY environment variable. Patch -contributed by Jérémy Attali. diff --git a/Misc/NEWS.d/next/Library/2020-05-27-22-19-42.bpo-40792.87Yx01.rst b/Misc/NEWS.d/next/Library/2020-05-27-22-19-42.bpo-40792.87Yx01.rst deleted file mode 100644 index 032a96c6a5cb6a8..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-27-22-19-42.bpo-40792.87Yx01.rst +++ /dev/null @@ -1,2 +0,0 @@ -The result of :func:`operator.index` now always has exact type :class:`int`. -Previously, the result could have been an instance of a subclass of ``int``. diff --git a/Misc/NEWS.d/next/Library/2020-05-28-16-51-00.bpo-38488.hFQNgA.rst b/Misc/NEWS.d/next/Library/2020-05-28-16-51-00.bpo-38488.hFQNgA.rst deleted file mode 100644 index c44da9fecb605bb..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-28-16-51-00.bpo-38488.hFQNgA.rst +++ /dev/null @@ -1 +0,0 @@ -Update ensurepip to install pip 20.1.1 and setuptools 47.1.0. diff --git a/Misc/NEWS.d/next/Library/2020-05-28-17-32-29.bpo-40777.1kJU6N.rst b/Misc/NEWS.d/next/Library/2020-05-28-17-32-29.bpo-40777.1kJU6N.rst deleted file mode 100644 index 761bc83562c34a0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-28-17-32-29.bpo-40777.1kJU6N.rst +++ /dev/null @@ -1,2 +0,0 @@ -Initialize PyDateTime_IsoCalendarDateType.tp_base at run-time to avoid -errors on some compilers. diff --git a/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst b/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst deleted file mode 100644 index 2d1d1f9a20e32e0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-30-08-10-23.bpo-40744.jKURVV.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`sqlite3` module uses SQLite API functions that require SQLite -v3.7.3 or higher. This patch removes support for older SQLite versions, and -explicitly requires SQLite 3.7.3 both at build, compile and runtime. Patch by -Sergey Fedoseev and Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2020-05-30-12-44-29.bpo-39384.Iqxy3q.rst b/Misc/NEWS.d/next/Library/2020-05-30-12-44-29.bpo-39384.Iqxy3q.rst deleted file mode 100644 index 482ae624da079de..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-30-12-44-29.bpo-39384.Iqxy3q.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed email.contentmanager to allow set_content() to set a null string. diff --git a/Misc/NEWS.d/next/Library/2020-05-30-14-19-47.bpo-26407.MjWLO1.rst b/Misc/NEWS.d/next/Library/2020-05-30-14-19-47.bpo-26407.MjWLO1.rst deleted file mode 100644 index d0e45cf1b1f2f41..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-30-14-19-47.bpo-26407.MjWLO1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Unexpected errors in calling the ``__iter__`` method are no longer masked -by ``TypeError`` in :func:`csv.reader`, :func:`csv.writer.writerow` and -:meth:`csv.writer.writerows`. diff --git a/Misc/NEWS.d/next/Library/2020-05-30-18-48-58.bpo-40755.IyOe2J.rst b/Misc/NEWS.d/next/Library/2020-05-30-18-48-58.bpo-40755.IyOe2J.rst deleted file mode 100644 index be5653ea58f275b..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-30-18-48-58.bpo-40755.IyOe2J.rst +++ /dev/null @@ -1 +0,0 @@ -Add rich comparisons to collections.Counter(). diff --git a/Misc/NEWS.d/next/Library/2020-05-31-15-52-18.bpo-40834.MO9_hb.rst b/Misc/NEWS.d/next/Library/2020-05-31-15-52-18.bpo-40834.MO9_hb.rst deleted file mode 100644 index 272783773ff9407..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-31-15-52-18.bpo-40834.MO9_hb.rst +++ /dev/null @@ -1 +0,0 @@ -Fix truncate when sending str object with_xxsubinterpreters.channel_send. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-05-31-23-32-36.bpo-17005.JlRUGB.rst b/Misc/NEWS.d/next/Library/2020-05-31-23-32-36.bpo-17005.JlRUGB.rst deleted file mode 100644 index 0fd01fb62309317..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-31-23-32-36.bpo-17005.JlRUGB.rst +++ /dev/null @@ -1,4 +0,0 @@ -The topological sort functionality that was introduced initially in the -:mod:`functools` module has been moved to a new :mod:`graphlib` module to -better accommodate the new tools and keep the original scope of the -:mod:`functools` module. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Library/2020-06-01-02-16-29.bpo-39314.0T9hlA.rst b/Misc/NEWS.d/next/Library/2020-06-01-02-16-29.bpo-39314.0T9hlA.rst deleted file mode 100644 index e805332efb62687..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-01-02-16-29.bpo-39314.0T9hlA.rst +++ /dev/null @@ -1,3 +0,0 @@ -:class:`rlcompleter.Completer` and the standard Python shell now close the -parenthesis for functions that take no arguments. Patch contributed by Rémi -Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst b/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst deleted file mode 100644 index 61753a57ca8b748..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst +++ /dev/null @@ -1 +0,0 @@ -Built-in loaders (SourceFileLoader and ZipImporter) now supply ``TraversableResources`` implementations for ``ResourceReader``, and the fallback function has been removed. diff --git a/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst b/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst deleted file mode 100644 index af284b06eaed6e3..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix reference leak in the :mod:`select` module when the module is -imported in a subinterpreter. diff --git a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst deleted file mode 100644 index c64a86295d7700e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). -from emitting each warning three times. diff --git a/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst b/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst deleted file mode 100644 index 73e0cbb013f8407..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst +++ /dev/null @@ -1 +0,0 @@ -Refresh importlib.metadata from importlib_metadata 1.6.1. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst b/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst deleted file mode 100644 index 75f62addbabbc52..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify error message in the :mod:`csv` module. diff --git a/Misc/NEWS.d/next/Library/2020-06-06-02-42-26.bpo-40884.n7fOwS.rst b/Misc/NEWS.d/next/Library/2020-06-06-02-42-26.bpo-40884.n7fOwS.rst deleted file mode 100644 index 64990e8023fba7c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-06-02-42-26.bpo-40884.n7fOwS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added a `defaults` parameter to :class:`logging.Formatter`, to allow -specifying default values for custom fields. Patch by Asaf Alon and Bar -Harel. diff --git a/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst b/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst deleted file mode 100644 index bc0756d02ddc9e8..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-06-14-09-55.bpo-33689.EFUDH7.rst +++ /dev/null @@ -1,4 +0,0 @@ -Ignore empty or whitespace-only lines in .pth files. This matches the -documentated behavior. Before, empty lines caused the site-packages -dir to appear multiple times in sys.path. -By Ido Michael, contributors Malcolm Smith and Tal Einat. diff --git a/Misc/NEWS.d/next/Library/2020-06-08-18-59-16.bpo-23427.ilg1Cz.rst b/Misc/NEWS.d/next/Library/2020-06-08-18-59-16.bpo-23427.ilg1Cz.rst deleted file mode 100644 index 37382975bb4fc23..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-08-18-59-16.bpo-23427.ilg1Cz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :data:`sys.orig_argv` attribute: the list of the original command line -arguments passed to the Python executable. diff --git a/Misc/NEWS.d/next/Library/2020-06-11-11-07-10.bpo-40939.-D5Asl.rst b/Misc/NEWS.d/next/Library/2020-06-11-11-07-10.bpo-40939.-D5Asl.rst deleted file mode 100644 index 0e831129dd87eb0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-11-11-07-10.bpo-40939.-D5Asl.rst +++ /dev/null @@ -1 +0,0 @@ -Use the new PEG parser when generating the stdlib :mod:`keyword` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-12-10-44-15.bpo-40855.jSot83.rst b/Misc/NEWS.d/next/Library/2020-06-12-10-44-15.bpo-40855.jSot83.rst deleted file mode 100644 index 201d510327a4785..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-12-10-44-15.bpo-40855.jSot83.rst +++ /dev/null @@ -1,2 +0,0 @@ -The standard deviation and variance functions in the statistics module were -ignoring their mu and xbar arguments. diff --git a/Misc/NEWS.d/next/Library/2020-06-12-11-55-30.bpo-40955.huixCg.rst b/Misc/NEWS.d/next/Library/2020-06-12-11-55-30.bpo-40955.huixCg.rst deleted file mode 100644 index 9a9803044ec96f4..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-12-11-55-30.bpo-40955.huixCg.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a minor memory leak in :mod:`subprocess` module when extra_groups was specified. diff --git a/Misc/NEWS.d/next/Library/2020-06-13-12-04-50.bpo-40924.SM_luS.rst b/Misc/NEWS.d/next/Library/2020-06-13-12-04-50.bpo-40924.SM_luS.rst deleted file mode 100644 index 4e4c6e88ac57296..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-13-12-04-50.bpo-40924.SM_luS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Ensure ``importlib.resources.path`` returns an extant path for the -SourceFileLoader's resource reader. Avoids the regression identified in -master while a long-term solution is devised. diff --git a/Misc/NEWS.d/next/Library/2020-06-15-00-13-57.bpo-40967._dx3OO.rst b/Misc/NEWS.d/next/Library/2020-06-15-00-13-57.bpo-40967._dx3OO.rst deleted file mode 100644 index 4694d991babd771..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-15-00-13-57.bpo-40967._dx3OO.rst +++ /dev/null @@ -1,2 +0,0 @@ -Removed :meth:`asyncio.Task.current_task` and -:meth:`asyncio.Task.all_tasks`. Patch contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2020-06-15-12-22-53.bpo-40448.1dk8Bu.rst b/Misc/NEWS.d/next/Library/2020-06-15-12-22-53.bpo-40448.1dk8Bu.rst deleted file mode 100644 index a755c5faa671c33..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-15-12-22-53.bpo-40448.1dk8Bu.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`ensurepip` now disables the use of `pip` cache when installing the -bundled versions of `pip` and `setuptools`. Patch by Krzysztof Konopko. diff --git a/Misc/NEWS.d/next/Library/2020-06-17-17-26-24.bpo-41002.NPBItE.rst b/Misc/NEWS.d/next/Library/2020-06-17-17-26-24.bpo-41002.NPBItE.rst deleted file mode 100644 index c3eebb7b9aed713..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-17-17-26-24.bpo-41002.NPBItE.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of HTTPResponse.read with a given amount. Patch by Bruce Merry. diff --git a/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst b/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst deleted file mode 100644 index f764323ae631cfc..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-17-23-49-45.bpo-35018.NP5_Qk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add the :class:`xml.sax.handler.LexicalHandler` class that is present in -other SAX XML implementations. diff --git a/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst b/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst deleted file mode 100644 index 21e184d0a40631e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-18-10-34-59.bpo-41025.elf_nz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed an issue preventing the C implementation of :class:`zoneinfo.ZoneInfo` -from being subclassed. diff --git a/Misc/NEWS.d/next/Library/2020-06-20-00-19-30.bpo-41043.p-Pk-H.rst b/Misc/NEWS.d/next/Library/2020-06-20-00-19-30.bpo-41043.p-Pk-H.rst deleted file mode 100644 index 9c6020eb8d73831..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-00-19-30.bpo-41043.p-Pk-H.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed the use of :func:`~glob.glob` in the stdlib: literal part of the path -is now always correctly escaped. diff --git a/Misc/NEWS.d/next/Library/2020-06-20-10-16-57.bpo-41048.hEXB-B.rst b/Misc/NEWS.d/next/Library/2020-06-20-10-16-57.bpo-41048.hEXB-B.rst deleted file mode 100644 index 2595900137d6965..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-10-16-57.bpo-41048.hEXB-B.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`mimetypes.read_mime_types` function reads the rule file using UTF-8 encoding, not the locale encoding. -Patch by Srinivas Reddy Thatiparthy. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-20-18-33-03.bpo-41056.gTH4Bq.rst b/Misc/NEWS.d/next/Library/2020-06-20-18-33-03.bpo-41056.gTH4Bq.rst deleted file mode 100644 index 0439d82a50ad12c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-18-33-03.bpo-41056.gTH4Bq.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed an instance where a MemoryError within the zoneinfo module might not be reported or not reported at its source. (found by Coverity) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-20-18-35-43.bpo-41056.Garcle.rst b/Misc/NEWS.d/next/Library/2020-06-20-18-35-43.bpo-41056.Garcle.rst deleted file mode 100644 index 1776f0d1cf8a32d..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-18-35-43.bpo-41056.Garcle.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a NULL pointer dereference within the ssl module during a MemoryError in the keylog callback. (discovered by Coverity) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-20-18-37-29.bpo-41056.d9v_uL.rst b/Misc/NEWS.d/next/Library/2020-06-20-18-37-29.bpo-41056.d9v_uL.rst deleted file mode 100644 index ddcc1102d5ed723..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-18-37-29.bpo-41056.d9v_uL.rst +++ /dev/null @@ -1 +0,0 @@ -Invalid file descriptor values are now prevented from being passed to os.fpathconf. (discovered by Coverity) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-06-20-21-03-55.bpo-41058.gztdZy.rst b/Misc/NEWS.d/next/Library/2020-06-20-21-03-55.bpo-41058.gztdZy.rst deleted file mode 100644 index 6ac90098aa52b06..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-20-21-03-55.bpo-41058.gztdZy.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`pdb.find_function` now correctly determines the source file encoding. diff --git a/Misc/NEWS.d/next/Library/2020-06-22-10-25-39.bpo-41068._bX2BW.rst b/Misc/NEWS.d/next/Library/2020-06-22-10-25-39.bpo-41068._bX2BW.rst deleted file mode 100644 index 20580c7886fac57..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-22-10-25-39.bpo-41068._bX2BW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed reading files with non-ASCII names from ZIP archive directly after -writing them. diff --git a/Misc/NEWS.d/next/Library/2020-06-22-20-08-40.bpo-31938.EVuko9.rst b/Misc/NEWS.d/next/Library/2020-06-22-20-08-40.bpo-31938.EVuko9.rst deleted file mode 100644 index 0488e94d42e8c5e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-22-20-08-40.bpo-31938.EVuko9.rst +++ /dev/null @@ -1 +0,0 @@ -Fix default-value signatures of several functions in the :mod:`select` module - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2020-06-23-06-09-59.bpo-40521.HUfxP7.rst b/Misc/NEWS.d/next/Library/2020-06-23-06-09-59.bpo-40521.HUfxP7.rst deleted file mode 100644 index 7689a1470b034da..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-23-06-09-59.bpo-40521.HUfxP7.rst +++ /dev/null @@ -1 +0,0 @@ -Remove freelist from collections.deque(). diff --git a/Misc/NEWS.d/next/Library/2020-06-25-10-11-47.bpo-31082.HsgDkx.rst b/Misc/NEWS.d/next/Library/2020-06-25-10-11-47.bpo-31082.HsgDkx.rst deleted file mode 100644 index 9746d33a4963800..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-25-10-11-47.bpo-31082.HsgDkx.rst +++ /dev/null @@ -1 +0,0 @@ -Use the term "iterable" in the docstring for :func:`functools.reduce`. diff --git a/Misc/NEWS.d/next/Library/2020-06-27-13-51-36.bpo-41138.bIpf7g.rst b/Misc/NEWS.d/next/Library/2020-06-27-13-51-36.bpo-41138.bIpf7g.rst deleted file mode 100644 index 839d430e89b6601..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-27-13-51-36.bpo-41138.bIpf7g.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed the :mod:`trace` module CLI for Python source files with non-UTF-8 -encoding. diff --git a/Misc/NEWS.d/next/Library/2020-06-28-21-16-51.bpo-40874.YImvzA.rst b/Misc/NEWS.d/next/Library/2020-06-28-21-16-51.bpo-40874.YImvzA.rst deleted file mode 100644 index a43eab8f4dcdd0d..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-28-21-16-51.bpo-40874.YImvzA.rst +++ /dev/null @@ -1 +0,0 @@ -The decimal module now requires libmpdec-2.5.0. diff --git a/Misc/NEWS.d/next/Library/2020-06-30-20-50-51.bpo-41161.QTdJjz.rst b/Misc/NEWS.d/next/Library/2020-06-30-20-50-51.bpo-41161.QTdJjz.rst deleted file mode 100644 index 0d8fb521bad5060..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-30-20-50-51.bpo-41161.QTdJjz.rst +++ /dev/null @@ -1,2 +0,0 @@ -The decimal module now requires libmpdec-2.5.0. Users of ---with-system-libmpdec should update their system library. diff --git a/Misc/NEWS.d/next/Library/2020-07-01-17-33-50.bpo-41182.FPFI0N.rst b/Misc/NEWS.d/next/Library/2020-07-01-17-33-50.bpo-41182.FPFI0N.rst deleted file mode 100644 index ae31db512abdc1d..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-01-17-33-50.bpo-41182.FPFI0N.rst +++ /dev/null @@ -1 +0,0 @@ -selector: use DefaultSelector based upon implementation diff --git a/Misc/NEWS.d/next/Library/2020-07-02-11-53-45.bpo-41193.8-Tnql.rst b/Misc/NEWS.d/next/Library/2020-07-02-11-53-45.bpo-41193.8-Tnql.rst deleted file mode 100644 index 8807d9c21febd59..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-02-11-53-45.bpo-41193.8-Tnql.rst +++ /dev/null @@ -1,4 +0,0 @@ -The ``write_history()`` atexit function of the readline completer now -ignores any :exc:`OSError` to ignore error if the filesystem is read-only, -instead of only ignoring :exc:`FileNotFoundError` and -:exc:`PermissionError`. diff --git a/Misc/NEWS.d/next/Library/2020-07-02-15-03-04.bpo-41195.cEnpO3.rst b/Misc/NEWS.d/next/Library/2020-07-02-15-03-04.bpo-41195.cEnpO3.rst deleted file mode 100644 index f96d5fadbdc7b83..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-02-15-03-04.bpo-41195.cEnpO3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add read-only ssl.SSLContext.security_level attribute to retrieve the -context's security level. diff --git a/Misc/NEWS.d/next/Library/2020-07-03-13-15-08.bpo-41194.djrKjs.rst b/Misc/NEWS.d/next/Library/2020-07-03-13-15-08.bpo-41194.djrKjs.rst deleted file mode 100644 index d63a0e5222ba9b9..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-03-13-15-08.bpo-41194.djrKjs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in the ``_ast`` module: it can no longer be loaded more than once. -It now uses a global state rather than a module state. diff --git a/Misc/NEWS.d/next/Library/2020-07-04-21-56-46.bpo-39168.DQWsXj.rst b/Misc/NEWS.d/next/Library/2020-07-04-21-56-46.bpo-39168.DQWsXj.rst deleted file mode 100644 index 667885eccd9c793..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-04-21-56-46.bpo-39168.DQWsXj.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the ``__new__`` method of :class:`typing.Generic`. diff --git a/Misc/NEWS.d/next/Library/2020-07-05-19-16-02.bpo-29727.Q6Z2rg.rst b/Misc/NEWS.d/next/Library/2020-07-05-19-16-02.bpo-29727.Q6Z2rg.rst deleted file mode 100644 index 85cfa4f89381122..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-05-19-16-02.bpo-29727.Q6Z2rg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Register :class:`array.array` as a -:class:`~collections.abc.MutableSequence`. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2020-07-06-16-58-53.bpo-41207.Emw7Nk.rst b/Misc/NEWS.d/next/Library/2020-07-06-16-58-53.bpo-41207.Emw7Nk.rst deleted file mode 100644 index db99c63f948837a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-06-16-58-53.bpo-41207.Emw7Nk.rst +++ /dev/null @@ -1 +0,0 @@ -In distutils.spawn, restore expectation that DistutilsExecError is raised when the command is not found. diff --git a/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst b/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst deleted file mode 100644 index c55275bb1c622b9..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the error handling in :meth:`ssl.SSLContext.load_dh_params`. diff --git a/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst b/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst deleted file mode 100644 index c08204b9908c635..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-11-00-15-01.bpo-41273.SVrsJh.rst +++ /dev/null @@ -1,3 +0,0 @@ -Speed up any transport using ``_ProactorReadPipeTransport`` by calling -``recv_into`` instead of ``recv``, thus not creating a new buffer for each -``recv`` call in the transport's read loop. diff --git a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst deleted file mode 100644 index ad26676f8b85633..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907). diff --git a/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst deleted file mode 100644 index 3c3adbabf16ff18..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now -UnpicklingError instead of crashing. diff --git a/Misc/NEWS.d/next/Library/2020-07-18-18-07-40.bpo-41333.upkHIm.rst b/Misc/NEWS.d/next/Library/2020-07-18-18-07-40.bpo-41333.upkHIm.rst deleted file mode 100644 index 73e8b1199772ded..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-18-18-07-40.bpo-41333.upkHIm.rst +++ /dev/null @@ -1 +0,0 @@ -:meth:`collections.OrderedDict.pop` is now 2 times faster. diff --git a/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst b/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst deleted file mode 100644 index 475bc9bddb0d54a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-20-13-27-48.bpo-41344.iKipNd.rst +++ /dev/null @@ -1 +0,0 @@ -Prevent creating :class:`shared_memory.SharedMemory` objects with :code:`size=0`. diff --git a/Misc/NEWS.d/next/Library/2020-07-20-19-13-17.bpo-41341.wqrj8C.rst b/Misc/NEWS.d/next/Library/2020-07-20-19-13-17.bpo-41341.wqrj8C.rst deleted file mode 100644 index c78b24d2faae720..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-20-19-13-17.bpo-41341.wqrj8C.rst +++ /dev/null @@ -1 +0,0 @@ -Recursive evaluation of `typing.ForwardRef` in `get_type_hints`. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-07-21-16-20-55.bpo-35328.jXovHb.rst b/Misc/NEWS.d/next/Library/2020-07-21-16-20-55.bpo-35328.jXovHb.rst deleted file mode 100644 index f4d1c6511d0d1cd..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-21-16-20-55.bpo-35328.jXovHb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Set the environment variable ``VIRTUAL_ENV_PROMPT`` at :mod:`venv` -activation. diff --git a/Misc/NEWS.d/next/Library/2020-07-21-21-45-55.bpo-41364.5O-k7A.rst b/Misc/NEWS.d/next/Library/2020-07-21-21-45-55.bpo-41364.5O-k7A.rst deleted file mode 100644 index f136e892ae5fe09..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-21-21-45-55.bpo-41364.5O-k7A.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce import overhead of :mod:`uuid`. diff --git a/Misc/NEWS.d/next/Library/2020-07-23-01-18-34.bpo-41317.O17Z6x.rst b/Misc/NEWS.d/next/Library/2020-07-23-01-18-34.bpo-41317.O17Z6x.rst deleted file mode 100644 index 1af985e90e3e989..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-23-01-18-34.bpo-41317.O17Z6x.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use add_done_callback() in asyncio.loop.sock_accept() to unsubscribe reader -early on cancellation. diff --git a/Misc/NEWS.d/next/Library/2020-07-26-21-18-43.bpo-41384.MlzIgV.rst b/Misc/NEWS.d/next/Library/2020-07-26-21-18-43.bpo-41384.MlzIgV.rst deleted file mode 100644 index d797374a09e6f60..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-26-21-18-43.bpo-41384.MlzIgV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise TclError instead of TypeError when an unknown option is passed to -tkinter.OptionMenu. diff --git a/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst b/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst deleted file mode 100644 index 139a170866ed49e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-28-12-08-58.bpo-41316.bSCbK4.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the :mod:`tarfile` module to write only basename of TAR file to GZIP compression header. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst b/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst deleted file mode 100644 index 3ee1f656d1870c5..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-30-14-56-58.bpo-41440.rju34k.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`os.cpu_count()` support for VxWorks RTOS. diff --git a/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst b/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst deleted file mode 100644 index cf291c60d8ad575..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-01-00-51-15.bpo-41421.dHKRVB.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make an algebraic simplification to random.paretovariate(). It now is -slightly less subject to round-off error and is slightly faster. Inputs that -used to cause ZeroDivisionError now cause an OverflowError instead. diff --git a/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst b/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst deleted file mode 100644 index 617df72faeb37f1..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-03-01-59-48.bpo-41425.KJo6zF.rst +++ /dev/null @@ -1 +0,0 @@ -Make tkinter doc example runnable. diff --git a/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst b/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst deleted file mode 100644 index f12693e117631a1..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-04-00-20-30.bpo-41467.Z8DgTL.rst +++ /dev/null @@ -1,3 +0,0 @@ -On Windows, fix asyncio ``recv_into()`` return value when the socket/pipe is -closed (:exc:`BrokenPipeError`): return ``0`` rather than an empty byte -string (``b''``). diff --git a/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst b/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst deleted file mode 100644 index 2c863ed7ffa3fad..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-07-06-06-29.bpo-41497.aBtsWz.rst +++ /dev/null @@ -1 +0,0 @@ -Fix potential UnicodeDecodeError in dis module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst b/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst deleted file mode 100644 index c34996d881937b7..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a race between setTarget and flush in logging.handlers.MemoryHandler. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst b/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst deleted file mode 100644 index cfb9f98c376a020..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-09-18-16-05.bpo-41513.e6K6EK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Minor algorithmic improvement to math.hypot() and math.dist() giving small -gains in speed and accuracy. diff --git a/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst b/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst deleted file mode 100644 index a4ba57c2438ed65..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-12-07-43-31.bpo-41528.bu83oD.rst +++ /dev/null @@ -1 +0,0 @@ -turtle uses math module functions to convert degrees to radians and vice versa and to calculate vector norm \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst b/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst deleted file mode 100644 index 0e140d91bb4b61c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-12-13-25-16.bpo-41520.BEUWa4.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`codeop` regression that prevented turning compile warnings into errors. diff --git a/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst b/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst deleted file mode 100644 index d4c7e0e2419df44..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-13-08-07-25.bpo-40782.aGZqmB.rst +++ /dev/null @@ -1 +0,0 @@ -Change the method asyncio.AbstractEventLoop.run_in_executor to not be a coroutine. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst b/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst deleted file mode 100644 index 694fbbbf346dc8a..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-15-15-21-40.bpo-37658.f9nivB.rst +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`asyncio.wait_for` now properly handles races between cancellation of -itself and the completion of the wrapped awaitable. diff --git a/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst b/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst deleted file mode 100644 index c172ce5d9e94870..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-15-15-50-12.bpo-32751.85je5X.rst +++ /dev/null @@ -1,3 +0,0 @@ -When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now -wait until the cancellation is complete also in the case when *timeout* is -<= 0, like it does with positive timeouts. diff --git a/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst b/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst deleted file mode 100644 index 46876c15ea199c9..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed pprint's handling of dict subclasses that override __repr__. diff --git a/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst b/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst deleted file mode 100644 index ecaf40eee7babfd..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-21-15-51-15.bpo-41609.JmiUKG.rst +++ /dev/null @@ -1 +0,0 @@ -The pdb whatis command correctly reports instance methods as 'Method' rather than 'Function'. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst b/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst deleted file mode 100644 index b4d0d9b63cf87d4..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-23-14-23-18.bpo-41513.DGqc_I.rst +++ /dev/null @@ -1,3 +0,0 @@ -Improved the accuracy of math.hypot(). Internally, each step is computed -with extra precision so that the result is now almost always correctly -rounded. diff --git a/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst b/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst deleted file mode 100644 index 0571c2d110beebf..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-29-16-07-36.bpo-41662.Mn79zh.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed crash when mutate list of parameters during iteration in :mod:`sqlite3`. diff --git a/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst b/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst deleted file mode 100644 index 8ab7b5e9903dcbf..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-29-16-45-12.bpo-41638.iZfW5N.rst +++ /dev/null @@ -1,3 +0,0 @@ -:exc:`~sqlite3.ProgrammingError` message for absent parameter in :mod:`sqlite3` -contains now the name of the parameter instead of its index when parameters -are supplied as a dict. diff --git a/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst b/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst deleted file mode 100644 index 0d9015b490e4cbe..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-30-10-24-26.bpo-39010._mzXJW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restarting a ``ProactorEventLoop`` on Windows no longer logs spurious -``ConnectionResetErrors``. diff --git a/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst b/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst deleted file mode 100644 index aecb0a1ea4d08f8..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-08-30-21-38-57.bpo-41662.6e9iZn.rst +++ /dev/null @@ -1,2 +0,0 @@ -No longer override exceptions raised in ``__len__()`` of a sequence of -parameters in :mod:`sqlite3` with :exc:`~sqlite3.ProgrammingError`. diff --git a/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst b/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst deleted file mode 100644 index 284f500735701ef..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-01-15-57-51.bpo-41687.m1b1KA.rst +++ /dev/null @@ -1 +0,0 @@ -Fix implementation of sendfile to be compatible with Solaris. diff --git a/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst b/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst deleted file mode 100644 index 67bbbb857f18cb0..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-03-01-35-32.bpo-41696.zkYGre.rst +++ /dev/null @@ -1 +0,0 @@ -Fix handling of debug mode in :func:`asyncio.run`. This allows setting ``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode when using :func:`asyncio.run`. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst b/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst deleted file mode 100644 index 5d2a5094ddeaa66..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-04-20-45-38.bpo-41720.PW9MzZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not int or -float. diff --git a/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst b/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst deleted file mode 100644 index caf237f37f4dee2..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-06-20-27-10.bpo-41732.1SKv26.rst +++ /dev/null @@ -1 +0,0 @@ -Added an :term:`iterator` to :class:`memoryview`. diff --git a/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst b/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst deleted file mode 100644 index 972d69b94b6ba6c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-08-13-51-16.bpo-1635741.wkPeoT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the ``_string`` extension module to the multi-phase initialization API -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst b/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst deleted file mode 100644 index 8b5bd5efdc2c09e..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-08-13-55-34.bpo-1635741.56MLP-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port the ``mashal`` extension module to the multi-phase initialization API -(:pep:`489`). diff --git a/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst b/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst deleted file mode 100644 index 78dcff137002927..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-11-12-38-55.bpo-39651.JMp9l2.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a race condition in the ``call_soon_threadsafe()`` method of -``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has been -closed. diff --git a/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst b/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst deleted file mode 100644 index d5832b9767b7041..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst +++ /dev/null @@ -1 +0,0 @@ -`enum.Flag` and `enum.IntFlag` members are now iterable diff --git a/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst b/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst deleted file mode 100644 index 5ce7a3ca67b7250..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-14-19-27-46.bpo-41789.pI_uZQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Honor `object` overrides in `Enum` class creation (specifically, `__str__`, -`__repr__`, `__format__`, and `__reduce_ex__`). diff --git a/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst b/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst deleted file mode 100644 index fbbc6724ba51ec6..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst +++ /dev/null @@ -1,6 +0,0 @@ -Add is_typeddict function to typing.py to check if a type is a TypedDict -class - -Previously there was no way to check that without using private API. See the -`relevant issue in python/typing -` diff --git a/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst b/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst deleted file mode 100644 index e2f2b64867bedbf..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-15-14-56-13.bpo-39587.69xzuh.rst +++ /dev/null @@ -1 +0,0 @@ -use the correct mix-in data type when constructing Enums diff --git a/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst b/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst deleted file mode 100644 index e7654711062cef9..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-15-22-43-30.bpo-41517.sLBH7g.rst +++ /dev/null @@ -1 +0,0 @@ -fix bug allowing Enums to be extended via multiple inheritance diff --git a/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst b/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst deleted file mode 100644 index 605c346f37a81d8..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-19-12-22-08.bpo-41816.ynynXJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -StrEnum added: it ensures that all members are already strings or string -candidates diff --git a/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst b/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst deleted file mode 100644 index 3560db9bc5d355b..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix SQLite3 segfault when backing up closed database. Patch contributed by -Peter David McCormick. diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst deleted file mode 100644 index 515aea9e36ce956..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst +++ /dev/null @@ -1,3 +0,0 @@ -:data:`types.EllipsisType`, :data:`types.NotImplementedType` and -:data:`types.NoneType` have been reintroduced, providing a new set -of types readily interpretable by static type checkers. diff --git a/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst b/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst deleted file mode 100644 index 6a634bb613260b6..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-22-00-23-30.bpo-41817.bnh-VG.rst +++ /dev/null @@ -1 +0,0 @@ -fix `tkinter.EventType` Enum so all members are strings, and none are tuples diff --git a/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst b/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst deleted file mode 100644 index abb3a077d91b814..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-22-13-51-14.bpo-41833.6HVDjT.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :class:`threading.Thread` constructor now uses the target name if the -*target* argument is specified but the *name* argument is omitted. diff --git a/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst b/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst deleted file mode 100644 index 0436194d736ab4f..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-22-14-55-34.bpo-40670.R5sm68.rst +++ /dev/null @@ -1,3 +0,0 @@ -More reliable validation of statements in :class:`timeit.Timer`. It now -accepts "empty" statements (only whitespaces and comments) and rejects -misindentent statements. diff --git a/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst b/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst deleted file mode 100644 index 085534734ec948d..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-23-03-33-37.bpo-40564.iXQqMq.rst +++ /dev/null @@ -1 +0,0 @@ -In ``zipfile.Path``, mutate the passed ZipFile object type instead of making a copy. Prevents issues when both the local copy and the caller’s copy attempt to close the same file handle. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst b/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst deleted file mode 100644 index 306b02d76fffe2c..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-23-22-52-24.bpo-41842.lIuhC9.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`codecs.unregister` function to unregister a codec search function. diff --git a/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst b/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst deleted file mode 100644 index e96942d8ebd07f5..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-23-23-17-59.bpo-41840.QRFr4L.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug in the :mod:`symtable` module that was causing module-scope global -variables to not be reported as both local and global. Patch by Pablo -Galindo. diff --git a/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst b/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst deleted file mode 100644 index cef7ff0188354e8..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-28-23-22-25.bpo-41773.oKkus0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Note in documentation that :func:`random.choices` doesn't support non-finite -weights, raise :exc:`ValueError` when given non-finite weights. diff --git a/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst b/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst deleted file mode 100644 index 2a43ab3f2890c78..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-30-23-49-42.bpo-41887.-ee2S-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document -stripping of spaces and tabs for :func:`eval`. diff --git a/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst b/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst deleted file mode 100644 index 6586c09ec985d52..000000000000000 --- a/Misc/NEWS.d/next/Library/2020-10-01-10-50-12.bpo-41900.Cho7oh.rst +++ /dev/null @@ -1,2 +0,0 @@ -C14N 2.0 serialisation in xml.etree.ElementTree failed for unprefixed attributes -when a default namespace was defined. diff --git a/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst deleted file mode 100644 index 990affc3edd9d8f..000000000000000 --- a/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent http header injection by rejecting control characters in -http.client.putrequest(...). diff --git a/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst deleted file mode 100644 index 1380b31fbe9f411..000000000000000 --- a/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst +++ /dev/null @@ -1 +0,0 @@ -The __hash__() methods of ipaddress.IPv4Interface and ipaddress.IPv6Interface incorrectly generated constant hash values of 32 and 128 respectively. This resulted in always causing hash collisions. The fix uses hash() to generate hash values for the tuple of (address, mask length, network address). diff --git a/Misc/NEWS.d/next/Security/2020-07-03-17-21-37.bpo-29778.cR_fGS.rst b/Misc/NEWS.d/next/Security/2020-07-03-17-21-37.bpo-29778.cR_fGS.rst deleted file mode 100644 index 998ffb1ee666777..000000000000000 --- a/Misc/NEWS.d/next/Security/2020-07-03-17-21-37.bpo-29778.cR_fGS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure :file:`python3.dll` is loaded from correct locations when Python is -embedded (CVE-2020-15523). diff --git a/Misc/NEWS.d/next/Security/2020-07-03-20-41-29.bpo-41162.tb8pVj.rst b/Misc/NEWS.d/next/Security/2020-07-03-20-41-29.bpo-41162.tb8pVj.rst deleted file mode 100644 index f0333ac4a7bb320..000000000000000 --- a/Misc/NEWS.d/next/Security/2020-07-03-20-41-29.bpo-41162.tb8pVj.rst +++ /dev/null @@ -1 +0,0 @@ -Audit hooks are now cleared later during finalization to avoid missing events. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst b/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst deleted file mode 100644 index 8cc4bb8d280a720..000000000000000 --- a/Misc/NEWS.d/next/Security/2020-07-15-20-15-08.bpo-41304.vNEeYA.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes `python3x._pth` being ignored on Windows, caused by the fix for :issue:`29778` (CVE-2020-15801). diff --git a/Misc/NEWS.d/next/Tests/2018-08-20-09-38-52.bpo-34401.eGxMPm.rst b/Misc/NEWS.d/next/Tests/2018-08-20-09-38-52.bpo-34401.eGxMPm.rst deleted file mode 100644 index 1b28d94c056d456..000000000000000 --- a/Misc/NEWS.d/next/Tests/2018-08-20-09-38-52.bpo-34401.eGxMPm.rst +++ /dev/null @@ -1 +0,0 @@ -Make test_gdb properly run on HP-UX. Patch by Michael Osipov. diff --git a/Misc/NEWS.d/next/Tests/2019-09-14-13-20-27.bpo-38169.hurq4B.rst b/Misc/NEWS.d/next/Tests/2019-09-14-13-20-27.bpo-38169.hurq4B.rst deleted file mode 100644 index 3972b9d440a8719..000000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-14-13-20-27.bpo-38169.hurq4B.rst +++ /dev/null @@ -1 +0,0 @@ -Increase code coverage for SharedMemory and ShareableList diff --git a/Misc/NEWS.d/next/Tests/2020-04-09-15-40-03.bpo-31904.TJ4k3d.rst b/Misc/NEWS.d/next/Tests/2020-04-09-15-40-03.bpo-31904.TJ4k3d.rst deleted file mode 100644 index 40d232ec2f1e4f9..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-04-09-15-40-03.bpo-31904.TJ4k3d.rst +++ /dev/null @@ -1 +0,0 @@ -Increase LOOPBACK_TIMEOUT to 10 for VxWorks RTOS. diff --git a/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst b/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst deleted file mode 100644 index 0a4b329b802e36b..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst +++ /dev/null @@ -1 +0,0 @@ -Skip some :mod:`multiprocessing` tests when MD5 hash digest is blocked. diff --git a/Misc/NEWS.d/next/Tests/2020-06-09-18-48-18.bpo-40927.67ylLg.rst b/Misc/NEWS.d/next/Tests/2020-06-09-18-48-18.bpo-40927.67ylLg.rst deleted file mode 100644 index 66209b84c94d690..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-09-18-48-18.bpo-40927.67ylLg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_binhex when run twice: it now uses import_fresh_module() to ensure -that it raises DeprecationWarning each time. diff --git a/Misc/NEWS.d/next/Tests/2020-06-12-20-46-23.bpo-40964.OBzf2c.rst b/Misc/NEWS.d/next/Tests/2020-06-12-20-46-23.bpo-40964.OBzf2c.rst deleted file mode 100644 index abfe4f0da4351c4..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-12-20-46-23.bpo-40964.OBzf2c.rst +++ /dev/null @@ -1,2 +0,0 @@ -Disable remote :mod:`imaplib` tests, host cyrus.andrew.cmu.edu is blocking -incoming connections. diff --git a/Misc/NEWS.d/next/Tests/2020-06-17-15-07-14.bpo-41003.tiH_Fy.rst b/Misc/NEWS.d/next/Tests/2020-06-17-15-07-14.bpo-41003.tiH_Fy.rst deleted file mode 100644 index 6f908d99feaf755..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-17-15-07-14.bpo-41003.tiH_Fy.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``test_copyreg`` when ``numpy`` is installed: ``test.pickletester`` now -saves/restores warnings filters when importing ``numpy``, to ignore filters -installed by ``numpy``. diff --git a/Misc/NEWS.d/next/Tests/2020-06-17-17-27-07.bpo-41009.Rvn6OQ.rst b/Misc/NEWS.d/next/Tests/2020-06-17-17-27-07.bpo-41009.Rvn6OQ.rst deleted file mode 100644 index 1208c119a35562d..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-17-17-27-07.bpo-41009.Rvn6OQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix use of ``support.require_{linux|mac|freebsd}_version()`` decorators as -class decorator. diff --git a/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst b/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst deleted file mode 100644 index 11a30761d36c9e0..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-17-18-00-21.bpo-38377.jfg4TH.rst +++ /dev/null @@ -1,4 +0,0 @@ -On Linux, skip tests using multiprocessing if the current user cannot create -a file in ``/dev/shm/`` directory. Add the -:func:`~test.support.skip_if_broken_multiprocessing_synchronize` function to -the :mod:`test.support` module. diff --git a/Misc/NEWS.d/next/Tests/2020-06-22-00-21-12.bpo-41069.bLZkX-.rst b/Misc/NEWS.d/next/Tests/2020-06-22-00-21-12.bpo-41069.bLZkX-.rst deleted file mode 100644 index 14bbd1a39a4cd0e..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-22-00-21-12.bpo-41069.bLZkX-.rst +++ /dev/null @@ -1,2 +0,0 @@ -:data:`test.support.TESTFN` and the current directory for tests when run via -``test.regrtest`` contain now non-ascii characters if possible. diff --git a/Misc/NEWS.d/next/Tests/2020-06-23-12-02-45.bpo-41085.JZKsyz.rst b/Misc/NEWS.d/next/Tests/2020-06-23-12-02-45.bpo-41085.JZKsyz.rst deleted file mode 100644 index 463dffdd653eeb0..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-06-23-12-02-45.bpo-41085.JZKsyz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix integer overflow in the :meth:`array.array.index` method on 64-bit Windows -for index larger than ``2**31``. diff --git a/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst b/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst deleted file mode 100644 index bf0f54abecd85d6..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-08-07-17-28-49.bpo-41477.GrFexU.rst +++ /dev/null @@ -1 +0,0 @@ -Make ctypes optional in test_genericalias. diff --git a/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst b/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst deleted file mode 100644 index 658372b1a7f2230..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-08-11-14-59-13.bpo-41521.w2UYK7.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`test.support`: Rename ``blacklist`` parameter of -:func:`~test.support.check__all__` to ``not_exported``. diff --git a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst b/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst deleted file mode 100644 index fa3d2f1aa374ec5..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-08-25-19-25-36.bpo-41602.Z64s0I.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for SIGINT handling in the runpy module. diff --git a/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst b/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst deleted file mode 100644 index e368a60f77b1ea7..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-09-11-19-12-31.bpo-41731.Ivxh4U.rst +++ /dev/null @@ -1 +0,0 @@ -Make test_cmd_line_script pass with option '-vv'. diff --git a/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst b/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst deleted file mode 100644 index e58ad2616da1ba4..000000000000000 --- a/Misc/NEWS.d/next/Tests/2020-10-05-09-37-43.bpo-41939.P4OlbA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_site.test_license_exists_at_url(): call -``urllib.request.urlcleanup()`` to reset the global -``urllib.request._opener``. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Windows/2019-07-11-06-11-09.bpo-37556.sygMUU.rst b/Misc/NEWS.d/next/Windows/2019-07-11-06-11-09.bpo-37556.sygMUU.rst deleted file mode 100644 index e8af96421b84532..000000000000000 --- a/Misc/NEWS.d/next/Windows/2019-07-11-06-11-09.bpo-37556.sygMUU.rst +++ /dev/null @@ -1 +0,0 @@ -Extend py.exe help to mention overrides via venv, shebang, environmental variables & ini files. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-05-19-04-11-12.bpo-40677.qQbLW8.rst b/Misc/NEWS.d/next/Windows/2020-05-19-04-11-12.bpo-40677.qQbLW8.rst deleted file mode 100644 index a09cb243aba3123..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-05-19-04-11-12.bpo-40677.qQbLW8.rst +++ /dev/null @@ -1 +0,0 @@ -Manually define IO_REPARSE_TAG_APPEXECLINK in case some old Windows SDK doesn't have it. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-05-19-14-43-33.bpo-39631.Z5yXam.rst b/Misc/NEWS.d/next/Windows/2020-05-19-14-43-33.bpo-39631.Z5yXam.rst deleted file mode 100644 index 38db4b431b6af6e..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-05-19-14-43-33.bpo-39631.Z5yXam.rst +++ /dev/null @@ -1,2 +0,0 @@ -Changes the registered MIME type for ``.py`` files on Windows to -``text/x-python`` instead of ``text/plain``. diff --git a/Misc/NEWS.d/next/Windows/2020-06-12-13-13-44.bpo-40164.SPrSn5.rst b/Misc/NEWS.d/next/Windows/2020-06-12-13-13-44.bpo-40164.SPrSn5.rst deleted file mode 100644 index 6390de717d71fbf..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-06-12-13-13-44.bpo-40164.SPrSn5.rst +++ /dev/null @@ -1 +0,0 @@ -Updates Windows OpenSSL to 1.1.1g \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2020-06-23-03-12-57.bpo-41039.0hgd0s.rst b/Misc/NEWS.d/next/Windows/2020-06-23-03-12-57.bpo-41039.0hgd0s.rst deleted file mode 100644 index acc3f7441f1b152..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-06-23-03-12-57.bpo-41039.0hgd0s.rst +++ /dev/null @@ -1,2 +0,0 @@ -Stable ABI redirection DLL (python3.dll) now uses ``#pragma -comment(linker)`` for re-exporting. diff --git a/Misc/NEWS.d/next/Windows/2020-06-24-21-30-42.bpo-41074.gaQc3C.rst b/Misc/NEWS.d/next/Windows/2020-06-24-21-30-42.bpo-41074.gaQc3C.rst deleted file mode 100644 index ec91fd361c3de18..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-06-24-21-30-42.bpo-41074.gaQc3C.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed support of non-ASCII names in functions :func:`msilib.OpenDatabase` -and :func:`msilib.init_database` and non-ASCII SQL in method -:meth:`msilib.Database.OpenView`. diff --git a/Misc/NEWS.d/next/Windows/2020-06-28-12-40-41.bpo-41142.jpZzzh.rst b/Misc/NEWS.d/next/Windows/2020-06-28-12-40-41.bpo-41142.jpZzzh.rst deleted file mode 100644 index 91406da7a2544ef..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-06-28-12-40-41.bpo-41142.jpZzzh.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`msilib` now supports creating CAB files with non-ASCII file path and -adding files with non-ASCII file path to them. diff --git a/Misc/NEWS.d/next/Windows/2020-07-20-23-26-26.bpo-40741.C9sc_d.rst b/Misc/NEWS.d/next/Windows/2020-07-20-23-26-26.bpo-40741.C9sc_d.rst deleted file mode 100644 index 69b7cce43803c69..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-07-20-23-26-26.bpo-40741.C9sc_d.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows release to include SQLite 3.32.3. diff --git a/Misc/NEWS.d/next/Windows/2020-07-28-11-55-43.bpo-41412.ME20KB.rst b/Misc/NEWS.d/next/Windows/2020-07-28-11-55-43.bpo-41412.ME20KB.rst deleted file mode 100644 index 274264ad876d3ca..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-07-28-11-55-43.bpo-41412.ME20KB.rst +++ /dev/null @@ -1,2 +0,0 @@ -The installer will now fail to install on Windows 7 and Windows 8. Further, -the UCRT dependency is now always downloaded on demand. diff --git a/Misc/NEWS.d/next/Windows/2020-07-28-12-39-32.bpo-40948.ISUFO6.rst b/Misc/NEWS.d/next/Windows/2020-07-28-12-39-32.bpo-40948.ISUFO6.rst deleted file mode 100644 index f8831d8c13701cb..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-07-28-12-39-32.bpo-40948.ISUFO6.rst +++ /dev/null @@ -1 +0,0 @@ -Improve post-install message to direct people to the "py" command. diff --git a/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst b/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst deleted file mode 100644 index 065803e2c207593..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-08-06-16-59-10.bpo-41492.2FQ9cM.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes the description that appears in UAC prompts. diff --git a/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst b/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst deleted file mode 100644 index 756c8270599f276..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-08-13-22-40-58.bpo-41526.-i2bwb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed layout of final page of the installer by removing the special thanks -to Mark Hammond (with his permission). diff --git a/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst b/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst deleted file mode 100644 index 043bd5e9341c3c7..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-09-04-21-35-28.bpo-41627.sx2KN1.rst +++ /dev/null @@ -1,2 +0,0 @@ -The user site directory for 32-bit now includes a ``-32`` suffix to -distinguish it from the 64-bit interpreter's directory. diff --git a/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst b/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst deleted file mode 100644 index 6106d6604c7dd58..000000000000000 --- a/Misc/NEWS.d/next/Windows/2020-09-11-17-59-33.bpo-41744.e_ugDQ.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes automatic import of props file when using the Nuget package. \ No newline at end of file diff --git a/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst deleted file mode 100644 index 6ff7b9a805b9572..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use SQLite 3.32.2. diff --git a/Misc/NEWS.d/next/macOS/2020-06-17-13-45-15.bpo-41005.zZegdV.rst b/Misc/NEWS.d/next/macOS/2020-06-17-13-45-15.bpo-41005.zZegdV.rst deleted file mode 100644 index 3b5f3f23a12f548..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-06-17-13-45-15.bpo-41005.zZegdV.rst +++ /dev/null @@ -1 +0,0 @@ -fixed an XDG settings issue not allowing macos to open browser in webbrowser.py \ No newline at end of file diff --git a/Misc/NEWS.d/next/macOS/2020-06-19-14-19-08.bpo-40741.L7yTbm.rst b/Misc/NEWS.d/next/macOS/2020-06-19-14-19-08.bpo-40741.L7yTbm.rst deleted file mode 100644 index 78a21b76c2fe4e7..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-06-19-14-19-08.bpo-40741.L7yTbm.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use SQLite 3.32.3. diff --git a/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst b/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst deleted file mode 100644 index d6bb61613669073..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-06-24-13-51-57.bpo-41100.mcHdc5.rst +++ /dev/null @@ -1,7 +0,0 @@ -Fix configure error when building on macOS 11. -Note that the current Python release was released -shortly after the first developer preview of macOS -11 (Big Sur); there are other known issues with -building and running on the developer preview. -Big Sur is expected to be fully supported in a -future bugfix release of Python 3.8.x and with 3.9.0. \ No newline at end of file diff --git a/Misc/NEWS.d/next/macOS/2020-06-25-06-09-00.bpo-39580.N_vJ9h.rst b/Misc/NEWS.d/next/macOS/2020-06-25-06-09-00.bpo-39580.N_vJ9h.rst deleted file mode 100644 index 95d65359804d034..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-06-25-06-09-00.bpo-39580.N_vJ9h.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid opening Finder window if running installer from the command line. -Patch contributed by Rick Heil. diff --git a/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst b/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst deleted file mode 100644 index 5f2d9937c0606dc..000000000000000 --- a/Misc/NEWS.d/next/macOS/2020-08-26-09-31-37.bpo-41557.mcQ75z.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use SQLite 3.33.0. diff --git a/README.rst b/README.rst index 14f4f32bca79651..176562cae308b7e 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.10.0 alpha 0 +This is Python version 3.10.0 alpha 1 ===================================== .. image:: https://travis-ci.com/python/cpython.svg?branch=master From 78731db96330ba93e5bdfe6796ed79ba8bd33c8b Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 5 Oct 2020 21:16:35 +0100 Subject: [PATCH 419/486] Post 3.10.0a1 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index c4468ad3f2223b6..eeb23af9766700c 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.10.0a1" +#define PY_VERSION "3.10.0a1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From ede0d6c443f48021a89f238b2906a95ceb88f625 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 6 Oct 2020 15:14:51 +0300 Subject: [PATCH 420/486] bpo-41944: No longer call eval() on content received via HTTP in the CJK codec tests (GH-22566) --- Lib/test/multibytecodec_support.py | 22 +++++++------------ .../2020-10-05-17-43-46.bpo-41944.rf1dYb.rst | 1 + 2 files changed, 9 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-10-05-17-43-46.bpo-41944.rf1dYb.rst diff --git a/Lib/test/multibytecodec_support.py b/Lib/test/multibytecodec_support.py index cca8af67d6d1d6c..f76c0153f5ecf72 100644 --- a/Lib/test/multibytecodec_support.py +++ b/Lib/test/multibytecodec_support.py @@ -305,29 +305,23 @@ def test_mapping_file(self): self._test_mapping_file_plain() def _test_mapping_file_plain(self): - unichrs = lambda s: ''.join(map(chr, map(eval, s.split('+')))) + def unichrs(s): + return ''.join(chr(int(x, 16)) for x in s.split('+')) + urt_wa = {} with self.open_mapping_file() as f: for line in f: if not line: break - data = line.split('#')[0].strip().split() + data = line.split('#')[0].split() if len(data) != 2: continue - csetval = eval(data[0]) - if csetval <= 0x7F: - csetch = bytes([csetval & 0xff]) - elif csetval >= 0x1000000: - csetch = bytes([(csetval >> 24), ((csetval >> 16) & 0xff), - ((csetval >> 8) & 0xff), (csetval & 0xff)]) - elif csetval >= 0x10000: - csetch = bytes([(csetval >> 16), ((csetval >> 8) & 0xff), - (csetval & 0xff)]) - elif csetval >= 0x100: - csetch = bytes([(csetval >> 8), (csetval & 0xff)]) - else: + if data[0][:2] != '0x': + self.fail(f"Invalid line: {line!r}") + csetch = bytes.fromhex(data[0][2:]) + if len(csetch) == 1 and 0x80 <= csetch[0]: continue unich = unichrs(data[1]) diff --git a/Misc/NEWS.d/next/Tests/2020-10-05-17-43-46.bpo-41944.rf1dYb.rst b/Misc/NEWS.d/next/Tests/2020-10-05-17-43-46.bpo-41944.rf1dYb.rst new file mode 100644 index 000000000000000..4f9782f1c85af9d --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-10-05-17-43-46.bpo-41944.rf1dYb.rst @@ -0,0 +1 @@ +Tests for CJK codecs no longer call ``eval()`` on content received via HTTP. From 77c6bdb73da4010cc029cf558b063063466c8635 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 6 Oct 2020 16:21:56 +0200 Subject: [PATCH 421/486] bpo-41944: No longer call eval() on content received via HTTP in the UnicodeNames tests (GH-22575) Similarly to GH-22566, those tests called eval() on content received via HTTP in test_named_sequences_full. This likely isn't exploitable because unicodedata.lookup(seqname) is called before self.checkletter(seqname, None) - thus any string which isn't a valid unicode character name wouldn't ever reach the checkletter method. Still, it's probably better to be safe than sorry. --- Lib/test/test_ucn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ucn.py b/Lib/test/test_ucn.py index e95f911d8eedddd..cbfd5af2bb751c7 100644 --- a/Lib/test/test_ucn.py +++ b/Lib/test/test_ucn.py @@ -7,6 +7,7 @@ """#" +import ast import unittest import unicodedata @@ -24,7 +25,7 @@ def checkletter(self, name, code): # Helper that put all \N escapes inside eval'd raw strings, # to make sure this script runs even if the compiler # chokes on \N escapes - res = eval(r'"\N{%s}"' % name) + res = ast.literal_eval(r'"\N{%s}"' % name) self.assertEqual(res, code) return res From 9f11c9d1ec30c12882134a88b51a7b9256130616 Mon Sep 17 00:00:00 2001 From: Ben Avrahami Date: Tue, 6 Oct 2020 20:40:50 +0300 Subject: [PATCH 422/486] bpo-41905: Add abc.update_abstractmethods() (GH-22485) This function recomputes `cls.__abstractmethods__`. Also update `@dataclass` to use it. --- Doc/library/abc.rst | 26 ++- Doc/library/functools.rst | 7 + Lib/abc.py | 38 +++++ Lib/dataclasses.py | 3 + Lib/test/test_abc.py | 149 ++++++++++++++++++ Lib/test/test_dataclasses.py | 37 +++++ .../2020-10-01-21-11-03.bpo-41905._JpjR4.rst | 1 + 7 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-01-21-11-03.bpo-41905._JpjR4.rst diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 424ae547d829a4c..3a7414d7358e7ab 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -174,10 +174,11 @@ The :mod:`abc` module also provides the following decorator: to declare abstract methods for properties and descriptors. Dynamically adding abstract methods to a class, or attempting to modify the - abstraction status of a method or class once it is created, are not - supported. The :func:`abstractmethod` only affects subclasses derived using - regular inheritance; "virtual subclasses" registered with the ABC's - :meth:`register` method are not affected. + abstraction status of a method or class once it is created, are only + supported using the :func:`update_abstractmethods` function. The + :func:`abstractmethod` only affects subclasses derived using regular + inheritance; "virtual subclasses" registered with the ABC's :meth:`register` + method are not affected. When :func:`abstractmethod` is applied in combination with other method descriptors, it should be applied as the innermost decorator, as shown in @@ -235,7 +236,6 @@ The :mod:`abc` module also provides the following decorator: super-call in a framework that uses cooperative multiple-inheritance. - The :mod:`abc` module also supports the following legacy decorators: .. decorator:: abstractclassmethod @@ -335,6 +335,22 @@ The :mod:`abc` module also provides the following functions: .. versionadded:: 3.4 +.. function:: update_abstractmethods(cls) + A function to recalculate an abstract class's abstraction status. This + function should be called if a class's abstract methods have been + implemented or changed after it was created. Usually, this function should + be called from within a class decorator. + + Returns *cls*, to allow usage as a class decorator. + + If *cls* is not an instance of ABCMeta, does nothing. + + .. note:: + + This function assumes that *cls*'s superclasses are already updated. + It does not update any subclasses. + + .. versionadded:: 3.10 .. rubric:: Footnotes diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 14aa184e2cd14c7..186cb4c381dee4a 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -254,6 +254,13 @@ The :mod:`functools` module defines the following functions: application, implementing all six rich comparison methods instead is likely to provide an easy speed boost. + .. note:: + + This decorator makes no attempt to override methods that have been + declared in the class *or its superclasses*. Meaning that if a + superclass defines a comparison operator, *total_ordering* will not + implement it again, even if the original method is abstract. + .. versionadded:: 3.2 .. versionchanged:: 3.4 diff --git a/Lib/abc.py b/Lib/abc.py index 431b64040a66e8c..276ef9a2cd4850a 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -122,6 +122,44 @@ def _abc_caches_clear(cls): _reset_caches(cls) +def update_abstractmethods(cls): + """Recalculate the set of abstract methods of an abstract class. + + If a class has had one of its abstract methods implemented after the + class was created, the method will not be considered implemented until + this function is called. Alternatively, if a new abstract method has been + added to the class, it will only be considered an abstract method of the + class after this function is called. + + This function should be called before any use is made of the class, + usually in class decorators that add methods to the subject class. + + Returns cls, to allow usage as a class decorator. + + If cls is not an instance of ABCMeta, does nothing. + """ + if not hasattr(cls, '__abstractmethods__'): + # We check for __abstractmethods__ here because cls might by a C + # implementation or a python implementation (especially during + # testing), and we want to handle both cases. + return cls + + abstracts = set() + # Check the existing abstract methods of the parents, keep only the ones + # that are not implemented. + for scls in cls.__bases__: + for name in getattr(scls, '__abstractmethods__', ()): + value = getattr(cls, name, None) + if getattr(value, "__isabstractmethod__", False): + abstracts.add(name) + # Also add any other newly added abstract methods. + for name, value in cls.__dict__.items(): + if getattr(value, "__isabstractmethod__", False): + abstracts.add(name) + cls.__abstractmethods__ = frozenset(abstracts) + return cls + + class ABC(metaclass=ABCMeta): """Helper class that provides a standard way to create an ABC using inheritance. diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 530d3e99574e8ea..65091021f37162c 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -6,6 +6,7 @@ import keyword import builtins import functools +import abc import _thread from types import GenericAlias @@ -992,6 +993,8 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): cls.__doc__ = (cls.__name__ + str(inspect.signature(cls)).replace(' -> None', '')) + abc.update_abstractmethods(cls) + return cls diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index 7e9c47b3cacb969..3d603e7734d8708 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -488,6 +488,155 @@ class C(with_metaclass(abc_ABCMeta, A, B)): pass self.assertEqual(C.__class__, abc_ABCMeta) + def test_update_del(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + del A.foo + self.assertEqual(A.__abstractmethods__, {'foo'}) + self.assertFalse(hasattr(A, 'foo')) + + abc.update_abstractmethods(A) + + self.assertEqual(A.__abstractmethods__, set()) + A() + + + def test_update_new_abstractmethods(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def bar(self): + pass + + @abc.abstractmethod + def updated_foo(self): + pass + + A.foo = updated_foo + abc.update_abstractmethods(A) + self.assertEqual(A.__abstractmethods__, {'foo', 'bar'}) + msg = "class A with abstract methods bar, foo" + self.assertRaisesRegex(TypeError, msg, A) + + def test_update_implementation(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + class B(A): + pass + + msg = "class B with abstract method foo" + self.assertRaisesRegex(TypeError, msg, B) + self.assertEqual(B.__abstractmethods__, {'foo'}) + + B.foo = lambda self: None + + abc.update_abstractmethods(B) + + B() + self.assertEqual(B.__abstractmethods__, set()) + + def test_update_as_decorator(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + def class_decorator(cls): + cls.foo = lambda self: None + return cls + + @abc.update_abstractmethods + @class_decorator + class B(A): + pass + + B() + self.assertEqual(B.__abstractmethods__, set()) + + def test_update_non_abc(self): + class A: + pass + + @abc.abstractmethod + def updated_foo(self): + pass + + A.foo = updated_foo + abc.update_abstractmethods(A) + A() + self.assertFalse(hasattr(A, '__abstractmethods__')) + + def test_update_del_implementation(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + class B(A): + def foo(self): + pass + + B() + + del B.foo + + abc.update_abstractmethods(B) + + msg = "class B with abstract method foo" + self.assertRaisesRegex(TypeError, msg, B) + + def test_update_layered_implementation(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + class B(A): + pass + + class C(B): + def foo(self): + pass + + C() + + del C.foo + + abc.update_abstractmethods(C) + + msg = "class C with abstract method foo" + self.assertRaisesRegex(TypeError, msg, C) + + def test_update_multi_inheritance(self): + class A(metaclass=abc_ABCMeta): + @abc.abstractmethod + def foo(self): + pass + + class B(metaclass=abc_ABCMeta): + def foo(self): + pass + + class C(B, A): + @abc.abstractmethod + def foo(self): + pass + + self.assertEqual(C.__abstractmethods__, {'foo'}) + + del C.foo + + abc.update_abstractmethods(C) + + self.assertEqual(C.__abstractmethods__, set()) + + C() + class TestABCWithInitSubclass(unittest.TestCase): def test_works_with_init_subclass(self): diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index b20103bdce51cb7..b31a469ec79227b 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -4,6 +4,7 @@ from dataclasses import * +import abc import pickle import inspect import builtins @@ -3332,6 +3333,42 @@ class C: ## replace(c, x=5) +class TestAbstract(unittest.TestCase): + def test_abc_implementation(self): + class Ordered(abc.ABC): + @abc.abstractmethod + def __lt__(self, other): + pass + + @abc.abstractmethod + def __le__(self, other): + pass + + @dataclass(order=True) + class Date(Ordered): + year: int + month: 'Month' + day: 'int' + + self.assertFalse(inspect.isabstract(Date)) + self.assertGreater(Date(2020,12,25), Date(2020,8,31)) + + def test_maintain_abc(self): + class A(abc.ABC): + @abc.abstractmethod + def foo(self): + pass + + @dataclass + class Date(A): + year: int + month: 'Month' + day: 'int' + + self.assertTrue(inspect.isabstract(Date)) + msg = 'class Date with abstract method foo' + self.assertRaisesRegex(TypeError, msg, Date) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-10-01-21-11-03.bpo-41905._JpjR4.rst b/Misc/NEWS.d/next/Library/2020-10-01-21-11-03.bpo-41905._JpjR4.rst new file mode 100644 index 000000000000000..0d8c0ba6a66bd18 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-01-21-11-03.bpo-41905._JpjR4.rst @@ -0,0 +1 @@ +A new function in abc: *update_abstractmethods* to re-calculate an abstract class's abstract status. In addition, *dataclass* has been changed to call this function. \ No newline at end of file From a38c4128f24f75cd5bd5a2d5ba97748de7e80f47 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Tue, 6 Oct 2020 23:03:02 +0300 Subject: [PATCH 423/486] bpo-38605: Make 'from __future__ import annotations' the default (GH-20434) The hard part was making all the tests pass; there are some subtle issues here, because apparently the future import wasn't tested very thoroughly in previous Python versions. For example, `inspect.signature()` returned type objects normally (except for forward references), but strings with the future import. We changed it to try and return type objects by calling `typing.get_type_hints()`, but fall back on returning strings if that function fails (which it may do if there are future references in the annotations that require passing in a specific namespace to resolve). --- Doc/reference/compound_stmts.rst | 10 +- Doc/whatsnew/3.10.rst | 17 ++ Lib/dataclasses.py | 13 +- Lib/inspect.py | 19 +- Lib/test/dataclass_module_1.py | 6 - Lib/test/dataclass_module_1_str.py | 32 --- Lib/test/dataclass_module_2.py | 6 - Lib/test/dataclass_module_2_str.py | 32 --- Lib/test/dataclass_textanno.py | 2 - Lib/test/test_annotations.py | 228 ++++++++++++++++++ Lib/test/test_coroutines.py | 8 - Lib/test/test_dataclasses.py | 79 +++--- Lib/test/test_dis.py | 38 ++- Lib/test/test_functools.py | 4 +- Lib/test/test_grammar.py | 56 ++--- Lib/test/test_inspect.py | 44 ++-- Lib/test/test_opcodes.py | 2 +- Lib/test/test_positional_only_arg.py | 17 +- Lib/test/test_pydoc.py | 4 +- Lib/test/test_syntax.py | 8 - Lib/test/test_types.py | 4 +- Lib/test/test_typing.py | 24 +- Lib/typing.py | 8 + .../2020-05-27-16-08-16.bpo-38605.rcs2uK.rst | 3 + Python/ast_opt.c | 24 -- Python/compile.c | 14 +- Python/future.c | 2 +- 27 files changed, 404 insertions(+), 300 deletions(-) delete mode 100644 Lib/test/dataclass_module_1_str.py delete mode 100644 Lib/test/dataclass_module_2_str.py create mode 100644 Lib/test/test_annotations.py create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-27-16-08-16.bpo-38605.rcs2uK.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 158d6a8f164e23c..04a3948d0c9dcf2 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -610,13 +610,9 @@ following the parameter name. Any parameter may have an annotation, even those ``*identifier`` or ``**identifier``. Functions may have "return" annotation of the form "``-> expression``" after the parameter list. These annotations can be any valid Python expression. The presence of annotations does not change the -semantics of a function. The annotation values are available as values of -a dictionary keyed by the parameters' names in the :attr:`__annotations__` -attribute of the function object. If the ``annotations`` import from -:mod:`__future__` is used, annotations are preserved as strings at runtime which -enables postponed evaluation. Otherwise, they are evaluated when the function -definition is executed. In this case annotations may be evaluated in -a different order than they appear in the source code. +semantics of a function. The annotation values are available as string values +in a dictionary keyed by the parameters' names in the :attr:`__annotations__` +attribute of the function object. .. index:: pair: lambda; expression diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 1ea5aeac8a3c623..2bcdba69957b61a 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -70,6 +70,23 @@ Summary -- Release highlights New Features ============ +.. _whatsnew310-pep563: + +PEP 563: Postponed Evaluation of Annotations Becomes Default +------------------------------------------------------------ + +In Python 3.7, postponed evaluation of annotations was added, +to be enabled with a ``from __future__ import annotations`` +directive. In 3.10 this became the default behavior, even +without that future directive. With this being default, all +annotations stored in :attr:`__annotations__` will be strings. +If needed, annotations can be resolved at runtime using +:func:`typing.get_type_hints`. See :pep:`563` for a full +description. Also, the :func:`inspect.signature` will try to +resolve types from now on, and when it fails it will fall back to +showing the string annotations. (Contributed by Batuhan Taskaya +in :issue:`38605`.) + * The :class:`int` type has a new method :meth:`int.bit_count`, returning the number of ones in the binary expansion of a given integer, also known as the population count. (Contributed by Niklas Fiekas in :issue:`29882`.) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 65091021f37162c..adfb9b7240b9f9a 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -399,8 +399,10 @@ def _create_fn(name, args, body, *, globals=None, locals=None, ns = {} exec(txt, globals, ns) - return ns['__create_fn__'](**locals) - + func = ns['__create_fn__'](**locals) + for arg, annotation in func.__annotations__.copy().items(): + func.__annotations__[arg] = locals[annotation] + return func def _field_assign(frozen, name, value, self_name): # If we're a frozen class, then assign to our fields in __init__ @@ -651,6 +653,11 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate): # a eval() penalty for every single field of every dataclass # that's defined. It was judged not worth it. + # Strip away the extra quotes as a result of double-stringifying when the + # 'annotations' feature became default. + if annotation.startswith(("'", '"')) and annotation.endswith(("'", '"')): + annotation = annotation[1:-1] + match = _MODULE_IDENTIFIER_RE.match(annotation) if match: ns = None @@ -991,7 +998,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): if not getattr(cls, '__doc__'): # Create a class doc-string. cls.__doc__ = (cls.__name__ + - str(inspect.signature(cls)).replace(' -> None', '')) + str(inspect.signature(cls)).replace(' -> NoneType', '')) abc.update_abstractmethods(cls) diff --git a/Lib/inspect.py b/Lib/inspect.py index 887a3424057b6e1..ac127cbd725b9b0 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -45,6 +45,7 @@ import tokenize import token import types +import typing import warnings import functools import builtins @@ -1877,7 +1878,10 @@ def _signature_is_functionlike(obj): code = getattr(obj, '__code__', None) defaults = getattr(obj, '__defaults__', _void) # Important to use _void ... kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here - annotations = getattr(obj, '__annotations__', None) + try: + annotations = _get_type_hints(obj) + except AttributeError: + annotations = None return (isinstance(code, types.CodeType) and isinstance(name, str) and @@ -2118,6 +2122,16 @@ def p(name_node, default_node, default=empty): return cls(parameters, return_annotation=cls.empty) +def _get_type_hints(func): + try: + return typing.get_type_hints(func) + except Exception: + # First, try to use the get_type_hints to resolve + # annotations. But for keeping the behavior intact + # if there was a problem with that (like the namespace + # can't resolve some annotation) continue to use + # string annotations + return func.__annotations__ def _signature_from_builtin(cls, func, skip_bound_arg=True): """Private helper function to get signature for @@ -2161,7 +2175,8 @@ def _signature_from_function(cls, func, skip_bound_arg=True): positional = arg_names[:pos_count] keyword_only_count = func_code.co_kwonlyargcount keyword_only = arg_names[pos_count:pos_count + keyword_only_count] - annotations = func.__annotations__ + annotations = _get_type_hints(func) + defaults = func.__defaults__ kwdefaults = func.__kwdefaults__ diff --git a/Lib/test/dataclass_module_1.py b/Lib/test/dataclass_module_1.py index 87a33f8191d3da0..9f0aeda67f9abb0 100644 --- a/Lib/test/dataclass_module_1.py +++ b/Lib/test/dataclass_module_1.py @@ -1,9 +1,3 @@ -#from __future__ import annotations -USING_STRINGS = False - -# dataclass_module_1.py and dataclass_module_1_str.py are identical -# except only the latter uses string annotations. - import dataclasses import typing diff --git a/Lib/test/dataclass_module_1_str.py b/Lib/test/dataclass_module_1_str.py deleted file mode 100644 index 6de490b7ad78418..000000000000000 --- a/Lib/test/dataclass_module_1_str.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import annotations -USING_STRINGS = True - -# dataclass_module_1.py and dataclass_module_1_str.py are identical -# except only the latter uses string annotations. - -import dataclasses -import typing - -T_CV2 = typing.ClassVar[int] -T_CV3 = typing.ClassVar - -T_IV2 = dataclasses.InitVar[int] -T_IV3 = dataclasses.InitVar - -@dataclasses.dataclass -class CV: - T_CV4 = typing.ClassVar - cv0: typing.ClassVar[int] = 20 - cv1: typing.ClassVar = 30 - cv2: T_CV2 - cv3: T_CV3 - not_cv4: T_CV4 # When using string annotations, this field is not recognized as a ClassVar. - -@dataclasses.dataclass -class IV: - T_IV4 = dataclasses.InitVar - iv0: dataclasses.InitVar[int] - iv1: dataclasses.InitVar - iv2: T_IV2 - iv3: T_IV3 - not_iv4: T_IV4 # When using string annotations, this field is not recognized as an InitVar. diff --git a/Lib/test/dataclass_module_2.py b/Lib/test/dataclass_module_2.py index 68fb733e29925da..8d120d181bd3d5d 100644 --- a/Lib/test/dataclass_module_2.py +++ b/Lib/test/dataclass_module_2.py @@ -1,9 +1,3 @@ -#from __future__ import annotations -USING_STRINGS = False - -# dataclass_module_2.py and dataclass_module_2_str.py are identical -# except only the latter uses string annotations. - from dataclasses import dataclass, InitVar from typing import ClassVar diff --git a/Lib/test/dataclass_module_2_str.py b/Lib/test/dataclass_module_2_str.py deleted file mode 100644 index b363d17c176c225..000000000000000 --- a/Lib/test/dataclass_module_2_str.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import annotations -USING_STRINGS = True - -# dataclass_module_2.py and dataclass_module_2_str.py are identical -# except only the latter uses string annotations. - -from dataclasses import dataclass, InitVar -from typing import ClassVar - -T_CV2 = ClassVar[int] -T_CV3 = ClassVar - -T_IV2 = InitVar[int] -T_IV3 = InitVar - -@dataclass -class CV: - T_CV4 = ClassVar - cv0: ClassVar[int] = 20 - cv1: ClassVar = 30 - cv2: T_CV2 - cv3: T_CV3 - not_cv4: T_CV4 # When using string annotations, this field is not recognized as a ClassVar. - -@dataclass -class IV: - T_IV4 = InitVar - iv0: InitVar[int] - iv1: InitVar - iv2: T_IV2 - iv3: T_IV3 - not_iv4: T_IV4 # When using string annotations, this field is not recognized as an InitVar. diff --git a/Lib/test/dataclass_textanno.py b/Lib/test/dataclass_textanno.py index 3eb6c943d4c4348..589b60f0cd61d49 100644 --- a/Lib/test/dataclass_textanno.py +++ b/Lib/test/dataclass_textanno.py @@ -1,5 +1,3 @@ -from __future__ import annotations - import dataclasses diff --git a/Lib/test/test_annotations.py b/Lib/test/test_annotations.py new file mode 100644 index 000000000000000..3e6b709fb4f1e3f --- /dev/null +++ b/Lib/test/test_annotations.py @@ -0,0 +1,228 @@ +import unittest +import sys +from textwrap import dedent + +class PostponedAnnotationsTestCase(unittest.TestCase): + template = dedent( + """ + def f() -> {ann}: + ... + def g(arg: {ann}) -> None: + ... + async def f2() -> {ann}: + ... + async def g2(arg: {ann}) -> None: + ... + var: {ann} + var2: {ann} = None + """ + ) + + def getActual(self, annotation): + scope = {} + exec(self.template.format(ann=annotation), {}, scope) + func_ret_ann = scope['f'].__annotations__['return'] + func_arg_ann = scope['g'].__annotations__['arg'] + async_func_ret_ann = scope['f2'].__annotations__['return'] + async_func_arg_ann = scope['g2'].__annotations__['arg'] + var_ann1 = scope['__annotations__']['var'] + var_ann2 = scope['__annotations__']['var2'] + self.assertEqual(func_ret_ann, func_arg_ann) + self.assertEqual(func_ret_ann, async_func_ret_ann) + self.assertEqual(func_ret_ann, async_func_arg_ann) + self.assertEqual(func_ret_ann, var_ann1) + self.assertEqual(func_ret_ann, var_ann2) + return func_ret_ann + + def assertAnnotationEqual( + self, annotation, expected=None, drop_parens=False, is_tuple=False, + ): + actual = self.getActual(annotation) + if expected is None: + expected = annotation if not is_tuple else annotation[1:-1] + if drop_parens: + self.assertNotEqual(actual, expected) + actual = actual.replace("(", "").replace(")", "") + + self.assertEqual(actual, expected) + + def test_annotations(self): + eq = self.assertAnnotationEqual + eq('...') + eq("'some_string'") + eq("u'some_string'") + eq("b'\\xa3'") + eq('Name') + eq('None') + eq('True') + eq('False') + eq('1') + eq('1.0') + eq('1j') + eq('True or False') + eq('True or False or None') + eq('True and False') + eq('True and False and None') + eq('Name1 and Name2 or Name3') + eq('Name1 and (Name2 or Name3)') + eq('Name1 or Name2 and Name3') + eq('(Name1 or Name2) and Name3') + eq('Name1 and Name2 or Name3 and Name4') + eq('Name1 or Name2 and Name3 or Name4') + eq('a + b + (c + d)') + eq('a * b * (c * d)') + eq('(a ** b) ** c ** d') + eq('v1 << 2') + eq('1 >> v2') + eq('1 % finished') + eq('1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8') + eq('not great') + eq('not not great') + eq('~great') + eq('+value') + eq('++value') + eq('-1') + eq('~int and not v1 ^ 123 + v2 | True') + eq('a + (not b)') + eq('lambda: None') + eq('lambda arg: None') + eq('lambda a=True: a') + eq('lambda a, b, c=True: a') + eq("lambda a, b, c=True, *, d=1 << v2, e='str': a") + eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b") + eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b") + eq('lambda x, /: x') + eq('lambda x=1, /: x') + eq('lambda x, /, y: x + y') + eq('lambda x=1, /, y=2: x + y') + eq('lambda x, /, y=1: x + y') + eq('lambda x, /, y=1, *, z=3: x + y + z') + eq('lambda x=1, /, y=2, *, z=3: x + y + z') + eq('lambda x=1, /, y=2, *, z: x + y + z') + eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2') + eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2') + eq('lambda x, /, y=1, *, z: x + y + z') + eq('lambda x: lambda y: x + y') + eq('1 if True else 2') + eq('str or None if int or True else str or bytes or None') + eq('str or None if (1 if True else 2) else str or bytes or None') + eq("0 if not x else 1 if x > 0 else -1") + eq("(1 if x > 0 else -1) if x else 0") + eq("{'2.7': dead, '3.7': long_live or die_hard}") + eq("{'2.7': dead, '3.7': long_live or die_hard, **{'3.6': verygood}}") + eq("{**a, **b, **c}") + eq("{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}") + eq("{*a, *b, *c}") + eq("({'a': 'b'}, True or False, +value, 'string', b'bytes') or None") + eq("()") + eq("(a,)") + eq("(a, b)") + eq("(a, b, c)") + eq("(*a, *b, *c)") + eq("[]") + eq("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]") + eq("[*a, *b, *c]") + eq("{i for i in (1, 2, 3)}") + eq("{i ** 2 for i in (1, 2, 3)}") + eq("{i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}") + eq("{i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)}") + eq("[i for i in (1, 2, 3)]") + eq("[i ** 2 for i in (1, 2, 3)]") + eq("[i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]") + eq("[i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)]") + eq("(i for i in (1, 2, 3))") + eq("(i ** 2 for i in (1, 2, 3))") + eq("(i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))") + eq("(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))") + eq("{i: 0 for i in (1, 2, 3)}") + eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}") + eq("[(x, y) for x, y in (a, b)]") + eq("[(x,) for x, in (a,)]") + eq("Python3 > Python2 > COBOL") + eq("Life is Life") + eq("call()") + eq("call(arg)") + eq("call(kwarg='hey')") + eq("call(arg, kwarg='hey')") + eq("call(arg, *args, another, kwarg='hey')") + eq("call(arg, another, kwarg='hey', **kwargs, kwarg2='ho')") + eq("lukasz.langa.pl") + eq("call.me(maybe)") + eq("1 .real") + eq("1.0.real") + eq("....__class__") + eq("list[str]") + eq("dict[str, int]") + eq("set[str,]") + eq("tuple[str, ...]") + eq("tuple[(str, *types)]") + eq("tuple[str, int, (str, int)]") + eq("tuple[(*int, str, str, (str, int))]") + eq("tuple[str, int, float, dict[str, int]]") + eq("slice[0]") + eq("slice[0:1]") + eq("slice[0:1:2]") + eq("slice[:]") + eq("slice[:-1]") + eq("slice[1:]") + eq("slice[::-1]") + eq("slice[:,]") + eq("slice[1:2,]") + eq("slice[1:2:3,]") + eq("slice[1:2, 1]") + eq("slice[1:2, 2, 3]") + eq("slice[()]") + eq("slice[a, b:c, d:e:f]") + eq("slice[(x for x in a)]") + eq('str or None if sys.version_info[0] > (3,) else str or bytes or None') + eq("f'f-string without formatted values is just a string'") + eq("f'{{NOT a formatted value}}'") + eq("f'some f-string with {a} {few():.2f} {formatted.values!r}'") + eq('''f"{f'{nested} inner'} outer"''') + eq("f'space between opening braces: { {a for a in (1, 2, 3)}}'") + eq("f'{(lambda x: x)}'") + eq("f'{(None if a else lambda x: x)}'") + eq("f'{x}'") + eq("f'{x!r}'") + eq("f'{x!a}'") + eq('(yield from outside_of_generator)') + eq('(yield)') + eq('(yield a + b)') + eq('await some.complicated[0].call(with_args=True or 1 is not 1)') + eq('[x for x in (a if b else c)]') + eq('[x for x in a if (b if c else d)]') + eq('f(x for x in a)') + eq('f(1, (x for x in a))') + eq('f((x for x in a), 2)') + eq('(((a)))', 'a') + eq('(((a, b)))', '(a, b)') + eq("(x := 10)") + eq("f'{(x := 10):=10}'") + eq("1 + 2") + eq("1 + 2 + 3") + + def test_fstring_debug_annotations(self): + # f-strings with '=' don't round trip very well, so set the expected + # result explicitely. + self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'") + self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'") + self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'") + self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'") + self.assertAnnotationEqual("f'{x=!a}'", expected="f'x={x!a}'") + self.assertAnnotationEqual("f'{x=!s:*^20}'", expected="f'x={x!s:*^20}'") + + def test_infinity_numbers(self): + inf = "1e" + repr(sys.float_info.max_10_exp + 1) + infj = f"{inf}j" + self.assertAnnotationEqual("1e1000", expected=inf) + self.assertAnnotationEqual("1e1000j", expected=infj) + self.assertAnnotationEqual("-1e1000", expected=f"-{inf}") + self.assertAnnotationEqual("3+1e1000j", expected=f"3 + {infj}") + self.assertAnnotationEqual("(1e1000, 1e1000j)", expected=f"({inf}, {infj})") + self.assertAnnotationEqual("'inf'") + self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})") + self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))") + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 145adb677817011..40c2eb8d232dd92 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -91,10 +91,6 @@ def test_badsyntax_1(self): pass """, - """async def foo(a:await something()): - pass - """, - """async def foo(): def bar(): [i async for i in els] @@ -299,10 +295,6 @@ def bar(): pass """, - """async def foo(a:await b): - pass - """, - """def baz(): async def foo(a=await b): pass diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index b31a469ec79227b..7c1d9c568f4ef6f 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -9,6 +9,7 @@ import inspect import builtins import unittest +from textwrap import dedent from unittest.mock import Mock from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional from typing import get_type_hints @@ -562,17 +563,17 @@ class C: self.assertEqual(len(the_fields), 3) self.assertEqual(the_fields[0].name, 'x') - self.assertEqual(the_fields[0].type, int) + self.assertEqual(the_fields[0].type, 'int') self.assertFalse(hasattr(C, 'x')) self.assertTrue (the_fields[0].init) self.assertTrue (the_fields[0].repr) self.assertEqual(the_fields[1].name, 'y') - self.assertEqual(the_fields[1].type, str) + self.assertEqual(the_fields[1].type, 'str') self.assertIsNone(getattr(C, 'y')) self.assertFalse(the_fields[1].init) self.assertTrue (the_fields[1].repr) self.assertEqual(the_fields[2].name, 'z') - self.assertEqual(the_fields[2].type, str) + self.assertEqual(the_fields[2].type, 'str') self.assertFalse(hasattr(C, 'z')) self.assertTrue (the_fields[2].init) self.assertFalse(the_fields[2].repr) @@ -758,11 +759,11 @@ class F: def validate_class(cls): # First, check __annotations__, even though they're not # function annotations. - self.assertEqual(cls.__annotations__['i'], int) - self.assertEqual(cls.__annotations__['j'], str) - self.assertEqual(cls.__annotations__['k'], F) - self.assertEqual(cls.__annotations__['l'], float) - self.assertEqual(cls.__annotations__['z'], complex) + self.assertEqual(cls.__annotations__['i'], 'int') + self.assertEqual(cls.__annotations__['j'], 'str') + self.assertEqual(cls.__annotations__['k'], 'F') + self.assertEqual(cls.__annotations__['l'], 'float') + self.assertEqual(cls.__annotations__['z'], 'complex') # Verify __init__. @@ -777,22 +778,22 @@ def validate_class(cls): self.assertEqual(param.name, 'self') param = next(params) self.assertEqual(param.name, 'i') - self.assertIs (param.annotation, int) + self.assertIs (param.annotation, 'int') self.assertEqual(param.default, inspect.Parameter.empty) self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD) param = next(params) self.assertEqual(param.name, 'j') - self.assertIs (param.annotation, str) + self.assertIs (param.annotation, 'str') self.assertEqual(param.default, inspect.Parameter.empty) self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD) param = next(params) self.assertEqual(param.name, 'k') - self.assertIs (param.annotation, F) + self.assertIs (param.annotation, 'F') # Don't test for the default, since it's set to MISSING. self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD) param = next(params) self.assertEqual(param.name, 'l') - self.assertIs (param.annotation, float) + self.assertIs (param.annotation, 'float') # Don't test for the default, since it's set to MISSING. self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_OR_KEYWORD) self.assertRaises(StopIteration, next, params) @@ -2806,13 +2807,10 @@ class C: class TestStringAnnotations(unittest.TestCase): def test_classvar(self): - # Some expressions recognized as ClassVar really aren't. But - # if you're using string annotations, it's not an exact - # science. # These tests assume that both "import typing" and "from # typing import *" have been run in this file. for typestr in ('ClassVar[int]', - 'ClassVar [int]' + 'ClassVar [int]', ' ClassVar [int]', 'ClassVar', ' ClassVar ', @@ -2823,17 +2821,15 @@ def test_classvar(self): 'typing. ClassVar[str]', 'typing.ClassVar [str]', 'typing.ClassVar [ str]', - + # Double stringified + '"typing.ClassVar[int]"', # Not syntactically valid, but these will - # be treated as ClassVars. + # be treated as ClassVars. 'typing.ClassVar.[int]', 'typing.ClassVar+', ): with self.subTest(typestr=typestr): - @dataclass - class C: - x: typestr - + C = dataclass(type("C", (), {"__annotations__": {"x": typestr}})) # x is a ClassVar, so C() takes no args. C() @@ -2854,9 +2850,7 @@ def test_isnt_classvar(self): 'typingxClassVar[str]', ): with self.subTest(typestr=typestr): - @dataclass - class C: - x: typestr + C = dataclass(type("C", (), {"__annotations__": {"x": typestr}})) # x is not a ClassVar, so C() takes one arg. self.assertEqual(C(10).x, 10) @@ -2876,16 +2870,16 @@ def test_initvar(self): 'dataclasses. InitVar[str]', 'dataclasses.InitVar [str]', 'dataclasses.InitVar [ str]', - + # Double stringified + '"dataclasses.InitVar[int]"', # Not syntactically valid, but these will # be treated as InitVars. 'dataclasses.InitVar.[int]', 'dataclasses.InitVar+', ): with self.subTest(typestr=typestr): - @dataclass - class C: - x: typestr + C = dataclass(type("C", (), {"__annotations__": {"x": typestr}})) + # x is an InitVar, so doesn't create a member. with self.assertRaisesRegex(AttributeError, @@ -2899,30 +2893,22 @@ def test_isnt_initvar(self): 'typing.xInitVar[int]', ): with self.subTest(typestr=typestr): - @dataclass - class C: - x: typestr + C = dataclass(type("C", (), {"__annotations__": {"x": typestr}})) # x is not an InitVar, so there will be a member x. self.assertEqual(C(10).x, 10) def test_classvar_module_level_import(self): from test import dataclass_module_1 - from test import dataclass_module_1_str from test import dataclass_module_2 - from test import dataclass_module_2_str - for m in (dataclass_module_1, dataclass_module_1_str, - dataclass_module_2, dataclass_module_2_str, - ): + for m in (dataclass_module_1, + dataclass_module_2): with self.subTest(m=m): # There's a difference in how the ClassVars are # interpreted when using string annotations or # not. See the imported modules for details. - if m.USING_STRINGS: - c = m.CV(10) - else: - c = m.CV() + c = m.CV(10) self.assertEqual(c.cv0, 20) @@ -2938,14 +2924,9 @@ def test_classvar_module_level_import(self): # not an instance field. getattr(c, field_name) - if m.USING_STRINGS: - # iv4 is interpreted as a normal field. - self.assertIn('not_iv4', c.__dict__) - self.assertEqual(c.not_iv4, 4) - else: - # iv4 is interpreted as an InitVar, so it - # won't exist on the instance. - self.assertNotIn('not_iv4', c.__dict__) + # iv4 is interpreted as a normal field. + self.assertIn('not_iv4', c.__dict__) + self.assertEqual(c.not_iv4, 4) def test_text_annotations(self): from test import dataclass_textanno diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 4533a016a2fab51..bbaddd57d291893 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -227,28 +227,26 @@ def bug1333982(x=[]): 2 0 SETUP_ANNOTATIONS 2 LOAD_CONST 0 (1) 4 STORE_NAME 0 (x) - 6 LOAD_NAME 1 (int) - 8 LOAD_NAME 2 (__annotations__) - 10 LOAD_CONST 1 ('x') + 6 LOAD_CONST 1 ('int') + 8 LOAD_NAME 1 (__annotations__) + 10 LOAD_CONST 2 ('x') 12 STORE_SUBSCR - 3 14 LOAD_NAME 3 (fun) - 16 LOAD_CONST 0 (1) - 18 CALL_FUNCTION 1 - 20 LOAD_NAME 2 (__annotations__) - 22 LOAD_CONST 2 ('y') - 24 STORE_SUBSCR - - 4 26 LOAD_CONST 0 (1) - 28 LOAD_NAME 4 (lst) - 30 LOAD_NAME 3 (fun) - 32 LOAD_CONST 3 (0) - 34 CALL_FUNCTION 1 - 36 STORE_SUBSCR - 38 LOAD_NAME 1 (int) - 40 POP_TOP - 42 LOAD_CONST 4 (None) - 44 RETURN_VALUE + 3 14 LOAD_CONST 3 ('fun(1)') + 16 LOAD_NAME 1 (__annotations__) + 18 LOAD_CONST 4 ('y') + 20 STORE_SUBSCR + + 4 22 LOAD_CONST 0 (1) + 24 LOAD_NAME 2 (lst) + 26 LOAD_NAME 3 (fun) + 28 LOAD_CONST 5 (0) + 30 CALL_FUNCTION 1 + 32 STORE_SUBSCR + 34 LOAD_NAME 4 (int) + 36 POP_TOP + 38 LOAD_CONST 6 (None) + 40 RETURN_VALUE """ compound_stmt_str = """\ diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index edd5773e13d5493..bee9f9112bf1835 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -618,7 +618,7 @@ def check_wrapper(self, wrapper, wrapped, def _default_update(self): - def f(a:'This is a new annotation'): + def f(a: int): """This is a test""" pass f.attr = 'This is also a test' @@ -635,7 +635,7 @@ def test_default_update(self): self.assertEqual(wrapper.__name__, 'f') self.assertEqual(wrapper.__qualname__, f.__qualname__) self.assertEqual(wrapper.attr, 'This is also a test') - self.assertEqual(wrapper.__annotations__['a'], 'This is a new annotation') + self.assertEqual(wrapper.__annotations__['a'], 'int') self.assertNotIn('b', wrapper.__annotations__) @unittest.skipIf(sys.flags.optimize >= 2, diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 5235fa2c783f04d..2f6716dfc9a130b 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -362,7 +362,7 @@ class C: z = 2 def __init__(self, x): self.x: int = x - self.assertEqual(C.__annotations__, {'_C__foo': int, 's': str}) + self.assertEqual(C.__annotations__, {'_C__foo': 'int', 's': 'str'}) with self.assertRaises(NameError): class CBad: no_such_name_defined.attr: int = 0 @@ -378,15 +378,15 @@ def __prepare__(metacls, name, bases, **kwds): return {'__annotations__': CNS()} class CC(metaclass=CMeta): XX: 'ANNOT' - self.assertEqual(CC.__annotations__['xx'], 'ANNOT') + self.assertEqual(CC.__annotations__['xx'], repr('ANNOT')) def test_var_annot_module_semantics(self): with self.assertRaises(AttributeError): print(test.__annotations__) self.assertEqual(ann_module.__annotations__, - {1: 2, 'x': int, 'y': str, 'f': typing.Tuple[int, int]}) + {1: 2, 'x': 'int', 'y': 'str', 'f': 'Tuple[int, int]'}) self.assertEqual(ann_module.M.__annotations__, - {'123': 123, 'o': type}) + {'123': 123, 'o': 'type'}) self.assertEqual(ann_module2.__annotations__, {}) def test_var_annot_in_module(self): @@ -405,7 +405,7 @@ def test_var_annot_simple_exec(self): exec("'docstring'\n" "__annotations__[1] = 2\n" "x: int = 5\n", gns, lns) - self.assertEqual(lns["__annotations__"], {1: 2, 'x': int}) + self.assertEqual(lns["__annotations__"], {1: 2, 'x': 'int'}) with self.assertRaises(KeyError): gns['__annotations__'] @@ -413,8 +413,8 @@ def test_var_annot_custom_maps(self): # tests with custom locals() and __annotations__ ns = {'__annotations__': CNS()} exec('X: int; Z: str = "Z"; (w): complex = 1j', ns) - self.assertEqual(ns['__annotations__']['x'], int) - self.assertEqual(ns['__annotations__']['z'], str) + self.assertEqual(ns['__annotations__']['x'], 'int') + self.assertEqual(ns['__annotations__']['z'], 'str') with self.assertRaises(KeyError): ns['__annotations__']['w'] nonloc_ns = {} @@ -428,7 +428,7 @@ def __setitem__(self, item, value): def __getitem__(self, item): return self._dct[item] exec('x: int = 1', {}, CNS2()) - self.assertEqual(nonloc_ns['__annotations__']['x'], int) + self.assertEqual(nonloc_ns['__annotations__']['x'], 'int') def test_var_annot_refleak(self): # complex case: custom locals plus custom __annotations__ @@ -445,7 +445,7 @@ def __setitem__(self, item, value): def __getitem__(self, item): return self._dct[item] exec('X: str', {}, CNS2()) - self.assertEqual(nonloc_ns['__annotations__']['x'], str) + self.assertEqual(nonloc_ns['__annotations__']['x'], 'str') def test_var_annot_rhs(self): ns = {} @@ -625,50 +625,46 @@ def f(*args, **kwargs): # argument annotation tests def f(x) -> list: pass - self.assertEqual(f.__annotations__, {'return': list}) + self.assertEqual(f.__annotations__, {'return': 'list'}) def f(x: int): pass - self.assertEqual(f.__annotations__, {'x': int}) + self.assertEqual(f.__annotations__, {'x': 'int'}) def f(x: int, /): pass - self.assertEqual(f.__annotations__, {'x': int}) + self.assertEqual(f.__annotations__, {'x': 'int'}) def f(x: int = 34, /): pass - self.assertEqual(f.__annotations__, {'x': int}) + self.assertEqual(f.__annotations__, {'x': 'int'}) def f(*x: str): pass - self.assertEqual(f.__annotations__, {'x': str}) + self.assertEqual(f.__annotations__, {'x': 'str'}) def f(**x: float): pass - self.assertEqual(f.__annotations__, {'x': float}) - def f(x, y: 1+2): pass - self.assertEqual(f.__annotations__, {'y': 3}) - def f(x, y: 1+2, /): pass - self.assertEqual(f.__annotations__, {'y': 3}) + self.assertEqual(f.__annotations__, {'x': 'float'}) def f(a, b: 1, c: 2, d): pass - self.assertEqual(f.__annotations__, {'b': 1, 'c': 2}) + self.assertEqual(f.__annotations__, {'b': '1', 'c': '2'}) def f(a, b: 1, /, c: 2, d): pass - self.assertEqual(f.__annotations__, {'b': 1, 'c': 2}) + self.assertEqual(f.__annotations__, {'b': '1', 'c': '2'}) def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass self.assertEqual(f.__annotations__, - {'b': 1, 'c': 2, 'e': 3, 'g': 6}) + {'b': '1', 'c': '2', 'e': '3', 'g': '6'}) def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6, h: 7, i=8, j: 9 = 10, **k: 11) -> 12: pass self.assertEqual(f.__annotations__, - {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, - 'k': 11, 'return': 12}) + {'b': '1', 'c': '2', 'e': '3', 'g': '6', 'h': '7', 'j': '9', + 'k': '11', 'return': '12'}) def f(a, b: 1, c: 2, d, e: 3 = 4, f: int = 5, /, *g: 6, h: 7, i=8, j: 9 = 10, **k: 11) -> 12: pass self.assertEqual(f.__annotations__, - {'b': 1, 'c': 2, 'e': 3, 'f': int, 'g': 6, 'h': 7, 'j': 9, - 'k': 11, 'return': 12}) + {'b': '1', 'c': '2', 'e': '3', 'f': 'int', 'g': '6', 'h': '7', 'j': '9', + 'k': '11', 'return': '12'}) # Check for issue #20625 -- annotations mangling class Spam: def f(self, *, __kw: 1): pass class Ham(Spam): pass - self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': 1}) - self.assertEqual(Ham.f.__annotations__, {'_Spam__kw': 1}) + self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': '1'}) + self.assertEqual(Ham.f.__annotations__, {'_Spam__kw': '1'}) # Check for SF Bug #1697248 - mixing decorators and a return annotation def null(x): return x @null def f(x) -> list: pass - self.assertEqual(f.__annotations__, {'return': list}) + self.assertEqual(f.__annotations__, {'return': 'list'}) # Test expressions as decorators (PEP 614): @False or null @@ -1116,8 +1112,6 @@ def g(): rest = 4, 5, 6; yield 1, 2, 3, *rest # Not allowed at class scope check_syntax_error(self, "class foo:yield 1") check_syntax_error(self, "class foo:yield from ()") - # Check annotation refleak on SyntaxError - check_syntax_error(self, "def g(a:(yield)): pass") def test_yield_in_comprehensions(self): # Check yield in comprehensions diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 6667dc91edbcec6..71c4f27d27b982a 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -862,7 +862,7 @@ def test_getfullargspec(self): self.assertFullArgSpecEquals(mod2.annotated, ['arg1'], ann_e={'arg1' : list}, - formatted='(arg1: list)') + formatted="(arg1: list)") self.assertFullArgSpecEquals(mod2.keyword_only_arg, [], kwonlyargs_e=['arg'], formatted='(*, arg)') @@ -2211,8 +2211,8 @@ def test(a, b:'foo') -> 123: pass self.assertEqual(self.signature(test), ((('a', ..., ..., "positional_or_keyword"), - ('b', ..., 'foo', "positional_or_keyword")), - 123)) + ('b', ..., repr('foo'), "positional_or_keyword")), + '123')) def test_signature_on_wkwonly(self): def test(*, a:float, b:str) -> int: @@ -2227,11 +2227,11 @@ def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int): pass self.assertEqual(self.signature(test), ((('a', ..., ..., "positional_or_keyword"), - ('b', 10, 'foo', "positional_or_keyword"), - ('args', ..., 'bar', "var_positional"), - ('spam', ..., 'baz', "keyword_only"), + ('b', 10, repr('foo'), "positional_or_keyword"), + ('args', ..., repr('bar'), "var_positional"), + ('spam', ..., repr('baz'), "keyword_only"), ('ham', 123, ..., "keyword_only"), - ('kwargs', ..., int, "var_keyword")), + ('kwargs', ..., 'int', "var_keyword")), ...)) def test_signature_without_self(self): @@ -2640,12 +2640,12 @@ def test(a, b, c:int) -> 42: self.assertEqual(self.signature(partial(partial(test, 1))), ((('b', ..., ..., "positional_or_keyword"), - ('c', ..., int, "positional_or_keyword")), - 42)) + ('c', ..., 'int', "positional_or_keyword")), + '42')) self.assertEqual(self.signature(partial(partial(test, 1), 2)), - ((('c', ..., int, "positional_or_keyword"),), - 42)) + ((('c', ..., 'int', "positional_or_keyword"),), + '42')) psig = inspect.signature(partial(partial(test, 1), 2)) @@ -2764,12 +2764,12 @@ def test(it, a, *, c) -> 'spam': ((('it', ..., ..., 'positional_or_keyword'), ('a', ..., ..., 'positional_or_keyword'), ('c', 1, ..., 'keyword_only')), - 'spam')) + repr('spam'))) self.assertEqual(self.signature(Spam().ham), ((('a', ..., ..., 'positional_or_keyword'), ('c', 1, ..., 'keyword_only')), - 'spam')) + repr('spam'))) class Spam: def test(self: 'anno', x): @@ -2778,7 +2778,7 @@ def test(self: 'anno', x): g = partialmethod(test, 1) self.assertEqual(self.signature(Spam.g), - ((('self', ..., 'anno', 'positional_or_keyword'),), + ((('self', ..., repr('anno'), 'positional_or_keyword'),), ...)) def test_signature_on_fake_partialmethod(self): @@ -3116,20 +3116,16 @@ def foo(a={}): pass with self.assertRaisesRegex(TypeError, 'unhashable type'): hash(inspect.signature(foo)) - def foo(a) -> {}: pass - with self.assertRaisesRegex(TypeError, 'unhashable type'): - hash(inspect.signature(foo)) - def test_signature_str(self): def foo(a:int=1, *, b, c=None, **kwargs) -> 42: pass self.assertEqual(str(inspect.signature(foo)), - '(a: int = 1, *, b, c=None, **kwargs) -> 42') + '(a: \'int\' = 1, *, b, c=None, **kwargs) -> \'42\'') def foo(a:int=1, *args, b, c=None, **kwargs) -> 42: pass self.assertEqual(str(inspect.signature(foo)), - '(a: int = 1, *args, b, c=None, **kwargs) -> 42') + '(a: \'int\' = 1, *args, b, c=None, **kwargs) -> \'42\'') def foo(): pass @@ -3172,8 +3168,8 @@ def test() -> 42: self.assertIs(sig.return_annotation, None) sig = sig.replace(return_annotation=sig.empty) self.assertIs(sig.return_annotation, sig.empty) - sig = sig.replace(return_annotation=42) - self.assertEqual(sig.return_annotation, 42) + sig = sig.replace(return_annotation='42') + self.assertEqual(sig.return_annotation, '42') self.assertEqual(sig, inspect.signature(test)) def test_signature_on_mangled_parameters(self): @@ -3185,8 +3181,8 @@ class Ham(Spam): self.assertEqual(self.signature(Spam.foo), ((('self', ..., ..., "positional_or_keyword"), - ('_Spam__p1', 2, 1, "positional_or_keyword"), - ('_Spam__p2', 3, 2, "keyword_only")), + ('_Spam__p1', 2, '1', "positional_or_keyword"), + ('_Spam__p2', 3, '2', "keyword_only")), ...)) self.assertEqual(self.signature(Spam.foo), diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py index 527aca664d38e85..1152eb65bb2c3d5 100644 --- a/Lib/test/test_opcodes.py +++ b/Lib/test/test_opcodes.py @@ -39,7 +39,7 @@ class C: pass def test_use_existing_annotations(self): ns = {'__annotations__': {1: 2}} exec('x: int', ns) - self.assertEqual(ns['__annotations__'], {'x': int, 1: 2}) + self.assertEqual(ns['__annotations__'], {'x': 'int', 1: 2}) def test_do_not_recreate_annotations(self): # Don't rely on the existence of the '__annotations__' global. diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index 0a9503e2025d6b4..1fe8256d46ea45f 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -302,14 +302,14 @@ def inner_has_pos_only(): def f(x: int, /): ... return f - assert inner_has_pos_only().__annotations__ == {'x': int} + assert inner_has_pos_only().__annotations__ == {'x': 'int'} class Something: def method(self): def f(x: int, /): ... return f - assert Something().method().__annotations__ == {'x': int} + assert Something().method().__annotations__ == {'x': 'int'} def multiple_levels(): def inner_has_pos_only(): @@ -317,7 +317,7 @@ def f(x: int, /): ... return f return inner_has_pos_only() - assert multiple_levels().__annotations__ == {'x': int} + assert multiple_levels().__annotations__ == {'x': 'int'} def test_same_keyword_as_positional_with_kwargs(self): def f(something,/,**kwargs): @@ -429,17 +429,6 @@ def method(self, /): self.assertEqual(C().method(), sentinel) - def test_annotations_constant_fold(self): - def g(): - def f(x: not (int is int), /): ... - - # without constant folding we end up with - # COMPARE_OP(is), IS_OP (0) - # with constant folding we should expect a IS_OP (1) - codes = [(i.opname, i.argval) for i in dis.get_instructions(g)] - self.assertNotIn(('UNARY_NOT', None), codes) - self.assertIn(('IS_OP', 1), codes) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 76d2af8e461ed1b..2f502627f4d0a28 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -81,7 +81,7 @@ class B(builtins.object) |\x20\x20 | NO_MEANING = 'eggs' |\x20\x20 - | __annotations__ = {'NO_MEANING': } + | __annotations__ = {'NO_MEANING': 'str'} \x20\x20\x20\x20 class C(builtins.object) | Methods defined here: @@ -194,7 +194,7 @@ class C(builtins.object) Data and other attributes defined here:
    NO_MEANING = 'eggs'
    -
    __annotations__ = {'NO_MEANING': <class 'str'>}
    +
    __annotations__ = {'NO_MEANING': 'str'}

    diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 09c6eb3375409b6..7c3302c1d46aeba 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -752,14 +752,6 @@ Traceback (most recent call last): SyntaxError: cannot assign to __debug__ - >>> def f(*args:(lambda __debug__:0)): pass - Traceback (most recent call last): - SyntaxError: cannot assign to __debug__ - - >>> def f(**kwargs:(lambda __debug__:0)): pass - Traceback (most recent call last): - SyntaxError: cannot assign to __debug__ - >>> with (lambda *:0): pass Traceback (most recent call last): SyntaxError: named arguments must follow bare * diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 52a59d54f044d9f..75c5eee42dc5439 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -671,8 +671,8 @@ def test_or_type_operator_with_forward(self): ForwardBefore = 'Forward' | T def forward_after(x: ForwardAfter[int]) -> None: ... def forward_before(x: ForwardBefore[int]) -> None: ... - assert typing.get_args(typing.get_type_hints(forward_after)['x']) == (int, Forward) - assert typing.get_args(typing.get_type_hints(forward_before)['x']) == (int, Forward) + assert typing.get_args(typing.get_type_hints(forward_after, localns=locals())['x']) == (int, Forward) + assert typing.get_args(typing.get_type_hints(forward_before, localns=locals())['x']) == (int, Forward) def test_or_type_operator_with_Protocol(self): class Proto(typing.Protocol): diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 42aa430c5e107e6..4bef42f4f32fc7b 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -349,7 +349,7 @@ def test_empty(self): def test_no_eval_union(self): u = Union[int, str] def f(x: u): ... - self.assertIs(get_type_hints(f)['x'], u) + self.assertIs(get_type_hints(f, globals(), locals())['x'], u) def test_function_repr_union(self): def fun() -> int: ... @@ -2849,11 +2849,11 @@ def test_get_type_hints_classes(self): self.assertEqual(gth(HasForeignBaseClass), {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 'some_b': mod_generics_cache.B}) - self.assertEqual(gth(XRepr.__new__), + self.assertEqual(gth(XRepr), {'x': int, 'y': int}) self.assertEqual(gth(mod_generics_cache.B), {'my_inner_a1': mod_generics_cache.B.A, - 'my_inner_a2': mod_generics_cache.B.A, + 'my_inner_a2': mod_generics_cache.A, 'my_outer_a': mod_generics_cache.A}) def test_respect_no_type_check(self): @@ -3641,7 +3641,7 @@ def test_annotation_usage(self): self.assertEqual(tim.cool, 9000) self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') self.assertEqual(CoolEmployee._fields, ('name', 'cool')) - self.assertEqual(CoolEmployee.__annotations__, + self.assertEqual(gth(CoolEmployee), collections.OrderedDict(name=str, cool=int)) def test_annotation_usage_with_default(self): @@ -3655,7 +3655,7 @@ def test_annotation_usage_with_default(self): self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) - self.assertEqual(CoolEmployeeWithDefault.__annotations__, + self.assertEqual(gth(CoolEmployeeWithDefault), dict(name=str, cool=int)) self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) @@ -3823,7 +3823,7 @@ def test_typeddict_errors(self): def test_py36_class_syntax_usage(self): self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') self.assertEqual(LabelPoint2D.__module__, __name__) - self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) + self.assertEqual(gth(LabelPoint2D), {'x': int, 'y': int, 'label': str}) self.assertEqual(LabelPoint2D.__bases__, (dict,)) self.assertEqual(LabelPoint2D.__total__, True) self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) @@ -3882,11 +3882,11 @@ class Cat(Animal): assert BaseAnimal.__required_keys__ == frozenset(['name']) assert BaseAnimal.__optional_keys__ == frozenset([]) - assert BaseAnimal.__annotations__ == {'name': str} + assert gth(BaseAnimal) == {'name': str} assert Animal.__required_keys__ == frozenset(['name']) assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) - assert Animal.__annotations__ == { + assert gth(Animal) == { 'name': str, 'tail': bool, 'voice': str, @@ -3894,7 +3894,7 @@ class Cat(Animal): assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) - assert Cat.__annotations__ == { + assert gth(Cat) == { 'fur_color': str, 'name': str, 'tail': bool, @@ -3915,7 +3915,7 @@ def test_io(self): def stuff(a: IO) -> AnyStr: return a.readline() - a = stuff.__annotations__['a'] + a = gth(stuff)['a'] self.assertEqual(a.__parameters__, (AnyStr,)) def test_textio(self): @@ -3923,7 +3923,7 @@ def test_textio(self): def stuff(a: TextIO) -> str: return a.readline() - a = stuff.__annotations__['a'] + a = gth(stuff)['a'] self.assertEqual(a.__parameters__, ()) def test_binaryio(self): @@ -3931,7 +3931,7 @@ def test_binaryio(self): def stuff(a: BinaryIO) -> bytes: return a.readline() - a = stuff.__annotations__['a'] + a = gth(stuff)['a'] self.assertEqual(a.__parameters__, ()) def test_io_submodule(self): diff --git a/Lib/typing.py b/Lib/typing.py index 8c61bd8e084a850..4cf33c1ae92659b 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -18,6 +18,7 @@ """ from abc import abstractmethod, ABCMeta +import ast import collections import collections.abc import contextlib @@ -469,6 +470,13 @@ class ForwardRef(_Final, _root=True): def __init__(self, arg, is_argument=True): if not isinstance(arg, str): raise TypeError(f"Forward reference must be a string -- got {arg!r}") + + # Double-stringified forward references is a result of activating + # the 'annotations' future by default. This way, we eliminate them in + # the runtime. + if arg.startswith(("'", '\"')) and arg.endswith(("'", '"')): + arg = arg[1:-1] + try: code = compile(arg, '', 'eval') except SyntaxError: diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-27-16-08-16.bpo-38605.rcs2uK.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-27-16-08-16.bpo-38605.rcs2uK.rst new file mode 100644 index 000000000000000..cbfe6e23523bbe9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-27-16-08-16.bpo-38605.rcs2uK.rst @@ -0,0 +1,3 @@ +Enable ``from __future__ import annotations`` (:pep:`563`) by default. +The values found in :attr:`__annotations__` dicts are now strings, e.g. +``{"x": "int"}`` instead of ``{"x": int}``. diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 5efaac4c8925a98..22ca6f23aefa30a 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -392,7 +392,6 @@ static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); #define CALL(FUNC, TYPE, ARG) \ @@ -595,25 +594,11 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - CALL_SEQ(astfold_arg, arg, node_->posonlyargs); - CALL_SEQ(astfold_arg, arg, node_->args); - CALL_OPT(astfold_arg, arg_ty, node_->vararg); - CALL_SEQ(astfold_arg, arg, node_->kwonlyargs); CALL_SEQ(astfold_expr, expr, node_->kw_defaults); - CALL_OPT(astfold_arg, arg_ty, node_->kwarg); CALL_SEQ(astfold_expr, expr, node_->defaults); return 1; } -static int -astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->annotation); - } - return 1; -} - static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { @@ -622,17 +607,11 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); - } break; case AsyncFunctionDef_kind: CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); - } break; case ClassDef_kind: CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases); @@ -656,9 +635,6 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) break; case AnnAssign_kind: CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation); - } CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value); break; case For_kind: diff --git a/Python/compile.c b/Python/compile.c index f2563d7f7a411cb..ddd2a049629c1f2 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2026,12 +2026,7 @@ compiler_visit_argannotation(struct compiler *c, identifier id, { if (annotation) { PyObject *mangled; - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, annotation) - } - else { - VISIT(c, expr, annotation); - } + VISIT(c, annexpr, annotation); mangled = _Py_Mangle(c->u->u_private, id); if (!mangled) return 0; @@ -5261,12 +5256,7 @@ compiler_annassign(struct compiler *c, stmt_ty s) if (s->v.AnnAssign.simple && (c->u->u_scope_type == COMPILER_SCOPE_MODULE || c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, s->v.AnnAssign.annotation) - } - else { - VISIT(c, expr, s->v.AnnAssign.annotation); - } + VISIT(c, annexpr, s->v.AnnAssign.annotation); ADDOP_NAME(c, LOAD_NAME, __annotations__, names); mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); ADDOP_LOAD_CONST_NEW(c, mangled); diff --git a/Python/future.c b/Python/future.c index 3cea4fee78085c7..4b73eb641290528 100644 --- a/Python/future.c +++ b/Python/future.c @@ -41,7 +41,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) { continue; } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) { - ff->ff_features |= CO_FUTURE_ANNOTATIONS; + continue; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); From 0fb1255c1ad6f16f55bffd63d1b4401f8a394927 Mon Sep 17 00:00:00 2001 From: Stefan Pochmann <609905+pochmann@users.noreply.github.com> Date: Wed, 7 Oct 2020 16:12:52 +0200 Subject: [PATCH 424/486] Fix comment about PyObject_IsTrue. (GH-22343) The `for` statement doesn't use a condition and this function, the `while` statement does. --- Objects/object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/object.c b/Objects/object.c index fe3734404f5cf97..9889503cfd89384 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1387,7 +1387,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) } -/* Test a value used as condition, e.g., in a for or if statement. +/* Test a value used as condition, e.g., in a while or if statement. Return -1 if an error occurred */ int From 04474001785559dd8c12ff51bb47f9bb3c71c5c8 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 8 Oct 2020 00:44:31 +0300 Subject: [PATCH 425/486] bpo-41923: PEP 613: Add TypeAlias to typing module (#22532) This special marker annotation is intended to help in distinguishing proper PEP 484-compliant type aliases from regular top-level variable assignments. --- Doc/library/typing.rst | 13 ++++++ Doc/whatsnew/3.10.rst | 25 +++++++++++- Lib/test/test_typing.py | 40 +++++++++++++++++++ Lib/typing.py | 16 ++++++++ Misc/ACKS | 1 + .../2020-10-03-23-14-50.bpo-41923.Buonw9.rst | 1 + 6 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-03-23-14-50.bpo-41923.Buonw9.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index a72632e61b07307..f4b2718cdc2f8ce 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -34,6 +34,8 @@ In the function ``greeting``, the argument ``name`` is expected to be of type :class:`str` and the return type :class:`str`. Subtypes are accepted as arguments. +.. _type-aliases: + Type aliases ============ @@ -489,6 +491,17 @@ These can be used as types in annotations and do not support ``[]``. .. versionadded:: 3.5.4 .. versionadded:: 3.6.2 +.. data:: TypeAlias + + Special annotation for explicitly declaring a :ref:`type alias `. + For example:: + + from typing import TypeAlias + + Factors: TypeAlias = list[int] + + .. versionadded:: 3.10 + Special forms """"""""""""" diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 2bcdba69957b61a..4ada4be3b667151 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -99,8 +99,29 @@ in :issue:`38605`.) * :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used to require that all the iterables have an equal length. -PEP604: New Type Operator -------------------------- +PEP 613: TypeAlias Annotation +----------------------------- + +:pep:`484` introduced the concept of type aliases, only requiring them to be +top-level unannotated assignments. This simplicity sometimes made it difficult +for type checkers to distinguish between type aliases and ordinary assignments, +especially when forward references or invalid types were involved. Compare:: + + StrCache = 'Cache[str]' # a type alias + LOG_PREFIX = 'LOG[DEBUG]' # a module constant + +Now the :mod:`typing` module has a special annotation :data:`TypeAlias` to +declare type aliases more explicitly:: + + StrCache: TypeAlias = 'Cache[str]' # a type alias + LOG_PREFIX = 'LOG[DEBUG]' # a module constant + +See :pep:`613` for more details. + +(Contributed by Mikhail Golubev in :issue:`41923`.) + +PEP604: New Type Union Operator +------------------------------- A new type union operator was introduced which enables the syntax ``X | Y``. This provides a cleaner way of expressing 'either type X or type Y' instead of diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 4bef42f4f32fc7b..57dd73c529da56e 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -24,6 +24,7 @@ from typing import IO, TextIO, BinaryIO from typing import Pattern, Match from typing import Annotated, ForwardRef +from typing import TypeAlias import abc import typing import weakref @@ -4176,6 +4177,45 @@ def test_annotated_in_other_types(self): self.assertEqual(X[int], List[Annotated[int, 5]]) +class TypeAliasTests(BaseTestCase): + def test_canonical_usage_with_variable_annotation(self): + Alias: TypeAlias = Employee + + def test_canonical_usage_with_type_comment(self): + Alias = Employee # type: TypeAlias + + def test_cannot_instantiate(self): + with self.assertRaises(TypeError): + TypeAlias() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(42, TypeAlias) + + def test_no_issubclass(self): + with self.assertRaises(TypeError): + issubclass(Employee, TypeAlias) + + with self.assertRaises(TypeError): + issubclass(TypeAlias, Employee) + + def test_cannot_subclass(self): + with self.assertRaises(TypeError): + class C(TypeAlias): + pass + + with self.assertRaises(TypeError): + class C(type(TypeAlias)): + pass + + def test_repr(self): + self.assertEqual(repr(TypeAlias), 'typing.TypeAlias') + + def test_cannot_subscript(self): + with self.assertRaises(TypeError): + TypeAlias[int] + + class AllTests(BaseTestCase): """Tests for __all__.""" diff --git a/Lib/typing.py b/Lib/typing.py index 4cf33c1ae92659b..0f457ab1f56dfcd 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -113,6 +113,7 @@ 'runtime_checkable', 'Text', 'TYPE_CHECKING', + 'TypeAlias', ] # The pseudo-submodules 're' and 'io' are part of the public @@ -460,6 +461,21 @@ def open_helper(file: str, mode: MODE) -> str: return _GenericAlias(self, parameters) +@_SpecialForm +def TypeAlias(self, parameters): + """Special marker indicating that an assignment should + be recognized as a proper type alias definition by type + checkers. + + For example:: + + Predicate: TypeAlias = Callable[..., bool] + + It's invalid when used anywhere except as in the example above. + """ + raise TypeError(f"{self} is not subscriptable") + + class ForwardRef(_Final, _root=True): """Internal wrapper to hold a forward reference.""" diff --git a/Misc/ACKS b/Misc/ACKS index 08449fe08269bdb..7d445c57214558b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -611,6 +611,7 @@ Christoph Gohlke Tim Golden Yonatan Goldschmidt Mark Gollahon +Mikhail Golubev Guilherme Gonçalves Tiago Gonçalves Chris Gonnerman diff --git a/Misc/NEWS.d/next/Library/2020-10-03-23-14-50.bpo-41923.Buonw9.rst b/Misc/NEWS.d/next/Library/2020-10-03-23-14-50.bpo-41923.Buonw9.rst new file mode 100644 index 000000000000000..dd9a1f709f33ff5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-03-23-14-50.bpo-41923.Buonw9.rst @@ -0,0 +1 @@ +Implement :pep:`613`, introducing :data:`typing.TypeAlias` annotation. From 9237628f2f4026ab26c580841d5e066470de7a54 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 7 Oct 2020 16:43:44 -0700 Subject: [PATCH 426/486] Revert "bpo-26680: Incorporate is_integer in all built-in and standard library numeric types (GH-6121)" (GH-22584) This reverts commit 58a7da9e125422323f79c4ee95ac5549989d8162. --- Doc/library/decimal.rst | 14 ------------ Doc/library/numbers.rst | 26 ++++++--------------- Doc/library/stdtypes.rst | 14 ++++++++---- Lib/_pydecimal.py | 25 --------------------- Lib/numbers.py | 21 +---------------- Lib/test/decimaltestdata/extra.decTest | 18 --------------- Lib/test/test_bool.py | 5 ----- Lib/test/test_decimal.py | 24 -------------------- Lib/test/test_fractions.py | 11 --------- Lib/test/test_long.py | 4 ---- Lib/test/test_numeric_tower.py | 31 -------------------------- Misc/ACKS | 1 - Modules/_decimal/_decimal.c | 6 ++--- Modules/_decimal/docstrings.h | 13 +++-------- Objects/clinic/longobject.c.h | 20 +---------------- Objects/longobject.c | 14 ------------ 16 files changed, 24 insertions(+), 223 deletions(-) diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 7a6497305952f1e..e194649e30d85c0 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -621,13 +621,6 @@ Decimal objects Return :const:`True` if the argument is either positive or negative infinity and :const:`False` otherwise. - .. method:: is_integer() - - Return :const:`True` if the argument is a finite integral value and - :const:`False` otherwise. - - .. versionadded:: 3.10 - .. method:: is_nan() Return :const:`True` if the argument is a (quiet or signaling) NaN and @@ -1222,13 +1215,6 @@ In addition to the three supplied contexts, new contexts can be created with the Returns ``True`` if *x* is infinite; otherwise returns ``False``. - .. method:: is_integer(x) - - Returns ``True`` if *x* is finite and integral; otherwise - returns ``False``. - - .. versionadded:: 3.10 - .. method:: is_nan(x) Returns ``True`` if *x* is a qNaN or sNaN; otherwise returns ``False``. diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index 5d49f5eb96b7ad8..1b594952ead7241 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -49,30 +49,19 @@ The numeric tower numbers. In short, those are: a conversion to :class:`float`, :func:`math.trunc`, - :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, - :func:`~Real.is_integer`, ``//``, ``%``, ``<``, ``<=``, ``>``, and ``>=``. + :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``, + ``%``, ``<``, ``<=``, ``>``, and ``>=``. Real also provides defaults for :func:`complex`, :attr:`~Complex.real`, :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`. - .. method:: is_integer() - - Returns :const:`True` if this number has a finite and integral value, - otherwise :const:`False`. This is a default implementation which - relies on successful conversion to :class:`int`. It may be overridden - in subclasses (such as it is in :class:`float`) for better performance, - or to handle special values such as NaN which are not - convertible to :class:`int`. - - .. versionadded:: 3.10 - .. class:: Rational Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which - should be in lowest terms. With these, it provides defaults for - :func:`float` and :func:`~Real.is_integer`. + should be in lowest terms. With these, it provides a default for + :func:`float`. .. attribute:: numerator @@ -86,10 +75,9 @@ The numeric tower .. class:: Integral Subtypes :class:`Rational` and adds a conversion to :class:`int`. Provides - defaults for :func:`float`, :attr:`~Rational.numerator`, - :attr:`~Rational.denominator`, and :func:`~Real.is_integer`. Adds abstract - methods for ``**`` and bit-string operations: ``<<``, ``>>``, ``&``, ``^``, - ``|``, ``~``. + defaults for :func:`float`, :attr:`~Rational.numerator`, and + :attr:`~Rational.denominator`. Adds abstract methods for ``**`` and + bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, ``~``. Notes for type implementors diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 04dfea276d2b1e5..5c6acc66bb4cc3c 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -310,10 +310,6 @@ the operations, see :ref:`operator-summary`): +---------------------+---------------------------------+---------+--------------------+ | ``x ** y`` | *x* to the power *y* | \(5) | | +---------------------+---------------------------------+---------+--------------------+ -| ``x.is_integer()`` | ``True`` if *x* has a finite | | :func:`~numbers\ | -| | and integral value, otherwise | | .Real.is_integer` | -| | ``False``. | | | -+---------------------+---------------------------------+---------+--------------------+ .. index:: triple: operations on; numeric; types @@ -587,6 +583,16 @@ class`. float also has the following additional methods. :exc:`OverflowError` on infinities and a :exc:`ValueError` on NaNs. +.. method:: float.is_integer() + + Return ``True`` if the float instance is finite with integral + value, and ``False`` otherwise:: + + >>> (-2.0).is_integer() + True + >>> (3.2).is_integer() + False + Two methods support conversion to and from hexadecimal strings. Since Python's floats are stored internally as binary numbers, converting a float to or from a diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 8c0ef570922197b..ab989e5206a9e90 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -3164,12 +3164,6 @@ def is_zero(self): """Return True if self is a zero; otherwise return False.""" return not self._is_special and self._int == '0' - def is_integer(self): - """Return True is self is finite and integral; otherwise False.""" - if self._is_special: - return False - return self.to_integral_value(rounding=ROUND_FLOOR) == self - def _ln_exp_bound(self): """Compute a lower bound for the adjusted exponent of self.ln(). In other words, compute r such that self.ln() >= 10**r. Assumes @@ -4665,25 +4659,6 @@ def is_zero(self, a): a = _convert_other(a, raiseit=True) return a.is_zero() - def is_integer(self, a): - """Return True if the operand is integral; otherwise return False. - - >>> ExtendedContext.is_integer(Decimal('0')) - True - >>> ExtendedContext.is_integer(Decimal('2.50')) - False - >>> ExtendedContext.is_integer(Decimal('-0E+2')) - True - >>> ExtendedContext.is_integer(Decimal('-0.5')) - False - >>> ExtendedContext.is_integer(Decimal('NaN')) - False - >>> ExtendedContext.is_integer(10) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_integer() - def ln(self, a): """Returns the natural (base e) logarithm of the operand. diff --git a/Lib/numbers.py b/Lib/numbers.py index 0634f62ff123c46..ed815ef41ebe121 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -148,7 +148,7 @@ class Real(Complex): """To Complex, Real adds the operations that work on real numbers. In short, those are: a conversion to float, trunc(), divmod, - is_integer, %, <, <=, >, and >=. + %, <, <=, >, and >=. Real also provides defaults for the derived operations. """ @@ -242,17 +242,6 @@ def __le__(self, other): """self <= other""" raise NotImplementedError - def is_integer(self): - """Return True if the Real is integral; otherwise return False. - - This default implementation can be overridden in subclasses - for performance reasons or to deal with values such as NaN, - which would otherwise cause an exception to be raised. - """ - # Although __int__ is not defined at this level, the int - # constructor falls back to __trunc__, which we do have. - return self == int(self) - # Concrete implementations of Complex abstract methods. def __complex__(self): """complex(self) == complex(float(self), 0)""" @@ -301,10 +290,6 @@ def __float__(self): """ return self.numerator / self.denominator - def is_integer(self): - """Return True if the Rational is integral; otherwise return False.""" - return self.denominator == 1 - class Integral(Rational): """Integral adds a conversion to int and the bit-string operations.""" @@ -401,8 +386,4 @@ def denominator(self): """Integers have a denominator of 1.""" return 1 - def is_integer(self): - """Return True; all Integrals represent an integral value.""" - return True - Integral.register(int) diff --git a/Lib/test/decimaltestdata/extra.decTest b/Lib/test/decimaltestdata/extra.decTest index 2f0719ed22342a2..b630d8e3f9d45ed 100644 --- a/Lib/test/decimaltestdata/extra.decTest +++ b/Lib/test/decimaltestdata/extra.decTest @@ -2346,24 +2346,6 @@ bool2096 iszero sNaN -> 0 bool2097 iszero -sNaN -> 0 bool2098 iszero sNaN123 -> 0 bool2099 iszero -sNaN123 -> 0 -bool2100 is_integer -1.0 -> 1 -bool2101 is_integer 0.0 -> 1 -bool2102 is_integer 1.0 -> 1 -bool2103 is_integer 42 -> 1 -bool2104 is_integer 1e2 -> 1 -bool2105 is_integer 1.5 -> 0 -bool2106 is_integer 1e-2 -> 0 -bool2107 is_integer NaN -> 0 -bool2109 is_integer -NaN -> 0 -bool2110 is_integer NaN123 -> 0 -bool2111 is_integer -NaN123 -> 0 -bool2112 is_integer sNaN -> 0 -bool2113 is_integer -sNaN -> 0 -bool2114 is_integer sNaN123 -> 0 -bool2115 is_integer -sNaN123 -> 0 -bool2116 is_integer Infinity -> 0 -bool2117 is_integer -Infinity -> 0 - ------------------------------------------------------------------------ -- The following tests (pwmx0 through pwmx440) are for the -- diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index bc201e10ff2671f..7b3a3859e089325 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -354,11 +354,6 @@ def test_real_and_imag(self): self.assertIs(type(False.real), int) self.assertIs(type(False.imag), int) - def test_always_is_integer(self): - # Issue #26680: Incorporating number.is_integer into bool - self.assertTrue(all(b.is_integer() for b in (False, True))) - - def test_main(): support.run_unittest(BoolTest) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index efb41fd46505661..dbd58e8a6519b19 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -276,7 +276,6 @@ def setUp(self): 'is_snan', 'is_subnormal', 'is_zero', - 'is_integer', 'same_quantum') def read_unlimited(self, v, context): @@ -2727,7 +2726,6 @@ def test_named_parameters(self): self.assertRaises(TypeError, D(1).is_snan, context=xc) self.assertRaises(TypeError, D(1).is_signed, context=xc) self.assertRaises(TypeError, D(1).is_zero, context=xc) - self.assertRaises(TypeError, D(1).is_integer, context=xc) self.assertFalse(D("0.01").is_normal(context=xc)) self.assertTrue(D("0.01").is_subnormal(context=xc)) @@ -3199,15 +3197,6 @@ def test_is_zero(self): self.assertEqual(c.is_zero(10), d) self.assertRaises(TypeError, c.is_zero, '10') - def test_is_integer(self): - Decimal = self.decimal.Decimal - Context = self.decimal.Context - - c = Context() - b = c.is_integer(Decimal(10)) - self.assertEqual(c.is_integer(10), b) - self.assertRaises(TypeError, c.is_integer, '10') - def test_ln(self): Decimal = self.decimal.Decimal Context = self.decimal.Context @@ -4371,19 +4360,6 @@ def test_implicit_context(self): self.assertTrue(Decimal("-1").is_signed()) self.assertTrue(Decimal("0").is_zero()) self.assertTrue(Decimal("0").is_zero()) - self.assertTrue(Decimal("-1").is_integer()) - self.assertTrue(Decimal("0").is_integer()) - self.assertTrue(Decimal("1").is_integer()) - self.assertTrue(Decimal("42").is_integer()) - self.assertTrue(Decimal("1e2").is_integer()) - self.assertFalse(Decimal("1.5").is_integer()) - self.assertFalse(Decimal("1e-2").is_integer()) - self.assertFalse(Decimal("NaN").is_integer()) - self.assertFalse(Decimal("-NaN").is_integer()) - self.assertFalse(Decimal("sNaN").is_integer()) - self.assertFalse(Decimal("-sNaN").is_integer()) - self.assertFalse(Decimal("Inf").is_integer()) - self.assertFalse(Decimal("-Inf").is_integer()) # Copy with localcontext() as c: diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 811b58fd8f56aac..0845f7921c39ec7 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -724,17 +724,6 @@ def denominator(self): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) - def test_is_integer(self): - # Issue #26680: Incorporating number.is_integer into Fraction - self.assertTrue(F(-1, 1).is_integer()) - self.assertTrue(F(0, 1).is_integer()) - self.assertTrue(F(1, 1).is_integer()) - self.assertTrue(F(42, 1).is_integer()) - self.assertTrue(F(2, 2).is_integer()) - self.assertTrue(F(8, 4).is_integer()) - self.assertFalse(F(1, 2).is_integer()) - self.assertFalse(F(1, 3).is_integer()) - self.assertFalse(F(2, 3).is_integer()) if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index 669826c0fa3c1bf..c97842b5bfd2338 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1381,10 +1381,6 @@ class myint(int): self.assertEqual(type(numerator), int) self.assertEqual(type(denominator), int) - def test_int_always_is_integer(self): - # Issue #26680: Incorporating number.is_integer into int - self.assertTrue(all(x.is_integer() for x in (-1, 0, 1, 42))) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_numeric_tower.py b/Lib/test/test_numeric_tower.py index 4e46aacad82b6aa..c54dedb8b793a0a 100644 --- a/Lib/test/test_numeric_tower.py +++ b/Lib/test/test_numeric_tower.py @@ -6,7 +6,6 @@ import sys import operator -from numbers import Real, Rational, Integral from decimal import Decimal as D from fractions import Fraction as F @@ -199,35 +198,5 @@ def test_complex(self): self.assertRaises(TypeError, op, v, z) -class IsIntegerTest(unittest.TestCase): - - def test_real_is_integer(self): - self.assertTrue(Real.is_integer(-1.0)) - self.assertTrue(Real.is_integer(0.0)) - self.assertTrue(Real.is_integer(1.0)) - self.assertTrue(Real.is_integer(42.0)) - - self.assertFalse(Real.is_integer(-0.5)) - self.assertFalse(Real.is_integer(4.2)) - - def test_rational_is_integer(self): - self.assertTrue(Rational.is_integer(F(-1, 1))) - self.assertTrue(Rational.is_integer(F(0, 1))) - self.assertTrue(Rational.is_integer(F(1, 1))) - self.assertTrue(Rational.is_integer(F(42, 1))) - self.assertTrue(Rational.is_integer(F(2, 2))) - self.assertTrue(Rational.is_integer(F(8, 4))) - - self.assertFalse(Rational.is_integer(F(1, 2))) - self.assertFalse(Rational.is_integer(F(1, 3))) - self.assertFalse(Rational.is_integer(F(2, 3))) - - def test_integral_is_integer(self): - self.assertTrue(Integral.is_integer(-1)) - self.assertTrue(Integral.is_integer(0)) - self.assertTrue(Integral.is_integer(1)) - self.assertTrue(Integral.is_integer(1729)) - - if __name__ == '__main__': unittest.main() diff --git a/Misc/ACKS b/Misc/ACKS index 7d445c57214558b..660b8ef7504eebc 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1613,7 +1613,6 @@ Roman Skurikhin Ville Skyttä Michael Sloan Nick Sloan -Robert Smallshire Václav Šmilauer Allen W. Smith Christopher Smith diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 5200b1a48e4bfad..e7c44acba02fc2e 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -4138,7 +4138,6 @@ Dec_BoolFunc(mpd_isqnan) Dec_BoolFunc(mpd_issnan) Dec_BoolFunc(mpd_issigned) Dec_BoolFunc(mpd_iszero) -Dec_BoolFunc(mpd_isinteger) /* Boolean functions, optional context arg */ Dec_BoolFuncVA(mpd_isnormal) @@ -4773,7 +4772,6 @@ static PyMethodDef dec_methods [] = { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan }, { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed }, { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, - { "is_integer", dec_mpd_isinteger, METH_NOARGS, doc_is_integer}, /* Boolean functions, optional context arg */ { "is_normal", (PyCFunction)(void(*)(void))dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal }, @@ -5185,7 +5183,6 @@ DecCtx_BoolFunc_NO_CTX(mpd_isqnan) DecCtx_BoolFunc_NO_CTX(mpd_issigned) DecCtx_BoolFunc_NO_CTX(mpd_issnan) DecCtx_BoolFunc_NO_CTX(mpd_iszero) -DecCtx_BoolFunc_NO_CTX(mpd_isinteger) static PyObject * ctx_iscanonical(PyObject *context UNUSED, PyObject *v) @@ -5467,7 +5464,6 @@ static PyMethodDef context_methods [] = { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan }, { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal }, { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero }, - { "is_integer", ctx_mpd_isinteger, METH_O, doc_ctx_is_integer }, /* Functions with a single decimal argument */ { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */ @@ -6101,3 +6097,5 @@ PyInit__decimal(void) return NULL; /* GCOV_NOT_REACHED */ } + + diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index bd602ab278e0edd..f7fd6e795299845 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -260,11 +260,6 @@ Return True if the argument is a (positive or negative) zero and False\n\ otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_integer, -"is_integer($self, /)\n--\n\n\ -Return True if the argument is finite and integral, otherwise False.\n\ -\n"); - PyDoc_STRVAR(doc_ln, "ln($self, /, context=None)\n--\n\n\ Return the natural (base e) logarithm of the operand. The function always\n\ @@ -690,11 +685,6 @@ PyDoc_STRVAR(doc_ctx_is_zero, Return True if x is a zero, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_integer, -"is_integer($self, x, /)\n--\n\n\ -+Return True if x is finite and integral, False otherwise.\n\ -+\n"); - PyDoc_STRVAR(doc_ctx_ln, "ln($self, x, /)\n--\n\n\ Return the natural (base e) logarithm of x.\n\ @@ -889,3 +879,6 @@ Convert a number to a string using scientific notation.\n\ #endif /* DOCSTRINGS_H */ + + + diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 16e6f7e619e8721..4bd47b116f883c6 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -121,24 +121,6 @@ int___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -PyDoc_STRVAR(int_is_integer__doc__, -"is_integer($self, /)\n" -"--\n" -"\n" -"Returns True for all integers."); - -#define INT_IS_INTEGER_METHODDEF \ - {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, - -static PyObject * -int_is_integer_impl(PyObject *self); - -static PyObject * -int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return int_is_integer_impl(self); -} - PyDoc_STRVAR(int___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" @@ -385,4 +367,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb exit: return return_value; } -/*[clinic end generated code: output=022614978e2fcdf3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index bc5b49dcf8b56fc..92514d4154e2cbb 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5233,19 +5233,6 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return result; } -/*[clinic input] -int.is_integer - -Returns True for all integers. -[clinic start generated code]*/ - -static PyObject * -int_is_integer_impl(PyObject *self) -/*[clinic end generated code: output=90f8e794ce5430ef input=1c1a86957301d26d]*/ -{ - Py_RETURN_TRUE; -} - /*[clinic input] int.__sizeof__ -> Py_ssize_t @@ -5560,7 +5547,6 @@ static PyMethodDef long_methods[] = { {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, INT___ROUND___METHODDEF - INT_IS_INTEGER_METHODDEF INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF From 115f99e0ac0d54575807632c47c3584fcd184fa0 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Thu, 8 Oct 2020 08:37:46 +0200 Subject: [PATCH 427/486] bpo-41376: Fix the documentation of `site.getusersitepackages()` (GH-21602) `site.getusersitepackages()` returns the location of the user-specific site-packages directory even when the user-specific site-packages is disabled. ``` $ python -s -m site sys.path = [ '/home/user/conda/lib/python37.zip', '/home/user/conda/lib/python3.7', '/home/user/conda/lib/python3.7/lib-dynload', '/home/user/conda/lib/python3.7/site-packages', ] USER_BASE: '/home/user/.local' (exists) USER_SITE: '/home/user/.local/lib/python3.7/site-packages' (doesn't exist) ENABLE_USER_SITE: False ``` It was not practical to prevent the function from returning None if user-specific site-packages are disabled, since there are other uses of the function which are relying on this behaviour (e.g. `python -m site`). --- Doc/library/site.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/site.rst b/Doc/library/site.rst index b424e1ba348d870..2e3646f6a74f80c 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -231,7 +231,9 @@ Module contents Return the path of the user-specific site-packages directory, :data:`USER_SITE`. If it is not initialized yet, this function will also set - it, respecting :envvar:`PYTHONNOUSERSITE` and :data:`USER_BASE`. + it, respecting :data:`USER_BASE`. To determine if the user-specific + site-packages was added to ``sys.path`` :data:`ENABLE_USER_SITE` should be + used. .. versionadded:: 3.2 From 17484b90541d36052523421277545f68c3e92c35 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 8 Oct 2020 14:24:28 +0100 Subject: [PATCH 428/486] bpo-41970: Avoid test failure in test_lib2to3 if the module is already imported (GH-22595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … Automerge-Triggered-By: @pablogsal --- Lib/test/test_lib2to3.py | 3 ++- .../NEWS.d/next/Tests/2020-10-08-14-00-17.bpo-41970.aZ8QFf.rst | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-10-08-14-00-17.bpo-41970.aZ8QFf.rst diff --git a/Lib/test/test_lib2to3.py b/Lib/test/test_lib2to3.py index 159a8387e4e97d4..fd12a7e7acbb46b 100644 --- a/Lib/test/test_lib2to3.py +++ b/Lib/test/test_lib2to3.py @@ -1,8 +1,9 @@ import unittest +from test.support.import_helper import import_fresh_module from test.support.warnings_helper import check_warnings with check_warnings(("", PendingDeprecationWarning)): - from lib2to3.tests import load_tests + load_tests = import_fresh_module('lib2to3.tests', fresh=['lib2to3']).load_tests if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Tests/2020-10-08-14-00-17.bpo-41970.aZ8QFf.rst b/Misc/NEWS.d/next/Tests/2020-10-08-14-00-17.bpo-41970.aZ8QFf.rst new file mode 100644 index 000000000000000..4cdca197fbfc648 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-10-08-14-00-17.bpo-41970.aZ8QFf.rst @@ -0,0 +1,2 @@ +Avoid a test failure in ``test_lib2to3`` if the module has already imported +at the time the test executes. Patch by Pablo Galindo. From 3f0137dd1e69a034b4d1a496a4e9f067e9c56757 Mon Sep 17 00:00:00 2001 From: E-Paine <63801254+E-Paine@users.noreply.github.com> Date: Thu, 8 Oct 2020 14:30:13 +0100 Subject: [PATCH 429/486] bpo-41306: Allow scale value to not be rounded (GH-21715) This fixes the test failure with Tk 6.8.10 which is caused by changes to how Tk rounds the `from`, `to` and `tickinterval` arguments. This PR uses `noconv` if the patchlevel is greater than or equal to 8.6.10 (credit to Serhiy for this idea as it is much simpler than what I previously proposed). Going into more detail for those who want it, the Tk change was made in [commit 591f68c](https://github.com/tcltk/tk/commit/591f68cb382525b72664c6fecaab87742b6cc87a) and means that the arguments listed above are rounded relative to the value of `from`. However, when rounding the `from` argument ([line 623](https://github.com/tcltk/tk/blob/591f68cb382525b72664c6fecaab87742b6cc87a/generic/tkScale.c#L623)), it is rounded relative to itself (i.e. rounding `0`) and therefore the assigned value for `from` is always what is given (no matter what values of `from` and `resolution`). Automerge-Triggered-By: @pablogsal --- Lib/tkinter/test/test_tkinter/test_widgets.py | 3 ++- .../NEWS.d/next/Tests/2020-08-03-13-44-37.bpo-41306.VDoWXI.rst | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-08-03-13-44-37.bpo-41306.VDoWXI.rst diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index 721e81369a8d5b7..b6f792d6c2cf856 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -940,7 +940,8 @@ def test_digits(self): def test_from(self): widget = self.create() - self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=float_round) + conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round + self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_label(self): widget = self.create() diff --git a/Misc/NEWS.d/next/Tests/2020-08-03-13-44-37.bpo-41306.VDoWXI.rst b/Misc/NEWS.d/next/Tests/2020-08-03-13-44-37.bpo-41306.VDoWXI.rst new file mode 100644 index 000000000000000..5e9ba2d8a27417e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-08-03-13-44-37.bpo-41306.VDoWXI.rst @@ -0,0 +1 @@ +Fixed a failure in ``test_tk.test_widgets.ScaleTest`` happening when executing the test with Tk 8.6.10. From 9ae339db20276f3c204b7cfc0fb95c155a0be71c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 8 Oct 2020 19:31:19 +0100 Subject: [PATCH 430/486] bpo-41976: Fix the fallback to gcc of ctypes.util.find_library when using gcc>9 (GH-22598) --- Lib/ctypes/test/test_find.py | 12 +++++++- Lib/ctypes/util.py | 30 +++++++++++++++---- .../2020-10-08-18-22-28.bpo-41976.Svm0wb.rst | 3 ++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py index bfb6b42cbb22771..4a8a3820f3fe1c0 100644 --- a/Lib/ctypes/test/test_find.py +++ b/Lib/ctypes/test/test_find.py @@ -1,4 +1,5 @@ import unittest +import unittest.mock import os.path import sys import test.support @@ -73,7 +74,7 @@ def test_shell_injection(self): @unittest.skipUnless(sys.platform.startswith('linux'), 'Test only valid for Linux') -class LibPathFindTest(unittest.TestCase): +class FindLibraryLinux(unittest.TestCase): def test_find_on_libpath(self): import subprocess import tempfile @@ -112,6 +113,15 @@ def test_find_on_libpath(self): # LD_LIBRARY_PATH) self.assertEqual(find_library(libname), 'lib%s.so' % libname) + def test_find_library_with_gcc(self): + with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None): + self.assertNotEqual(find_library('c'), None) + + def test_find_library_with_ld(self): + with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \ + unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None): + self.assertNotEqual(find_library('c'), None) + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 01176bf96965770..0c2510e1619c8ed 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -93,6 +93,12 @@ def find_library(name): # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump import re, tempfile + def _is_elf(filename): + "Return True if the given file is an ELF file" + elf_header = b'\x7fELF' + with open(filename, 'br') as thefile: + return thefile.read(4) == elf_header + def _findLib_gcc(name): # Run GCC's linker with the -t (aka --trace) option and examine the # library name it prints out. The GCC command will fail because we @@ -130,10 +136,17 @@ def _findLib_gcc(name): # Raised if the file was already removed, which is the normal # behaviour of GCC if linking fails pass - res = re.search(expr, trace) + res = re.findall(expr, trace) if not res: return None - return os.fsdecode(res.group(0)) + + for file in res: + # Check if the given file is an elf file: gcc can report + # some files that are linker scripts and not actual + # shared objects. See bpo-41976 for more details + if not _is_elf(file): + continue + return os.fsdecode(file) if sys.platform == "sunos5": @@ -299,9 +312,14 @@ def _findLib_ld(name): stderr=subprocess.PIPE, universal_newlines=True) out, _ = p.communicate() - res = re.search(expr, os.fsdecode(out)) - if res: - result = res.group(0) + res = re.findall(expr, os.fsdecode(out)) + for file in res: + # Check if the given file is an elf file: gcc can report + # some files that are linker scripts and not actual + # shared objects. See bpo-41976 for more details + if not _is_elf(file): + continue + return os.fsdecode(file) except Exception: pass # result will be None return result @@ -309,7 +327,7 @@ def _findLib_ld(name): def find_library(name): # See issue #9998 return _findSoname_ldconfig(name) or \ - _get_soname(_findLib_gcc(name) or _findLib_ld(name)) + _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) ################################################################ # test code diff --git a/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst b/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst new file mode 100644 index 000000000000000..c8b3fc771845e3c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst @@ -0,0 +1,3 @@ +Fixed a bug that was causing :func:`ctypes.util.find_library` to return +``None`` when triying to locate a library in an environment when gcc>=9 is +available and ``ldconfig`` is not. Patch by Pablo Galindo From f5ef6e86f0cd7f66b17339a8da4c3ea45f1e563b Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Thu, 8 Oct 2020 20:40:27 +0200 Subject: [PATCH 431/486] bpo-41557: Update Windows installer to use SQLite 3.33.0 (GH-21960) --- .../next/Windows/2020-08-26-09-35-06.bpo-41557.vt00cQ.rst | 1 + PCbuild/get_externals.bat | 2 +- PCbuild/python.props | 2 +- PCbuild/readme.txt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2020-08-26-09-35-06.bpo-41557.vt00cQ.rst diff --git a/Misc/NEWS.d/next/Windows/2020-08-26-09-35-06.bpo-41557.vt00cQ.rst b/Misc/NEWS.d/next/Windows/2020-08-26-09-35-06.bpo-41557.vt00cQ.rst new file mode 100644 index 000000000000000..9d85461f00923f8 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-08-26-09-35-06.bpo-41557.vt00cQ.rst @@ -0,0 +1 @@ +Update Windows installer to use SQLite 3.33.0. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index a48b59cad2ed1c1..3bb281904f6a618 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ set libraries= set libraries=%libraries% bzip2-1.0.6 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g -set libraries=%libraries% sqlite-3.32.3.0 +set libraries=%libraries% sqlite-3.33.0.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 diff --git a/PCbuild/python.props b/PCbuild/python.props index 5f4926efa25172c..acc41a2c017684d 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -56,7 +56,7 @@ $(EXTERNALS_DIR) $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ - $(ExternalsDir)sqlite-3.32.3.0\ + $(ExternalsDir)sqlite-3.33.0.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index b8849757e893a78..73833d54637d5fa 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -185,7 +185,7 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.32.3.0, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.33.0, which is itself built by sqlite3.vcxproj Homepage: http://www.sqlite.org/ _tkinter From 66487616421ca095d4594a9efab884d1273bdfc7 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 9 Oct 2020 03:20:57 +0800 Subject: [PATCH 432/486] bpo-39337: Add a test case for normalizing of codec names (GH-19069) --- Lib/test/test_codecs.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index ed508f36ad42343..ddf4e08af6247a3 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3415,5 +3415,30 @@ def test_rot13_func(self): 'To be, or not to be, that is the question') +class CodecNameNormalizationTest(unittest.TestCase): + """Test codec name normalization""" + def test_normalized_encoding(self): + FOUND = (1, 2, 3, 4) + NOT_FOUND = (None, None, None, None) + def search_function(encoding): + if encoding == "aaa_8": + return FOUND + else: + return NOT_FOUND + + codecs.register(search_function) + self.addCleanup(codecs.unregister, search_function) + self.assertEqual(FOUND, codecs.lookup('aaa_8')) + self.assertEqual(FOUND, codecs.lookup('AAA-8')) + self.assertEqual(FOUND, codecs.lookup('AAA---8')) + self.assertEqual(FOUND, codecs.lookup('AAA 8')) + self.assertEqual(FOUND, codecs.lookup('aaa\xe9\u20ac-8')) + self.assertEqual(NOT_FOUND, codecs.lookup('AAA.8')) + self.assertEqual(NOT_FOUND, codecs.lookup('AAA...8')) + self.assertEqual(NOT_FOUND, codecs.lookup('BBB-8')) + self.assertEqual(NOT_FOUND, codecs.lookup('BBB.8')) + self.assertEqual(NOT_FOUND, codecs.lookup('a\xe9\u20ac-8')) + + if __name__ == "__main__": unittest.main() From 80c1a535700af04decccf8a122a9851919bd8502 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Fri, 9 Oct 2020 00:38:36 +0300 Subject: [PATCH 433/486] Fix the attribute names in the docstring of GenericAlias (GH-22594) --- Objects/genericaliasobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index ab56e1c4bf1a860..6508c69cbf7e361 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -582,7 +582,7 @@ PyTypeObject Py_GenericAliasType = { .tp_name = "types.GenericAlias", .tp_doc = "Represent a PEP 585 generic type\n" "\n" - "E.g. for t = list[int], t.origin is list and t.args is (int,).", + "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", .tp_basicsize = sizeof(gaobject), .tp_dealloc = ga_dealloc, .tp_repr = ga_repr, From 2942af1d296b7363cb0cac8a577ed45410d479b4 Mon Sep 17 00:00:00 2001 From: Nishit Date: Fri, 9 Oct 2020 15:02:15 +0530 Subject: [PATCH 434/486] Updated README for python 3.10 (GH-22605) Updated python version and link to the release schedule --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 176562cae308b7e..33ccfc01d9c291e 100644 --- a/README.rst +++ b/README.rst @@ -244,7 +244,7 @@ All current PEPs, as well as guidelines for submitting a new PEP, are listed at Release Schedule ---------------- -See :pep:`596` for Python 3.9 release details. +See :pep:`619` for Python 3.10 release details. Copyright and License Information From 6d3d9f55499f9ad15a946c74b68852b9e18bad7d Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Fri, 9 Oct 2020 12:56:48 +0300 Subject: [PATCH 435/486] bpo-41979: Accept star-unpacking on with-item targets (GH-22611) Co-authored-by: Pablo Galindo --- Grammar/python.gram | 2 +- Lib/test/test_with.py | 8 +++++++- .../2020-10-09-10-55-50.bpo-41979.ImXIk2.rst | 1 + Parser/parser.c | 15 +++++++++------ 4 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-09-10-55-50.bpo-41979.ImXIk2.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index e4533b1a1b87971..2f52bd7f2f6a41a 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -182,7 +182,7 @@ with_stmt[stmt_ty]: | ASYNC 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) } with_item[withitem_ty]: - | e=expression 'as' t=target &(',' | ')' | ':') { _Py_withitem(e, t, p->arena) } + | e=expression 'as' t=star_target &(',' | ')' | ':') { _Py_withitem(e, t, p->arena) } | invalid_with_item | e=expression { _Py_withitem(e, NULL, p->arena) } diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index b1d7a15b5e4ee3a..f21bf65fed8499d 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -7,7 +7,7 @@ import sys import unittest from collections import deque -from contextlib import _GeneratorContextManager, contextmanager +from contextlib import _GeneratorContextManager, contextmanager, nullcontext class MockContextManager(_GeneratorContextManager): @@ -641,6 +641,12 @@ class B: pass self.assertEqual(blah.two, 2) self.assertEqual(blah.three, 3) + def testWithExtendedTargets(self): + with nullcontext(range(1, 5)) as (a, *b, c): + self.assertEqual(a, 1) + self.assertEqual(b, [2, 3]) + self.assertEqual(c, 4) + class ExitSwallowsExceptionTestCase(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-09-10-55-50.bpo-41979.ImXIk2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-09-10-55-50.bpo-41979.ImXIk2.rst new file mode 100644 index 000000000000000..3250309ca22cd31 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-09-10-55-50.bpo-41979.ImXIk2.rst @@ -0,0 +1 @@ +Star-unpacking is now allowed for with item's targets in the PEG parser. diff --git a/Parser/parser.c b/Parser/parser.c index 1bd74a38fbc2bae..0d92256a3ebe2d7 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -4290,7 +4290,10 @@ with_stmt_rule(Parser *p) return _res; } -// with_item: expression 'as' target &(',' | ')' | ':') | invalid_with_item | expression +// with_item: +// | expression 'as' star_target &(',' | ')' | ':') +// | invalid_with_item +// | expression static withitem_ty with_item_rule(Parser *p) { @@ -4301,12 +4304,12 @@ with_item_rule(Parser *p) } withitem_ty _res = NULL; int _mark = p->mark; - { // expression 'as' target &(',' | ')' | ':') + { // expression 'as' star_target &(',' | ')' | ':') if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' target &(',' | ')' | ':')")); + D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); Token * _keyword; expr_ty e; expr_ty t; @@ -4315,12 +4318,12 @@ with_item_rule(Parser *p) && (_keyword = _PyPegen_expect_token(p, 520)) // token='as' && - (t = target_rule(p)) // target + (t = star_target_rule(p)) // star_target && _PyPegen_lookahead(1, _tmp_47_rule, p) ) { - D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' target &(',' | ')' | ':')")); + D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); _res = _Py_withitem ( e , t , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -4331,7 +4334,7 @@ with_item_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s with_item[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' target &(',' | ')' | ':')")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); } { // invalid_with_item if (p->error_indicator) { From 9420ce0f7a8d6636b55573362c171fc1be60956d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 14:14:37 +0300 Subject: [PATCH 436/486] bpo-41974: Remove complex.__float__, complex.__floordiv__, etc (GH-22593) Remove complex special methods __int__, __float__, __floordiv__, __mod__, __divmod__, __rfloordiv__, __rmod__ and __rdivmod__ which always raised a TypeError. --- Doc/whatsnew/3.10.rst | 6 ++ Lib/test/test_complex.py | 62 ++++++++++++++++--- .../2020-10-08-09-58-19.bpo-41974.8B-q8O.rst | 4 ++ Objects/abstract.c | 10 +-- Objects/bytesobject.c | 2 +- Objects/complexobject.c | 59 ++++-------------- Objects/floatobject.c | 2 +- Objects/unicodeobject.c | 2 +- 8 files changed, 81 insertions(+), 66 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-08-09-58-19.bpo-41974.8B-q8O.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 4ada4be3b667151..7401ba722fb4f98 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -255,6 +255,12 @@ Deprecated Removed ======= +* Removed special methods ``__int__``, ``__float__``, ``__floordiv__``, + ``__mod__``, ``__divmod__``, ``__rfloordiv__``, ``__rmod__`` and + ``__rdivmod__`` of the :class:`complex` class. They always raised + a :exc:`TypeError`. + (Contributed by Serhiy Storchaka in :issue:`41974`.) + * The ``ParserBase.error()`` method from the private and undocumented ``_markupbase`` module has been removed. :class:`html.parser.HTMLParser` is the only subclass of ``ParserBase`` and its ``error()`` implementation has already been removed in diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index d1f241f7a60c9fb..af39ee878dc913d 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -11,6 +11,14 @@ NAN = float("nan") # These tests ensure that complex math does the right thing +ZERO_DIVISION = ( + (1+1j, 0+0j), + (1+1j, 0.0), + (1+1j, 0), + (1.0, 0+0j), + (1, 0+0j), +) + class ComplexTest(unittest.TestCase): def assertAlmostEqual(self, a, b): @@ -99,20 +107,34 @@ def test_truediv(self): self.check_div(complex(random(), random()), complex(random(), random())) - self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) - self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) - self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) - self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: z = complex(0, 0) / complex(denom_real, denom_imag) self.assertTrue(isnan(z.real)) self.assertTrue(isnan(z.imag)) + def test_truediv_zero_division(self): + for a, b in ZERO_DIVISION: + with self.assertRaises(ZeroDivisionError): + a / b + def test_floordiv(self): - self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) - self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) + with self.assertRaises(TypeError): + (1+1j) // (1+0j) + with self.assertRaises(TypeError): + (1+1j) // 1.0 + with self.assertRaises(TypeError): + (1+1j) // 1 + with self.assertRaises(TypeError): + 1.0 // (1+0j) + with self.assertRaises(TypeError): + 1 // (1+0j) + + def test_floordiv_zero_division(self): + for a, b in ZERO_DIVISION: + with self.assertRaises(TypeError): + a // b def test_richcompare(self): self.assertIs(complex.__eq__(1+1j, 1<<10000), False) @@ -159,13 +181,32 @@ def check(n, deltas, is_equal, imag = 0.0): def test_mod(self): # % is no longer supported on complex numbers - self.assertRaises(TypeError, (1+1j).__mod__, 0+0j) - self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0) - self.assertRaises(TypeError, (1+1j).__mod__, 4.3j) + with self.assertRaises(TypeError): + (1+1j) % (1+0j) + with self.assertRaises(TypeError): + (1+1j) % 1.0 + with self.assertRaises(TypeError): + (1+1j) % 1 + with self.assertRaises(TypeError): + 1.0 % (1+0j) + with self.assertRaises(TypeError): + 1 % (1+0j) + + def test_mod_zero_division(self): + for a, b in ZERO_DIVISION: + with self.assertRaises(TypeError): + a % b def test_divmod(self): self.assertRaises(TypeError, divmod, 1+1j, 1+0j) - self.assertRaises(TypeError, divmod, 1+1j, 0+0j) + self.assertRaises(TypeError, divmod, 1+1j, 1.0) + self.assertRaises(TypeError, divmod, 1+1j, 1) + self.assertRaises(TypeError, divmod, 1.0, 1+0j) + self.assertRaises(TypeError, divmod, 1, 1+0j) + + def test_divmod_zero_division(self): + for a, b in ZERO_DIVISION: + self.assertRaises(TypeError, divmod, a, b) def test_pow(self): self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) @@ -174,6 +215,7 @@ def test_pow(self): self.assertAlmostEqual(pow(1j, -1), 1/1j) self.assertAlmostEqual(pow(1j, 200), 1) self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) + self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) a = 3.33+4.43j self.assertEqual(a ** 0j, 1) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-08-09-58-19.bpo-41974.8B-q8O.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-08-09-58-19.bpo-41974.8B-q8O.rst new file mode 100644 index 000000000000000..034cfede84b8ada --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-08-09-58-19.bpo-41974.8B-q8O.rst @@ -0,0 +1,4 @@ +Removed special methods ``__int__``, ``__float__``, ``__floordiv__``, +``__mod__``, ``__divmod__``, ``__rfloordiv__``, ``__rmod__`` and +``__rdivmod__`` of the :class:`complex` class. They always raised +a :exc:`TypeError`. diff --git a/Objects/abstract.c b/Objects/abstract.c index c30fb4eb6a604e2..2ab3371a3f3cb9a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -747,10 +747,10 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) int PyNumber_Check(PyObject *o) { - return o && Py_TYPE(o)->tp_as_number && - (Py_TYPE(o)->tp_as_number->nb_index || - Py_TYPE(o)->tp_as_number->nb_int || - Py_TYPE(o)->tp_as_number->nb_float); + if (o == NULL) + return 0; + PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; + return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); } /* Binary operators */ @@ -1461,7 +1461,7 @@ PyNumber_Long(PyObject *o) } return type_error("int() argument must be a string, a bytes-like object " - "or a number, not '%.200s'", o); + "or a real number, not '%.200s'", o); } PyObject * diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 836a736037ba438..990730cd8cdc106 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -522,7 +522,7 @@ formatlong(PyObject *v, int flags, int prec, int type) PyErr_Format(PyExc_TypeError, "%%%c format: %s is required, not %.200s", type, (type == 'o' || type == 'x' || type == 'X') ? "an integer" - : "a number", + : "a real number", Py_TYPE(v)->tp_name); return NULL; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 69f6c17b4a49cd0..5ab839a9e9423a2 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -509,23 +509,6 @@ complex_div(PyObject *v, PyObject *w) return PyComplex_FromCComplex(quot); } -static PyObject * -complex_remainder(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't mod complex numbers."); - return NULL; -} - - -static PyObject * -complex_divmod(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor or mod of complex number."); - return NULL; -} - static PyObject * complex_pow(PyObject *v, PyObject *w, PyObject *z) { @@ -562,14 +545,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) return PyComplex_FromCComplex(p); } -static PyObject * -complex_int_div(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor of complex number."); - return NULL; -} - static PyObject * complex_neg(PyComplexObject *v) { @@ -668,22 +643,6 @@ complex_richcompare(PyObject *v, PyObject *w, int op) Py_RETURN_NOTIMPLEMENTED; } -static PyObject * -complex_int(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to int"); - return NULL; -} - -static PyObject * -complex_float(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to float"); - return NULL; -} - /*[clinic input] complex.conjugate @@ -966,7 +925,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } nbr = Py_TYPE(r)->tp_as_number; - if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { + if (nbr == NULL || + (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r))) + { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " "not '%.200s'", @@ -978,7 +939,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } if (i != NULL) { nbi = Py_TYPE(i)->tp_as_number; - if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { + if (nbi == NULL || + (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i))) + { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " "not '%.200s'", @@ -1057,8 +1020,8 @@ static PyNumberMethods complex_as_number = { (binaryfunc)complex_add, /* nb_add */ (binaryfunc)complex_sub, /* nb_subtract */ (binaryfunc)complex_mul, /* nb_multiply */ - (binaryfunc)complex_remainder, /* nb_remainder */ - (binaryfunc)complex_divmod, /* nb_divmod */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ (ternaryfunc)complex_pow, /* nb_power */ (unaryfunc)complex_neg, /* nb_negative */ (unaryfunc)complex_pos, /* nb_positive */ @@ -1070,9 +1033,9 @@ static PyNumberMethods complex_as_number = { 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ - complex_int, /* nb_int */ + 0, /* nb_int */ 0, /* nb_reserved */ - complex_float, /* nb_float */ + 0, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply*/ @@ -1083,7 +1046,7 @@ static PyNumberMethods complex_as_number = { 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ - (binaryfunc)complex_int_div, /* nb_floor_divide */ + 0, /* nb_floor_divide */ (binaryfunc)complex_div, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d0af0ea1a982574..828bde18df70ca1 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -215,7 +215,7 @@ PyFloat_FromString(PyObject *v) } else { PyErr_Format(PyExc_TypeError, - "float() argument must be a string or a number, not '%.200s'", + "float() argument must be a string or a real number, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6ae06a508c6140a..01e5c728b383fb4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14839,7 +14839,7 @@ mainformatlong(PyObject *v, break; default: PyErr_Format(PyExc_TypeError, - "%%%c format: a number is required, " + "%%%c format: a real number is required, " "not %.200s", type, Py_TYPE(v)->tp_name); break; From 82afe970944d4b2cb00c353ea4844149b411f75d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 21:45:46 +0300 Subject: [PATCH 437/486] bpo-41831: Add tests for tkinter.Event.__repr__ (GH-22354) --- Lib/tkinter/test/test_tkinter/test_misc.py | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index 1e089747a91ee5d..b8eea2544f5228e 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -192,6 +192,54 @@ def test_clipboard_astral(self): with self.assertRaises(tkinter.TclError): root.clipboard_get() + def test_event_repr_defaults(self): + e = tkinter.Event() + e.serial = 12345 + e.num = '??' + e.height = '??' + e.keycode = '??' + e.state = 0 + e.time = 123456789 + e.width = '??' + e.x = '??' + e.y = '??' + e.char = '' + e.keysym = '??' + e.keysym_num = '??' + e.type = '100' + e.widget = '??' + e.x_root = '??' + e.y_root = '??' + e.delta = 0 + self.assertEqual(repr(e), '<100 event>') + + def test_event_repr(self): + e = tkinter.Event() + e.serial = 12345 + e.num = 3 + e.focus = True + e.height = 200 + e.keycode = 65 + e.state = 0x30405 + e.time = 123456789 + e.width = 300 + e.x = 10 + e.y = 20 + e.char = 'A' + e.send_event = True + e.keysym = 'Key-A' + e.keysym_num = ord('A') + e.type = tkinter.EventType.Configure + e.widget = '.text' + e.x_root = 1010 + e.y_root = 1020 + e.delta = -1 + self.assertEqual(repr(e), + "") tests_gui = (MiscTest, ) From 69dee9cab10e190565646f7118d459f63d3d0610 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 22:57:34 +0300 Subject: [PATCH 438/486] bpo-41831: Restore str implementation of __str__ in tkinter.EventType (GH-22355) --- Lib/tkinter/__init__.py | 5 ++--- .../next/Library/2020-09-22-11-07-50.bpo-41831.k-Eop_.rst | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-22-11-07-50.bpo-41831.k-Eop_.rst diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 3919397d3cead24..3bfeb7a0179036e 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -185,8 +185,7 @@ class EventType(enum.StrEnum): Deactivate = '37' MouseWheel = '38' - def __str__(self): - return self.name + __str__ = str.__str__ class Event: @@ -266,7 +265,7 @@ def __repr__(self): 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( - self.type, + getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) diff --git a/Misc/NEWS.d/next/Library/2020-09-22-11-07-50.bpo-41831.k-Eop_.rst b/Misc/NEWS.d/next/Library/2020-09-22-11-07-50.bpo-41831.k-Eop_.rst new file mode 100644 index 000000000000000..84a3f5253a0604d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-22-11-07-50.bpo-41831.k-Eop_.rst @@ -0,0 +1,3 @@ +``str()`` for the ``type`` attribute of the ``tkinter.Event`` object always +returns now the numeric code returned by Tk instead of the name of the event +type. From 0c15527b14c6b8cd7a68881722068a1c4924f435 Mon Sep 17 00:00:00 2001 From: Saiyang Gou Date: Fri, 9 Oct 2020 13:00:15 -0700 Subject: [PATCH 439/486] bpo-39481: Fix duplicate SimpleQueue type in test_genericalias.py (GH-22619) There are two different `SimpleQueue` types imported (from `multiprocessing.queues` and `queue`) in `Lib/test/test_genericalias.py`, the second one shadowing the first one, making the first one not actually tested. Fix by using different names. Automerge-Triggered-By: @gvanrossum --- Lib/test/test_genericalias.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 643fffc073e82f3..2979cfb55083cb4 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -29,7 +29,7 @@ except ImportError: # multiprocessing.shared_memory is not available on e.g. Android ShareableList = None -from multiprocessing.queues import SimpleQueue +from multiprocessing.queues import SimpleQueue as MPSimpleQueue from os import DirEntry from re import Pattern, Match from types import GenericAlias, MappingProxyType, AsyncGeneratorType @@ -81,7 +81,7 @@ def test_subscriptable(self): SplitResult, ParseResult, ValueProxy, ApplyResult, WeakSet, ReferenceType, ref, - ShareableList, SimpleQueue, + ShareableList, MPSimpleQueue, Future, _WorkItem, Morsel] if ctypes is not None: From b335271ef7411d91bf171a7ea6974c4cb3d23bd3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 23:00:45 +0300 Subject: [PATCH 440/486] bpo-41985: Add _PyLong_FileDescriptor_Converter and AC converter for "fildes". (GH-22620) --- Include/cpython/fileobject.h | 2 ++ Modules/clinic/fcntlmodule.c.h | 10 +++++----- Modules/clinic/posixmodule.c.h | 10 +++++----- Modules/clinic/selectmodule.c.h | 20 ++++++++++---------- Modules/fcntlmodule.c | 28 ++++++++-------------------- Modules/posixmodule.c | 18 +----------------- Modules/selectmodule.c | 19 ------------------- Modules/termios.c | 24 ++++++------------------ Objects/fileobject.c | 11 +++++++++++ Tools/clinic/clinic.py | 13 +++++++++++++ 10 files changed, 61 insertions(+), 94 deletions(-) diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index 4f2408c7e876089..fb54cabac75f8c4 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -22,3 +22,5 @@ typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); + +PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index c6bf45fa494f065..adf527fd4431134 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -35,7 +35,7 @@ fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -105,7 +105,7 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); @@ -155,7 +155,7 @@ fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -215,7 +215,7 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) { goto exit; } - if (!conv_descriptor(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } code = _PyLong_AsInt(args[1]); @@ -243,4 +243,4 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=91c2295402509595 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8ea34bd0f7cf25ec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index c15def0a0f2b8df..df680d5738c8e82 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -357,7 +357,7 @@ os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fchdir_impl(module, fd); @@ -727,7 +727,7 @@ os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fsync_impl(module, fd); @@ -787,7 +787,7 @@ os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = os_fdatasync_impl(module, fd); @@ -6821,7 +6821,7 @@ os_fpathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("fpathconf", nargs, 2, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!conv_path_confname(args[1], &name)) { @@ -8919,4 +8919,4 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=a0fbdea47249ee0c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=936f33448cd66ccb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 3a06d6d0ec90053..00a78c48477b414 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -92,7 +92,7 @@ select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -140,7 +140,7 @@ select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("modify", nargs, 2, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { @@ -174,7 +174,7 @@ select_poll_unregister(pollObject *self, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!fildes_converter(arg, &fd)) { + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { goto exit; } return_value = select_poll_unregister_impl(self, fd); @@ -256,7 +256,7 @@ select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t n if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -306,7 +306,7 @@ select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nar if (!_PyArg_CheckPositional("modify", nargs, 1, 2)) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (nargs < 2) { @@ -344,7 +344,7 @@ select_devpoll_unregister(devpollObject *self, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!fildes_converter(arg, &fd)) { + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { goto exit; } return_value = select_devpoll_unregister_impl(self, fd); @@ -668,7 +668,7 @@ select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t na if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } if (!noptargs) { @@ -721,7 +721,7 @@ select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t narg if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); @@ -766,7 +766,7 @@ select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t if (!args) { goto exit; } - if (!fildes_converter(args[0], &fd)) { + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { goto exit; } return_value = select_epoll_unregister_impl(self, fd); @@ -1179,4 +1179,4 @@ select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=7144233c42e18279 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=162f4f4efa850416 input=a9049054013a1b77]*/ diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 39baea01ec84ea2..afd28106faf4b70 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -20,24 +20,12 @@ module fcntl [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/ -static int -conv_descriptor(PyObject *object, int *target) -{ - int fd = PyObject_AsFileDescriptor(object); - - if (fd < 0) - return 0; - *target = fd; - return 1; -} - -/* Must come after conv_descriptor definition. */ #include "clinic/fcntlmodule.c.h" /*[clinic input] fcntl.fcntl - fd: object(type='int', converter='conv_descriptor') + fd: fildes cmd as code: int arg: object(c_default='NULL') = 0 / @@ -57,7 +45,7 @@ corresponding to the return value of the fcntl call in the C code. static PyObject * fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) -/*[clinic end generated code: output=888fc93b51c295bd input=8cefbe59b29efbe2]*/ +/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/ { unsigned int int_arg = 0; int ret; @@ -116,7 +104,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) /*[clinic input] fcntl.ioctl - fd: object(type='int', converter='conv_descriptor') + fd: fildes request as code: unsigned_int(bitwise=True) arg as ob_arg: object(c_default='NULL') = 0 mutate_flag as mutate_arg: bool = True @@ -155,7 +143,7 @@ code. static PyObject * fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg) -/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/ +/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/ { #define IOCTL_BUFSZ 1024 /* We use the unsigned non-checked 'I' format for the 'code' parameter @@ -280,7 +268,7 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, /*[clinic input] fcntl.flock - fd: object(type='int', converter='conv_descriptor') + fd: fildes operation as code: int / @@ -292,7 +280,7 @@ function is emulated using fcntl()). static PyObject * fcntl_flock_impl(PyObject *module, int fd, int code) -/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/ +/*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/ { int ret; int async_err = 0; @@ -346,7 +334,7 @@ fcntl_flock_impl(PyObject *module, int fd, int code) /*[clinic input] fcntl.lockf - fd: object(type='int', converter='conv_descriptor') + fd: fildes cmd as code: int len as lenobj: object(c_default='NULL') = 0 start as startobj: object(c_default='NULL') = 0 @@ -380,7 +368,7 @@ starts. `whence` is as with fileobj.seek(), specifically: static PyObject * fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence) -/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/ +/*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/ { int ret; int async_err = 0; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7c496938ed4c5e5..165625c9a670a5c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1634,18 +1634,6 @@ path_error2(path_t *path, path_t *path2) /* POSIX generic methods */ -static int -fildes_converter(PyObject *o, void *p) -{ - int fd; - int *pointer = (int *)p; - fd = PyObject_AsFileDescriptor(o); - if (fd < 0) - return 0; - *pointer = fd; - return 1; -} - static PyObject * posix_fildes_fd(int fd, int (*func)(int)) { @@ -2642,10 +2630,6 @@ class dir_fd_converter(CConverter): else: self.converter = 'dir_fd_converter' -class fildes_converter(CConverter): - type = 'int' - converter = 'fildes_converter' - class uid_t_converter(CConverter): type = "uid_t" converter = '_Py_Uid_Converter' @@ -2708,7 +2692,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/ /*[clinic input] diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 13ffe09c6d4f8d7..fe852f93c37d1dd 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -88,25 +88,6 @@ class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_T [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/ -static int -fildes_converter(PyObject *o, void *p) -{ - int fd; - int *pointer = (int *)p; - fd = PyObject_AsFileDescriptor(o); - if (fd == -1) - return 0; - *pointer = fd; - return 1; -} - -/*[python input] -class fildes_converter(CConverter): - type = 'int' - converter = 'fildes_converter' -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/ - /* list of Python objects and their file descriptor */ typedef struct { PyObject *obj; /* owned reference */ diff --git a/Modules/termios.c b/Modules/termios.c index cc0d5853f85e352..79b60ffaaba4a32 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -51,18 +51,6 @@ get_termios_state(PyObject *module) return (termiosmodulestate *)state; } -static int fdconv(PyObject* obj, void* p) -{ - int fd; - - fd = PyObject_AsFileDescriptor(obj); - if (fd >= 0) { - *(int*)p = fd; - return 1; - } - return 0; -} - static struct PyModuleDef termiosmodule; PyDoc_STRVAR(termios_tcgetattr__doc__, @@ -81,7 +69,7 @@ termios_tcgetattr(PyObject *module, PyObject *args) { int fd; if (!PyArg_ParseTuple(args, "O&:tcgetattr", - fdconv, (void*)&fd)) { + _PyLong_FileDescriptor_Converter, (void*)&fd)) { return NULL; } @@ -160,7 +148,7 @@ termios_tcsetattr(PyObject *module, PyObject *args) int fd, when; PyObject *term; if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", - fdconv, &fd, &when, &term)) { + _PyLong_FileDescriptor_Converter, &fd, &when, &term)) { return NULL; } @@ -233,7 +221,7 @@ termios_tcsendbreak(PyObject *module, PyObject *args) { int fd, duration; if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", - fdconv, &fd, &duration)) { + _PyLong_FileDescriptor_Converter, &fd, &duration)) { return NULL; } @@ -255,7 +243,7 @@ termios_tcdrain(PyObject *module, PyObject *args) { int fd; if (!PyArg_ParseTuple(args, "O&:tcdrain", - fdconv, &fd)) { + _PyLong_FileDescriptor_Converter, &fd)) { return NULL; } @@ -280,7 +268,7 @@ termios_tcflush(PyObject *module, PyObject *args) { int fd, queue; if (!PyArg_ParseTuple(args, "O&i:tcflush", - fdconv, &fd, &queue)) { + _PyLong_FileDescriptor_Converter, &fd, &queue)) { return NULL; } @@ -305,7 +293,7 @@ termios_tcflow(PyObject *module, PyObject *args) { int fd, action; if (!PyArg_ParseTuple(args, "O&i:tcflow", - fdconv, &fd, &action)) { + _PyLong_FileDescriptor_Converter, &fd, &action)) { return NULL; } diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 1c6ecaf82c24eff..9b89448006e8445 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -223,6 +223,17 @@ PyObject_AsFileDescriptor(PyObject *o) return fd; } +int +_PyLong_FileDescriptor_Converter(PyObject *o, void *ptr) +{ + int fd = PyObject_AsFileDescriptor(o); + if (fd == -1) { + return 0; + } + *(int *)ptr = fd; + return 1; +} + /* ** Py_UniversalNewlineFgets is an fgets variation that understands ** all of \r, \n and \r\n conventions. diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 1bbbd4f9fb19334..5f2eb53e6a092af 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -3103,6 +3103,19 @@ def parse_arg(self, argname, displayname): return super().parse_arg(argname, displayname) +class fildes_converter(CConverter): + type = 'int' + converter = '_PyLong_FileDescriptor_Converter' + + def _parse_arg(self, argname, displayname): + return """ + {paramname} = PyObject_AsFileDescriptor({argname}); + if ({paramname} == -1) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.name) + + class float_converter(CConverter): type = 'float' default_type = float From da7a55b454884b1520a1feceed36d6958e6121d0 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 9 Oct 2020 17:15:15 -0700 Subject: [PATCH 441/486] bpo-41756: Add PyIter_Send function (#22443) --- Doc/c-api/gen.rst | 5 ---- Doc/c-api/iter.rst | 14 +++++++++++ Doc/data/refcounts.dat | 5 ++++ Doc/whatsnew/3.10.rst | 4 ++++ Include/abstract.h | 16 +++++++++++++ Include/genobject.h | 8 +------ .../2020-09-28-14-31-07.bpo-41756.ZZ5wJG.rst | 3 +++ Modules/_asynciomodule.c | 9 +------ Modules/_testcapimodule.c | 3 ++- Objects/abstract.c | 24 +++++++++++++++++++ Objects/genobject.c | 8 +------ Python/ceval.c | 21 ++++++---------- 12 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-09-28-14-31-07.bpo-41756.ZZ5wJG.rst diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst index e098425e6364d9e..600f53486f79d5b 100644 --- a/Doc/c-api/gen.rst +++ b/Doc/c-api/gen.rst @@ -15,11 +15,6 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. The C structure used for generator objects. -.. c:type:: PySendResult - - The enum value used to represent different results of :c:func:`PyGen_Send`. - - .. c:var:: PyTypeObject PyGen_Type The type object corresponding to generator objects. diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index a2992b3452f91c3..a068a43c86b6c39 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -44,3 +44,17 @@ something like this:: else { /* continue doing useful work */ } + + +.. c:type:: PySendResult + + The enum value used to represent different results of :c:func:`PyIter_Send`. + + +.. c:function:: PySendResult PyIter_Send(PyObject *iter, PyObject *arg, PyObject **presult) + + Sends the *arg* value into the iterator *iter*. Returns: + + - ``PYGEN_RETURN`` if iterator returns. Return value is returned via *presult*. + - ``PYGEN_NEXT`` if iterator yields. Yielded value is returned via *presult*. + - ``PYGEN_ERROR`` if iterator has raised and exception. *presult* is set to ``NULL``. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 6b1bde37967ae93..87ce5d03d006443 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1081,6 +1081,11 @@ PyIter_Check:PyObject*:o:0: PyIter_Next:PyObject*::+1: PyIter_Next:PyObject*:o:0: +PyIter_Send:int::: +PyIter_Send:PyObject*:iter:0: +PyIter_Send:PyObject*:arg:0: +PyIter_Send:PyObject**:presult:+1: + PyList_Append:int::: PyList_Append:PyObject*:list:0: PyList_Append:PyObject*:item:+1: diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 7401ba722fb4f98..1c50978a8b7501d 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -314,6 +314,10 @@ New Features search function. (Contributed by Hai Shi in :issue:`41842`.) +* The :c:func:`PyIter_Send` and :c:func:`PyGen_Send` functions were added to allow + sending value into iterator without raising ``StopIteration`` exception. + (Contributed by Vladimir Matveev in :issue:`41756`.) + Porting to Python 3.10 ---------------------- diff --git a/Include/abstract.h b/Include/abstract.h index a23b7dc78f480d7..716cd4b5ebbba3e 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -338,6 +338,22 @@ PyAPI_FUNC(int) PyIter_Check(PyObject *); NULL with an exception means an error occurred. */ PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); +typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, +} PySendResult; + +/* Takes generator, coroutine or iterator object and sends the value into it. + Returns: + - PYGEN_RETURN (0) if generator has returned. + 'result' parameter is filled with return value + - PYGEN_ERROR (-1) if exception was raised. + 'result' parameter is NULL + - PYGEN_NEXT (1) if generator has yielded. + 'result' parameter is filled with yielded value. */ +PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **); + /* === Number Protocol ================================================== */ diff --git a/Include/genobject.h b/Include/genobject.h index 7488054c68fcd8b..e719b25a8007294 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -9,6 +9,7 @@ extern "C" { #endif #include "pystate.h" /* _PyErr_StackItem */ +#include "abstract.h" /* PySendResult */ /* _PyGenObject_HEAD defines the initial segment of generator and coroutine objects. */ @@ -41,16 +42,9 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, PyObject *name, PyObject *qualname); PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); -PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *); PyObject *_PyGen_yf(PyGenObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); -typedef enum { - PYGEN_RETURN = 0, - PYGEN_ERROR = -1, - PYGEN_NEXT = 1, -} PySendResult; - /* Sends the value into the generator or the coroutine. Returns: - PYGEN_RETURN (0) if generator has returned. 'result' parameter is filled with return value diff --git a/Misc/NEWS.d/next/C API/2020-09-28-14-31-07.bpo-41756.ZZ5wJG.rst b/Misc/NEWS.d/next/C API/2020-09-28-14-31-07.bpo-41756.ZZ5wJG.rst new file mode 100644 index 000000000000000..f7e27b440152963 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-09-28-14-31-07.bpo-41756.ZZ5wJG.rst @@ -0,0 +1,3 @@ +Add `PyIter_Send` function to allow sending value into +generator/coroutine/iterator without raising StopIteration exception to +signal return. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2151f20281a31bc..f01e5884c6fe201 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -16,7 +16,6 @@ _Py_IDENTIFIER(add_done_callback); _Py_IDENTIFIER(call_soon); _Py_IDENTIFIER(cancel); _Py_IDENTIFIER(get_event_loop); -_Py_IDENTIFIER(send); _Py_IDENTIFIER(throw); @@ -2695,13 +2694,7 @@ task_step_impl(TaskObj *task, PyObject *exc) int gen_status = PYGEN_ERROR; if (exc == NULL) { - if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { - gen_status = PyGen_Send((PyGenObject*)coro, Py_None, &result); - } - else { - result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); - gen_status = gen_status_from_result(&result); - } + gen_status = PyIter_Send(coro, Py_None, &result); } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 0e098779696b737..8c7544fa90e280b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5028,6 +5028,7 @@ dict_get_version(PyObject *self, PyObject *args) static PyObject * raise_SIGINT_then_send_None(PyObject *self, PyObject *args) { + _Py_IDENTIFIER(send); PyGenObject *gen; if (!PyArg_ParseTuple(args, "O!", &PyGen_Type, &gen)) @@ -5044,7 +5045,7 @@ raise_SIGINT_then_send_None(PyObject *self, PyObject *args) because we check for signals before every bytecode operation. */ raise(SIGINT); - return _PyGen_Send(gen, Py_None); + return _PyObject_CallMethodIdOneArg((PyObject *)gen, &PyId_send, Py_None); } diff --git a/Objects/abstract.c b/Objects/abstract.c index 2ab3371a3f3cb9a..502a2d64e25e112 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2669,6 +2669,30 @@ PyIter_Next(PyObject *iter) return result; } +PySendResult +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) +{ + _Py_IDENTIFIER(send); + assert(result != NULL); + + if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { + return PyGen_Send((PyGenObject *)iter, arg, result); + } + + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; +} /* * Flatten a sequence of bytes() objects into a C array of diff --git a/Objects/genobject.c b/Objects/genobject.c index f0943ae847c5438..eb134ebf4bc8785 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -308,12 +308,6 @@ gen_send(PyGenObject *gen, PyObject *arg) return gen_send_ex(gen, arg, 0, 0); } -PyObject * -_PyGen_Send(PyGenObject *gen, PyObject *arg) -{ - return gen_send(gen, arg); -} - PyDoc_STRVAR(close_doc, "close() -> raise GeneratorExit inside generator."); @@ -1012,7 +1006,7 @@ PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); static PyMethodDef coro_methods[] = { - {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc}, + {"send",(PyCFunction)gen_send, METH_O, coro_send_doc}, {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, {NULL, NULL} /* Sentinel */ diff --git a/Python/ceval.c b/Python/ceval.c index 500c588e3c2afb7..762de577e6b5505 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2210,24 +2210,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) case TARGET(YIELD_FROM): { PyObject *v = POP(); PyObject *receiver = TOP(); - int is_gen_or_coro = PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver); - int gen_status; - if (tstate->c_tracefunc == NULL && is_gen_or_coro) { - gen_status = PyGen_Send((PyGenObject *)receiver, v, &retval); + PySendResult gen_status; + if (tstate->c_tracefunc == NULL) { + gen_status = PyIter_Send(receiver, v, &retval); } else { - if (is_gen_or_coro) { - retval = _PyGen_Send((PyGenObject *)receiver, v); + _Py_IDENTIFIER(send); + if (v == Py_None && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); } else { - _Py_IDENTIFIER(send); - if (v == Py_None) { - retval = Py_TYPE(receiver)->tp_iternext(receiver); - } - else { - retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); - } + retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); } - if (retval == NULL) { if (tstate->c_tracefunc != NULL && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) From fac6798b63bc168368e1cd1579e1b634ad3e4606 Mon Sep 17 00:00:00 2001 From: Xie Yanbo Date: Sat, 10 Oct 2020 10:38:43 +0800 Subject: [PATCH 442/486] Fix incorrect parameter name (GH-22613) Automerge-Triggered-By: @Mariatta --- Doc/library/shutil.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index ecc3309ed5cc09e..3f5122760ee16f1 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -349,7 +349,7 @@ Directory and files operations will be created in or as *dst* and *src* will be removed. If *copy_function* is given, it must be a callable that takes two arguments - *src* and *dst*, and will be used to copy *src* to *dest* if + *src* and *dst*, and will be used to copy *src* to *dst* if :func:`os.rename` cannot be used. If the source is a directory, :func:`copytree` is called, passing it the :func:`copy_function`. The default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the From abcd67a729859c74498d08f548b47a711a235931 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 10 Oct 2020 17:09:45 +0300 Subject: [PATCH 443/486] bpo-41986: Add Py_FileSystemDefaultEncodeErrors and Py_UTF8Mode back to limited API (GH-22621) --- Include/cpython/fileobject.h | 8 -------- Include/fileobject.h | 7 +++++++ .../next/C API/2020-10-09-22-50-46.bpo-41986.JUPE59.rst | 2 ++ 3 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-09-22-50-46.bpo-41986.JUPE59.rst diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index fb54cabac75f8c4..cff2243d625e767 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -4,14 +4,6 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_DATA(int) Py_UTF8Mode; -#endif - /* The std printer acts as a preliminary sys.stderr until the new io infrastructure is in place. */ PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); diff --git a/Include/fileobject.h b/Include/fileobject.h index 456887ef9d045da..6ec2994aa859b6f 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -20,8 +20,15 @@ PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); If non-NULL, this is different than the default encoding for strings */ PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +#endif PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_DATA(int) Py_UTF8Mode; +#endif + /* A routine to check if a file descriptor can be select()-ed. */ #ifdef _MSC_VER /* On Windows, any socket fd can be select()-ed, no matter how high */ diff --git a/Misc/NEWS.d/next/C API/2020-10-09-22-50-46.bpo-41986.JUPE59.rst b/Misc/NEWS.d/next/C API/2020-10-09-22-50-46.bpo-41986.JUPE59.rst new file mode 100644 index 000000000000000..d456ba66bafd616 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-09-22-50-46.bpo-41986.JUPE59.rst @@ -0,0 +1,2 @@ +:c:data:`Py_FileSystemDefaultEncodeErrors` and :c:data:`Py_UTF8Mode` are +available again in limited API. From 880e854a94bf87c28b5c599159d47174a913f025 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sat, 10 Oct 2020 20:14:59 +0300 Subject: [PATCH 444/486] bpo-42000: Cleanup the AST related C-code (GH-22641) - Use the proper asdl sequence when creating empty arguments - Remove reduntant casts (thanks to new typed asdl_sequences) - Remove MarshalPrototypeVisitor and some utilities from asdl generator - Fix the header of `Python/ast.c` (kept from pgen times) Automerge-Triggered-By: @pablogsal --- Parser/asdl_c.py | 42 ------------------------------------------ Parser/pegen.c | 2 +- Python/ast.c | 14 ++++---------- 3 files changed, 5 insertions(+), 53 deletions(-) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 242eccf3d37d783..481261cd85359a7 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -618,16 +618,6 @@ def visitField(self, field, name, sum=None, prod=None, depth=0): self.emit("}", depth) -class MarshalPrototypeVisitor(PickleVisitor): - - def prototype(self, sum, name): - ctype = get_c_type(name) - self.emit("static int marshal_write_%s(PyObject **, int *, %s);" - % (name, ctype), 0) - - visitProduct = visitSum = prototype - - class SequenceConstructorVisitor(EmitVisitor): def visitModule(self, mod): for dfn in mod.dfns: @@ -1167,25 +1157,6 @@ def addObj(self, name): self.emit("Py_INCREF(state->%s_type);" % name, 1) -_SPECIALIZED_SEQUENCES = ('stmt', 'expr') - -def find_sequence(fields, doing_specialization): - """Return True if any field uses a sequence.""" - for f in fields: - if f.seq: - if not doing_specialization: - return True - if str(f.type) not in _SPECIALIZED_SEQUENCES: - return True - return False - -def has_sequence(types, doing_specialization): - for t in types: - if find_sequence(t.fields, doing_specialization): - return True - return False - - class StaticVisitor(PickleVisitor): CODE = '''Very simple, always emit this static code. Override CODE''' @@ -1283,18 +1254,6 @@ def emit(s, d): emit("goto failed;", 1) emit("Py_DECREF(value);", 0) - def emitSeq(self, field, value, depth, emit): - emit("seq = %s;" % value, 0) - emit("n = asdl_seq_LEN(seq);", 0) - emit("value = PyList_New(n);", 0) - emit("if (!value) goto failed;", 0) - emit("for (i = 0; i < n; i++) {", 0) - self.set("value", field, "asdl_seq_GET(seq, i)", depth + 1) - emit("if (!value1) goto failed;", 1) - emit("PyList_SET_ITEM(value, i, value1);", 1) - emit("value1 = NULL;", 1) - emit("}", 0) - def set(self, field, value, depth): if field.seq: # XXX should really check for is_simple, but that requires a symbol table @@ -1313,7 +1272,6 @@ def set(self, field, value, depth): else: self.emit("value = ast2obj_list(state, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) else: - ctype = get_c_type(field.type) self.emit("value = ast2obj_%s(state, %s);" % (field.type, value), depth, reflow=False) diff --git a/Parser/pegen.c b/Parser/pegen.c index 1de495eaf398e84..efa5ed9f288ee0b 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -1897,7 +1897,7 @@ _PyPegen_empty_arguments(Parser *p) return NULL; } - return _Py_arguments(posonlyargs, posargs, NULL, kwonlyargs, kwdefaults, NULL, kwdefaults, + return _Py_arguments(posonlyargs, posargs, NULL, kwonlyargs, kwdefaults, NULL, posdefaults, p->arena); } diff --git a/Python/ast.c b/Python/ast.c index 4b7bbd229c99b25..5e74f65a2c013b9 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1,18 +1,12 @@ /* - * This file includes functions to transform a concrete syntax tree (CST) to - * an abstract syntax tree (AST). The main function is PyAST_FromNode(). - * + * This file exposes PyAST_Validate interface to check the integrity + * of the given abstract syntax tree (potentially constructed manually). */ #include "Python.h" #include "Python-ast.h" #include "ast.h" -#include "token.h" -#include "pythonrun.h" #include -#include - -#define MAXLEVEL 200 /* Max parentheses level */ static int validate_stmts(asdl_stmt_seq *); static int validate_exprs(asdl_expr_seq*, expr_context_ty, int); @@ -62,7 +56,7 @@ validate_keywords(asdl_keyword_seq *keywords) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(keywords); i++) - if (!validate_expr(((keyword_ty)asdl_seq_GET(keywords, i))->value, Load)) + if (!validate_expr((asdl_seq_GET(keywords, i))->value, Load)) return 0; return 1; } @@ -556,7 +550,7 @@ _PyAST_GetDocString(asdl_stmt_seq *body) if (!asdl_seq_LEN(body)) { return NULL; } - stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0); + stmt_ty st = asdl_seq_GET(body, 0); if (st->kind != Expr_kind) { return NULL; } From 59a999372fd6e5ef4a63a56a642ca9f0b3417d23 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 10 Oct 2020 22:23:42 +0300 Subject: [PATCH 445/486] bpo-41991: Remove _PyObject_HasAttrId (GH-22629) It can silence arbitrary exceptions. --- Include/cpython/object.h | 1 - Objects/object.c | 11 ----------- Objects/unionobject.c | 13 +++++++------ Python/errors.c | 19 +++++++++++++++++-- Python/pythonrun.c | 6 ++++-- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index ae3920d4508e14d..875a600f79565ad 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -306,7 +306,6 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); -PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); /* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which don't raise AttributeError. diff --git a/Objects/object.c b/Objects/object.c index 9889503cfd89384..7bc3e48d40a6fdd 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -854,17 +854,6 @@ _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name) return result; } -int -_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name) -{ - int result; - PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ - if (!oname) - return -1; - result = PyObject_HasAttr(v, oname); - return result; -} - int _PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) { diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 8cfb2a664753f8d..89fdaf42560c1b5 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -311,21 +311,22 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) _Py_IDENTIFIER(__args__); PyObject *qualname = NULL; PyObject *module = NULL; + PyObject *tmp; PyObject *r = NULL; int err; - int has_origin = _PyObject_HasAttrId(p, &PyId___origin__); - if (has_origin < 0) { + if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) { goto exit; } - if (has_origin) { - int has_args = _PyObject_HasAttrId(p, &PyId___args__); - if (has_args < 0) { + if (tmp) { + Py_DECREF(tmp); + if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) { goto exit; } - if (has_args) { + if (tmp) { // It looks like a GenericAlias + Py_DECREF(tmp); goto use_repr; } } diff --git a/Python/errors.c b/Python/errors.c index 720f18bc224d4dc..02cf47992b695ff 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1593,9 +1593,18 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) } Py_DECREF(tmp); } + else { + _PyErr_Clear(tstate); + } } if (exc != PyExc_SyntaxError) { - if (!_PyObject_HasAttrId(v, &PyId_msg)) { + if (_PyObject_LookupAttrId(v, &PyId_msg, &tmp) < 0) { + _PyErr_Clear(tstate); + } + else if (tmp) { + Py_DECREF(tmp); + } + else { tmp = PyObject_Str(v); if (tmp) { if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { @@ -1607,7 +1616,13 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _PyErr_Clear(tstate); } } - if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { + if (_PyObject_LookupAttrId(v, &PyId_print_file_and_line, &tmp) < 0) { + _PyErr_Clear(tstate); + } + else if (tmp) { + Py_DECREF(tmp); + } + else { if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, Py_None)) { _PyErr_Clear(tstate); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ff80103050e4e2c..a45ca3b18311dd7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -770,7 +770,7 @@ static void print_exception(PyObject *f, PyObject *value) { int err = 0; - PyObject *type, *tb; + PyObject *type, *tb, *tmp; _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { @@ -789,10 +789,12 @@ print_exception(PyObject *f, PyObject *value) if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && - _PyObject_HasAttrId(value, &PyId_print_file_and_line)) + (err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0) { PyObject *message, *filename, *text; Py_ssize_t lineno, offset; + err = 0; + Py_DECREF(tmp); if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); From 7a38d43a9491a1de974b2051a4aee06a5b95106b Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 11 Oct 2020 01:19:46 +0300 Subject: [PATCH 446/486] bpo-38605: bump the magic number for 'annotations' future (#22630) --- Lib/importlib/_bootstrap_external.py | 3 +- Python/importlib_external.h | 222 +++++++++++++-------------- 2 files changed, 113 insertions(+), 112 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 4f06039f3d23c54..b08ad032ab309d4 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -277,6 +277,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.9a2 3423 (add IS_OP, CONTAINS_OP and JUMP_IF_NOT_EXC_MATCH bytecodes #39156) # Python 3.9a2 3424 (simplify bytecodes for *value unpacking) # Python 3.9a2 3425 (simplify bytecodes for **value unpacking) +# Python 3.10a1 3430 (Make 'annotations' future by default) # # MAGIC must change whenever the bytecode emitted by the compiler may no @@ -286,7 +287,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3425).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3430).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 0ef1b45594fbf72..6daddb1fb8dfb78 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -285,7 +285,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,218,13,95,119,114,105,116,101,95,97,116,111,109,105,99, 120,0,0,0,115,28,0,0,0,0,5,16,1,6,1,22, 255,4,2,2,3,14,1,40,1,16,1,12,1,2,1,14, - 1,12,1,6,1,114,69,0,0,0,105,97,13,0,0,114, + 1,12,1,6,1,114,69,0,0,0,105,102,13,0,0,114, 28,0,0,0,114,17,0,0,0,115,2,0,0,0,13,10, 90,11,95,95,112,121,99,97,99,104,101,95,95,122,4,111, 112,116,45,122,3,46,112,121,122,4,46,112,121,99,78,41, @@ -399,7 +399,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 90,15,97,108,109,111,115,116,95,102,105,108,101,110,97,109, 101,218,8,102,105,108,101,110,97,109,101,114,5,0,0,0, 114,5,0,0,0,114,8,0,0,0,218,17,99,97,99,104, - 101,95,102,114,111,109,95,115,111,117,114,99,101,45,1,0, + 101,95,102,114,111,109,95,115,111,117,114,99,101,46,1,0, 0,115,72,0,0,0,0,18,8,1,6,1,2,255,4,2, 8,1,4,1,8,1,12,1,10,1,12,1,16,1,8,1, 8,1,8,1,24,1,8,1,12,1,6,2,8,1,8,1, @@ -480,7 +480,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,90,9,111,112,116,95,108,101,118,101,108,90,13,98, 97,115,101,95,102,105,108,101,110,97,109,101,114,5,0,0, 0,114,5,0,0,0,114,8,0,0,0,218,17,115,111,117, - 114,99,101,95,102,114,111,109,95,99,97,99,104,101,116,1, + 114,99,101,95,102,114,111,109,95,99,97,99,104,101,117,1, 0,0,115,60,0,0,0,0,9,12,1,8,1,10,1,12, 1,4,1,10,1,12,1,14,1,16,1,4,1,4,1,12, 1,8,1,8,1,2,255,8,2,10,1,8,1,16,1,10, @@ -516,7 +516,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 120,116,101,110,115,105,111,110,218,11,115,111,117,114,99,101, 95,112,97,116,104,114,5,0,0,0,114,5,0,0,0,114, 8,0,0,0,218,15,95,103,101,116,95,115,111,117,114,99, - 101,102,105,108,101,156,1,0,0,115,20,0,0,0,0,7, + 101,102,105,108,101,157,1,0,0,115,20,0,0,0,0,7, 12,1,4,1,16,1,24,1,4,1,2,1,12,1,16,1, 18,1,114,108,0,0,0,99,1,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,8,0,0,0,67,0,0,0, @@ -529,7 +529,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,114,101,0,0,0,114,97,0,0,0,114,82,0,0,0, 114,88,0,0,0,41,1,114,96,0,0,0,114,5,0,0, 0,114,5,0,0,0,114,8,0,0,0,218,11,95,103,101, - 116,95,99,97,99,104,101,100,175,1,0,0,115,16,0,0, + 116,95,99,97,99,104,101,100,176,1,0,0,115,16,0,0, 0,0,1,14,1,2,1,10,1,12,1,6,1,14,1,4, 2,114,112,0,0,0,99,1,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, @@ -543,7 +543,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,233,128,0,0,0,41,3,114,49,0,0,0,114,51, 0,0,0,114,50,0,0,0,41,2,114,44,0,0,0,114, 52,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,10,95,99,97,108,99,95,109,111,100,101,187, + 0,0,0,218,10,95,99,97,108,99,95,109,111,100,101,188, 1,0,0,115,12,0,0,0,0,2,2,1,14,1,12,1, 10,3,8,1,114,114,0,0,0,99,1,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,8,0,0,0,3,0, @@ -582,7 +582,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 103,115,218,6,107,119,97,114,103,115,169,1,218,6,109,101, 116,104,111,100,114,5,0,0,0,114,8,0,0,0,218,19, 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, - 112,101,114,207,1,0,0,115,18,0,0,0,0,1,8,1, + 112,101,114,208,1,0,0,115,18,0,0,0,0,1,8,1, 8,1,10,1,4,1,8,255,2,1,2,255,6,2,122,40, 95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,99, 97,108,115,62,46,95,99,104,101,99,107,95,110,97,109,101, @@ -600,7 +600,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 95,100,105,99,116,95,95,218,6,117,112,100,97,116,101,41, 3,90,3,110,101,119,90,3,111,108,100,114,67,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 5,95,119,114,97,112,218,1,0,0,115,8,0,0,0,0, + 5,95,119,114,97,112,219,1,0,0,115,8,0,0,0,0, 1,8,1,10,1,20,1,122,26,95,99,104,101,99,107,95, 110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,119, 114,97,112,41,1,78,41,3,218,10,95,98,111,111,116,115, @@ -608,7 +608,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,114,111,114,41,3,114,122,0,0,0,114,123,0,0,0, 114,133,0,0,0,114,5,0,0,0,114,121,0,0,0,114, 8,0,0,0,218,11,95,99,104,101,99,107,95,110,97,109, - 101,199,1,0,0,115,14,0,0,0,0,8,14,7,2,1, + 101,200,1,0,0,115,14,0,0,0,0,8,14,7,2,1, 10,1,12,2,14,5,10,1,114,136,0,0,0,99,2,0, 0,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0, 0,0,67,0,0,0,115,60,0,0,0,124,0,160,0,124, @@ -636,7 +636,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,97,100,101,114,218,8,112,111,114,116,105,111,110,115,218, 3,109,115,103,114,5,0,0,0,114,5,0,0,0,114,8, 0,0,0,218,17,95,102,105,110,100,95,109,111,100,117,108, - 101,95,115,104,105,109,227,1,0,0,115,10,0,0,0,0, + 101,95,115,104,105,109,228,1,0,0,115,10,0,0,0,0, 10,14,1,16,1,4,1,22,1,114,143,0,0,0,99,3, 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4, 0,0,0,67,0,0,0,115,166,0,0,0,124,0,100,1, @@ -703,7 +703,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,95,100,101,116,97,105,108,115,90,5,109,97,103,105,99, 114,92,0,0,0,114,2,0,0,0,114,5,0,0,0,114, 5,0,0,0,114,8,0,0,0,218,13,95,99,108,97,115, - 115,105,102,121,95,112,121,99,244,1,0,0,115,28,0,0, + 115,105,102,121,95,112,121,99,245,1,0,0,115,28,0,0, 0,0,16,12,1,8,1,16,1,12,1,16,1,12,1,10, 1,12,1,8,1,16,2,8,1,16,1,16,1,114,152,0, 0,0,99,5,0,0,0,0,0,0,0,0,0,0,0,6, @@ -758,7 +758,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,116,0,0,0,114,151,0,0,0,114,92,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,23, 95,118,97,108,105,100,97,116,101,95,116,105,109,101,115,116, - 97,109,112,95,112,121,99,21,2,0,0,115,16,0,0,0, + 97,109,112,95,112,121,99,22,2,0,0,115,16,0,0,0, 0,19,24,1,10,1,12,1,16,1,8,1,22,255,2,2, 114,156,0,0,0,99,4,0,0,0,0,0,0,0,0,0, 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,42, @@ -804,7 +804,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 218,11,115,111,117,114,99,101,95,104,97,115,104,114,116,0, 0,0,114,151,0,0,0,114,5,0,0,0,114,5,0,0, 0,114,8,0,0,0,218,18,95,118,97,108,105,100,97,116, - 101,95,104,97,115,104,95,112,121,99,49,2,0,0,115,12, + 101,95,104,97,115,104,95,112,121,99,50,2,0,0,115,12, 0,0,0,0,17,16,1,2,1,8,255,4,2,2,254,114, 158,0,0,0,99,4,0,0,0,0,0,0,0,0,0,0, 0,5,0,0,0,5,0,0,0,67,0,0,0,115,80,0, @@ -828,7 +828,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,116,0,0,0,114,106,0,0,0,114,107,0, 0,0,218,4,99,111,100,101,114,5,0,0,0,114,5,0, 0,0,114,8,0,0,0,218,17,95,99,111,109,112,105,108, - 101,95,98,121,116,101,99,111,100,101,73,2,0,0,115,18, + 101,95,98,121,116,101,99,111,100,101,74,2,0,0,115,18, 0,0,0,0,2,10,1,10,1,12,1,8,1,12,1,4, 2,10,1,4,255,114,165,0,0,0,114,73,0,0,0,99, 3,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, @@ -847,7 +847,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,155,0,0,0,114,26,0,0,0,114,5,0,0,0,114, 5,0,0,0,114,8,0,0,0,218,22,95,99,111,100,101, 95,116,111,95,116,105,109,101,115,116,97,109,112,95,112,121, - 99,86,2,0,0,115,12,0,0,0,0,2,8,1,14,1, + 99,87,2,0,0,115,12,0,0,0,0,2,8,1,14,1, 14,1,14,1,16,1,114,170,0,0,0,84,99,3,0,0, 0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0, 0,67,0,0,0,115,80,0,0,0,116,0,116,1,131,1, @@ -865,7 +865,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 7,99,104,101,99,107,101,100,114,26,0,0,0,114,2,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, 0,218,17,95,99,111,100,101,95,116,111,95,104,97,115,104, - 95,112,121,99,96,2,0,0,115,14,0,0,0,0,2,8, + 95,112,121,99,97,2,0,0,115,14,0,0,0,0,2,8, 1,12,1,14,1,16,1,10,1,16,1,114,171,0,0,0, 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, 0,6,0,0,0,67,0,0,0,115,62,0,0,0,100,1, @@ -892,7 +892,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 108,105,110,101,218,8,101,110,99,111,100,105,110,103,90,15, 110,101,119,108,105,110,101,95,100,101,99,111,100,101,114,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,13, - 100,101,99,111,100,101,95,115,111,117,114,99,101,107,2,0, + 100,101,99,111,100,101,95,115,111,117,114,99,101,108,2,0, 0,115,10,0,0,0,0,5,8,1,12,1,10,1,12,1, 114,176,0,0,0,169,2,114,140,0,0,0,218,26,115,117, 98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108, @@ -954,7 +954,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,90,7,100,105,114,110,97,109,101,114,5,0,0,0,114, 5,0,0,0,114,8,0,0,0,218,23,115,112,101,99,95, 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, - 111,110,124,2,0,0,115,62,0,0,0,0,12,8,4,4, + 111,110,125,2,0,0,115,62,0,0,0,0,12,8,4,4, 1,10,2,2,1,14,1,12,1,6,2,10,8,16,1,6, 3,8,1,14,1,14,1,10,1,6,1,6,2,4,3,8, 2,10,1,2,1,14,1,12,1,6,2,4,1,8,2,6, @@ -991,7 +991,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 65,76,95,77,65,67,72,73,78,69,41,2,218,3,99,108, 115,114,7,0,0,0,114,5,0,0,0,114,5,0,0,0, 114,8,0,0,0,218,14,95,111,112,101,110,95,114,101,103, - 105,115,116,114,121,204,2,0,0,115,8,0,0,0,0,2, + 105,115,116,114,121,205,2,0,0,115,8,0,0,0,0,2, 2,1,16,1,12,1,122,36,87,105,110,100,111,119,115,82, 101,103,105,115,116,114,121,70,105,110,100,101,114,46,95,111, 112,101,110,95,114,101,103,105,115,116,114,121,99,2,0,0, @@ -1018,7 +1018,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 95,107,101,121,114,7,0,0,0,90,4,104,107,101,121,218, 8,102,105,108,101,112,97,116,104,114,5,0,0,0,114,5, 0,0,0,114,8,0,0,0,218,16,95,115,101,97,114,99, - 104,95,114,101,103,105,115,116,114,121,211,2,0,0,115,24, + 104,95,114,101,103,105,115,116,114,121,212,2,0,0,115,24, 0,0,0,0,2,6,1,8,2,6,1,6,1,16,255,6, 2,2,1,12,1,46,1,12,1,8,1,122,38,87,105,110, 100,111,119,115,82,101,103,105,115,116,114,121,70,105,110,100, @@ -1040,7 +1040,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,44,0,0,0,218,6,116,97,114,103,101,116, 114,199,0,0,0,114,140,0,0,0,114,189,0,0,0,114, 187,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,9,102,105,110,100,95,115,112,101,99,226,2, + 0,0,0,218,9,102,105,110,100,95,115,112,101,99,227,2, 0,0,115,28,0,0,0,0,2,10,1,8,1,4,1,2, 1,12,1,12,1,8,1,14,1,14,1,6,1,8,1,2, 254,6,3,122,31,87,105,110,100,111,119,115,82,101,103,105, @@ -1059,7 +1059,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 78,169,2,114,203,0,0,0,114,140,0,0,0,169,4,114, 193,0,0,0,114,139,0,0,0,114,44,0,0,0,114,187, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,242, + 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,243, 2,0,0,115,8,0,0,0,0,7,12,1,8,1,6,2, 122,33,87,105,110,100,111,119,115,82,101,103,105,115,116,114, 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, @@ -1069,7 +1069,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 11,99,108,97,115,115,109,101,116,104,111,100,114,194,0,0, 0,114,200,0,0,0,114,203,0,0,0,114,206,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,191,0,0,0,192,2,0,0,115,28,0, + 8,0,0,0,114,191,0,0,0,193,2,0,0,115,28,0, 0,0,8,2,4,3,2,255,2,4,2,255,2,3,4,2, 2,1,10,6,2,1,10,14,2,1,12,15,2,1,114,191, 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, @@ -1105,7 +1105,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,139,0,0,0,114,96,0,0,0,90,13,102,105,108, 101,110,97,109,101,95,98,97,115,101,90,9,116,97,105,108, 95,110,97,109,101,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,182,0,0,0,5,3,0,0,115,8,0, + 8,0,0,0,114,182,0,0,0,6,3,0,0,115,8,0, 0,0,0,3,18,1,16,1,14,1,122,24,95,76,111,97, 100,101,114,66,97,115,105,99,115,46,105,115,95,112,97,99, 107,97,103,101,99,2,0,0,0,0,0,0,0,0,0,0, @@ -1116,7 +1116,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 105,111,110,46,78,114,5,0,0,0,169,2,114,118,0,0, 0,114,187,0,0,0,114,5,0,0,0,114,5,0,0,0, 114,8,0,0,0,218,13,99,114,101,97,116,101,95,109,111, - 100,117,108,101,13,3,0,0,115,2,0,0,0,0,1,122, + 100,117,108,101,14,3,0,0,115,2,0,0,0,0,1,122, 27,95,76,111,97,100,101,114,66,97,115,105,99,115,46,99, 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,5,0,0, @@ -1136,7 +1136,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,114,131,0,0,0,41,3,114,118,0,0,0,218,6,109, 111,100,117,108,101,114,164,0,0,0,114,5,0,0,0,114, 5,0,0,0,114,8,0,0,0,218,11,101,120,101,99,95, - 109,111,100,117,108,101,16,3,0,0,115,12,0,0,0,0, + 109,111,100,117,108,101,17,3,0,0,115,12,0,0,0,0, 2,12,1,8,1,6,1,4,255,6,2,122,25,95,76,111, 97,100,101,114,66,97,115,105,99,115,46,101,120,101,99,95, 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, @@ -1148,13 +1148,13 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 117,108,101,95,115,104,105,109,169,2,114,118,0,0,0,114, 139,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, - 24,3,0,0,115,2,0,0,0,0,2,122,25,95,76,111, + 25,3,0,0,115,2,0,0,0,0,2,122,25,95,76,111, 97,100,101,114,66,97,115,105,99,115,46,108,111,97,100,95, 109,111,100,117,108,101,78,41,8,114,125,0,0,0,114,124, 0,0,0,114,126,0,0,0,114,127,0,0,0,114,182,0, 0,0,114,212,0,0,0,114,217,0,0,0,114,220,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,208,0,0,0,0,3,0,0,115,10, + 114,8,0,0,0,114,208,0,0,0,1,3,0,0,115,10, 0,0,0,8,2,4,3,8,8,8,3,8,8,114,208,0, 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,3,0,0,0,64,0,0,0,115,74,0,0,0, @@ -1179,7 +1179,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 10,32,32,32,32,32,32,32,32,78,41,1,114,50,0,0, 0,169,2,114,118,0,0,0,114,44,0,0,0,114,5,0, 0,0,114,5,0,0,0,114,8,0,0,0,218,10,112,97, - 116,104,95,109,116,105,109,101,31,3,0,0,115,2,0,0, + 116,104,95,109,116,105,109,101,32,3,0,0,115,2,0,0, 0,0,6,122,23,83,111,117,114,99,101,76,111,97,100,101, 114,46,112,97,116,104,95,109,116,105,109,101,99,2,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, @@ -1213,7 +1213,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 108,101,100,46,10,32,32,32,32,32,32,32,32,114,169,0, 0,0,41,1,114,223,0,0,0,114,222,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,218,10,112, - 97,116,104,95,115,116,97,116,115,39,3,0,0,115,2,0, + 97,116,104,95,115,116,97,116,115,40,3,0,0,115,2,0, 0,0,0,12,122,23,83,111,117,114,99,101,76,111,97,100, 101,114,46,112,97,116,104,95,115,116,97,116,115,99,4,0, 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0, @@ -1237,7 +1237,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,114,107,0,0,0,90,10,99,97,99,104,101,95,112, 97,116,104,114,26,0,0,0,114,5,0,0,0,114,5,0, 0,0,114,8,0,0,0,218,15,95,99,97,99,104,101,95, - 98,121,116,101,99,111,100,101,53,3,0,0,115,2,0,0, + 98,121,116,101,99,111,100,101,54,3,0,0,115,2,0,0, 0,0,8,122,28,83,111,117,114,99,101,76,111,97,100,101, 114,46,95,99,97,99,104,101,95,98,121,116,101,99,111,100, 101,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, @@ -1254,7 +1254,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 108,101,115,46,10,32,32,32,32,32,32,32,32,78,114,5, 0,0,0,41,3,114,118,0,0,0,114,44,0,0,0,114, 26,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,114,225,0,0,0,63,3,0,0,115,2,0,0, + 0,0,0,114,225,0,0,0,64,3,0,0,115,2,0,0, 0,0,1,122,21,83,111,117,114,99,101,76,111,97,100,101, 114,46,115,101,116,95,100,97,116,97,99,2,0,0,0,0, 0,0,0,0,0,0,0,5,0,0,0,10,0,0,0,67, @@ -1275,7 +1275,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,41,5,114,118,0,0,0,114,139,0,0,0,114, 44,0,0,0,114,174,0,0,0,218,3,101,120,99,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,218,10,103, - 101,116,95,115,111,117,114,99,101,70,3,0,0,115,20,0, + 101,116,95,115,111,117,114,99,101,71,3,0,0,115,20,0, 0,0,0,2,10,1,2,1,14,1,14,1,4,1,2,255, 4,1,2,255,24,2,122,23,83,111,117,114,99,101,76,111, 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,114, @@ -1298,7 +1298,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,114,26,0,0,0,114,44,0,0,0,114,230,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, 218,14,115,111,117,114,99,101,95,116,111,95,99,111,100,101, - 80,3,0,0,115,6,0,0,0,0,5,12,1,4,255,122, + 81,3,0,0,115,6,0,0,0,0,5,12,1,4,255,122, 27,83,111,117,114,99,101,76,111,97,100,101,114,46,115,111, 117,114,99,101,95,116,111,95,99,111,100,101,99,2,0,0, 0,0,0,0,0,0,0,0,0,15,0,0,0,9,0,0, @@ -1374,7 +1374,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 115,116,114,26,0,0,0,114,151,0,0,0,114,2,0,0, 0,90,10,98,121,116,101,115,95,100,97,116,97,90,11,99, 111,100,101,95,111,98,106,101,99,116,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,213,0,0,0,88,3, + 5,0,0,0,114,8,0,0,0,114,213,0,0,0,89,3, 0,0,115,152,0,0,0,0,7,10,1,4,1,4,1,4, 1,4,1,4,1,2,1,12,1,12,1,12,2,2,1,14, 1,12,1,8,2,12,1,2,1,14,1,12,1,6,3,2, @@ -1391,7 +1391,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,114,226,0,0,0,114,225,0,0,0,114,229,0,0, 0,114,233,0,0,0,114,213,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 221,0,0,0,29,3,0,0,115,14,0,0,0,8,2,8, + 221,0,0,0,30,3,0,0,115,14,0,0,0,8,2,8, 8,8,14,8,10,8,7,8,10,14,8,114,221,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,4,0,0,0,0,0,0,0,115,92,0,0,0,101,0, @@ -1418,7 +1418,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 32,32,32,32,32,32,32,102,105,110,100,101,114,46,78,114, 159,0,0,0,41,3,114,118,0,0,0,114,139,0,0,0, 114,44,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,209,0,0,0,178,3,0,0,115,4,0, + 8,0,0,0,114,209,0,0,0,179,3,0,0,115,4,0, 0,0,0,3,6,1,122,19,70,105,108,101,76,111,97,100, 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, @@ -1427,7 +1427,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,109,0,0,0,169,2,218,9,95,95,99,108,97,115, 115,95,95,114,131,0,0,0,169,2,114,118,0,0,0,90, 5,111,116,104,101,114,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,6,95,95,101,113,95,95,184,3,0, + 114,8,0,0,0,218,6,95,95,101,113,95,95,185,3,0, 0,115,6,0,0,0,0,1,12,1,10,255,122,17,70,105, 108,101,76,111,97,100,101,114,46,95,95,101,113,95,95,99, 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, @@ -1436,7 +1436,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,109,0,0,0,169,3,218,4,104,97,115,104,114,116, 0,0,0,114,44,0,0,0,169,1,114,118,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,8, - 95,95,104,97,115,104,95,95,188,3,0,0,115,2,0,0, + 95,95,104,97,115,104,95,95,189,3,0,0,115,2,0,0, 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, @@ -1450,7 +1450,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,97,100,46,10,10,32,32,32,32,32,32,32,32,41,3, 218,5,115,117,112,101,114,114,239,0,0,0,114,220,0,0, 0,114,219,0,0,0,169,1,114,241,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,220,0,0,0,191,3,0,0, + 0,0,114,8,0,0,0,114,220,0,0,0,192,3,0,0, 115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,97, 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, @@ -1460,7 +1460,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 117,114,99,101,32,102,105,108,101,32,97,115,32,102,111,117, 110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,114, 46,114,48,0,0,0,114,219,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,179,0,0,0,203, + 114,5,0,0,0,114,8,0,0,0,114,179,0,0,0,204, 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, @@ -1482,7 +1482,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 84,0,0,0,90,4,114,101,97,100,114,65,0,0,0,41, 3,114,118,0,0,0,114,44,0,0,0,114,68,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 227,0,0,0,208,3,0,0,115,10,0,0,0,0,2,14, + 227,0,0,0,209,3,0,0,115,10,0,0,0,0,2,14, 1,16,1,40,2,14,1,122,19,70,105,108,101,76,111,97, 100,101,114,46,103,101,116,95,100,97,116,97,99,2,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0, @@ -1494,7 +1494,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,118,0,0,0,114,216,0,0,0,114,253,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,19, 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, - 100,101,114,217,3,0,0,115,4,0,0,0,0,2,12,1, + 100,101,114,218,3,0,0,115,4,0,0,0,0,2,12,1, 122,30,70,105,108,101,76,111,97,100,101,114,46,103,101,116, 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, 41,13,114,125,0,0,0,114,124,0,0,0,114,126,0,0, @@ -1503,7 +1503,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 179,0,0,0,114,227,0,0,0,114,254,0,0,0,90,13, 95,95,99,108,97,115,115,99,101,108,108,95,95,114,5,0, 0,0,114,5,0,0,0,114,249,0,0,0,114,8,0,0, - 0,114,239,0,0,0,173,3,0,0,115,22,0,0,0,8, + 0,114,239,0,0,0,174,3,0,0,115,22,0,0,0,8, 2,4,3,8,6,8,4,8,3,2,1,14,11,2,1,10, 4,8,9,2,1,114,239,0,0,0,99,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, @@ -1525,7 +1525,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 3,114,49,0,0,0,218,8,115,116,95,109,116,105,109,101, 90,7,115,116,95,115,105,122,101,41,3,114,118,0,0,0, 114,44,0,0,0,114,238,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,224,0,0,0,227,3, + 5,0,0,0,114,8,0,0,0,114,224,0,0,0,228,3, 0,0,115,4,0,0,0,0,2,8,1,122,27,83,111,117, 114,99,101,70,105,108,101,76,111,97,100,101,114,46,112,97, 116,104,95,115,116,97,116,115,99,4,0,0,0,0,0,0, @@ -1536,7 +1536,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,225,0,0,0,41,5,114,118,0,0,0,114,107,0, 0,0,114,106,0,0,0,114,26,0,0,0,114,52,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 114,226,0,0,0,232,3,0,0,115,4,0,0,0,0,2, + 114,226,0,0,0,233,3,0,0,115,4,0,0,0,0,2, 8,1,122,32,83,111,117,114,99,101,70,105,108,101,76,111, 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, 99,111,100,101,114,60,0,0,0,114,1,1,0,0,99,3, @@ -1571,7 +1571,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,218,6,112,97,114,101,110,116,114,96,0,0,0,114,37, 0,0,0,114,33,0,0,0,114,228,0,0,0,114,5,0, 0,0,114,5,0,0,0,114,8,0,0,0,114,225,0,0, - 0,237,3,0,0,115,46,0,0,0,0,2,12,1,4,2, + 0,238,3,0,0,115,46,0,0,0,0,2,12,1,4,2, 12,1,12,1,12,2,12,1,10,1,2,1,14,1,12,2, 8,1,14,3,6,1,4,255,4,2,26,1,2,1,12,1, 16,1,14,2,8,1,2,255,122,25,83,111,117,114,99,101, @@ -1580,7 +1580,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,126,0,0,0,114,127,0,0,0,114,224,0,0,0,114, 226,0,0,0,114,225,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,255,0, - 0,0,223,3,0,0,115,8,0,0,0,8,2,4,2,8, + 0,0,224,3,0,0,115,8,0,0,0,8,2,4,2,8, 5,8,5,114,255,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, @@ -1602,7 +1602,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,41,5,114,118,0,0,0,114,139,0,0,0,114, 44,0,0,0,114,26,0,0,0,114,151,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,213,0, - 0,0,16,4,0,0,115,22,0,0,0,0,1,10,1,10, + 0,0,17,4,0,0,115,22,0,0,0,0,1,10,1,10, 4,2,1,2,254,6,4,12,1,2,1,14,1,2,1,2, 253,122,29,83,111,117,114,99,101,108,101,115,115,70,105,108, 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, @@ -1612,14 +1612,14 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,32,97,115,32,116,104,101,114,101,32,105,115,32,110,111, 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,5, 0,0,0,114,219,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,229,0,0,0,32,4,0,0, + 0,0,114,8,0,0,0,114,229,0,0,0,33,4,0,0, 115,2,0,0,0,0,2,122,31,83,111,117,114,99,101,108, 101,115,115,70,105,108,101,76,111,97,100,101,114,46,103,101, 116,95,115,111,117,114,99,101,78,41,6,114,125,0,0,0, 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, 213,0,0,0,114,229,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,5,1, - 0,0,12,4,0,0,115,6,0,0,0,8,2,4,2,8, + 0,0,13,4,0,0,115,6,0,0,0,8,2,4,2,8, 16,114,5,1,0,0,99,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, 92,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, @@ -1640,7 +1640,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,0,83,0,114,109,0,0,0,114,159,0,0,0,41,3, 114,118,0,0,0,114,116,0,0,0,114,44,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,209, - 0,0,0,49,4,0,0,115,4,0,0,0,0,1,6,1, + 0,0,0,50,4,0,0,115,4,0,0,0,0,1,6,1, 122,28,69,120,116,101,110,115,105,111,110,70,105,108,101,76, 111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, @@ -1648,7 +1648,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 124,1,106,0,107,2,111,22,124,0,106,1,124,1,106,1, 107,2,83,0,114,109,0,0,0,114,240,0,0,0,114,242, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,243,0,0,0,53,4,0,0,115,6,0,0,0, + 0,0,114,243,0,0,0,54,4,0,0,115,6,0,0,0, 0,1,12,1,10,255,122,26,69,120,116,101,110,115,105,111, 110,70,105,108,101,76,111,97,100,101,114,46,95,95,101,113, 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, @@ -1656,7 +1656,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 116,0,124,0,106,1,131,1,116,0,124,0,106,2,131,1, 65,0,83,0,114,109,0,0,0,114,244,0,0,0,114,246, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,247,0,0,0,57,4,0,0,115,2,0,0,0, + 0,0,114,247,0,0,0,58,4,0,0,115,2,0,0,0, 0,1,122,28,69,120,116,101,110,115,105,111,110,70,105,108, 101,76,111,97,100,101,114,46,95,95,104,97,115,104,95,95, 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, @@ -1673,7 +1673,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 110,97,109,105,99,114,149,0,0,0,114,116,0,0,0,114, 44,0,0,0,41,3,114,118,0,0,0,114,187,0,0,0, 114,216,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,212,0,0,0,60,4,0,0,115,14,0, + 8,0,0,0,114,212,0,0,0,61,4,0,0,115,14,0, 0,0,0,2,4,1,6,255,4,2,6,1,8,255,4,2, 122,33,69,120,116,101,110,115,105,111,110,70,105,108,101,76, 111,97,100,101,114,46,99,114,101,97,116,101,95,109,111,100, @@ -1691,7 +1691,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,114,149,0,0,0,114,116,0,0,0,114,44,0,0,0, 169,2,114,118,0,0,0,114,216,0,0,0,114,5,0,0, 0,114,5,0,0,0,114,8,0,0,0,114,217,0,0,0, - 68,4,0,0,115,8,0,0,0,0,2,14,1,6,1,8, + 69,4,0,0,115,8,0,0,0,0,2,14,1,6,1,8, 255,122,31,69,120,116,101,110,115,105,111,110,70,105,108,101, 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117, 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, @@ -1709,7 +1709,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,169,2,114,32,0,0,0,218,6,115,117,102,102, 105,120,169,1,90,9,102,105,108,101,95,110,97,109,101,114, 5,0,0,0,114,8,0,0,0,218,9,60,103,101,110,101, - 120,112,114,62,77,4,0,0,115,4,0,0,0,4,1,2, + 120,112,114,62,78,4,0,0,115,4,0,0,0,4,1,2, 255,122,49,69,120,116,101,110,115,105,111,110,70,105,108,101, 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, 101,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, @@ -1717,7 +1717,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 218,3,97,110,121,218,18,69,88,84,69,78,83,73,79,78, 95,83,85,70,70,73,88,69,83,114,219,0,0,0,114,5, 0,0,0,114,9,1,0,0,114,8,0,0,0,114,182,0, - 0,0,74,4,0,0,115,8,0,0,0,0,2,14,1,12, + 0,0,75,4,0,0,115,8,0,0,0,0,2,14,1,12, 1,2,255,122,30,69,120,116,101,110,115,105,111,110,70,105, 108,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, 97,103,101,99,2,0,0,0,0,0,0,0,0,0,0,0, @@ -1728,7 +1728,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,116,32,99,114,101,97,116,101,32,97,32,99,111,100,101, 32,111,98,106,101,99,116,46,78,114,5,0,0,0,114,219, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,114,213,0,0,0,80,4,0,0,115,2,0,0,0, + 0,0,114,213,0,0,0,81,4,0,0,115,2,0,0,0, 0,2,122,28,69,120,116,101,110,115,105,111,110,70,105,108, 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, @@ -1738,14 +1738,14 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,100,117,108,101,115,32,104,97,118,101,32,110,111,32,115, 111,117,114,99,101,32,99,111,100,101,46,78,114,5,0,0, 0,114,219,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,229,0,0,0,84,4,0,0,115,2, + 114,8,0,0,0,114,229,0,0,0,85,4,0,0,115,2, 0,0,0,0,2,122,30,69,120,116,101,110,115,105,111,110, 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,115, 111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,6, 0,0,0,124,0,106,0,83,0,114,250,0,0,0,114,48, 0,0,0,114,219,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,179,0,0,0,88,4,0,0, + 0,0,114,8,0,0,0,114,179,0,0,0,89,4,0,0, 115,2,0,0,0,0,3,122,32,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, 95,102,105,108,101,110,97,109,101,78,41,14,114,125,0,0, @@ -1754,7 +1754,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 212,0,0,0,114,217,0,0,0,114,182,0,0,0,114,213, 0,0,0,114,229,0,0,0,114,136,0,0,0,114,179,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,252,0,0,0,41,4,0,0,115, + 0,114,8,0,0,0,114,252,0,0,0,42,4,0,0,115, 22,0,0,0,8,2,4,6,8,4,8,4,8,3,8,8, 8,6,8,6,8,4,8,4,2,1,114,252,0,0,0,99, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -1797,7 +1797,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,169,4,114,118,0,0,0,114,116,0,0,0,114,44,0, 0,0,90,11,112,97,116,104,95,102,105,110,100,101,114,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,209, - 0,0,0,101,4,0,0,115,8,0,0,0,0,1,6,1, + 0,0,0,102,4,0,0,115,8,0,0,0,0,1,6,1, 6,1,14,1,122,23,95,78,97,109,101,115,112,97,99,101, 80,97,116,104,46,95,95,105,110,105,116,95,95,99,1,0, 0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,0, @@ -1814,7 +1814,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 4,114,118,0,0,0,114,4,1,0,0,218,3,100,111,116, 90,2,109,101,114,5,0,0,0,114,5,0,0,0,114,8, 0,0,0,218,23,95,102,105,110,100,95,112,97,114,101,110, - 116,95,112,97,116,104,95,110,97,109,101,115,107,4,0,0, + 116,95,112,97,116,104,95,110,97,109,101,115,108,4,0,0, 115,8,0,0,0,0,2,18,1,8,2,4,3,122,38,95, 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,102, 105,110,100,95,112,97,114,101,110,116,95,112,97,116,104,95, @@ -1827,7 +1827,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,118,0,0,0,90,18,112,97,114,101,110,116,95,109,111, 100,117,108,101,95,110,97,109,101,90,14,112,97,116,104,95, 97,116,116,114,95,110,97,109,101,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,16,1,0,0,117,4,0, + 0,0,0,114,8,0,0,0,114,16,1,0,0,118,4,0, 0,115,4,0,0,0,0,1,12,1,122,31,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,95,103,101,116,95, 112,97,114,101,110,116,95,112,97,116,104,99,1,0,0,0, @@ -1843,7 +1843,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,15,1,0,0,41,3,114,118,0,0,0,90, 11,112,97,114,101,110,116,95,112,97,116,104,114,187,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 218,12,95,114,101,99,97,108,99,117,108,97,116,101,121,4, + 218,12,95,114,101,99,97,108,99,117,108,97,116,101,122,4, 0,0,115,16,0,0,0,0,2,12,1,10,1,14,3,18, 1,6,1,8,1,6,1,122,27,95,78,97,109,101,115,112, 97,99,101,80,97,116,104,46,95,114,101,99,97,108,99,117, @@ -1852,7 +1852,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,116,0,124,0,160,1,161,0,131,1,83,0,114,109, 0,0,0,41,2,218,4,105,116,101,114,114,23,1,0,0, 114,246,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,8,95,95,105,116,101,114,95,95,134,4, + 8,0,0,0,218,8,95,95,105,116,101,114,95,95,135,4, 0,0,115,2,0,0,0,0,1,122,23,95,78,97,109,101, 115,112,97,99,101,80,97,116,104,46,95,95,105,116,101,114, 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, @@ -1861,7 +1861,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,169,1,114,23,1,0,0,41,2,114,118,0,0,0,218, 5,105,110,100,101,120,114,5,0,0,0,114,5,0,0,0, 114,8,0,0,0,218,11,95,95,103,101,116,105,116,101,109, - 95,95,137,4,0,0,115,2,0,0,0,0,1,122,26,95, + 95,95,138,4,0,0,115,2,0,0,0,0,1,122,26,95, 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, 103,101,116,105,116,101,109,95,95,99,3,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,0, @@ -1869,7 +1869,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,100,0,83,0,114,109,0,0,0,41,1,114,15,1,0, 0,41,3,114,118,0,0,0,114,27,1,0,0,114,44,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,11,95,95,115,101,116,105,116,101,109,95,95,140,4, + 0,218,11,95,95,115,101,116,105,116,101,109,95,95,141,4, 0,0,115,2,0,0,0,0,1,122,26,95,78,97,109,101, 115,112,97,99,101,80,97,116,104,46,95,95,115,101,116,105, 116,101,109,95,95,99,1,0,0,0,0,0,0,0,0,0, @@ -1877,7 +1877,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,116,0,124,0,160,1,161,0,131,1,83,0,114, 109,0,0,0,41,2,114,23,0,0,0,114,23,1,0,0, 114,246,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,7,95,95,108,101,110,95,95,143,4,0, + 8,0,0,0,218,7,95,95,108,101,110,95,95,144,4,0, 0,115,2,0,0,0,0,1,122,22,95,78,97,109,101,115, 112,97,99,101,80,97,116,104,46,95,95,108,101,110,95,95, 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, @@ -1886,7 +1886,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 78,97,109,101,115,112,97,99,101,80,97,116,104,40,123,33, 114,125,41,41,2,114,62,0,0,0,114,15,1,0,0,114, 246,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,8,95,95,114,101,112,114,95,95,146,4,0, + 0,0,0,218,8,95,95,114,101,112,114,95,95,147,4,0, 0,115,2,0,0,0,0,1,122,23,95,78,97,109,101,115, 112,97,99,101,80,97,116,104,46,95,95,114,101,112,114,95, 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, @@ -1894,7 +1894,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 1,124,0,160,0,161,0,118,0,83,0,114,109,0,0,0, 114,26,1,0,0,169,2,114,118,0,0,0,218,4,105,116, 101,109,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,149, + 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,150, 4,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,95,95,99,111,110, 116,97,105,110,115,95,95,99,2,0,0,0,0,0,0,0, @@ -1902,7 +1902,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 115,16,0,0,0,124,0,106,0,160,1,124,1,161,1,1, 0,100,0,83,0,114,109,0,0,0,41,2,114,15,1,0, 0,114,186,0,0,0,114,32,1,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,186,0,0,0,152, + 114,5,0,0,0,114,8,0,0,0,114,186,0,0,0,153, 4,0,0,115,2,0,0,0,0,1,122,21,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,97,112,112,101,110, 100,78,41,15,114,125,0,0,0,114,124,0,0,0,114,126, @@ -1911,7 +1911,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,28,1,0,0,114,29,1,0,0,114,30,1,0,0, 114,31,1,0,0,114,34,1,0,0,114,186,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,114,13,1,0,0,94,4,0,0,115,24,0,0, + 0,0,0,114,13,1,0,0,95,4,0,0,115,24,0,0, 0,8,1,4,6,8,6,8,10,8,4,8,13,8,3,8, 3,8,3,8,3,8,3,8,3,114,13,1,0,0,99,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, @@ -1927,7 +1927,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 124,1,124,2,124,3,131,3,124,0,95,1,100,0,83,0, 114,109,0,0,0,41,2,114,13,1,0,0,114,15,1,0, 0,114,19,1,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,209,0,0,0,158,4,0,0,115,2, + 114,8,0,0,0,114,209,0,0,0,159,4,0,0,115,2, 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, 101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,95, 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, @@ -1945,20 +1945,20 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,125,0,0,0,41,2,114,193,0,0,0,114, 216,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, 0,0,0,218,11,109,111,100,117,108,101,95,114,101,112,114, - 161,4,0,0,115,2,0,0,0,0,7,122,28,95,78,97, + 162,4,0,0,115,2,0,0,0,0,7,122,28,95,78,97, 109,101,115,112,97,99,101,76,111,97,100,101,114,46,109,111, 100,117,108,101,95,114,101,112,114,99,2,0,0,0,0,0, 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, 0,0,115,4,0,0,0,100,1,83,0,41,2,78,84,114, 5,0,0,0,114,219,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,182,0,0,0,170,4,0, + 0,0,0,114,8,0,0,0,114,182,0,0,0,171,4,0, 0,115,2,0,0,0,0,1,122,27,95,78,97,109,101,115, 112,97,99,101,76,111,97,100,101,114,46,105,115,95,112,97, 99,107,97,103,101,99,2,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, 0,0,0,100,1,83,0,41,2,78,114,40,0,0,0,114, 5,0,0,0,114,219,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,229,0,0,0,173,4,0, + 0,0,0,114,8,0,0,0,114,229,0,0,0,174,4,0, 0,115,2,0,0,0,0,1,122,27,95,78,97,109,101,115, 112,97,99,101,76,111,97,100,101,114,46,103,101,116,95,115, 111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,0, @@ -1968,20 +1968,20 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,105,110,103,62,114,215,0,0,0,84,41,1,114,231,0, 0,0,41,1,114,232,0,0,0,114,219,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,213,0, - 0,0,176,4,0,0,115,2,0,0,0,0,1,122,25,95, + 0,0,177,4,0,0,115,2,0,0,0,0,1,122,25,95, 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, 0,115,4,0,0,0,100,1,83,0,114,210,0,0,0,114, 5,0,0,0,114,211,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,212,0,0,0,179,4,0, + 0,0,0,114,8,0,0,0,114,212,0,0,0,180,4,0, 0,115,2,0,0,0,0,1,122,30,95,78,97,109,101,115, 112,97,99,101,76,111,97,100,101,114,46,99,114,101,97,116, 101,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, 0,115,4,0,0,0,100,0,83,0,114,109,0,0,0,114, 5,0,0,0,114,6,1,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,217,0,0,0,182,4,0, + 0,0,0,114,8,0,0,0,114,217,0,0,0,183,4,0, 0,115,2,0,0,0,0,1,122,28,95,78,97,109,101,115, 112,97,99,101,76,111,97,100,101,114,46,101,120,101,99,95, 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, @@ -1999,7 +1999,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 116,104,32,112,97,116,104,32,123,33,114,125,41,4,114,134, 0,0,0,114,149,0,0,0,114,15,1,0,0,114,218,0, 0,0,114,219,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,220,0,0,0,185,4,0,0,115, + 0,114,8,0,0,0,114,220,0,0,0,186,4,0,0,115, 8,0,0,0,0,7,6,1,4,255,4,2,122,28,95,78, 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,108, 111,97,100,95,109,111,100,117,108,101,78,41,12,114,125,0, @@ -2008,7 +2008,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,229,0,0,0,114,213,0,0,0,114,212,0,0,0,114, 217,0,0,0,114,220,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,35,1, - 0,0,157,4,0,0,115,18,0,0,0,8,1,8,3,2, + 0,0,158,4,0,0,115,18,0,0,0,8,1,8,3,2, 1,10,8,8,3,8,3,8,3,8,3,8,3,114,35,1, 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,4,0,0,0,64,0,0,0,115,118,0,0,0, @@ -2045,7 +2045,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,128,0,0,0,114,38,1,0,0,41,3,114,193,0,0, 0,114,116,0,0,0,218,6,102,105,110,100,101,114,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,38,1, - 0,0,203,4,0,0,115,10,0,0,0,0,4,22,1,8, + 0,0,204,4,0,0,115,10,0,0,0,0,4,22,1,8, 1,10,1,10,1,122,28,80,97,116,104,70,105,110,100,101, 114,46,105,110,118,97,108,105,100,97,116,101,95,99,97,99, 104,101,115,99,2,0,0,0,0,0,0,0,0,0,0,0, @@ -2065,7 +2065,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 117,0,0,0,41,3,114,193,0,0,0,114,44,0,0,0, 90,4,104,111,111,107,114,5,0,0,0,114,5,0,0,0, 114,8,0,0,0,218,11,95,112,97,116,104,95,104,111,111, - 107,115,213,4,0,0,115,16,0,0,0,0,3,16,1,12, + 107,115,214,4,0,0,115,16,0,0,0,0,3,16,1,12, 1,10,1,2,1,14,1,12,1,10,2,122,22,80,97,116, 104,70,105,110,100,101,114,46,95,112,97,116,104,95,104,111, 111,107,115,99,2,0,0,0,0,0,0,0,0,0,0,0, @@ -2096,7 +2096,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,114,111,114,114,44,1,0,0,41,3,114,193,0,0,0, 114,44,0,0,0,114,42,1,0,0,114,5,0,0,0,114, 5,0,0,0,114,8,0,0,0,218,20,95,112,97,116,104, - 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,226, + 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,227, 4,0,0,115,22,0,0,0,0,8,8,1,2,1,12,1, 12,3,8,1,2,1,14,1,12,1,10,1,16,1,122,31, 80,97,116,104,70,105,110,100,101,114,46,95,112,97,116,104, @@ -2114,7 +2114,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,139,0,0,0,114,42,1,0,0,114,140,0, 0,0,114,141,0,0,0,114,187,0,0,0,114,5,0,0, 0,114,5,0,0,0,114,8,0,0,0,218,16,95,108,101, - 103,97,99,121,95,103,101,116,95,115,112,101,99,248,4,0, + 103,97,99,121,95,103,101,116,95,115,112,101,99,249,4,0, 0,115,18,0,0,0,0,4,10,1,16,2,10,1,4,1, 8,1,12,1,12,1,6,1,122,27,80,97,116,104,70,105, 110,100,101,114,46,95,108,101,103,97,99,121,95,103,101,116, @@ -2146,7 +2146,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 97,116,104,90,5,101,110,116,114,121,114,42,1,0,0,114, 187,0,0,0,114,141,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,8,0,0,0,218,9,95,103,101,116,95,115, - 112,101,99,7,5,0,0,115,40,0,0,0,0,5,4,1, + 112,101,99,8,5,0,0,115,40,0,0,0,0,5,4,1, 8,1,14,1,2,1,10,1,8,1,10,1,14,2,12,1, 8,1,2,1,10,1,8,1,6,1,8,1,8,5,12,2, 12,1,6,1,122,20,80,97,116,104,70,105,110,100,101,114, @@ -2173,7 +2173,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 193,0,0,0,114,139,0,0,0,114,44,0,0,0,114,202, 0,0,0,114,187,0,0,0,114,50,1,0,0,114,5,0, 0,0,114,5,0,0,0,114,8,0,0,0,114,203,0,0, - 0,39,5,0,0,115,26,0,0,0,0,6,8,1,6,1, + 0,40,5,0,0,115,26,0,0,0,0,6,8,1,6,1, 14,1,8,1,4,1,10,1,6,1,4,3,6,1,16,1, 4,2,4,2,122,20,80,97,116,104,70,105,110,100,101,114, 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, @@ -2193,7 +2193,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, 32,32,32,32,78,114,204,0,0,0,114,205,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,206, - 0,0,0,63,5,0,0,115,8,0,0,0,0,8,12,1, + 0,0,0,64,5,0,0,115,8,0,0,0,0,8,12,1, 8,1,4,1,122,22,80,97,116,104,70,105,110,100,101,114, 46,102,105,110,100,95,109,111,100,117,108,101,99,1,0,0, 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, @@ -2225,7 +2225,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 98,117,116,105,111,110,115,41,4,114,193,0,0,0,114,119, 0,0,0,114,120,0,0,0,114,52,1,0,0,114,5,0, 0,0,114,5,0,0,0,114,8,0,0,0,114,53,1,0, - 0,76,5,0,0,115,4,0,0,0,0,10,12,1,122,29, + 0,77,5,0,0,115,4,0,0,0,0,10,12,1,122,29, 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, 100,105,115,116,114,105,98,117,116,105,111,110,115,41,1,78, 41,2,78,78,41,1,78,41,13,114,125,0,0,0,114,124, @@ -2234,7 +2234,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,48,1,0,0,114,51,1,0,0,114,203,0,0,0, 114,206,0,0,0,114,53,1,0,0,114,5,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,37, - 1,0,0,199,4,0,0,115,34,0,0,0,8,2,4,2, + 1,0,0,200,4,0,0,115,34,0,0,0,8,2,4,2, 2,1,10,9,2,1,10,12,2,1,10,21,2,1,10,14, 2,1,12,31,2,1,12,23,2,1,12,12,2,1,114,37, 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, @@ -2279,7 +2279,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 2,86,0,1,0,113,2,100,0,83,0,114,109,0,0,0, 114,5,0,0,0,114,7,1,0,0,169,1,114,140,0,0, 0,114,5,0,0,0,114,8,0,0,0,114,10,1,0,0, - 105,5,0,0,243,0,0,0,0,122,38,70,105,108,101,70, + 106,5,0,0,243,0,0,0,0,122,38,70,105,108,101,70, 105,110,100,101,114,46,95,95,105,110,105,116,95,95,46,60, 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, 62,114,71,0,0,0,114,104,0,0,0,78,41,7,114,167, @@ -2291,7 +2291,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,218,14,108,111,97,100,101,114,95,100,101,116,97,105, 108,115,90,7,108,111,97,100,101,114,115,114,189,0,0,0, 114,5,0,0,0,114,55,1,0,0,114,8,0,0,0,114, - 209,0,0,0,99,5,0,0,115,16,0,0,0,0,4,4, + 209,0,0,0,100,5,0,0,115,16,0,0,0,0,4,4, 1,12,1,26,1,6,2,10,1,6,1,8,1,122,19,70, 105,108,101,70,105,110,100,101,114,46,95,95,105,110,105,116, 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, @@ -2301,7 +2301,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,99,116,111,114,121,32,109,116,105,109,101,46,114,104,0, 0,0,78,41,1,114,58,1,0,0,114,246,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,38, - 1,0,0,113,5,0,0,115,2,0,0,0,0,2,122,28, + 1,0,0,114,5,0,0,115,2,0,0,0,0,2,122,28, 70,105,108,101,70,105,110,100,101,114,46,105,110,118,97,108, 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, @@ -2324,7 +2324,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,203,0,0,0,114,140,0,0,0,114,178,0,0,0,41, 3,114,118,0,0,0,114,139,0,0,0,114,187,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 137,0,0,0,119,5,0,0,115,8,0,0,0,0,7,10, + 137,0,0,0,120,5,0,0,115,8,0,0,0,0,7,10, 1,8,1,8,1,122,22,70,105,108,101,70,105,110,100,101, 114,46,102,105,110,100,95,108,111,97,100,101,114,99,6,0, 0,0,0,0,0,0,0,0,0,0,7,0,0,0,6,0, @@ -2334,7 +2334,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 190,0,0,0,41,7,114,118,0,0,0,114,188,0,0,0, 114,139,0,0,0,114,44,0,0,0,90,4,115,109,115,108, 114,202,0,0,0,114,140,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,51,1,0,0,131,5, + 5,0,0,0,114,8,0,0,0,114,51,1,0,0,132,5, 0,0,115,8,0,0,0,0,1,10,1,8,1,2,255,122, 20,70,105,108,101,70,105,110,100,101,114,46,95,103,101,116, 95,115,112,101,99,78,99,3,0,0,0,0,0,0,0,0, @@ -2389,7 +2389,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 13,105,110,105,116,95,102,105,108,101,110,97,109,101,90,9, 102,117,108,108,95,112,97,116,104,114,187,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,8,0,0,0,114,203,0, - 0,0,136,5,0,0,115,72,0,0,0,0,5,4,1,14, + 0,0,137,5,0,0,115,72,0,0,0,0,5,4,1,14, 1,2,1,24,1,12,1,10,1,10,1,8,1,6,2,6, 1,6,1,10,2,6,1,4,2,8,1,12,1,14,1,8, 1,10,1,8,1,24,4,8,2,14,1,16,1,16,1,12, @@ -2420,7 +2420,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 124,1,160,0,161,0,146,2,113,4,83,0,114,5,0,0, 0,41,1,114,105,0,0,0,41,2,114,32,0,0,0,90, 2,102,110,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,9,60,115,101,116,99,111,109,112,62,213,5,0, + 0,0,218,9,60,115,101,116,99,111,109,112,62,214,5,0, 0,114,56,1,0,0,122,41,70,105,108,101,70,105,110,100, 101,114,46,95,102,105,108,108,95,99,97,99,104,101,46,60, 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, @@ -2437,7 +2437,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 120,95,99,111,110,116,101,110,116,115,114,33,1,0,0,114, 116,0,0,0,114,20,1,0,0,114,8,1,0,0,90,8, 110,101,119,95,110,97,109,101,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,63,1,0,0,184,5,0,0, + 0,0,114,8,0,0,0,114,63,1,0,0,185,5,0,0, 115,34,0,0,0,0,2,6,1,2,1,22,1,18,3,10, 3,12,1,12,7,6,1,8,1,16,1,4,1,18,2,4, 1,12,1,6,1,12,1,122,22,70,105,108,101,70,105,110, @@ -2476,14 +2476,14 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,169,2,114,193,0,0,0,114,62,1,0,0,114, 5,0,0,0,114,8,0,0,0,218,24,112,97,116,104,95, 104,111,111,107,95,102,111,114,95,70,105,108,101,70,105,110, - 100,101,114,225,5,0,0,115,6,0,0,0,0,2,8,1, + 100,101,114,226,5,0,0,115,6,0,0,0,0,2,8,1, 12,1,122,54,70,105,108,101,70,105,110,100,101,114,46,112, 97,116,104,95,104,111,111,107,46,60,108,111,99,97,108,115, 62,46,112,97,116,104,95,104,111,111,107,95,102,111,114,95, 70,105,108,101,70,105,110,100,101,114,114,5,0,0,0,41, 3,114,193,0,0,0,114,62,1,0,0,114,69,1,0,0, 114,5,0,0,0,114,68,1,0,0,114,8,0,0,0,218, - 9,112,97,116,104,95,104,111,111,107,215,5,0,0,115,4, + 9,112,97,116,104,95,104,111,111,107,216,5,0,0,115,4, 0,0,0,0,10,14,6,122,20,70,105,108,101,70,105,110, 100,101,114,46,112,97,116,104,95,104,111,111,107,99,1,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, @@ -2492,7 +2492,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 70,105,110,100,101,114,40,123,33,114,125,41,41,2,114,62, 0,0,0,114,44,0,0,0,114,246,0,0,0,114,5,0, 0,0,114,5,0,0,0,114,8,0,0,0,114,31,1,0, - 0,233,5,0,0,115,2,0,0,0,0,1,122,19,70,105, + 0,234,5,0,0,115,2,0,0,0,0,1,122,19,70,105, 108,101,70,105,110,100,101,114,46,95,95,114,101,112,114,95, 95,41,1,78,41,15,114,125,0,0,0,114,124,0,0,0, 114,126,0,0,0,114,127,0,0,0,114,209,0,0,0,114, @@ -2500,7 +2500,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,51,1,0,0,114,203,0,0,0,114,63,1, 0,0,114,207,0,0,0,114,70,1,0,0,114,31,1,0, 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,54,1,0,0,90,5,0,0,115,22, + 114,8,0,0,0,114,54,1,0,0,91,5,0,0,115,22, 0,0,0,8,2,4,7,8,14,8,4,4,2,8,12,8, 5,10,48,8,31,2,1,10,17,114,54,1,0,0,99,4, 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,8, @@ -2523,7 +2523,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,90,8,112,97,116,104,110,97,109,101,90,9,99,112,97, 116,104,110,97,109,101,114,140,0,0,0,114,187,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,239, + 14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,240, 5,0,0,115,34,0,0,0,0,2,10,1,10,1,4,1, 4,1,8,1,8,1,12,2,10,1,4,1,14,1,2,1, 8,1,8,1,8,1,12,1,12,2,114,75,1,0,0,99, @@ -2543,7 +2543,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,5,1,0,0,114,88,0,0,0,41,3,90,10,101,120, 116,101,110,115,105,111,110,115,90,6,115,111,117,114,99,101, 90,8,98,121,116,101,99,111,100,101,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,184,0,0,0,6,6, + 5,0,0,0,114,8,0,0,0,114,184,0,0,0,7,6, 0,0,115,8,0,0,0,0,5,12,1,8,1,8,1,114, 184,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, 0,10,0,0,0,9,0,0,0,67,0,0,0,115,130,1, @@ -2591,7 +2591,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,0,107,2,86,0,1,0,113,2,100,1,83,0,41,2, 114,39,0,0,0,78,41,1,114,23,0,0,0,41,2,114, 32,0,0,0,114,94,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,10,1,0,0,35,6,0, + 0,0,0,114,8,0,0,0,114,10,1,0,0,36,6,0, 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, @@ -2603,7 +2603,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, 4,83,0,41,1,114,74,0,0,0,114,5,0,0,0,41, 2,114,32,0,0,0,218,1,115,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,64,1,0,0,52,6,0, + 0,0,0,114,8,0,0,0,114,64,1,0,0,53,6,0, 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, 62,41,3,114,64,0,0,0,114,75,0,0,0,114,160,0, @@ -2624,7 +2624,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 110,97,109,101,115,90,12,98,117,105,108,116,105,110,95,110, 97,109,101,90,14,98,117,105,108,116,105,110,95,109,111,100, 117,108,101,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,6,95,115,101,116,117,112,17,6,0,0,115,70, + 0,0,218,6,95,115,101,116,117,112,18,6,0,0,115,70, 0,0,0,0,8,4,1,6,1,6,2,10,3,22,1,12, 2,22,1,8,1,10,1,10,1,6,2,2,1,10,1,10, 1,12,1,10,2,8,2,12,1,12,1,18,1,22,3,8, @@ -2644,7 +2644,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,37,1,0,0,41,2,114,81,1,0,0,90,17,115, 117,112,112,111,114,116,101,100,95,108,111,97,100,101,114,115, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 8,95,105,110,115,116,97,108,108,74,6,0,0,115,8,0, + 8,95,105,110,115,116,97,108,108,75,6,0,0,115,8,0, 0,0,0,2,8,1,6,1,20,1,114,84,1,0,0,41, 1,114,60,0,0,0,41,1,78,41,3,78,78,78,41,2, 114,73,0,0,0,114,73,0,0,0,41,1,84,41,1,78, @@ -2678,7 +2678,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,117,108,101,62,1,0,0,0,115,126,0,0,0,4,22, 4,1,4,1,2,1,2,255,4,4,8,17,8,5,8,5, 8,6,8,6,8,12,8,10,8,9,8,5,8,7,8,9, - 10,22,10,127,0,20,16,1,12,2,4,1,4,2,6,2, + 10,22,10,127,0,21,16,1,12,2,4,1,4,2,6,2, 6,2,8,2,16,71,8,40,8,19,8,12,8,12,8,28, 8,17,8,33,8,28,8,24,10,13,10,10,10,11,8,14, 6,3,4,1,2,255,12,68,14,64,14,29,16,127,0,17, From c7f74c93d82986a4e6e1c862b476bce014b09a10 Mon Sep 17 00:00:00 2001 From: abdo Date: Sun, 11 Oct 2020 09:10:21 +0300 Subject: [PATCH 447/486] Fix typo in typing.rst (GH-22625) --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index f4b2718cdc2f8ce..6111603a995c589 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1723,7 +1723,7 @@ Constant If ``from __future__ import annotations`` is used in Python 3.7 or later, annotations are not evaluated at function definition time. - Instead, the are stored as strings in ``__annotations__``, + Instead, they are stored as strings in ``__annotations__``, This makes it unnecessary to use quotes around the annotation. (see :pep:`563`). From 9146814dbf93a3ee91b44ae8bd204c2899715326 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 11 Oct 2020 15:30:43 +0300 Subject: [PATCH 448/486] bpo-42002: Clean up initialization of the sys module. (GH-22642) Makes the code clearer and make errors handling more correct. --- Python/sysmodule.c | 152 ++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 107 deletions(-) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 9fcdb5dbc49b144..bfcf4e85140a84b 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2649,18 +2649,7 @@ static struct PyModuleDef sysmodule = { }; /* Updating the sys namespace, returning NULL pointer on error */ -#define SET_SYS_FROM_STRING_BORROW(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) { \ - goto err_occurred; \ - } \ - res = PyDict_SetItemString(sysdict, key, v); \ - if (res < 0) { \ - goto err_occurred; \ - } \ - } while (0) -#define SET_SYS_FROM_STRING(key, value) \ +#define SET_SYS(key, value) \ do { \ PyObject *v = (value); \ if (v == NULL) { \ @@ -2673,6 +2662,9 @@ static struct PyModuleDef sysmodule = { } \ } while (0) +#define SET_SYS_FROM_STRING(key, value) \ + SET_SYS(key, PyUnicode_FromString(value)) + static PyStatus _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) { @@ -2681,65 +2673,48 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) /* stdin/stdout/stderr are set in pylifecycle.c */ - SET_SYS_FROM_STRING_BORROW("__displayhook__", - PyDict_GetItemString(sysdict, "displayhook")); - SET_SYS_FROM_STRING_BORROW("__excepthook__", - PyDict_GetItemString(sysdict, "excepthook")); - SET_SYS_FROM_STRING_BORROW( - "__breakpointhook__", - PyDict_GetItemString(sysdict, "breakpointhook")); - SET_SYS_FROM_STRING_BORROW("__unraisablehook__", - PyDict_GetItemString(sysdict, "unraisablehook")); - - SET_SYS_FROM_STRING("version", - PyUnicode_FromString(Py_GetVersion())); - SET_SYS_FROM_STRING("hexversion", - PyLong_FromLong(PY_VERSION_HEX)); - SET_SYS_FROM_STRING("_git", - Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), - _Py_gitversion())); - SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK)); - SET_SYS_FROM_STRING("api_version", - PyLong_FromLong(PYTHON_API_VERSION)); - SET_SYS_FROM_STRING("copyright", - PyUnicode_FromString(Py_GetCopyright())); - SET_SYS_FROM_STRING("platform", - PyUnicode_FromString(Py_GetPlatform())); - SET_SYS_FROM_STRING("maxsize", - PyLong_FromSsize_t(PY_SSIZE_T_MAX)); - SET_SYS_FROM_STRING("float_info", - PyFloat_GetInfo()); - SET_SYS_FROM_STRING("int_info", - PyLong_GetInfo()); +#define COPY_SYS_ATTR(tokey, fromkey) \ + SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey)) + + COPY_SYS_ATTR("__displayhook__", "displayhook"); + COPY_SYS_ATTR("__excepthook__", "excepthook"); + COPY_SYS_ATTR("__breakpointhook__", "breakpointhook"); + COPY_SYS_ATTR("__unraisablehook__", "unraisablehook"); + +#undef COPY_SYS_ATTR + + SET_SYS_FROM_STRING("version", Py_GetVersion()); + SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX)); + SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), + _Py_gitversion())); + SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK); + SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION)); + SET_SYS_FROM_STRING("copyright", Py_GetCopyright()); + SET_SYS_FROM_STRING("platform", Py_GetPlatform()); + SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); + SET_SYS("float_info", PyFloat_GetInfo()); + SET_SYS("int_info", PyLong_GetInfo()); /* initialize hash_info */ if (Hash_InfoType.tp_name == NULL) { if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { goto type_init_failed; } } - SET_SYS_FROM_STRING("hash_info", - get_hash_info(tstate)); - SET_SYS_FROM_STRING("maxunicode", - PyLong_FromLong(0x10FFFF)); - SET_SYS_FROM_STRING("builtin_module_names", - list_builtin_module_names()); + SET_SYS("hash_info", get_hash_info(tstate)); + SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF)); + SET_SYS("builtin_module_names", list_builtin_module_names()); #if PY_BIG_ENDIAN - SET_SYS_FROM_STRING("byteorder", - PyUnicode_FromString("big")); + SET_SYS_FROM_STRING("byteorder", "big"); #else - SET_SYS_FROM_STRING("byteorder", - PyUnicode_FromString("little")); + SET_SYS_FROM_STRING("byteorder", "little"); #endif #ifdef MS_COREDLL - SET_SYS_FROM_STRING("dllhandle", - PyLong_FromVoidPtr(PyWin_DLLhModule)); - SET_SYS_FROM_STRING("winver", - PyUnicode_FromString(PyWin_DLLVersionString)); + SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); + SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString); #endif #ifdef ABIFLAGS - SET_SYS_FROM_STRING("abiflags", - PyUnicode_FromString(ABIFLAGS)); + SET_SYS_FROM_STRING("abiflags", ABIFLAGS); #endif /* version_info */ @@ -2750,7 +2725,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) } } version_info = make_version_info(tstate); - SET_SYS_FROM_STRING("version_info", version_info); + SET_SYS("version_info", version_info); /* prevent user from creating new instances */ VersionInfoType.tp_init = NULL; VersionInfoType.tp_new = NULL; @@ -2760,7 +2735,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) } /* implementation */ - SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); + SET_SYS("implementation", make_impl_info(version_info)); /* flags */ if (FlagsType.tp_name == 0) { @@ -2769,7 +2744,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(tstate)); + SET_SYS("flags", make_flags(tstate)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2790,14 +2765,12 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR - SET_SYS_FROM_STRING("float_repr_style", - PyUnicode_FromString("short")); + SET_SYS_FROM_STRING("float_repr_style", "short"); #else - SET_SYS_FROM_STRING("float_repr_style", - PyUnicode_FromString("legacy")); + SET_SYS_FROM_STRING("float_repr_style", "legacy"); #endif - SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo()); + SET_SYS("thread_info", PyThread_GetInfo()); /* initialize asyncgen_hooks */ if (AsyncGenHooksType.tp_name == NULL) { @@ -2819,20 +2792,6 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) return _PyStatus_ERR("can't initialize sys module"); } -/* Updating the sys namespace, returning integer error codes */ -#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) \ - return -1; \ - res = PyDict_SetItemString(sysdict, key, v); \ - Py_DECREF(v); \ - if (res < 0) { \ - return res; \ - } \ - } while (0) - - static int sys_add_xoption(PyObject *opts, const wchar_t *s) { @@ -2895,24 +2854,10 @@ _PySys_InitMain(PyThreadState *tstate) int res; #define COPY_LIST(KEY, VALUE) \ - do { \ - PyObject *list = _PyWideStringList_AsList(&(VALUE)); \ - if (list == NULL) { \ - return -1; \ - } \ - SET_SYS_FROM_STRING_BORROW(KEY, list); \ - Py_DECREF(list); \ - } while (0) + SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE))); #define SET_SYS_FROM_WSTR(KEY, VALUE) \ - do { \ - PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \ - if (str == NULL) { \ - return -1; \ - } \ - SET_SYS_FROM_STRING_BORROW(KEY, str); \ - Py_DECREF(str); \ - } while (0) + SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1)); COPY_LIST("path", config->module_search_paths); @@ -2934,19 +2879,14 @@ _PySys_InitMain(PyThreadState *tstate) COPY_LIST("orig_argv", config->orig_argv); COPY_LIST("warnoptions", config->warnoptions); - PyObject *xoptions = sys_create_xoptions_dict(config); - if (xoptions == NULL) { - return -1; - } - SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions); - Py_DECREF(xoptions); + SET_SYS("_xoptions", sys_create_xoptions_dict(config)); #undef COPY_LIST #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(tstate)); + SET_SYS("flags", make_flags(tstate)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2958,8 +2898,7 @@ _PySys_InitMain(PyThreadState *tstate) _PyErr_Clear(tstate); } - SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode", - PyBool_FromLong(!config->write_bytecode)); + SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); if (get_warnoptions(tstate) == NULL) { return -1; @@ -2978,9 +2917,8 @@ _PySys_InitMain(PyThreadState *tstate) return -1; } +#undef SET_SYS #undef SET_SYS_FROM_STRING -#undef SET_SYS_FROM_STRING_BORROW -#undef SET_SYS_FROM_STRING_INT_RESULT /* Set up a preliminary stderr printer until we have enough From 38658f7240a2c3bc8939e41fb005a0e840b1508d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 11 Oct 2020 16:51:07 +0300 Subject: [PATCH 449/486] bpo-41993: Fix possible issues in remove_module() (GH-22631) * PyMapping_HasKey() is not safe because it silences all exceptions and can return incorrect result. * Informative exceptions from PyMapping_DelItem() are overridden with RuntimeError and the original exception raised before calling remove_module() is lost. * There is a race condition between PyMapping_HasKey() and PyMapping_DelItem(). --- .../2020-10-10-13-53-52.bpo-41993.YMzixQ.rst | 2 ++ Python/import.c | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst new file mode 100644 index 000000000000000..3669cf11ea4cd36 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst @@ -0,0 +1,2 @@ +Fixed potential issues with removing not completely initialized module from +``sys.modules`` when import fails. diff --git a/Python/import.c b/Python/import.c index 505688400ef3e3a..26b80f320c34370 100644 --- a/Python/import.c +++ b/Python/import.c @@ -902,7 +902,11 @@ PyImport_AddModule(const char *name) } -/* Remove name from sys.modules, if it's there. */ +/* Remove name from sys.modules, if it's there. + * Can be called with an exception raised. + * If fail to remove name a new exception will be chained with the old + * exception, otherwise the old exception is preserved. + */ static void remove_module(PyThreadState *tstate, PyObject *name) { @@ -910,18 +914,17 @@ remove_module(PyThreadState *tstate, PyObject *name) _PyErr_Fetch(tstate, &type, &value, &traceback); PyObject *modules = tstate->interp->modules; - if (!PyMapping_HasKey(modules, name)) { - goto out; + if (PyDict_CheckExact(modules)) { + PyObject *mod = _PyDict_Pop(modules, name, Py_None); + Py_XDECREF(mod); } - if (PyMapping_DelItem(modules, name) < 0) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "deleting key in sys.modules failed"); - _PyErr_ChainExceptions(type, value, traceback); - return; + else if (PyMapping_DelItem(modules, name) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); + } } -out: - _PyErr_Restore(tstate, type, value, traceback); + _PyErr_ChainExceptions(type, value, traceback); } From c47291f30a032d2f5647bd63033ab81e611a6a5a Mon Sep 17 00:00:00 2001 From: Gaurav Kamath Date: Sun, 11 Oct 2020 11:13:43 -0700 Subject: [PATCH 450/486] Fix typo (GH-22582) /af/of/s Automerge-Triggered-By: @Mariatta --- Doc/library/math.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index bbf64643ff59fc7..145bac4966e18cc 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -130,7 +130,7 @@ Number-theoretic and representation functions Return the greatest common divisor of the specified integer arguments. If any of the arguments is nonzero, then the returned value is the largest - positive integer that is a divisor af all arguments. If all arguments + positive integer that is a divisor of all arguments. If all arguments are zero, then the returned value is ``0``. ``gcd()`` without arguments returns ``0``. From ea85058664c598e6bf1ec848c3632128c3e6e60c Mon Sep 17 00:00:00 2001 From: chilaxan Date: Sun, 11 Oct 2020 14:21:51 -0400 Subject: [PATCH 451/486] Fix typo in listobject.h (GH-22588) --- Include/cpython/listobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index 70b9d83d8a232cc..e1b9462d5b3612a 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -26,7 +26,7 @@ PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); /* Macro, trading safety for speed */ -/* Cast argument to PyTupleObject* type. */ +/* Cast argument to PyListObject* type. */ #define _PyList_CAST(op) (assert(PyList_Check(op)), (PyListObject *)(op)) #define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i]) From c43014900ddfd6cd242b3e20136269a99d7c7af9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 11 Oct 2020 11:26:50 -0700 Subject: [PATCH 452/486] Fix .. code-block :: directives in decimal.rst (GH-22571) --- Doc/c-api/decimal.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/decimal.rst b/Doc/c-api/decimal.rst index f530571ebae5771..94cc4a7b8457913 100644 --- a/Doc/c-api/decimal.rst +++ b/Doc/c-api/decimal.rst @@ -16,7 +16,7 @@ Initialize Typically, a C extension module that uses the decimal API will do these steps in its init function: -.. code-block:: +.. code-block:: c #include "pydecimal.h" @@ -88,7 +88,7 @@ Data structures The conversion functions use the following status codes and data structures: -.. code-block:: +.. code-block:: c /* status cases for getting a triple */ enum mpd_triple_class { @@ -126,7 +126,7 @@ Functions For simplicity, the usage of the function and all special cases are explained in code form and comments: -.. code-block:: +.. code-block:: c triple = PyDec_AsUint128Triple(dec); switch (triple.tag) { From d758a709c3c7a4912cc3edf3eeeb0f5179446732 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 11 Oct 2020 13:54:11 -0500 Subject: [PATCH 453/486] bpo-40422: create a common _Py_closerange API (GH-19754) Such an API can be used both for os.closerange and subprocess. For the latter, this yields potential improvement for platforms that have fdwalk but wouldn't have used it there. This will prove even more beneficial later for platforms that have close_range(2), as the new API will prefer that over all else if it's available. The new API is structured to look more like close_range(2), closing from [start, end] rather than the [low, high) of os.closerange(). Automerge-Triggered-By: @gpshead --- .../2020-10-10-14-05-24.bpo-40422.sh8IDY.rst | 1 + Modules/_posixsubprocess.c | 15 +--- Modules/posixmodule.c | 70 ++++++++++++------- Modules/posixmodule.h | 2 + 4 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-10-14-05-24.bpo-40422.sh8IDY.rst diff --git a/Misc/NEWS.d/next/C API/2020-10-10-14-05-24.bpo-40422.sh8IDY.rst b/Misc/NEWS.d/next/C API/2020-10-10-14-05-24.bpo-40422.sh8IDY.rst new file mode 100644 index 000000000000000..1b6d9e034b52960 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-10-14-05-24.bpo-40422.sh8IDY.rst @@ -0,0 +1 @@ +Add `_Py_closerange` function to provide performant closing of a range of file descriptors. \ No newline at end of file diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 5d1691ace419200..ed046fc5c1ba9f3 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -250,7 +250,6 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) long end_fd = safe_get_max_fd(); Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); Py_ssize_t keep_seq_idx; - int fd_num; /* As py_fds_to_keep is sorted we can loop through the list closing * fds in between any in the keep list falling within our range. */ for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { @@ -258,21 +257,11 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) int keep_fd = PyLong_AsLong(py_keep_fd); if (keep_fd < start_fd) continue; - for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { - close(fd_num); - } + _Py_closerange(start_fd, keep_fd - 1); start_fd = keep_fd + 1; } if (start_fd <= end_fd) { -#if defined(__FreeBSD__) - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(start_fd); -#else - for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { - /* Ignore errors */ - (void)close(fd_num); - } -#endif + _Py_closerange(start_fd, end_fd); } } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 165625c9a670a5c..321eaec63c4a489 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8740,8 +8740,23 @@ os_close_impl(PyObject *module, int fd) Py_RETURN_NONE; } +/* Our selection logic for which function to use is as follows: + * 1. If closefrom(2) is available, we'll attempt to use that next if we're + * closing up to sysconf(_SC_OPEN_MAX). + * 1a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * as that will be more performant if the range happens to have any chunk of + * non-opened fd in the middle. + * 1b. If fdwalk(3) isn't available, just do a plain close(2) loop. + */ +#ifdef __FreeBSD__ +#define USE_CLOSEFROM +#endif /* __FreeBSD__ */ #ifdef HAVE_FDWALK +#define USE_FDWALK +#endif /* HAVE_FDWALK */ + +#ifdef USE_FDWALK static int _fdwalk_close_func(void *lohi, int fd) { @@ -8757,7 +8772,36 @@ _fdwalk_close_func(void *lohi, int fd) } return 0; } -#endif /* HAVE_FDWALK */ +#endif /* USE_FDWALK */ + +/* Closes all file descriptors in [first, last], ignoring errors. */ +void +_Py_closerange(int first, int last) +{ + first = Py_MAX(first, 0); +#ifdef USE_CLOSEFROM + if (last >= sysconf(_SC_OPEN_MAX)) { + /* Any errors encountered while closing file descriptors are ignored */ + closefrom(first); + } + else +#endif /* USE_CLOSEFROM */ +#ifdef USE_FDWALK + { + int lohi[2]; + lohi[0] = first; + lohi[1] = last + 1; + fdwalk(_fdwalk_close_func, lohi); + } +#else + { + for (int i = first; i <= last; i++) { + /* Ignore errors */ + (void)close(i); + } + } +#endif /* USE_FDWALK */ +} /*[clinic input] os.closerange @@ -8773,31 +8817,9 @@ static PyObject * os_closerange_impl(PyObject *module, int fd_low, int fd_high) /*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ { -#ifdef HAVE_FDWALK - int lohi[2]; -#endif Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_FDWALK - lohi[0] = Py_MAX(fd_low, 0); - lohi[1] = fd_high; - fdwalk(_fdwalk_close_func, lohi); -#else - fd_low = Py_MAX(fd_low, 0); -#ifdef __FreeBSD__ - if (fd_high >= sysconf(_SC_OPEN_MAX)) { - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(fd_low); - } - else -#endif - { - for (int i = fd_low; i < fd_high; i++) { - /* Ignore errors */ - (void)close(i); - } - } -#endif + _Py_closerange(fd_low, fd_high - 1); _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 1e00562abc3370e..749833f71cd4de5 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -28,6 +28,8 @@ PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); #endif /* HAVE_SIGSET_T */ #endif /* Py_LIMITED_API */ +PyAPI_FUNC(void) _Py_closerange(int first, int last); + #ifdef __cplusplus } #endif From 9dce2e731caa253abc3b37b33fe942327e9be649 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 11 Oct 2020 15:18:53 -0500 Subject: [PATCH 454/486] bpo-40423: Optimization: use close_range(2) if available (GH-22651) close_range(2) should be preferred at all times if it's available, otherwise we'll use closefrom(2) if available with a fallback to fdwalk(3) or plain old loop over fd range in order of most efficient to least. [note that this version does check for ENOSYS, but currently ignores all other errors] Automerge-Triggered-By: @pablogsal --- .../2020-10-11-19-17-44.bpo-40423.GsmgEj.rst | 3 +++ Modules/posixmodule.c | 17 ++++++++++++++--- configure | 4 ++-- configure.ac | 4 ++-- pyconfig.h.in | 3 +++ 5 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst diff --git a/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst b/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst new file mode 100644 index 000000000000000..44e571ebf86daf5 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst @@ -0,0 +1,3 @@ +The :mod:`subprocess` module and ``os.closerange`` will now use the +``close_range(low, high, flags)`` syscall when it is available for more +efficient closing of ranges of descriptors. \ No newline at end of file diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 321eaec63c4a489..2e0caaa3e561ba7 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8741,12 +8741,15 @@ os_close_impl(PyObject *module, int fd) } /* Our selection logic for which function to use is as follows: - * 1. If closefrom(2) is available, we'll attempt to use that next if we're + * 1. If close_range(2) is available, always prefer that; it's better for + * contiguous ranges like this than fdwalk(3) which entails iterating over + * the entire fd space and simply doing nothing for those outside the range. + * 2. If closefrom(2) is available, we'll attempt to use that next if we're * closing up to sysconf(_SC_OPEN_MAX). - * 1a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), * as that will be more performant if the range happens to have any chunk of * non-opened fd in the middle. - * 1b. If fdwalk(3) isn't available, just do a plain close(2) loop. + * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. */ #ifdef __FreeBSD__ #define USE_CLOSEFROM @@ -8779,6 +8782,14 @@ void _Py_closerange(int first, int last) { first = Py_MAX(first, 0); +#ifdef HAVE_CLOSE_RANGE + if (close_range(first, last, 0) == 0 || errno != ENOSYS) { + /* Any errors encountered while closing file descriptors are ignored; + * ENOSYS means no kernel support, though, + * so we'll fallback to the other methods. */ + } + else +#endif /* HAVE_CLOSE_RANGE */ #ifdef USE_CLOSEFROM if (last >= sysconf(_SC_OPEN_MAX)) { /* Any errors encountered while closing file descriptors are ignored */ diff --git a/configure b/configure index ad74754e9a72154..89577d85a41482d 100755 --- a/configure +++ b/configure @@ -11672,8 +11672,8 @@ fi # checks for library functions for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ - faccessat fchmod fchmodat fchown fchownat \ + clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ + explicit_memset faccessat fchmod fchmodat fchown fchownat \ fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/configure.ac b/configure.ac index f0bc8c625844b6b..3ec274c576edfd6 100644 --- a/configure.ac +++ b/configure.ac @@ -3664,8 +3664,8 @@ fi # checks for library functions AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ - faccessat fchmod fchmodat fchown fchownat \ + clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ + explicit_memset faccessat fchmod fchmodat fchown fchownat \ fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/pyconfig.h.in b/pyconfig.h.in index c162a3c33e57b67..298cb4fa12f80c4 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -139,6 +139,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #undef HAVE_CLOCK_SETTIME +/* Define to 1 if you have the `close_range' function. */ +#undef HAVE_CLOSE_RANGE + /* Define if the C compiler supports computed gotos. */ #undef HAVE_COMPUTED_GOTOS From 14358bfa9cce4868a1cd648174145cf7719b4752 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 11 Oct 2020 21:34:51 +0100 Subject: [PATCH 455/486] bpo-41971: Fix test failure in test.test_tools.test_c_analyzer when mutating global state (GH-22652) --- Tools/c-analyzer/c_analyzer/common/files.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tools/c-analyzer/c_analyzer/common/files.py b/Tools/c-analyzer/c_analyzer/common/files.py index f630afe62592424..a8a044757d00b2b 100644 --- a/Tools/c-analyzer/c_analyzer/common/files.py +++ b/Tools/c-analyzer/c_analyzer/common/files.py @@ -60,7 +60,7 @@ def glob_tree(root, *, def iter_files(root, suffix=None, relparent=None, *, - get_files=os.walk, + get_files=None, _glob=glob_tree, _walk=walk_tree, ): @@ -75,6 +75,8 @@ def iter_files(root, suffix=None, relparent=None, *, if "relparent" is provided then it is used to resolve each filename as a relative path. """ + if get_files is None: + get_files = os.walk if not isinstance(root, str): roots = root for root in roots: From 9fcfc0ecf869e0b86b4fdcf74ed9d8c400a66bb0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 12 Oct 2020 00:37:20 +0200 Subject: [PATCH 456/486] bpo-41739: Fix test_logging.test_race_between_set_target_and_flush() (GH-22655) The test now waits until all threads complete to avoid leaking running threads. Also, use regular threads rather than daemon threads. --- Lib/test/test_logging.py | 21 ++++++++++++------- .../2020-10-12-00-11-47.bpo-41739.wSCc4K.rst | 2 ++ 2 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2020-10-12-00-11-47.bpo-41739.wSCc4K.rst diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 4cd8c7e25daa938..7c98e19b7408fc8 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1164,22 +1164,27 @@ def test_race_between_set_target_and_flush(self): class MockRaceConditionHandler: def __init__(self, mem_hdlr): self.mem_hdlr = mem_hdlr + self.threads = [] def removeTarget(self): self.mem_hdlr.setTarget(None) def handle(self, msg): - t = threading.Thread(target=self.removeTarget) - t.daemon = True - t.start() + thread = threading.Thread(target=self.removeTarget) + self.threads.append(thread) + thread.start() target = MockRaceConditionHandler(self.mem_hdlr) - self.mem_hdlr.setTarget(target) + try: + self.mem_hdlr.setTarget(target) - for _ in range(10): - time.sleep(0.005) - self.mem_logger.info("not flushed") - self.mem_logger.warning("flushed") + for _ in range(10): + time.sleep(0.005) + self.mem_logger.info("not flushed") + self.mem_logger.warning("flushed") + finally: + for thread in target.threads: + threading_helper.join_thread(thread) class ExceptionFormatter(logging.Formatter): diff --git a/Misc/NEWS.d/next/Tests/2020-10-12-00-11-47.bpo-41739.wSCc4K.rst b/Misc/NEWS.d/next/Tests/2020-10-12-00-11-47.bpo-41739.wSCc4K.rst new file mode 100644 index 000000000000000..7aee2b94444727c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-10-12-00-11-47.bpo-41739.wSCc4K.rst @@ -0,0 +1,2 @@ +Fix test_logging.test_race_between_set_target_and_flush(): the test now +waits until all threads complete to avoid leaking running threads. From c516e64b9ff2cf260a794c5059c89720a8ea1f68 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Mon, 12 Oct 2020 10:52:30 -0300 Subject: [PATCH 457/486] [doc] Remove mention of async and await as soft keywords (GH-22144) --- Doc/reference/compound_stmts.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 04a3948d0c9dcf2..62986cb151964a8 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -768,10 +768,8 @@ Coroutine function definition keyword: await Execution of Python coroutines can be suspended and resumed at many points -(see :term:`coroutine`). Inside the body of a coroutine function, ``await`` and -``async`` identifiers become reserved keywords; :keyword:`await` expressions, -:keyword:`async for` and :keyword:`async with` can only be used in -coroutine function bodies. +(see :term:`coroutine`). :keyword:`await` expressions, :keyword:`async for` and +:keyword:`async with` can only be used in the body of a coroutine function. Functions defined with ``async def`` syntax are always coroutine functions, even if they do not contain ``await`` or ``async`` keywords. @@ -785,6 +783,9 @@ An example of a coroutine function:: do_stuff() await some_coroutine() +.. versionchanged:: 3.7 + ``await`` and ``async`` are now keywords; previously they were only + treated as such inside the body of a coroutine function. .. index:: statement: async for .. _`async for`: From 67122b0fd103460603ec9398dc9e53eebea153e7 Mon Sep 17 00:00:00 2001 From: linchiwei123 <40888469+linchiwei123@users.noreply.github.com> Date: Mon, 12 Oct 2020 22:33:34 +0800 Subject: [PATCH 458/486] [doc] Fix typo in the graphlib docs (GH-22661) Automerge-Triggered-By: @pablogsal --- Lib/graphlib.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/graphlib.py b/Lib/graphlib.py index 948f62f1dc30340..d0e7a4814c565dc 100644 --- a/Lib/graphlib.py +++ b/Lib/graphlib.py @@ -22,7 +22,8 @@ def __init__(self, node): class CycleError(ValueError): - """Subclass of ValueError raised by TopologicalSorterif cycles exist in the graph + """Subclass of ValueError raised by TopologicalSorter.prepare if cycles + exist in the working graph. If multiple cycles exist, only one undefined choice among them will be reported and included in the exception. The detected cycle can be accessed via the second @@ -129,7 +130,7 @@ def get_ready(self): return result def is_active(self): - """Return True if more progress can be made and ``False`` otherwise. + """Return ``True`` if more progress can be made and ``False`` otherwise. Progress can be made if cycles do not block the resolution and either there are still nodes ready that haven't yet been returned by "get_ready" or the @@ -149,7 +150,7 @@ def done(self, *nodes): """Marks a set of nodes returned by "get_ready" as processed. This method unblocks any successor of each node in *nodes* for being returned - in the future by a a call to "get_ready" + in the future by a call to "get_ready". Raises :exec:`ValueError` if any node in *nodes* has already been marked as processed by a previous call to this method, if a node was not added to the From 0ca6db1d296b01d2368a947553f3cd39686986c7 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 12 Oct 2020 12:10:42 -0700 Subject: [PATCH 459/486] Delete PyGen_Send (#22663) --- Doc/c-api/gen.rst | 10 ---------- Doc/data/refcounts.dat | 5 ----- Doc/whatsnew/3.10.rst | 2 +- Include/genobject.h | 9 --------- Misc/NEWS.d/3.10.0a1.rst | 10 ---------- Objects/abstract.c | 25 ------------------------- Objects/genobject.c | 24 ++++++++++++++++++++---- 7 files changed, 21 insertions(+), 64 deletions(-) diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst index 600f53486f79d5b..74410927bfde107 100644 --- a/Doc/c-api/gen.rst +++ b/Doc/c-api/gen.rst @@ -42,13 +42,3 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. A reference to *frame* is stolen by this function. The *frame* argument must not be ``NULL``. - -.. c:function:: PySendResult PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **presult) - - Sends the *arg* value into the generator *gen*. Coroutine objects - are also allowed to be as the *gen* argument but they need to be - explicitly casted to PyGenObject*. Returns: - - - ``PYGEN_RETURN`` if generator returns. Return value is returned via *presult*. - - ``PYGEN_NEXT`` if generator yields. Yielded value is returned via *presult*. - - ``PYGEN_ERROR`` if generator has raised and exception. *presult* is set to ``NULL``. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 87ce5d03d006443..d01e99ca5e3191b 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -959,11 +959,6 @@ PyGen_NewWithQualName:PyFrameObject*:frame:0: PyGen_NewWithQualName:PyObject*:name:0: PyGen_NewWithQualName:PyObject*:qualname:0: -PyGen_Send:int::: -PyGen_Send:PyGenObject*:gen:0: -PyGen_Send:PyObject*:arg:0: -PyGen_Send:PyObject**:presult:+1: - PyCoro_CheckExact:int::: PyCoro_CheckExact:PyObject*:ob:0: diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 1c50978a8b7501d..c8ddcd2d24296e5 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -314,7 +314,7 @@ New Features search function. (Contributed by Hai Shi in :issue:`41842`.) -* The :c:func:`PyIter_Send` and :c:func:`PyGen_Send` functions were added to allow +* The :c:func:`PyIter_Send` function was added to allow sending value into iterator without raising ``StopIteration`` exception. (Contributed by Vladimir Matveev in :issue:`41756`.) diff --git a/Include/genobject.h b/Include/genobject.h index e719b25a8007294..e965334a0140c80 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -45,15 +45,6 @@ PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); PyObject *_PyGen_yf(PyGenObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); -/* Sends the value into the generator or the coroutine. Returns: - - PYGEN_RETURN (0) if generator has returned. - 'result' parameter is filled with return value - - PYGEN_ERROR (-1) if exception was raised. - 'result' parameter is NULL - - PYGEN_NEXT (1) if generator has yielded. - 'result' parameter is filled with yielded value. */ -PyAPI_FUNC(PySendResult) PyGen_Send(PyGenObject *, PyObject *, PyObject **); - #ifndef Py_LIMITED_API typedef struct { _PyGenObject_HEAD(cr) diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst index 725dfd16b180a77..044bd20594cc379 100644 --- a/Misc/NEWS.d/3.10.0a1.rst +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -133,16 +133,6 @@ Port the :mod:`_lsprof` extension module to multi-phase initialization .. -.. bpo: 41756 -.. date: 2020-09-12-12-55-45 -.. nonce: 1h0tbV -.. section: Core and Builtins - -Add PyGen_Send function to allow sending value into generator/coroutine -without raising StopIteration exception to signal return - -.. - .. bpo: 1635741 .. date: 2020-09-08-21-58-47 .. nonce: vdjSLH diff --git a/Objects/abstract.c b/Objects/abstract.c index 502a2d64e25e112..562549876beed82 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2669,31 +2669,6 @@ PyIter_Next(PyObject *iter) return result; } -PySendResult -PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) -{ - _Py_IDENTIFIER(send); - assert(result != NULL); - - if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { - return PyGen_Send((PyGenObject *)iter, arg, result); - } - - if (arg == Py_None && PyIter_Check(iter)) { - *result = Py_TYPE(iter)->tp_iternext(iter); - } - else { - *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); - } - if (*result != NULL) { - return PYGEN_NEXT; - } - if (_PyGen_FetchStopIterationValue(result) == 0) { - return PYGEN_RETURN; - } - return PYGEN_ERROR; -} - /* * Flatten a sequence of bytes() objects into a C array of * NULL terminated string pointers with a NULL char* terminating the array. diff --git a/Objects/genobject.c b/Objects/genobject.c index eb134ebf4bc8785..c1b26e9da33bea4 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -269,13 +269,29 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } PySendResult -PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **result) +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) { - assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen)); - assert(result != NULL); + _Py_IDENTIFIER(send); assert(arg != NULL); + assert(result != NULL); + + if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { + return gen_send_ex2((PyGenObject *)iter, arg, result, 0, 0); + } - return gen_send_ex2(gen, arg, result, 0, 0); + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; } static PyObject * From 0b6c5b5fc9278471774f9bda66399c616cbfc8eb Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Mon, 12 Oct 2020 23:06:19 +0200 Subject: [PATCH 460/486] bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept alive long enough (GH-22670) --- .../next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst | 3 +++ Objects/methodobject.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst diff --git a/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst b/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst new file mode 100644 index 000000000000000..d77619f64bb178f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-12-20-13-58.bpo-42015.X4H2_V.rst @@ -0,0 +1,3 @@ +Fix potential crash in deallocating method objects when dynamically +allocated `PyMethodDef`'s lifetime is managed through the ``self`` +argument of a `PyCFunction`. diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 5659f2143d18233..7b430416c5a0487 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -164,9 +164,11 @@ meth_dealloc(PyCFunctionObject *m) if (m->m_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*) m); } + // Dereference class before m_self: PyCFunction_GET_CLASS accesses + // PyMethodDef m_ml, which could be kept alive by m_self + Py_XDECREF(PyCFunction_GET_CLASS(m)); Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); - Py_XDECREF(PyCFunction_GET_CLASS(m)); PyObject_GC_Del(m); } @@ -243,9 +245,9 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure) static int meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) { + Py_VISIT(PyCFunction_GET_CLASS(m)); Py_VISIT(m->m_self); Py_VISIT(m->m_module); - Py_VISIT(PyCFunction_GET_CLASS(m)); return 0; } From 9214f67774953a8e2033fb82d1a99e322f215a28 Mon Sep 17 00:00:00 2001 From: Saiyang Gou Date: Mon, 12 Oct 2020 16:34:33 -0700 Subject: [PATCH 461/486] Fix typo in "Context manager types" section in typing.rst (GH-22676) Fix typo in the "Context manager types" section in `typing.rst`. Automerge-Triggered-By: @gvanrossum --- Doc/library/typing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 6111603a995c589..5fb78bbde69b1cd 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1478,7 +1478,7 @@ Context manager types .. versionadded:: 3.6.0 .. deprecated:: 3.9 - :class:`collections.contextlib.AbstractContextManager` now supports ``[]``. See :pep:`585`. + :class:`contextlib.AbstractContextManager` now supports ``[]``. See :pep:`585`. .. class:: AsyncContextManager(Generic[T_co]) @@ -1488,7 +1488,7 @@ Context manager types .. versionadded:: 3.6.2 .. deprecated:: 3.9 - :class:`collections.contextlib.AbstractAsyncContextManager` now supports ``[]``. See :pep:`585`. + :class:`contextlib.AbstractAsyncContextManager` now supports ``[]``. See :pep:`585`. Protocols --------- From 51a5601e55d9761977f91dc19e758eab6d2d5bcb Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 12 Oct 2020 18:53:16 -0500 Subject: [PATCH 462/486] bpo-40422: Move _Py_*_SUPPRESS_IPH bits into _Py_closerange (GH-22672) This suppression is no longer needed in os_closerange_impl, as it just invokes the internal _Py_closerange implementation. On the other hand, consumers of _Py_closerange may not have any other reason to suppress invalid parameter issues, so narrow the scope to here. --- Modules/posixmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2e0caaa3e561ba7..de81db8b84fe120 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8782,6 +8782,7 @@ void _Py_closerange(int first, int last) { first = Py_MAX(first, 0); + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_CLOSE_RANGE if (close_range(first, last, 0) == 0 || errno != ENOSYS) { /* Any errors encountered while closing file descriptors are ignored; @@ -8812,6 +8813,7 @@ _Py_closerange(int first, int last) } } #endif /* USE_FDWALK */ + _Py_END_SUPPRESS_IPH } /*[clinic input] @@ -8829,9 +8831,7 @@ os_closerange_impl(PyObject *module, int fd_low, int fd_high) /*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ { Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH _Py_closerange(fd_low, fd_high - 1); - _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; } From a75ce93aeeee7114048e54d255be7cd63fce7116 Mon Sep 17 00:00:00 2001 From: Yunlongs Date: Tue, 13 Oct 2020 14:46:31 +0800 Subject: [PATCH 463/486] bpo-41995: Fix null ptr deref in tracemalloc_copy_trace() (GH-22660) Fix a null pointer dereference in tracemalloc_copy_trace() of _tracemalloc. --- Modules/_tracemalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index fc91622d3925b84..04f6c243b5ca4d1 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1199,7 +1199,7 @@ tracemalloc_copy_trace(_Py_hashtable_t *traces, trace_t *trace = (trace_t *)value; trace_t *trace2 = raw_malloc(sizeof(trace_t)); - if (traces2 == NULL) { + if (trace2 == NULL) { return -1; } *trace2 = *trace; From 58d63b78c030d6595eb6adfe1e8210100dd1a4f1 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 13 Oct 2020 10:26:51 -0700 Subject: [PATCH 464/486] bpo-41756: Export PyGen_Send and wrap it in if-defs (#22677) --- Doc/c-api/iter.rst | 4 ++++ Include/abstract.h | 2 ++ PC/python3dll.c | 1 + 3 files changed, 7 insertions(+) diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index a068a43c86b6c39..68df6f6e89f5132 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -50,6 +50,8 @@ something like this:: The enum value used to represent different results of :c:func:`PyIter_Send`. + .. versionadded:: 3.10 + .. c:function:: PySendResult PyIter_Send(PyObject *iter, PyObject *arg, PyObject **presult) @@ -58,3 +60,5 @@ something like this:: - ``PYGEN_RETURN`` if iterator returns. Return value is returned via *presult*. - ``PYGEN_NEXT`` if iterator yields. Yielded value is returned via *presult*. - ``PYGEN_ERROR`` if iterator has raised and exception. *presult* is set to ``NULL``. + + .. versionadded:: 3.10 diff --git a/Include/abstract.h b/Include/abstract.h index 716cd4b5ebbba3e..28e576b92935f9e 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -338,6 +338,7 @@ PyAPI_FUNC(int) PyIter_Check(PyObject *); NULL with an exception means an error occurred. */ PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 typedef enum { PYGEN_RETURN = 0, PYGEN_ERROR = -1, @@ -353,6 +354,7 @@ typedef enum { - PYGEN_NEXT (1) if generator has yielded. 'result' parameter is filled with yielded value. */ PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **); +#endif /* === Number Protocol ================================================== */ diff --git a/PC/python3dll.c b/PC/python3dll.c index ff69ea7ca5efaa4..153ba612b7804f5 100644 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -287,6 +287,7 @@ EXPORT_FUNC(PyInterpreterState_GetID) EXPORT_FUNC(PyInterpreterState_New) EXPORT_FUNC(PyIter_Check) EXPORT_FUNC(PyIter_Next) +EXPORT_FUNC(PyIter_Send) EXPORT_FUNC(PyList_Append) EXPORT_FUNC(PyList_AsTuple) EXPORT_FUNC(PyList_GetItem) From 609262d6c22b6026ce5a6d675aa4432b17b773c9 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 13 Oct 2020 11:54:21 -0700 Subject: [PATCH 465/486] Add recipe for a version of random() with a larger population (GH-22664) --- Doc/library/random.rst | 55 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index af5131df280c247..c19a8e0a7cb5baf 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -391,8 +391,8 @@ change across Python versions, but two aspects are guaranteed not to change: .. _random-examples: -Examples and Recipes --------------------- +Examples +-------- Basic examples:: @@ -516,6 +516,52 @@ Simulation of arrival times and service deliveries for a multiserver queue:: print(f'Mean wait: {mean(waits):.1f} Max wait: {max(waits):.1f}') print('Quartiles:', [round(q, 1) for q in quantiles(waits)]) +Recipes +------- + +The default :func:`.random` returns multiples of 2⁻⁵³ in the range +*0.0 ≤ x < 1.0*. All such numbers are evenly spaced and exactly +representable as Python floats. However, many floats in that interval +are not possible selections. For example, ``0.05954861408025609`` +isn't an integer multiple of 2⁻⁵³. + +The following recipe takes a different approach. All floats in the +interval are possible selections. Conceptually it works by choosing +from evenly spaced multiples of 2⁻¹⁰⁷⁴ and then rounding down to the +nearest representable float. + +For efficiency, the actual mechanics involve calling +:func:`~math.ldexp` to construct a representable float. The mantissa +comes from a uniform distribution of integers in the range *2⁵² ≤ +mantissa < 2⁵³*. The exponent comes from a geometric distribution +where exponents smaller than *-53* occur half as often as the next +larger exponent. + +:: + + from random import Random + from math import ldexp + + class FullRandom(Random): + + def random(self): + mantissa = 0x10_0000_0000_0000 | self.getrandbits(52) + exponent = -53 + x = 0 + while not x: + x = self.getrandbits(32) + exponent += x.bit_length() - 32 + return ldexp(mantissa, exponent) + +All of the real valued distributions will use the new method:: + + >>> fr = FullRandom() + >>> fr.random() + 0.05954861408025609 + >>> fr.expovariate(0.25) + 8.87925541791544 + + .. seealso:: `Statistics for Hackers `_ @@ -536,3 +582,8 @@ Simulation of arrival times and service deliveries for a multiserver queue:: a tutorial by `Peter Norvig `_ covering the basics of probability theory, how to write simulations, and how to perform data analysis using Python. + + `Generating Pseudo-random Floating-Point Values + `_ a + paper by Allen B. Downey describing ways to generate more + fine-grained floats than normally generated by :func:`.random`. From 0eb3a0cebd507c09915bbe9ceaced19235ca5e22 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Tue, 13 Oct 2020 15:04:44 -0500 Subject: [PATCH 466/486] bpo-40422: Move _Py_closerange to fileutils.c (GH-22680) This API is relatively lightweight and organizationally, given that it's used by multiple modules, it makes sense to move it to fileutils. Requires making sure that _posixsubprocess is compiled with the appropriate Py_BUIILD_CORE_BUILTIN macro. --- Include/internal/pycore_fileutils.h | 2 + Modules/Setup | 2 +- Modules/_posixsubprocess.c | 1 + Modules/posixmodule.c | 77 +---------------------------- Modules/posixmodule.h | 2 - Python/fileutils.c | 76 ++++++++++++++++++++++++++++ setup.py | 3 +- 7 files changed, 83 insertions(+), 80 deletions(-) diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index bbee58617fd05e4..9cb5fc66ee2e03c 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -48,6 +48,8 @@ PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( PyObject **decimal_point, PyObject **thousands_sep); +PyAPI_FUNC(void) _Py_closerange(int first, int last); + #ifdef __cplusplus } #endif diff --git a/Modules/Setup b/Modules/Setup index 470bf6bc2efbf5b..87f3a7cb43a0257 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -226,7 +226,7 @@ _symtable symtablemodule.c #termios termios.c # Steen Lumholt's termios module #resource resource.c # Jeremy Hylton's rlimit interface -#_posixsubprocess _posixsubprocess.c # POSIX subprocess module helper +#_posixsubprocess -DPy_BUILD_CORE_BUILTIN _posixsubprocess.c # POSIX subprocess module helper # Multimedia modules -- off by default. # These don't work for 64-bit platforms!!! diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index ed046fc5c1ba9f3..d08c47980e9c6a9 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -1,5 +1,6 @@ /* Authors: Gregory P. Smith & Jeffrey Yasskin */ #include "Python.h" +#include "pycore_fileutils.h" #if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index de81db8b84fe120..6ce0bcb9fe8ca48 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -22,6 +22,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_fileutils.h" #ifdef MS_WINDOWS /* include early to avoid conflict with pycore_condvar.h: @@ -8740,82 +8741,6 @@ os_close_impl(PyObject *module, int fd) Py_RETURN_NONE; } -/* Our selection logic for which function to use is as follows: - * 1. If close_range(2) is available, always prefer that; it's better for - * contiguous ranges like this than fdwalk(3) which entails iterating over - * the entire fd space and simply doing nothing for those outside the range. - * 2. If closefrom(2) is available, we'll attempt to use that next if we're - * closing up to sysconf(_SC_OPEN_MAX). - * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), - * as that will be more performant if the range happens to have any chunk of - * non-opened fd in the middle. - * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. - */ -#ifdef __FreeBSD__ -#define USE_CLOSEFROM -#endif /* __FreeBSD__ */ - -#ifdef HAVE_FDWALK -#define USE_FDWALK -#endif /* HAVE_FDWALK */ - -#ifdef USE_FDWALK -static int -_fdwalk_close_func(void *lohi, int fd) -{ - int lo = ((int *)lohi)[0]; - int hi = ((int *)lohi)[1]; - - if (fd >= hi) { - return 1; - } - else if (fd >= lo) { - /* Ignore errors */ - (void)close(fd); - } - return 0; -} -#endif /* USE_FDWALK */ - -/* Closes all file descriptors in [first, last], ignoring errors. */ -void -_Py_closerange(int first, int last) -{ - first = Py_MAX(first, 0); - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_CLOSE_RANGE - if (close_range(first, last, 0) == 0 || errno != ENOSYS) { - /* Any errors encountered while closing file descriptors are ignored; - * ENOSYS means no kernel support, though, - * so we'll fallback to the other methods. */ - } - else -#endif /* HAVE_CLOSE_RANGE */ -#ifdef USE_CLOSEFROM - if (last >= sysconf(_SC_OPEN_MAX)) { - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(first); - } - else -#endif /* USE_CLOSEFROM */ -#ifdef USE_FDWALK - { - int lohi[2]; - lohi[0] = first; - lohi[1] = last + 1; - fdwalk(_fdwalk_close_func, lohi); - } -#else - { - for (int i = first; i <= last; i++) { - /* Ignore errors */ - (void)close(i); - } - } -#endif /* USE_FDWALK */ - _Py_END_SUPPRESS_IPH -} - /*[clinic input] os.closerange diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 749833f71cd4de5..1e00562abc3370e 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -28,8 +28,6 @@ PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); #endif /* HAVE_SIGSET_T */ #endif /* Py_LIMITED_API */ -PyAPI_FUNC(void) _Py_closerange(int first, int last); - #ifdef __cplusplus } #endif diff --git a/Python/fileutils.c b/Python/fileutils.c index 50ef3c174acc844..b79067f2b5d38b8 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2106,3 +2106,79 @@ _Py_GetLocaleconvNumeric(struct lconv *lc, PyMem_Free(oldloc); return res; } + +/* Our selection logic for which function to use is as follows: + * 1. If close_range(2) is available, always prefer that; it's better for + * contiguous ranges like this than fdwalk(3) which entails iterating over + * the entire fd space and simply doing nothing for those outside the range. + * 2. If closefrom(2) is available, we'll attempt to use that next if we're + * closing up to sysconf(_SC_OPEN_MAX). + * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * as that will be more performant if the range happens to have any chunk of + * non-opened fd in the middle. + * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. + */ +#ifdef __FreeBSD__ +# define USE_CLOSEFROM +#endif /* __FreeBSD__ */ + +#ifdef HAVE_FDWALK +# define USE_FDWALK +#endif /* HAVE_FDWALK */ + +#ifdef USE_FDWALK +static int +_fdwalk_close_func(void *lohi, int fd) +{ + int lo = ((int *)lohi)[0]; + int hi = ((int *)lohi)[1]; + + if (fd >= hi) { + return 1; + } + else if (fd >= lo) { + /* Ignore errors */ + (void)close(fd); + } + return 0; +} +#endif /* USE_FDWALK */ + +/* Closes all file descriptors in [first, last], ignoring errors. */ +void +_Py_closerange(int first, int last) +{ + first = Py_MAX(first, 0); + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_CLOSE_RANGE + if (close_range(first, last, 0) == 0 || errno != ENOSYS) { + /* Any errors encountered while closing file descriptors are ignored; + * ENOSYS means no kernel support, though, + * so we'll fallback to the other methods. */ + } + else +#endif /* HAVE_CLOSE_RANGE */ +#ifdef USE_CLOSEFROM + if (last >= sysconf(_SC_OPEN_MAX)) { + /* Any errors encountered while closing file descriptors are ignored */ + closefrom(first); + } + else +#endif /* USE_CLOSEFROM */ +#ifdef USE_FDWALK + { + int lohi[2]; + lohi[0] = first; + lohi[1] = last + 1; + fdwalk(_fdwalk_close_func, lohi); + } +#else + { + for (int i = first; i <= last; i++) { + /* Ignore errors */ + (void)close(i); + } + } +#endif /* USE_FDWALK */ + _Py_END_SUPPRESS_IPH +} diff --git a/setup.py b/setup.py index 476f8c414978ead..d3fd7bca6438afd 100644 --- a/setup.py +++ b/setup.py @@ -950,7 +950,8 @@ def detect_simple_extensions(self): self.add(Extension('_csv', ['_csv.c'])) # POSIX subprocess module helper. - self.add(Extension('_posixsubprocess', ['_posixsubprocess.c'])) + self.add(Extension('_posixsubprocess', ['_posixsubprocess.c'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) def detect_test_extensions(self): # Python C API test module From 022468094313e1387c98bc59a1505d4abebb47dd Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 13 Oct 2020 16:41:26 -0700 Subject: [PATCH 467/486] Improve recipe readability (GH-22685) --- Doc/library/random.rst | 68 +++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index c19a8e0a7cb5baf..635f9e1c032da37 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -253,6 +253,8 @@ Functions for sequences order so that the sample is reproducible. +.. _real-valued-distributions: + Real-valued distributions ------------------------- @@ -516,26 +518,42 @@ Simulation of arrival times and service deliveries for a multiserver queue:: print(f'Mean wait: {mean(waits):.1f} Max wait: {max(waits):.1f}') print('Quartiles:', [round(q, 1) for q in quantiles(waits)]) +.. seealso:: + + `Statistics for Hackers `_ + a video tutorial by + `Jake Vanderplas `_ + on statistical analysis using just a few fundamental concepts + including simulation, sampling, shuffling, and cross-validation. + + `Economics Simulation + `_ + a simulation of a marketplace by + `Peter Norvig `_ that shows effective + use of many of the tools and distributions provided by this module + (gauss, uniform, sample, betavariate, choice, triangular, and randrange). + + `A Concrete Introduction to Probability (using Python) + `_ + a tutorial by `Peter Norvig `_ covering + the basics of probability theory, how to write simulations, and + how to perform data analysis using Python. + + Recipes ------- The default :func:`.random` returns multiples of 2⁻⁵³ in the range -*0.0 ≤ x < 1.0*. All such numbers are evenly spaced and exactly +*0.0 ≤ x < 1.0*. All such numbers are evenly spaced and are exactly representable as Python floats. However, many floats in that interval are not possible selections. For example, ``0.05954861408025609`` isn't an integer multiple of 2⁻⁵³. The following recipe takes a different approach. All floats in the -interval are possible selections. Conceptually it works by choosing -from evenly spaced multiples of 2⁻¹⁰⁷⁴ and then rounding down to the -nearest representable float. - -For efficiency, the actual mechanics involve calling -:func:`~math.ldexp` to construct a representable float. The mantissa -comes from a uniform distribution of integers in the range *2⁵² ≤ -mantissa < 2⁵³*. The exponent comes from a geometric distribution -where exponents smaller than *-53* occur half as often as the next -larger exponent. +interval are possible selections. The mantissa comes from a uniform +distribution of integers in the range *2⁵² ≤ mantissa < 2⁵³*. The +exponent comes from a geometric distribution where exponents smaller +than *-53* occur half as often as the next larger exponent. :: @@ -553,7 +571,8 @@ larger exponent. exponent += x.bit_length() - 32 return ldexp(mantissa, exponent) -All of the real valued distributions will use the new method:: +All :ref:`real valued distributions ` +in the class will use the new method:: >>> fr = FullRandom() >>> fr.random() @@ -561,27 +580,14 @@ All of the real valued distributions will use the new method:: >>> fr.expovariate(0.25) 8.87925541791544 +The recipe is conceptually equivalent to an algorithm that chooses from +all the multiples of 2⁻¹⁰⁷⁴ in the range *0.0 ≤ x < 1.0*. All such +numbers are evenly spaced, but most have to be rounded down to the +nearest representable Python float. (The value 2⁻¹⁰⁷⁴ is the smallest +positive unnormalized float and is equal to ``math.ulp(0.0)``.) -.. seealso:: - - `Statistics for Hackers `_ - a video tutorial by - `Jake Vanderplas `_ - on statistical analysis using just a few fundamental concepts - including simulation, sampling, shuffling, and cross-validation. - - `Economics Simulation - `_ - a simulation of a marketplace by - `Peter Norvig `_ that shows effective - use of many of the tools and distributions provided by this module - (gauss, uniform, sample, betavariate, choice, triangular, and randrange). - `A Concrete Introduction to Probability (using Python) - `_ - a tutorial by `Peter Norvig `_ covering - the basics of probability theory, how to write simulations, and - how to perform data analysis using Python. +.. seealso:: `Generating Pseudo-random Floating-Point Values `_ a From 9df0d2e1a63779dd05a0f97b155d476ec30aaa39 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Tue, 13 Oct 2020 21:38:56 -0400 Subject: [PATCH 468/486] bpo-41939: always enable test_site.test_license_exists_at_url (GH-22688) --- Lib/test/test_site.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index a475ed1ab4c469a..2e70880f56d1416 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -516,8 +516,6 @@ def test_sitecustomize_executed(self): @test.support.requires_resource('network') @test.support.system_must_validate_cert - @unittest.skipUnless(sys.version_info[3] == 'final', - 'only for released versions') @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') def test_license_exists_at_url(self): From dfa8403f0b5f4faa73a27bde3186e8a7801fb836 Mon Sep 17 00:00:00 2001 From: Kevin Adler Date: Tue, 13 Oct 2020 20:49:24 -0500 Subject: [PATCH 469/486] closes bpo-42029: Remove dynload_dl (GH-22687) All references to this dynamic loading method were removed in b9949db, when support for this method was dropped, but the implementation code was not dropped (seemingly in oversight). --- Python/dynload_dl.c | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 Python/dynload_dl.c diff --git a/Python/dynload_dl.c b/Python/dynload_dl.c deleted file mode 100644 index 2bec645fbd7aff0..000000000000000 --- a/Python/dynload_dl.c +++ /dev/null @@ -1,23 +0,0 @@ - -/* Support for dynamic loading of extension modules */ - -#include "dl.h" - -#include "Python.h" -#include "importdl.h" - - -extern char *Py_GetProgramName(void); - -const char *_PyImport_DynLoadFiletab[] = {".o", NULL}; - - -dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, - const char *shortname, - const char *pathname, FILE *fp) -{ - char funcname[258]; - - PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); - return dl_loadmod(Py_GetProgramName(), pathname, funcname); -} From d3cc4a8049579ffca3561dde5f12787764db5efe Mon Sep 17 00:00:00 2001 From: Anatoliy Platonov <31926941+p4m-dev@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:02:51 +0300 Subject: [PATCH 470/486] bpo-41876: Overload __repr__ for tkinter Font objects (GH-22450) --- Lib/tkinter/font.py | 4 ++++ Lib/tkinter/test/test_tkinter/test_font.py | 6 ++++++ Misc/ACKS | 1 + .../next/Library/2020-09-29-16-23-54.bpo-41876.QicdDU.rst | 1 + 4 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-29-16-23-54.bpo-41876.QicdDU.rst diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py index 15ad7ab4b63a815..a9f79d8e456bb71 100644 --- a/Lib/tkinter/font.py +++ b/Lib/tkinter/font.py @@ -100,6 +100,10 @@ def __init__(self, root=None, font=None, name=None, exists=False, def __str__(self): return self.name + def __repr__(self): + return f"<{self.__class__.__module__}.{self.__class__.__qualname__}" \ + f" object {self.name!r}>" + def __eq__(self, other): if not isinstance(other, Font): return NotImplemented diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py index a021ea336807bb8..6d1eea44b4d2f32 100644 --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -101,6 +101,12 @@ def test_names(self): self.assertTrue(name) self.assertIn(fontname, names) + def test_repr(self): + self.assertEqual( + repr(self.font), f'' + ) + + tests_gui = (FontTest, ) if __name__ == "__main__": diff --git a/Misc/ACKS b/Misc/ACKS index 660b8ef7504eebc..7f4a9bcbc0f8cdb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1353,6 +1353,7 @@ Zero Piraeus Antoine Pitrou Jean-François Piéronne Oleg Plakhotnyuk +Anatoliy Platonov Marcel Plch Remi Pointel Jon Poler diff --git a/Misc/NEWS.d/next/Library/2020-09-29-16-23-54.bpo-41876.QicdDU.rst b/Misc/NEWS.d/next/Library/2020-09-29-16-23-54.bpo-41876.QicdDU.rst new file mode 100644 index 000000000000000..d4f5f0a37bf4843 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-29-16-23-54.bpo-41876.QicdDU.rst @@ -0,0 +1 @@ +Tkinter font class repr uses font name \ No newline at end of file From bb71c6ddbefe0b1858e7212ffb048060d5a34305 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Wed, 14 Oct 2020 23:43:31 +0800 Subject: [PATCH 471/486] bpo-39337: encodings.normalize_encoding() now ignores non-ASCII characters (GH-22219) --- Doc/whatsnew/3.10.rst | 5 +++++ Lib/encodings/__init__.py | 3 ++- Lib/test/test_codecs.py | 14 +++++++++++++- .../2020-09-13-02-02-18.bpo-39337.L3NXTt.rst | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-09-13-02-02-18.bpo-39337.L3NXTt.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index c8ddcd2d24296e5..738ef974e7867b3 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -186,6 +186,11 @@ by :func:`curses.color_content`, :func:`curses.init_color`, support is provided by the underlying ncurses library. (Contributed by Jeffrey Kintscher and Hans Petter Jansson in :issue:`36982`.) +encodings +--------- +:func:`encodings.normalize_encoding` now ignores non-ASCII characters. +(Contributed by Hai Shi in :issue:`39337`.) + glob ---- diff --git a/Lib/encodings/__init__.py b/Lib/encodings/__init__.py index ddd5afdcf2dab02..4b37d3321c9033d 100644 --- a/Lib/encodings/__init__.py +++ b/Lib/encodings/__init__.py @@ -61,7 +61,8 @@ def normalize_encoding(encoding): if c.isalnum() or c == '.': if punct and chars: chars.append('_') - chars.append(c) + if c.isascii(): + chars.append(c) punct = False else: punct = True diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index ddf4e08af6247a3..09ceef76eb098da 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3417,7 +3417,7 @@ def test_rot13_func(self): class CodecNameNormalizationTest(unittest.TestCase): """Test codec name normalization""" - def test_normalized_encoding(self): + def test_codecs_lookup(self): FOUND = (1, 2, 3, 4) NOT_FOUND = (None, None, None, None) def search_function(encoding): @@ -3439,6 +3439,18 @@ def search_function(encoding): self.assertEqual(NOT_FOUND, codecs.lookup('BBB.8')) self.assertEqual(NOT_FOUND, codecs.lookup('a\xe9\u20ac-8')) + def test_encodings_normalize_encoding(self): + # encodings.normalize_encoding() ignores non-ASCII characters. + normalize = encodings.normalize_encoding + self.assertEqual(normalize('utf_8'), 'utf_8') + self.assertEqual(normalize('utf\xE9\u20AC\U0010ffff-8'), 'utf_8') + self.assertEqual(normalize('utf 8'), 'utf_8') + # encodings.normalize_encoding() doesn't convert + # characters to lower case. + self.assertEqual(normalize('UTF 8'), 'UTF_8') + self.assertEqual(normalize('utf.8'), 'utf.8') + self.assertEqual(normalize('utf...8'), 'utf...8') + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-09-13-02-02-18.bpo-39337.L3NXTt.rst b/Misc/NEWS.d/next/Library/2020-09-13-02-02-18.bpo-39337.L3NXTt.rst new file mode 100644 index 000000000000000..c2b4dbe4d12e8ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-13-02-02-18.bpo-39337.L3NXTt.rst @@ -0,0 +1 @@ +:func:`encodings.normalize_encoding` now ignores non-ASCII characters. From 0a16624cd555105311ccbd954a79212bb4d61bb3 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 14 Oct 2020 10:04:04 -0700 Subject: [PATCH 472/486] Update timings for the final release (GH-22697) --- Doc/whatsnew/3.9.rst | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 95188b7493ad448..22fdbd565a16677 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -652,41 +652,41 @@ Here's a summary of performance improvements from Python 3.4 through Python 3.9: -------------- --- --- --- --- --- --- Variable and attribute read access: - read_local 7.1 7.1 5.4 5.1 3.9 4.0 - read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8 - read_global 15.5 19.0 14.3 13.6 7.6 7.7 - read_builtin 21.1 21.6 18.5 19.0 7.5 7.7 - read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6 - read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1 - read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7 - read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5 - read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2 - read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9 + read_local 7.1 7.1 5.4 5.1 3.9 3.9 + read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.5 + read_global 15.5 19.0 14.3 13.6 7.6 7.8 + read_builtin 21.1 21.6 18.5 19.0 7.5 7.8 + read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 17.9 + read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 16.9 + read_instancevar 32.4 33.1 28.0 26.3 25.4 25.3 + read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 20.5 + read_namedtuple 73.8 57.5 45.0 46.8 18.4 18.7 + read_boundmethod 37.6 37.9 29.6 26.9 27.7 41.1 Variable and attribute write access: - write_local 8.7 9.3 5.5 5.3 4.3 4.2 - write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9 - write_global 19.7 21.2 18.0 18.0 15.8 17.2 - write_classvar 92.9 96.0 104.6 102.1 39.2 43.2 - write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7 - write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7 + write_local 8.7 9.3 5.5 5.3 4.3 4.3 + write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.8 + write_global 19.7 21.2 18.0 18.0 15.8 16.7 + write_classvar 92.9 96.0 104.6 102.1 39.2 39.8 + write_instancevar 44.6 45.8 40.0 38.9 35.5 37.4 + write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 25.8 Data structure read access: - read_list 24.2 24.5 20.8 20.8 19.0 21.1 - read_deque 24.7 25.5 20.2 20.6 19.8 21.6 - read_dict 24.3 25.7 22.3 23.0 21.0 22.5 - read_strdict 22.6 24.3 19.5 21.2 18.9 21.6 + read_list 24.2 24.5 20.8 20.8 19.0 19.5 + read_deque 24.7 25.5 20.2 20.6 19.8 20.2 + read_dict 24.3 25.7 22.3 23.0 21.0 22.4 + read_strdict 22.6 24.3 19.5 21.2 18.9 21.5 Data structure write access: - write_list 27.1 28.5 22.5 21.6 20.0 21.6 - write_deque 28.7 30.1 22.7 21.8 23.5 23.2 - write_dict 31.4 33.3 29.3 29.2 24.7 27.8 - write_strdict 28.4 29.9 27.5 25.2 23.1 29.8 + write_list 27.1 28.5 22.5 21.6 20.0 20.0 + write_deque 28.7 30.1 22.7 21.8 23.5 21.7 + write_dict 31.4 33.3 29.3 29.2 24.7 25.4 + write_strdict 28.4 29.9 27.5 25.2 23.1 24.5 Stack (or queue) operations: - list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9 - deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5 - deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5 + list_append_pop 93.4 112.7 75.4 74.2 50.8 50.6 + deque_append_pop 43.5 57.0 49.4 49.2 42.5 44.2 + deque_append_popleft 43.7 57.3 49.7 49.7 42.8 46.4 Timing loop: loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3 From 172009c1b8f139147cf847618f97283ee2e2b751 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Wed, 14 Oct 2020 18:44:07 -0700 Subject: [PATCH 473/486] bpo-41984: GC track all user classes (GH-22701) --- Lib/test/test_finalization.py | 23 +++++++++++++++++-- Lib/test/test_gc.py | 6 ++--- .../2020-10-14-16-19-43.bpo-41984.SEtKMr.rst | 2 ++ Modules/_testcapimodule.c | 20 ++++++++++++++++ Objects/typeobject.c | 22 +++++------------- 5 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-14-16-19-43.bpo-41984.SEtKMr.rst diff --git a/Lib/test/test_finalization.py b/Lib/test/test_finalization.py index 35d7913e5b89b52..1d134430909d848 100644 --- a/Lib/test/test_finalization.py +++ b/Lib/test/test_finalization.py @@ -16,6 +16,15 @@ def __new__(cls, *args, **kwargs): raise TypeError('requires _testcapi.with_tp_del') return C +try: + from _testcapi import without_gc +except ImportError: + def without_gc(cls): + class C: + def __new__(cls, *args, **kwargs): + raise TypeError('requires _testcapi.without_gc') + return C + from test import support @@ -94,9 +103,11 @@ def check_sanity(self): assert self.id_ == id(self) +@without_gc class NonGC(NonGCSimpleBase): __slots__ = () +@without_gc class NonGCResurrector(NonGCSimpleBase): __slots__ = () @@ -109,8 +120,14 @@ def side_effect(self): class Simple(SimpleBase): pass -class SimpleResurrector(NonGCResurrector, SimpleBase): - pass +# Can't inherit from NonGCResurrector, in case importing without_gc fails. +class SimpleResurrector(SimpleBase): + + def side_effect(self): + """ + Resurrect self by storing self in a class-wide list. + """ + self.survivors.append(self) class TestBase: @@ -178,6 +195,7 @@ def test_simple_resurrect(self): self.assert_survivors([]) self.assertIs(wr(), None) + @support.cpython_only def test_non_gc(self): with SimpleBase.test(): s = NonGC() @@ -191,6 +209,7 @@ def test_non_gc(self): self.assert_del_calls(ids) self.assert_survivors([]) + @support.cpython_only def test_non_gc_resurrect(self): with SimpleBase.test(): s = NonGCResurrector() diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 1b096efdbcf5fb7..ba6673701590631 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -582,9 +582,9 @@ class UserIntSlots(int): self.assertTrue(gc.is_tracked(UserInt())) self.assertTrue(gc.is_tracked([])) self.assertTrue(gc.is_tracked(set())) - self.assertFalse(gc.is_tracked(UserClassSlots())) - self.assertFalse(gc.is_tracked(UserFloatSlots())) - self.assertFalse(gc.is_tracked(UserIntSlots())) + self.assertTrue(gc.is_tracked(UserClassSlots())) + self.assertTrue(gc.is_tracked(UserFloatSlots())) + self.assertTrue(gc.is_tracked(UserIntSlots())) def test_is_finalized(self): # Objects not tracked by the always gc return false diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-14-16-19-43.bpo-41984.SEtKMr.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-14-16-19-43.bpo-41984.SEtKMr.rst new file mode 100644 index 000000000000000..e70d5dc2b8ddec1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-14-16-19-43.bpo-41984.SEtKMr.rst @@ -0,0 +1,2 @@ +The garbage collector now tracks all user-defined classes. Patch by Brandt +Bucher. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8c7544fa90e280b..28d2c124d517758 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3888,6 +3888,25 @@ with_tp_del(PyObject *self, PyObject *args) return obj; } +static PyObject * +without_gc(PyObject *Py_UNUSED(self), PyObject *obj) +{ + PyTypeObject *tp = (PyTypeObject*)obj; + if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { + return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj); + } + if (PyType_IS_GC(tp)) { + // Don't try this at home, kids: + tp->tp_flags -= Py_TPFLAGS_HAVE_GC; + tp->tp_free = PyObject_Del; + tp->tp_traverse = NULL; + tp->tp_clear = NULL; + } + assert(!PyType_IS_GC(tp)); + Py_INCREF(obj); + return obj; +} + static PyMethodDef ml; static PyObject * @@ -5805,6 +5824,7 @@ static PyMethodDef TestMethods[] = { {"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL}, {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS}, {"pynumber_tobase", pynumber_tobase, METH_VARARGS}, + {"without_gc", without_gc, METH_O}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3bb2c338fe0b530..36c7662e081a40e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2612,10 +2612,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) slots = NULL; /* Initialize tp_flags */ + // All heap types need GC, since we can create a reference cycle by storing + // an instance on one of its parents: type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | - Py_TPFLAGS_BASETYPE; - if (base->tp_flags & Py_TPFLAGS_HAVE_GC) - type->tp_flags |= Py_TPFLAGS_HAVE_GC; + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC; /* Initialize essential fields */ type->tp_as_async = &et->as_async; @@ -2815,21 +2815,11 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } type->tp_dealloc = subtype_dealloc; - /* Enable GC unless this class is not adding new instance variables and - the base class did not use GC. */ - if ((base->tp_flags & Py_TPFLAGS_HAVE_GC) || - type->tp_basicsize > base->tp_basicsize) - type->tp_flags |= Py_TPFLAGS_HAVE_GC; - /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; - if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { - type->tp_free = PyObject_GC_Del; - type->tp_traverse = subtype_traverse; - type->tp_clear = subtype_clear; - } - else - type->tp_free = PyObject_Del; + type->tp_free = PyObject_GC_Del; + type->tp_traverse = subtype_traverse; + type->tp_clear = subtype_clear; /* store type in class' cell if one is supplied */ cell = _PyDict_GetItemIdWithError(dict, &PyId___classcell__); From 8aebfc700c72568f8f436dbcaaec821cd0fbc28f Mon Sep 17 00:00:00 2001 From: Kevin Adler Date: Wed, 14 Oct 2020 20:53:27 -0500 Subject: [PATCH 474/486] bpo-41894: Fix UnicodeDecodeError while loading native module (GH-22466) When running in a non-UTF-8 locale, if an error occurs while importing a native Python module (say because a dependent share library is missing), the error message string returned may contain non-ASCII code points causing a UnicodeDecodeError. PyUnicode_DecodeFSDefault is used for buffers which may contain filesystem paths. For consistency with os.strerror(), PyUnicode_DecodeLocale is used for buffers which contain system error messages. While the shortname parameter is always encoded in ASCII according to PEP 489, it is left decoded using PyUnicode_FromString to minimize the changes and since it should not affect the decoding (albeit _potentially_ slower). In dynload_hpux, since the error buffer contains a message generated from a static ASCII string and the module filesystem path, PyUnicode_DecodeFSDefault is used instead of PyUnicode_DecodeLocale as is used elsewhere. * bpo-41894: Fix bugs in dynload error msg handling For both dynload_aix and dynload_hpux, properly handle the possibility that decoding strings may return NULL and when such an error happens, properly decrement any previously decoded strings and return early. In addition, in dynload_aix, ensure that we pass the decoded string *object* pathname_ob to PyErr_SetImportError instead of the original pathname buffer. Co-authored-by: Serhiy Storchaka --- .../2020-10-02-11-35-33.bpo-41894.ffmtOt.rst | 3 +++ Python/dynload_aix.c | 14 ++++++++++---- Python/dynload_hpux.c | 15 +++++++++++++-- Python/dynload_shlib.c | 4 ++-- 4 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-02-11-35-33.bpo-41894.ffmtOt.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-02-11-35-33.bpo-41894.ffmtOt.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-02-11-35-33.bpo-41894.ffmtOt.rst new file mode 100644 index 000000000000000..571f5dae1a4a1a0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-02-11-35-33.bpo-41894.ffmtOt.rst @@ -0,0 +1,3 @@ +When loading a native module and a load failure occurs, prevent a possible +UnicodeDecodeError when not running in a UTF-8 locale by decoding the load +error message using the current locale's encoding. diff --git a/Python/dynload_aix.c b/Python/dynload_aix.c index 684f10a8b919363..97f7698ef4b2d94 100644 --- a/Python/dynload_aix.c +++ b/Python/dynload_aix.c @@ -144,10 +144,16 @@ aix_loaderror(const char *pathname) ERRBUF_APPEND(message[i]); ERRBUF_APPEND("\n"); } - errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */ - pathname_ob = PyUnicode_FromString(pathname); - errbuf_ob = PyUnicode_FromString(errbuf); - PyErr_SetImportError(errbuf_ob, NULL, pathname); + /* Subtract 1 from the length to trim off trailing newline */ + errbuf_ob = PyUnicode_DecodeLocaleAndSize(errbuf, strlen(errbuf)-1, "surrogateescape"); + if (errbuf_ob == NULL) + return; + pathname_ob = PyUnicode_DecodeFSDefault(pathname); + if (pathname_ob == NULL) { + Py_DECREF(errbuf_ob); + return; + } + PyErr_SetImportError(errbuf_ob, NULL, pathname_ob); Py_DECREF(pathname_ob); Py_DECREF(errbuf_ob); return; diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c index 4b964a69d3bde6c..e36d608c6dca448 100644 --- a/Python/dynload_hpux.c +++ b/Python/dynload_hpux.c @@ -36,9 +36,20 @@ dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, char buf[256]; PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s", pathname); - PyObject *buf_ob = PyUnicode_FromString(buf); + PyObject *buf_ob = PyUnicode_DecodeFSDefault(buf); + if (buf_ob == NULL) + return NULL; PyObject *shortname_ob = PyUnicode_FromString(shortname); - PyObject *pathname_ob = PyUnicode_FromString(pathname); + if (shortname_ob == NULL) { + Py_DECREF(buf_ob); + return NULL; + } + PyObject *pathname_ob = PyUnicode_DecodeFSDefault(pathname); + if (pathname_ob == NULL) { + Py_DECREF(buf_ob); + Py_DECREF(shortname_ob); + return NULL; + } PyErr_SetImportError(buf_ob, shortname_ob, pathname_ob); Py_DECREF(buf_ob); Py_DECREF(shortname_ob); diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 082154dd91b1fc8..23828898d35a5d5 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -106,7 +106,7 @@ _PyImport_FindSharedFuncptr(const char *prefix, const char *error = dlerror(); if (error == NULL) error = "unknown dlopen() error"; - error_ob = PyUnicode_FromString(error); + error_ob = PyUnicode_DecodeLocale(error, "surrogateescape"); if (error_ob == NULL) return NULL; mod_name = PyUnicode_FromString(shortname); @@ -114,7 +114,7 @@ _PyImport_FindSharedFuncptr(const char *prefix, Py_DECREF(error_ob); return NULL; } - path = PyUnicode_FromString(pathname); + path = PyUnicode_DecodeFSDefault(pathname); if (path == NULL) { Py_DECREF(error_ob); Py_DECREF(mod_name); From 263a60439d63561f64b7cac8350860e41a567eef Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 14 Oct 2020 23:41:55 -0700 Subject: [PATCH 475/486] Minor clarification (GH-22708) --- Doc/library/random.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 635f9e1c032da37..5a9359484d11a88 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -545,9 +545,9 @@ Recipes The default :func:`.random` returns multiples of 2⁻⁵³ in the range *0.0 ≤ x < 1.0*. All such numbers are evenly spaced and are exactly -representable as Python floats. However, many floats in that interval -are not possible selections. For example, ``0.05954861408025609`` -isn't an integer multiple of 2⁻⁵³. +representable as Python floats. However, many other representable +floats in that interval are not possible selections. For example, +``0.05954861408025609`` isn't an integer multiple of 2⁻⁵³. The following recipe takes a different approach. All floats in the interval are possible selections. The mantissa comes from a uniform From fb5cf25c2a764201e644d2139969f5e42390de3e Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Thu, 15 Oct 2020 14:20:15 +0200 Subject: [PATCH 476/486] bpo-42021: Fix possible ref leaks during _sqlite3 module init (GH-22673) --- .../2020-10-12-21-21-24.bpo-42021.8yv_8-.rst | 1 + Modules/_sqlite/microprotocols.c | 9 +- Modules/_sqlite/microprotocols.h | 2 +- Modules/_sqlite/module.c | 210 +++++++----------- 4 files changed, 93 insertions(+), 129 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-12-21-21-24.bpo-42021.8yv_8-.rst diff --git a/Misc/NEWS.d/next/Library/2020-10-12-21-21-24.bpo-42021.8yv_8-.rst b/Misc/NEWS.d/next/Library/2020-10-12-21-21-24.bpo-42021.8yv_8-.rst new file mode 100644 index 000000000000000..7d71e9a70079b95 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-12-21-21-24.bpo-42021.8yv_8-.rst @@ -0,0 +1 @@ +Fix possible ref leaks in :mod:`sqlite3` module init. diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 64095adb4db2b2c..ddc30e8a89b460e 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -37,14 +37,19 @@ static PyObject *psyco_adapters = NULL; /* pysqlite_microprotocols_init - initialize the adapters dictionary */ int -pysqlite_microprotocols_init(PyObject *dict) +pysqlite_microprotocols_init(PyObject *module) { /* create adapters dictionary and put it in module namespace */ if ((psyco_adapters = PyDict_New()) == NULL) { return -1; } - return PyDict_SetItemString(dict, "adapters", psyco_adapters); + if (PyModule_AddObject(module, "adapters", psyco_adapters) < 0) { + Py_DECREF(psyco_adapters); + return -1; + } + + return 0; } diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index 5418c2b98fd7519..87df6bac55797ae 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -38,7 +38,7 @@ /** exported functions **/ /* used by module.c to init the microprotocols system */ -extern int pysqlite_microprotocols_init(PyObject *dict); +extern int pysqlite_microprotocols_init(PyObject *module); extern int pysqlite_microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); extern PyObject *pysqlite_microprotocols_adapt( diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 102026663abd839..0297e2fab292e57 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -236,14 +236,17 @@ PyDoc_STRVAR(enable_callback_tracebacks_doc, \n\ Enable or disable callback functions throwing errors to stderr."); -static void converters_init(PyObject* dict) +static void converters_init(PyObject* module) { _pysqlite_converters = PyDict_New(); if (!_pysqlite_converters) { return; } - PyDict_SetItemString(dict, "converters", _pysqlite_converters); + if (PyModule_AddObject(module, "converters", _pysqlite_converters) < 0) { + Py_DECREF(_pysqlite_converters); + } + return; } static PyMethodDef module_methods[] = { @@ -264,59 +267,52 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; -struct _IntConstantPair { - const char *constant_name; - int constant_value; -}; - -typedef struct _IntConstantPair IntConstantPair; - -static const IntConstantPair _int_constants[] = { - {"PARSE_DECLTYPES", PARSE_DECLTYPES}, - {"PARSE_COLNAMES", PARSE_COLNAMES}, - - {"SQLITE_OK", SQLITE_OK}, - {"SQLITE_DENY", SQLITE_DENY}, - {"SQLITE_IGNORE", SQLITE_IGNORE}, - {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX}, - {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE}, - {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX}, - {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE}, - {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER}, - {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW}, - {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER}, - {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW}, - {"SQLITE_DELETE", SQLITE_DELETE}, - {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX}, - {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE}, - {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX}, - {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE}, - {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER}, - {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW}, - {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER}, - {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW}, - {"SQLITE_INSERT", SQLITE_INSERT}, - {"SQLITE_PRAGMA", SQLITE_PRAGMA}, - {"SQLITE_READ", SQLITE_READ}, - {"SQLITE_SELECT", SQLITE_SELECT}, - {"SQLITE_TRANSACTION", SQLITE_TRANSACTION}, - {"SQLITE_UPDATE", SQLITE_UPDATE}, - {"SQLITE_ATTACH", SQLITE_ATTACH}, - {"SQLITE_DETACH", SQLITE_DETACH}, - {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, - {"SQLITE_REINDEX", SQLITE_REINDEX}, - {"SQLITE_ANALYZE", SQLITE_ANALYZE}, - {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, - {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, - {"SQLITE_FUNCTION", SQLITE_FUNCTION}, - {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, +static int add_integer_constants(PyObject *module) { + int ret = 0; + + ret += PyModule_AddIntMacro(module, PARSE_DECLTYPES); + ret += PyModule_AddIntMacro(module, PARSE_COLNAMES); + ret += PyModule_AddIntMacro(module, SQLITE_OK); + ret += PyModule_AddIntMacro(module, SQLITE_DENY); + ret += PyModule_AddIntMacro(module, SQLITE_IGNORE); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_INDEX); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TABLE); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TEMP_INDEX); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TEMP_TABLE); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TEMP_TRIGGER); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TEMP_VIEW); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_TRIGGER); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_VIEW); + ret += PyModule_AddIntMacro(module, SQLITE_DELETE); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_INDEX); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TABLE); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TEMP_INDEX); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TEMP_TABLE); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TEMP_TRIGGER); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TEMP_VIEW); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_TRIGGER); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_VIEW); + ret += PyModule_AddIntMacro(module, SQLITE_INSERT); + ret += PyModule_AddIntMacro(module, SQLITE_PRAGMA); + ret += PyModule_AddIntMacro(module, SQLITE_READ); + ret += PyModule_AddIntMacro(module, SQLITE_SELECT); + ret += PyModule_AddIntMacro(module, SQLITE_TRANSACTION); + ret += PyModule_AddIntMacro(module, SQLITE_UPDATE); + ret += PyModule_AddIntMacro(module, SQLITE_ATTACH); + ret += PyModule_AddIntMacro(module, SQLITE_DETACH); + ret += PyModule_AddIntMacro(module, SQLITE_ALTER_TABLE); + ret += PyModule_AddIntMacro(module, SQLITE_REINDEX); + ret += PyModule_AddIntMacro(module, SQLITE_ANALYZE); + ret += PyModule_AddIntMacro(module, SQLITE_CREATE_VTABLE); + ret += PyModule_AddIntMacro(module, SQLITE_DROP_VTABLE); + ret += PyModule_AddIntMacro(module, SQLITE_FUNCTION); + ret += PyModule_AddIntMacro(module, SQLITE_SAVEPOINT); #if SQLITE_VERSION_NUMBER >= 3008003 - {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, + ret += PyModule_AddIntMacro(module, SQLITE_RECURSIVE); #endif - {"SQLITE_DONE", SQLITE_DONE}, - {(char*)NULL, 0} -}; - + ret += PyModule_AddIntMacro(module, SQLITE_DONE); + return ret; +} static struct PyModuleDef _sqlite3module = { PyModuleDef_HEAD_INIT, @@ -338,11 +334,21 @@ do { \ } \ } while (0) +#define ADD_EXCEPTION(module, name, exc, base) \ +do { \ + exc = PyErr_NewException(MODULE_NAME "." name, base, NULL); \ + if (!exc) { \ + goto error; \ + } \ + if (PyModule_AddObject(module, name, exc) < 0) { \ + Py_DECREF(exc); \ + goto error; \ + } \ +} while (0) + PyMODINIT_FUNC PyInit__sqlite3(void) { - PyObject *module, *dict; - PyObject *tmp_obj; - int i; + PyObject *module; if (sqlite3_libversion_number() < 3007003) { PyErr_SetString(PyExc_ImportError, MODULE_NAME ": SQLite 3.7.3 or higher required"); @@ -368,65 +374,21 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_TYPE(module, *pysqlite_PrepareProtocolType); ADD_TYPE(module, *pysqlite_RowType); - if (!(dict = PyModule_GetDict(module))) { - goto error; - } - /*** Create DB-API Exception hierarchy */ - - if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "Error", pysqlite_Error); - - if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "Warning", pysqlite_Warning); + ADD_EXCEPTION(module, "Error", pysqlite_Error, PyExc_Exception); + ADD_EXCEPTION(module, "Warning", pysqlite_Warning, PyExc_Exception); /* Error subclasses */ - - if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); - - if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); + ADD_EXCEPTION(module, "InterfaceError", pysqlite_InterfaceError, pysqlite_Error); + ADD_EXCEPTION(module, "DatabaseError", pysqlite_DatabaseError, pysqlite_Error); /* pysqlite_DatabaseError subclasses */ - - if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); - - if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); - - if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); - - if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { - goto error; - } - PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); - - if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "DataError", pysqlite_DataError); - - if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); + ADD_EXCEPTION(module, "InternalError", pysqlite_InternalError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "OperationalError", pysqlite_OperationalError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "ProgrammingError", pysqlite_ProgrammingError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "IntegrityError", pysqlite_IntegrityError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "DataError", pysqlite_DataError, pysqlite_DatabaseError); + ADD_EXCEPTION(module, "NotSupportedError", pysqlite_NotSupportedError, pysqlite_DatabaseError); /* In Python 2.x, setting Connection.text_factory to OptimizedUnicode caused Unicode objects to be returned for @@ -434,35 +396,31 @@ PyMODINIT_FUNC PyInit__sqlite3(void) Now OptimizedUnicode is an alias for str, so it has no effect. */ Py_INCREF((PyObject*)&PyUnicode_Type); - PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); + if (PyModule_AddObject(module, "OptimizedUnicode", (PyObject*)&PyUnicode_Type) < 0) { + Py_DECREF((PyObject*)&PyUnicode_Type); + goto error; + } /* Set integer constants */ - for (i = 0; _int_constants[i].constant_name != NULL; i++) { - tmp_obj = PyLong_FromLong(_int_constants[i].constant_value); - if (!tmp_obj) { - goto error; - } - PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); - Py_DECREF(tmp_obj); + if (add_integer_constants(module) < 0) { + goto error; } - if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { + if (PyModule_AddStringConstant(module, "version", PYSQLITE_VERSION) < 0) { goto error; } - PyDict_SetItemString(dict, "version", tmp_obj); - Py_DECREF(tmp_obj); - if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { + if (PyModule_AddStringConstant(module, "sqlite_version", sqlite3_libversion())) { goto error; } - PyDict_SetItemString(dict, "sqlite_version", tmp_obj); - Py_DECREF(tmp_obj); /* initialize microprotocols layer */ - pysqlite_microprotocols_init(dict); + if (pysqlite_microprotocols_init(module) < 0) { + goto error; + } /* initialize the default converters */ - converters_init(dict); + converters_init(module); error: if (PyErr_Occurred()) From 3bedbcca2cf2047f4782b16d27f74bd26a8da03d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 15 Oct 2020 16:22:19 +0200 Subject: [PATCH 477/486] bpo-1635741: Add a global module state to unicodedata (GH-22712) Prepare unicodedata to add a state per module: start with a global "module" state, pass it to subfunctions which access &UCD_Type. This change also prepares the conversion of the UCD_Type static type to a heap type. --- Modules/unicodedata.c | 161 ++++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 54 deletions(-) diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 8e11cfc4dafa923..941fd2faa742a60 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -93,22 +93,33 @@ static PyMemberDef DB_members[] = { /* forward declaration */ static PyTypeObject UCD_Type; -// Check if self is an instance of UCD_Type. +typedef struct { + // Borrowed reference to &UCD_Type. It is used to prepare the code + // to convert the UCD_Type static type to a heap type. + PyTypeObject *ucd_type; +} unicodedata_module_state; + +// bpo-1635741: Temporary global state until the unicodedata module +// gets a real module state. +static unicodedata_module_state global_module_state; + +// Check if self is an instance of ucd_type. // Return 0 if self is NULL (when the PyCapsule C API is used). #define UCD_Check(self, ucd_type) (self != NULL && Py_IS_TYPE(self, ucd_type)) static PyObject* -new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), +new_previous_version(unicodedata_module_state *state, + const char*name, const change_record* (*getrecord)(Py_UCS4), Py_UCS4 (*normalization)(Py_UCS4)) { - PreviousDBVersion *self; - self = PyObject_New(PreviousDBVersion, &UCD_Type); - if (self == NULL) - return NULL; - self->name = name; - self->getrecord = getrecord; - self->normalization = normalization; - return (PyObject*)self; + PreviousDBVersion *self; + self = PyObject_New(PreviousDBVersion, state->ucd_type); + if (self == NULL) + return NULL; + self->name = name; + self->getrecord = getrecord; + self->normalization = normalization; + return (PyObject*)self; } @@ -134,11 +145,12 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, PyObject *default_value) /*[clinic end generated code: output=be23376e1a185231 input=933f8107993f23d0]*/ { + unicodedata_module_state *state = &global_module_state; int have_old = 0; long rc; Py_UCS4 c = (Py_UCS4)chr; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -222,11 +234,12 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, PyObject *default_value) /*[clinic end generated code: output=53ce281fe85b10c4 input=fdf5871a5542893c]*/ { + unicodedata_module_state *state = &global_module_state; int have_old = 0; double rc; Py_UCS4 c = (Py_UCS4)chr; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -268,10 +281,11 @@ static PyObject * unicodedata_UCD_category_impl(PyObject *self, int chr) /*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/ { + unicodedata_module_state *state = &global_module_state; int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->category; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed != 0xFF) index = old->category_changed; @@ -295,10 +309,11 @@ static PyObject * unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) /*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/ { + unicodedata_module_state *state = &global_module_state; int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->bidirectional; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -324,10 +339,11 @@ static int unicodedata_UCD_combining_impl(PyObject *self, int chr) /*[clinic end generated code: output=cad056d0cb6a5920 input=9f2d6b2a95d0a22a]*/ { + unicodedata_module_state *state = &global_module_state; int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->combining; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -352,10 +368,11 @@ static int unicodedata_UCD_mirrored_impl(PyObject *self, int chr) /*[clinic end generated code: output=2532dbf8121b50e6 input=5dd400d351ae6f3b]*/ { + unicodedata_module_state *state = &global_module_state; int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->mirrored; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -379,10 +396,11 @@ static PyObject * unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) /*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/ { + unicodedata_module_state *state = &global_module_state; int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->east_asian_width; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -408,6 +426,7 @@ static PyObject * unicodedata_UCD_decomposition_impl(PyObject *self, int chr) /*[clinic end generated code: output=7d699f3ec7565d27 input=e4c12459ad68507b]*/ { + unicodedata_module_state *state = &global_module_state; char decomp[256]; int code, index, count; size_t i; @@ -416,7 +435,7 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) code = (int)c; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) return PyUnicode_FromString(""); /* unassigned */ @@ -459,11 +478,12 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) } static void -get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count) +get_decomp_record(unicodedata_module_state *state, PyObject *self, + Py_UCS4 code, int *index, int *prefix, int *count) { if (code >= 0x110000) { *index = 0; - } else if (UCD_Check(self, &UCD_Type) && + } else if (UCD_Check(self, state->ucd_type) && get_old_record(self, code)->category_changed==0) { /* unassigned in old version */ *index = 0; @@ -493,7 +513,8 @@ get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *co #define SCount (LCount*NCount) static PyObject* -nfd_nfkd(PyObject *self, PyObject *input, int k) +nfd_nfkd(unicodedata_module_state *state, PyObject *self, + PyObject *input, int k) { PyObject *result; Py_UCS4 *output; @@ -561,7 +582,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) continue; } /* normalization changes */ - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); if (value != 0) { stack[stackptr++] = value; @@ -570,7 +591,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) } /* Other decompositions. */ - get_decomp_record(self, code, &index, &prefix, &count); + get_decomp_record(state, self, code, &index, &prefix, &count); /* Copy character if it is not decomposable, or has a compatibility decomposition, but we do NFD. */ @@ -642,7 +663,7 @@ find_nfc_index(const struct reindex* nfc, Py_UCS4 code) } static PyObject* -nfc_nfkc(PyObject *self, PyObject *input, int k) +nfc_nfkc(unicodedata_module_state *state, PyObject *self, PyObject *input, int k) { PyObject *result; int kind; @@ -654,7 +675,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) Py_ssize_t skipped[20]; int cskipped = 0; - result = nfd_nfkd(self, input, k); + result = nfd_nfkd(state, self, input, k); if (!result) return NULL; /* result will be "ready". */ @@ -797,12 +818,12 @@ typedef enum {YES = 0, MAYBE = 1, NO = 2} QuickcheckResult; * https://www.unicode.org/reports/tr15/#Detecting_Normalization_Forms */ static QuickcheckResult -is_normalized_quickcheck(PyObject *self, PyObject *input, - bool nfc, bool k, bool yes_only) +is_normalized_quickcheck(unicodedata_module_state *state, PyObject *self, + PyObject *input, bool nfc, bool k, bool yes_only) { /* An older version of the database is requested, quickchecks must be disabled. */ - if (UCD_Check(self, &UCD_Type)) + if (UCD_Check(self, state->ucd_type)) return NO; Py_ssize_t i, len; @@ -862,6 +883,7 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, PyObject *input) /*[clinic end generated code: output=11e5a3694e723ca5 input=a544f14cea79e508]*/ { + unicodedata_module_state *state = &global_module_state; if (PyUnicode_READY(input) == -1) { return NULL; } @@ -897,10 +919,10 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, return NULL; } - m = is_normalized_quickcheck(self, input, nfc, k, false); + m = is_normalized_quickcheck(state, self, input, nfc, k, false); if (m == MAYBE) { - cmp = (nfc ? nfc_nfkc : nfd_nfkd)(self, input, k); + cmp = (nfc ? nfc_nfkc : nfd_nfkd)(state, self, input, k); if (cmp == NULL) { return NULL; } @@ -935,6 +957,7 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, PyObject *input) /*[clinic end generated code: output=05ca4385a2ad6983 input=3a5206c0ad2833fb]*/ { + unicodedata_module_state *state = &global_module_state; if (PyUnicode_GET_LENGTH(input) == 0) { /* Special case empty input strings, since resizing them later would cause internal errors. */ @@ -943,32 +966,36 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { - if (is_normalized_quickcheck(self, input, true, false, true) == YES) { + if (is_normalized_quickcheck(state, self, input, + true, false, true) == YES) { Py_INCREF(input); return input; } - return nfc_nfkc(self, input, 0); + return nfc_nfkc(state, self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { - if (is_normalized_quickcheck(self, input, true, true, true) == YES) { + if (is_normalized_quickcheck(state, self, input, + true, true, true) == YES) { Py_INCREF(input); return input; } - return nfc_nfkc(self, input, 1); + return nfc_nfkc(state, self, input, 1); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { - if (is_normalized_quickcheck(self, input, false, false, true) == YES) { + if (is_normalized_quickcheck(state, self, input, + false, false, true) == YES) { Py_INCREF(input); return input; } - return nfd_nfkd(self, input, 0); + return nfd_nfkd(state, self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { - if (is_normalized_quickcheck(self, input, false, true, true) == YES) { + if (is_normalized_quickcheck(state, self, input, + false, true, true) == YES) { Py_INCREF(input); return input; } - return nfd_nfkd(self, input, 1); + return nfd_nfkd(state, self, input, 1); } PyErr_SetString(PyExc_ValueError, "invalid normalization form"); return NULL; @@ -1051,8 +1078,8 @@ is_unified_ideograph(Py_UCS4 code) (cp < named_sequences_end)) static int -_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq) +_getucname(unicodedata_module_state *state, PyObject *self, + Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) { /* Find the name associated with the given code point. * If with_alias_and_seq is 1, check for names in the Private Use Area 15 @@ -1069,7 +1096,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) return 0; - if (UCD_Check(self, &UCD_Type)) { + if (UCD_Check(self, state->ucd_type)) { /* in 3.2.0 there are no aliases and named sequences */ const change_record *old; if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) @@ -1153,12 +1180,22 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, } static int -_cmpname(PyObject *self, int code, const char* name, int namelen) +capi_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, + int with_alias_and_seq) +{ + unicodedata_module_state *state = &global_module_state; + return _getucname(state, self, code, buffer, buflen, with_alias_and_seq); + +} + +static int +_cmpname(unicodedata_module_state *state, PyObject *self, + int code, const char* name, int namelen) { /* check if code corresponds to the given name */ int i; char buffer[NAME_MAXLEN+1]; - if (!_getucname(self, code, buffer, NAME_MAXLEN, 1)) + if (!_getucname(state, self, code, buffer, NAME_MAXLEN, 1)) return 0; for (i = 0; i < namelen; i++) { if (Py_TOUPPER(name[i]) != buffer[i]) @@ -1203,8 +1240,8 @@ _check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) } static int -_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, - int with_named_seq) +_getcode(unicodedata_module_state *state, PyObject* self, + const char* name, int namelen, Py_UCS4* code, int with_named_seq) { /* Return the code point associated with the given name. * Named aliases are resolved too (unless self != NULL (i.e. we are using @@ -1265,8 +1302,9 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(state, self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = (h ^ (h >> 3)) & mask; if (!incr) incr = mask; @@ -1275,19 +1313,29 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(state, self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = incr << 1; if (incr > mask) incr = incr ^ code_poly; } } +static int +capi_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, + int with_named_seq) +{ + unicodedata_module_state *state = &global_module_state; + return _getcode(state, self, name, namelen, code, with_named_seq); + +} + static const _PyUnicode_Name_CAPI hashAPI = { sizeof(_PyUnicode_Name_CAPI), - _getucname, - _getcode + capi_getucname, + capi_getcode }; /* -------------------------------------------------------------------- */ @@ -1311,10 +1359,11 @@ static PyObject * unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) /*[clinic end generated code: output=6bbb37a326407707 input=3e0367f534de56d9]*/ { + unicodedata_module_state *state = &global_module_state; char name[NAME_MAXLEN+1]; Py_UCS4 c = (Py_UCS4)chr; - if (!_getucname(self, c, name, NAME_MAXLEN, 0)) { + if (!_getucname(state, self, c, name, NAME_MAXLEN, 0)) { if (default_value == NULL) { PyErr_SetString(PyExc_ValueError, "no such name"); return NULL; @@ -1346,6 +1395,7 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, Py_ssize_clean_t name_length) /*[clinic end generated code: output=765cb8186788e6be input=a557be0f8607a0d6]*/ { + unicodedata_module_state *state = &global_module_state; Py_UCS4 code; unsigned int index; if (name_length > NAME_MAXLEN) { @@ -1353,7 +1403,7 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, return NULL; } - if (!_getcode(self, name, (int)name_length, &code, 1)) { + if (!_getcode(state, self, name, (int)name_length, &code, 1)) { PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); return NULL; } @@ -1458,19 +1508,22 @@ PyMODINIT_FUNC PyInit_unicodedata(void) { PyObject *m, *v; + unicodedata_module_state *state = &global_module_state; Py_SET_TYPE(&UCD_Type, &PyType_Type); + state->ucd_type = &UCD_Type; m = PyModule_Create(&unicodedatamodule); if (!m) return NULL; PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); - Py_INCREF(&UCD_Type); - PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); + Py_INCREF(state->ucd_type); + PyModule_AddObject(m, "UCD", (PyObject*)state->ucd_type); /* Previous versions */ - v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0); + v = new_previous_version(state, "3.2.0", + get_change_3_2_0, normalization_3_2_0); if (v != NULL) PyModule_AddObject(m, "ucd_3_2_0", v); From c6bca2de19170df4c4c685a95448474ec843dbc9 Mon Sep 17 00:00:00 2001 From: Saiyang Gou Date: Thu, 15 Oct 2020 12:06:23 -0700 Subject: [PATCH 478/486] Document that `test.support.bytecode_helper` is new in 3.9 (GH-22618) --- Doc/library/test.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 6495b4844449e59..ce6b868458ea4f5 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1168,6 +1168,8 @@ script execution tests. The :mod:`test.support.bytecode_helper` module provides support for testing and inspecting bytecode generation. +.. versionadded:: 3.9 + The module defines the following class: .. class:: BytecodeTestCase(unittest.TestCase) From 9011f3f6dbd647f4a390994d105640ab93fb1e91 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 16 Oct 2020 16:34:15 +0800 Subject: [PATCH 479/486] bpo-41919, test_codecs: Move codecs.register calls to setUp() (GH-22513) * Move the codecs' (un)register operation to testcases. * Remove _codecs._forget_codec() and _PyCodec_Forget() --- Lib/test/test_charmapcodec.py | 7 ++++-- Lib/test/test_codecs.py | 25 +++----------------- Lib/test/test_io.py | 7 +++--- Lib/test/test_unicode.py | 5 +++- Modules/_codecsmodule.c | 20 ---------------- Modules/clinic/_codecsmodule.c.h | 39 +------------------------------- Python/codecs.c | 25 -------------------- 7 files changed, 16 insertions(+), 112 deletions(-) diff --git a/Lib/test/test_charmapcodec.py b/Lib/test/test_charmapcodec.py index 0d4594d8c05f2cf..3f628902a1fd31f 100644 --- a/Lib/test/test_charmapcodec.py +++ b/Lib/test/test_charmapcodec.py @@ -20,12 +20,15 @@ def codec_search_function(encoding): return tuple(testcodec.getregentry()) return None -codecs.register(codec_search_function) - # test codec's name (see test/testcodec.py) codecname = 'testcodec' class CharmapCodecTest(unittest.TestCase): + + def setUp(self): + codecs.register(codec_search_function) + self.addCleanup(codecs.unregister, codec_search_function) + def test_constructorx(self): self.assertEqual(str(b'abc', codecname), 'abc') self.assertEqual(str(b'xdef', codecname), 'abcdef') diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 09ceef76eb098da..9be8281ce5af5ca 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2754,29 +2754,14 @@ def test_uu_invalid(self): def _get_test_codec(codec_name): return _TEST_CODECS.get(codec_name) -codecs.register(_get_test_codec) # Returns None, not usable as a decorator - -try: - # Issue #22166: Also need to clear the internal cache in CPython - from _codecs import _forget_codec -except ImportError: - def _forget_codec(codec_name): - pass class ExceptionChainingTest(unittest.TestCase): def setUp(self): - # There's no way to unregister a codec search function, so we just - # ensure we render this one fairly harmless after the test - # case finishes by using the test case repr as the codec name - # The codecs module normalizes codec names, although this doesn't - # appear to be formally documented... - # We also make sure we use a truly unique id for the custom codec - # to avoid issues with the codec cache when running these tests - # multiple times (e.g. when hunting for refleaks) - unique_id = repr(self) + str(id(self)) - self.codec_name = encodings.normalize_encoding(unique_id).lower() + self.codec_name = 'exception_chaining_test' + codecs.register(_get_test_codec) + self.addCleanup(codecs.unregister, _get_test_codec) # We store the object to raise on the instance because of a bad # interaction between the codec caching (which means we can't @@ -2791,10 +2776,6 @@ def tearDown(self): _TEST_CODECS.pop(self.codec_name, None) # Issue #22166: Also pop from caches to avoid appearance of ref leaks encodings._cache.pop(self.codec_name, None) - try: - _forget_codec(self.codec_name) - except KeyError: - pass def set_codec(self, encode, decode): codec_info = codecs.CodecInfo(encode, decode, diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 85fac30e300a659..fbaea3aaec3cbe4 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -2529,10 +2529,6 @@ def lookupTestDecoder(cls, name): streamreader=None, streamwriter=None, incrementaldecoder=cls) -# Register the previous decoder for testing. -# Disabled by default, tests will enable it. -codecs.register(StatefulIncrementalDecoder.lookupTestDecoder) - class StatefulIncrementalDecoderTest(unittest.TestCase): """ @@ -2583,6 +2579,9 @@ def setUp(self): self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n" self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii") os_helper.unlink(os_helper.TESTFN) + codecs.register(StatefulIncrementalDecoder.lookupTestDecoder) + self.addCleanup(codecs.unregister, + StatefulIncrementalDecoder.lookupTestDecoder) def tearDown(self): os_helper.unlink(os_helper.TESTFN) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index d485bc7ede2b923..90b0965582272c3 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -36,7 +36,6 @@ def decode2(input, errors="strict"): return (encode2, decode2, None, None) else: return None -codecs.register(search_function) def duplicate_string(text): """ @@ -58,6 +57,10 @@ class UnicodeTest(string_tests.CommonTest, type2test = str + def setUp(self): + codecs.register(search_function) + self.addCleanup(codecs.unregister, search_function) + def checkequalnofix(self, result, object, methodname, *args): method = getattr(object, methodname) realresult = method(*args) diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 08a3d4ab024cc2d..2e8cb97fe77c920 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -160,25 +160,6 @@ _codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, /* --- Helpers ------------------------------------------------------------ */ -/*[clinic input] -_codecs._forget_codec - - encoding: str - / - -Purge the named codec from the internal codec lookup cache -[clinic start generated code]*/ - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding) -/*[clinic end generated code: output=0bde9f0a5b084aa2 input=18d5d92d0e386c38]*/ -{ - if (_PyCodec_Forget(encoding) < 0) { - return NULL; - }; - Py_RETURN_NONE; -} - static PyObject *codec_tuple(PyObject *decoded, Py_ssize_t len) @@ -1057,7 +1038,6 @@ static PyMethodDef _codecs_functions[] = { _CODECS_CODE_PAGE_DECODE_METHODDEF _CODECS_REGISTER_ERROR_METHODDEF _CODECS_LOOKUP_ERROR_METHODDEF - _CODECS__FORGET_CODEC_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index e2ebb6861299e46..43378f94f984501 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -217,43 +217,6 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje return return_value; } -PyDoc_STRVAR(_codecs__forget_codec__doc__, -"_forget_codec($module, encoding, /)\n" -"--\n" -"\n" -"Purge the named codec from the internal codec lookup cache"); - -#define _CODECS__FORGET_CODEC_METHODDEF \ - {"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_O, _codecs__forget_codec__doc__}, - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding); - -static PyObject * -_codecs__forget_codec(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *encoding; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("_forget_codec", "argument", "str", arg); - goto exit; - } - Py_ssize_t encoding_length; - encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); - if (encoding == NULL) { - goto exit; - } - if (strlen(encoding) != (size_t)encoding_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - return_value = _codecs__forget_codec_impl(module, encoding); - -exit: - return return_value; -} - PyDoc_STRVAR(_codecs_escape_decode__doc__, "escape_decode($module, data, errors=None, /)\n" "--\n" @@ -2838,4 +2801,4 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=9a97e2ddf3e69072 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=557c3b37e4c492ac input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index a8233a73c4ed3f5..ade14187204f09a 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -208,31 +208,6 @@ PyObject *_PyCodec_Lookup(const char *encoding) return NULL; } -int _PyCodec_Forget(const char *encoding) -{ - PyObject *v; - int result; - - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL) { - return -1; - } - - /* Convert the encoding to a normalized Python string: all - characters are converted to lower case, spaces and hyphens are - replaced with underscores. */ - v = normalizestring(encoding); - if (v == NULL) { - return -1; - } - - /* Drop the named codec from the internal cache */ - result = PyDict_DelItem(interp->codec_search_cache, v); - Py_DECREF(v); - - return result; -} - /* Codec registry encoding check API. */ int PyCodec_KnownEncoding(const char *encoding) From 3be247578e29b7b693613a8358e040e0bd891155 Mon Sep 17 00:00:00 2001 From: Necdet Can Atesman Date: Fri, 16 Oct 2020 16:14:07 +0200 Subject: [PATCH 480/486] bpo-42011: Update documentation of logging.Filter.filter() (GH-22692) --- Lib/logging/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 787cb4eefa10613..265e286101e9137 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -763,8 +763,8 @@ def filter(self, record): """ Determine if the specified record is to be logged. - Is the specified record to be logged? Returns 0 for no, nonzero for - yes. If deemed appropriate, the record may be modified in-place. + Returns True if the record should be logged, or False otherwise. + If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True From 9a8345738ea6b3197bcda73c71c0e1abb46b08ff Mon Sep 17 00:00:00 2001 From: Kevin Adler Date: Fri, 16 Oct 2020 13:03:28 -0500 Subject: [PATCH 481/486] closes bpo-42030: Remove legacy AIX dynload support (GH-22717) Since c19c5a6, AIX builds have defaulted to using dynload_shlib over dynload_aix when dlopen is available. This function has been available since AIX 4.3, which went out of support in 2003, the same year the previously referenced commit was made. It has been nearly 20 years since a version of AIX has been supported which has not used dynload_shlib so there's no reason to keep this legacy code around. --- .../2020-10-15-21-55-32.bpo-42030.PmU2CA.rst | 3 + Python/dynload_aix.c | 190 ------------------ configure | 6 - configure.ac | 6 - 4 files changed, 3 insertions(+), 202 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-15-21-55-32.bpo-42030.PmU2CA.rst delete mode 100644 Python/dynload_aix.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-15-21-55-32.bpo-42030.PmU2CA.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-15-21-55-32.bpo-42030.PmU2CA.rst new file mode 100644 index 000000000000000..e8c691d809614fa --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-15-21-55-32.bpo-42030.PmU2CA.rst @@ -0,0 +1,3 @@ +Support for the legacy AIX-specific shared library loading support has been +removed. All versions of AIX since 4.3 have supported and defaulted to using +the common Unix mechanism instead. diff --git a/Python/dynload_aix.c b/Python/dynload_aix.c deleted file mode 100644 index 97f7698ef4b2d94..000000000000000 --- a/Python/dynload_aix.c +++ /dev/null @@ -1,190 +0,0 @@ - -/* Support for dynamic loading of extension modules */ - -#include "Python.h" -#include "importdl.h" - -#include /* for global errno */ -#include /* for strerror() */ -#include /* for malloc(), free() */ -#include - - -#ifdef AIX_GENUINE_CPLUSPLUS -#include -#define aix_load loadAndInit -#else -#define aix_load load -#endif - - -extern char *Py_GetProgramName(void); - -typedef struct Module { - struct Module *next; - void *entry; -} Module, *ModulePtr; - -const char *_PyImport_DynLoadFiletab[] = {".so", NULL}; - -static int -aix_getoldmodules(void **modlistptr) -{ - ModulePtr modptr, prevmodptr; - struct ld_info *ldiptr; - char *ldibuf; - int errflag, bufsize = 1024; - unsigned int offset; - char *progname = Py_GetProgramName(); - - /* - -- Get the list of loaded modules into ld_info structures. - */ - if ((ldibuf = malloc(bufsize)) == NULL) { - PyErr_SetString(PyExc_ImportError, strerror(errno)); - return -1; - } - while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1 - && errno == ENOMEM) { - free(ldibuf); - bufsize += 1024; - if ((ldibuf = malloc(bufsize)) == NULL) { - PyErr_SetString(PyExc_ImportError, strerror(errno)); - return -1; - } - } - if (errflag == -1) { - PyErr_SetString(PyExc_ImportError, strerror(errno)); - return -1; - } - /* - -- Make the modules list from the ld_info structures. - */ - ldiptr = (struct ld_info *)ldibuf; - prevmodptr = NULL; - do { - if (strstr(progname, ldiptr->ldinfo_filename) == NULL && - strstr(ldiptr->ldinfo_filename, "python") == NULL) { - /* - -- Extract only the modules belonging to the main - -- executable + those containing "python" as a - -- substring (like the "python[version]" binary or - -- "libpython[version].a" in case it's a shared lib). - */ - offset = (unsigned int)ldiptr->ldinfo_next; - ldiptr = (struct ld_info *)((char*)ldiptr + offset); - continue; - } - if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) { - PyErr_SetString(PyExc_ImportError, strerror(errno)); - while (*modlistptr) { - modptr = (ModulePtr)*modlistptr; - *modlistptr = (void *)modptr->next; - free(modptr); - } - return -1; - } - modptr->entry = ldiptr->ldinfo_dataorg; - modptr->next = NULL; - if (prevmodptr == NULL) - *modlistptr = (void *)modptr; - else - prevmodptr->next = modptr; - prevmodptr = modptr; - offset = (unsigned int)ldiptr->ldinfo_next; - ldiptr = (struct ld_info *)((char*)ldiptr + offset); - } while (offset); - free(ldibuf); - return 0; -} - - -static void -aix_loaderror(const char *pathname) -{ - - char *message[1024], errbuf[1024]; - PyObject *pathname_ob = NULL; - PyObject *errbuf_ob = NULL; - int i,j; - - struct errtab { - int errNo; - char *errstr; - } load_errtab[] = { - {L_ERROR_TOOMANY, "too many errors, rest skipped."}, - {L_ERROR_NOLIB, "can't load library:"}, - {L_ERROR_UNDEF, "can't find symbol in library:"}, - {L_ERROR_RLDBAD, - "RLD index out of range or bad relocation type:"}, - {L_ERROR_FORMAT, "not a valid, executable xcoff file:"}, - {L_ERROR_MEMBER, - "file not an archive or does not contain requested member:"}, - {L_ERROR_TYPE, "symbol table mismatch:"}, - {L_ERROR_ALIGN, "text alignment in file is wrong."}, - {L_ERROR_SYSTEM, "System error:"}, - {L_ERROR_ERRNO, NULL} - }; - -#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1) - - PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname); - - if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) { - ERRBUF_APPEND(strerror(errno)); - ERRBUF_APPEND("\n"); - } - for(i = 0; message[i] && *message[i]; i++) { - int nerr = atoi(message[i]); - for (j=0; j < Py_ARRAY_LENGTH(load_errtab); j++) { - if (nerr == load_errtab[j].errNo && load_errtab[j].errstr) - ERRBUF_APPEND(load_errtab[j].errstr); - } - while (Py_ISDIGIT(*message[i])) message[i]++ ; - ERRBUF_APPEND(message[i]); - ERRBUF_APPEND("\n"); - } - /* Subtract 1 from the length to trim off trailing newline */ - errbuf_ob = PyUnicode_DecodeLocaleAndSize(errbuf, strlen(errbuf)-1, "surrogateescape"); - if (errbuf_ob == NULL) - return; - pathname_ob = PyUnicode_DecodeFSDefault(pathname); - if (pathname_ob == NULL) { - Py_DECREF(errbuf_ob); - return; - } - PyErr_SetImportError(errbuf_ob, NULL, pathname_ob); - Py_DECREF(pathname_ob); - Py_DECREF(errbuf_ob); - return; -} - - -dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, - const char *shortname, - const char *pathname, FILE *fp) -{ - dl_funcptr p; - - /* - -- Invoke load() with L_NOAUTODEFER leaving the imported symbols - -- of the shared module unresolved. Thus we have to resolve them - -- explicitly with loadbind. The new module is loaded, then we - -- resolve its symbols using the list of already loaded modules - -- (only those that belong to the python executable). Get these - -- with loadquery(L_GETINFO). - */ - - static void *staticmodlistptr = NULL; - - if (!staticmodlistptr) - if (aix_getoldmodules(&staticmodlistptr) == -1) - return NULL; - p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0); - if (p == NULL) { - aix_loaderror(pathname); - return NULL; - } - - return p; -} diff --git a/configure b/configure index 89577d85a41482d..88b78947767fa9a 100755 --- a/configure +++ b/configure @@ -11625,12 +11625,6 @@ $as_echo_n "checking DYNLOADFILE... " >&6; } if test -z "$DYNLOADFILE" then case $ac_sys_system/$ac_sys_release in - AIX*) # Use dynload_shlib.c and dlopen() if we have it; otherwise dynload_aix.c - if test "$ac_cv_func_dlopen" = yes - then DYNLOADFILE="dynload_shlib.o" - else DYNLOADFILE="dynload_aix.o" - fi - ;; hp*|HP*) DYNLOADFILE="dynload_hpux.o";; *) # use dynload_shlib.c and dlopen() if we have it; otherwise stub diff --git a/configure.ac b/configure.ac index 3ec274c576edfd6..6ffe90a4c426cc5 100644 --- a/configure.ac +++ b/configure.ac @@ -3622,12 +3622,6 @@ AC_MSG_CHECKING(DYNLOADFILE) if test -z "$DYNLOADFILE" then case $ac_sys_system/$ac_sys_release in - AIX*) # Use dynload_shlib.c and dlopen() if we have it; otherwise dynload_aix.c - if test "$ac_cv_func_dlopen" = yes - then DYNLOADFILE="dynload_shlib.o" - else DYNLOADFILE="dynload_aix.o" - fi - ;; hp*|HP*) DYNLOADFILE="dynload_hpux.o";; *) # use dynload_shlib.c and dlopen() if we have it; otherwise stub From e5d33ffc72d34b765bb4deeb12b649107a9dd9c4 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 16 Oct 2020 12:44:17 -0600 Subject: [PATCH 482/486] bpo-40341: Remove some "discouraged solutions" in Doc/faq/programming.rst (GH-22726) --- Doc/faq/programming.rst | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 7bcedb0b5d75b46..2d542cfb1dbb4be 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -942,7 +942,7 @@ There are various techniques. f() -* Use :func:`locals` or :func:`eval` to resolve the function name:: +* Use :func:`locals` to resolve the function name:: def myFunc(): print("hello") @@ -952,12 +952,6 @@ There are various techniques. f = locals()[fname] f() - f = eval(fname) - f() - - Note: Using :func:`eval` is slow and dangerous. If you don't have absolute - control over the contents of the string, someone could pass a string that - resulted in an arbitrary function being executed. Is there an equivalent to Perl's chomp() for removing trailing newlines from strings? ------------------------------------------------------------------------------------- @@ -1381,20 +1375,6 @@ out the element you want. :: ['else', 'sort', 'to', 'something'] -An alternative for the last step is:: - - >>> result = [] - >>> for p in pairs: result.append(p[1]) - -If you find this more legible, you might prefer to use this instead of the final -list comprehension. However, it is almost twice as slow for long lists. Why? -First, the ``append()`` operation has to reallocate memory, and while it uses -some tricks to avoid doing that each time, it still has to do it occasionally, -and that costs quite a bit. Second, the expression "result.append" requires an -extra attribute lookup, and third, there's a speed reduction from having to make -all those function calls. - - Objects ======= From fb18dfd23bbc7914c26e8f2471574ed02e3ab26f Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Fri, 16 Oct 2020 23:34:01 -0300 Subject: [PATCH 483/486] [doc] Add mentions of PEP 613 (TypeAlias) to docs (GH-22733) --- Doc/library/typing.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 5fb78bbde69b1cd..402dd24fde6e08e 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -18,7 +18,7 @@ -------------- This module provides runtime support for type hints as specified by -:pep:`484`, :pep:`526`, :pep:`544`, :pep:`586`, :pep:`589`, and :pep:`591`. +:pep:`484`, :pep:`526`, :pep:`544`, :pep:`586`, :pep:`589`, :pep:`591`, and :pep:`613`. The most fundamental support consists of the types :data:`Any`, :data:`Union`, :data:`Tuple`, :data:`Callable`, :class:`TypeVar`, and :class:`Generic`. For full specification please see :pep:`484`. For @@ -500,6 +500,8 @@ These can be used as types in annotations and do not support ``[]``. Factors: TypeAlias = list[int] + See :pep:`613` for more details about explicit type aliases. + .. versionadded:: 3.10 Special forms From 3721e74318be0bb7cc94f0fe9b62ba6896e73d3b Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Sat, 17 Oct 2020 13:38:21 -0700 Subject: [PATCH 484/486] bpo-42065: Fix incorrectly formatted _codecs.charmap_decode error message (GH-19940) --- Lib/test/test_codecs.py | 12 ++++++++++++ .../Library/2020-10-17-23-17-18.bpo-42065.85BsRA.rst | 3 +++ Objects/unicodeobject.c | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-10-17-23-17-18.bpo-42065.85BsRA.rst diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 9be8281ce5af5ca..328a47b2e376693 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2197,6 +2197,18 @@ def test_decode_with_int2str_map(self): ("", len(allbytes)) ) + self.assertRaisesRegex(TypeError, + "character mapping must be in range\\(0x110000\\)", + codecs.charmap_decode, + b"\x00\x01\x02", "strict", {0: "A", 1: 'Bb', 2: -2} + ) + + self.assertRaisesRegex(TypeError, + "character mapping must be in range\\(0x110000\\)", + codecs.charmap_decode, + b"\x00\x01\x02", "strict", {0: "A", 1: 'Bb', 2: 999999999} + ) + def test_decode_with_int2int_map(self): a = ord('a') b = ord('b') diff --git a/Misc/NEWS.d/next/Library/2020-10-17-23-17-18.bpo-42065.85BsRA.rst b/Misc/NEWS.d/next/Library/2020-10-17-23-17-18.bpo-42065.85BsRA.rst new file mode 100644 index 000000000000000..83c86c0799ebfad --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-17-23-17-18.bpo-42065.85BsRA.rst @@ -0,0 +1,3 @@ +Fix an incorrectly formatted error from :meth:`_codecs.charmap_decode` when +called with a mapped value outside the range of valid Unicode code points. +PR by Max Bernstein. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 01e5c728b383fb4..c4e73ebd45d2065 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8304,7 +8304,7 @@ charmap_decode_mapping(const char *s, goto Undefined; if (value < 0 || value > MAX_UNICODE) { PyErr_Format(PyExc_TypeError, - "character mapping must be in range(0x%lx)", + "character mapping must be in range(0x%x)", (unsigned long)MAX_UNICODE + 1); goto onError; } From 8f88cbb4c5ec412fb8548a9923b331b33f0756ca Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2020 14:33:53 +0000 Subject: [PATCH 485/486] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by?= =?UTF-8?q?=20blurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst diff --git a/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst new file mode 100644 index 000000000000000..11b51dd5b87c5d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst @@ -0,0 +1 @@ +Made NamedTemporaryFile its own iterator to mimic file objects. \ No newline at end of file From c487ed758bde63ff1d31952fbf366c40a36d743e Mon Sep 17 00:00:00 2001 From: Seth Sims Date: Sat, 17 Oct 2020 19:30:44 -0400 Subject: [PATCH 486/486] Addressing comments from review --- Lib/test/test_tempfile.py | 11 ++++------- .../Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 400c9788d6df4e4..a3f44551195b331 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -888,18 +888,15 @@ def make_file(): def test_next(self): lines = [b'spam\n', b'eggs\n', b'beans\n'] - def make_file(): - f = tempfile.NamedTemporaryFile(mode='w+b') - f.write(b''.join(lines)) - f.seek(0) - return f + with tempfile.NamedTemporaryFile(mode='w+b') as fd: + fd.write(b''.join(lines)) + fd.seek(0) - with make_file() as fd: for i, l in enumerate(lines): self.assertEqual(l, next(fd)) self.assertEqual(i, len(lines) - 1) - with self.assertRaises(StopIteration) as context: + with self.assertRaises(StopIteration): next(fd) def test_creates_named(self): diff --git a/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst index 11b51dd5b87c5d2..897099bb4fbb640 100644 --- a/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst +++ b/Misc/NEWS.d/next/Library/2020-07-10-14-33-52.bpo-41270.pjUqyd.rst @@ -1 +1 @@ -Made NamedTemporaryFile its own iterator to mimic file objects. \ No newline at end of file +Added :func:`tempfile._TemporaryFileWrapper.__next__` so that the object returned by :func:`tempfile.NamedTemporaryFile` can be used to iterate over the contents of the file.